00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "SundanceDiscreteFunction.hpp"
00032 #include "SundanceOut.hpp"
00033 #include "PlayaTabs.hpp"
00034 #include "SundanceMaximalCellFilter.hpp"
00035 #include "SundanceCellFilter.hpp"
00036 #include "SundanceCellSet.hpp"
00037 #include "SundanceSubtypeEvaluator.hpp"
00038 #include "PlayaDefaultBlockVectorDecl.hpp"
00039 
00040 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00041 #include "PlayaVectorImpl.hpp"
00042 #include "PlayaDefaultBlockVectorImpl.hpp"
00043 #endif
00044 
00045 namespace Sundance
00046 {
00047 using namespace Teuchos;
00048 using std::string;
00049 using std::runtime_error;
00050 using std::endl;
00051 
00052 static Time& getLocalValsTimer() 
00053 {
00054   static RCP<Time> rtn 
00055     = TimeMonitor::getNewTimer("DF getLocalValues"); 
00056   return *rtn;
00057 }
00058 static Time& dfCtorTimer() 
00059 {
00060   static RCP<Time> rtn 
00061     = TimeMonitor::getNewTimer("DF ctor"); 
00062   return *rtn;
00063 }
00064 
00065 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00066   const string& name)
00067   : DiscreteFunctionStub(tuple(name), space.dimStructure(),
00068     getRCP(new DiscreteFunctionData(space))), 
00069     FuncWithBasis(space.basis()),
00070     data_()
00071 {
00072   TimeMonitor timer(dfCtorTimer());
00073   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00074 }
00075 
00076 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00077   const Array<string>& name)
00078   : DiscreteFunctionStub(name, space.dimStructure(),
00079     getRCP(new DiscreteFunctionData(space))), 
00080     FuncWithBasis(space.basis()),
00081     data_()
00082 {
00083   TimeMonitor timer(dfCtorTimer());
00084   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00085 }
00086 
00087 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00088   const double& constantValue,
00089   const string& name)
00090   : DiscreteFunctionStub(tuple(name), space.dimStructure(),
00091     getRCP(new DiscreteFunctionData(space, constantValue))), 
00092     FuncWithBasis(space.basis()),
00093     data_()
00094 {
00095   TimeMonitor timer(dfCtorTimer());
00096   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00097   Vector<double> vec = data_->getVector();
00098   vec.setToConstant(constantValue);
00099   data_->setVector(vec);
00100 }
00101 
00102 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00103   const double& constantValue,
00104   const Array<string>& name)
00105   : DiscreteFunctionStub(name, space.dimStructure(),
00106     getRCP(new DiscreteFunctionData(space, constantValue))), 
00107     FuncWithBasis(space.basis()),
00108     data_()
00109 {
00110   TimeMonitor timer(dfCtorTimer());
00111   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00112   Vector<double> vec = data_->getVector();
00113   vec.setToConstant(constantValue);
00114   data_->setVector(vec);
00115 }
00116 
00117 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00118   const Vector<double>& vec,
00119   const string& name)
00120   : DiscreteFunctionStub(tuple(name), space.dimStructure(),
00121     getRCP(new DiscreteFunctionData(space, vec))), 
00122     FuncWithBasis(space.basis()),
00123     data_()
00124 {
00125   TimeMonitor timer(dfCtorTimer());
00126   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00127 }
00128 
00129 DiscreteFunction::DiscreteFunction(const DiscreteSpace& space, 
00130   const Vector<double>& vec,
00131   const Array<string>& name)
00132   : DiscreteFunctionStub(name, space.dimStructure(),
00133     getRCP(new DiscreteFunctionData(space, vec))), 
00134     FuncWithBasis(space.basis()),
00135     data_()
00136 {
00137   TimeMonitor timer(dfCtorTimer());
00138   data_ = rcp_dynamic_cast<DiscreteFunctionData>(dataStub());
00139 }
00140 
00141 void DiscreteFunction::setVector(const Vector<double>& vec) 
00142 {
00143   data_->setVector(vec);
00144 }
00145 
00146 void DiscreteFunction::updateGhosts() const
00147 {
00148   data_->updateGhosts();
00149 }
00150 
00151 
00152 RCP<const MapStructure> DiscreteFunction::getLocalValues(int cellDim, 
00153   const Array<int>& cellLID,
00154   Array<Array<double> >& localValues) const 
00155 {
00156   TimeMonitor timer(getLocalValsTimer());
00157   return data_->getLocalValues(cellDim, cellLID, localValues);
00158 }
00159 
00160 
00161 const DiscreteFunction* DiscreteFunction::discFunc(const Expr& expr)
00162 {
00163   const ExprBase* e = expr.ptr().get();
00164   const DiscreteFunction* df 
00165     = dynamic_cast<const DiscreteFunction*>(e);
00166 
00167   TEUCHOS_TEST_FOR_EXCEPTION(df==0, runtime_error,
00168     "failed to cast " << expr << " to a discrete function. "
00169     "It appears to be of type " << e->typeName());
00170 
00171   return df;
00172 }
00173 
00174 
00175 
00176 DiscreteFunction* DiscreteFunction::discFunc(Expr& expr)
00177 {
00178   DiscreteFunction* df 
00179     = dynamic_cast<DiscreteFunction*>(expr.ptr().get());
00180 
00181   TEUCHOS_TEST_FOR_EXCEPTION(df==0, runtime_error,
00182     "failed to cast " << expr << " to a discrete function. "
00183     "It appears to be of type " << expr.ptr()->typeName());
00184 
00185   return df;
00186 }
00187 
00188 
00189 RCP<DiscreteFuncDataStub> DiscreteFunction::getRCP(DiscreteFunctionData* ptr)
00190 {
00191   return rcp_dynamic_cast<DiscreteFuncDataStub>(rcp(ptr));
00192 }
00193 
00194 
00195 
00196 
00197 
00198 void updateDiscreteFunction(const Expr& newVals, Expr old)
00199 {
00200   Vector<double> vIn = getDiscreteFunctionVector(newVals);
00201   Vector<double> vOut = getDiscreteFunctionVector(old);
00202 
00203   vOut.acceptCopyOf(vIn);
00204   setDiscreteFunctionVector(old, vOut);
00205 }
00206 
00207 void addVecToDiscreteFunction(Expr df, const Vector<double>& v)
00208 {
00209   Vector<double> dfVec = getDiscreteFunctionVector(df);
00210   dfVec.update(1.0, v);
00211   setDiscreteFunctionVector(df, dfVec);
00212 }
00213 
00214 Expr copyDiscreteFunction(const Expr& u0, const string& name)
00215 {
00216   const DiscreteFunction* df 
00217     = dynamic_cast<const DiscreteFunction*>(u0.ptr().get());
00218 
00219   
00220   if (df != 0)
00221   {
00222     Vector<double> dfVec = df->getVector().copy();
00223     return new DiscreteFunction(df->discreteSpace(), dfVec, name);
00224   }
00225 
00226   
00227 
00228   const DiscreteFuncElement* dfe 
00229     = dynamic_cast<const DiscreteFuncElement*>(u0.ptr().get());
00230   TEUCHOS_TEST_FOR_EXCEPTION(dfe!=0 && u0.size() > 1, runtime_error,
00231     "attempt to access vector of a single element of a multicomponent "
00232     "DiscreteFunction");
00233   if (dfe != 0)
00234   {
00235     Vector<double> dfVec 
00236       = DiscreteFunctionData::getData(dfe)->getVector().copy();
00237     return new DiscreteFunction(
00238       DiscreteFunctionData::getData(dfe)->discreteSpace(),
00239       dfVec, name);
00240   }
00241 
00242   
00243   Array<Expr> rtn(u0.size());
00244   for (int b=0; b<u0.size(); b++)
00245   {
00246     rtn[b] = copyDiscreteFunction(u0[b], 
00247       name + "[" + Teuchos::toString(b) + "]");
00248   }
00249   return new ListExpr(rtn);
00250 }
00251 
00252 void setDiscreteFunctionVector(Expr u, const Vector<double>& v)
00253 {
00254   DiscreteFunction* df 
00255     = dynamic_cast<DiscreteFunction*>(u.ptr().get());
00256 
00257   
00258   if (df != 0)
00259   {
00260     df->setVector(v);
00261     return;
00262   }
00263 
00264   
00265 
00266   DiscreteFuncElement* dfe 
00267     = dynamic_cast<DiscreteFuncElement*>(u.ptr().get());
00268   TEUCHOS_TEST_FOR_EXCEPTION(dfe!=0 && u.size() > 1, runtime_error,
00269     "attempt to set vector of a single element of a multicomponent "
00270     "DiscreteFunction");
00271   if (dfe != 0)
00272   {
00273     DiscreteFunctionData::getData(dfe)->setVector(v);
00274     return;
00275   }
00276 
00277   
00278   TEUCHOS_TEST_FOR_EXCEPTION((df==0 && dfe==0) && u.size()==1, 
00279     runtime_error,
00280     "non-block vector should be a discrete function in setDFVector()");
00281 
00282   
00283   for (int b=0; b<u.size(); b++)
00284   {
00285     setDiscreteFunctionVector(u[b], v.getBlock(b));
00286   }
00287 }
00288 
00289 Vector<double> getDiscreteFunctionVector(const Expr& u)
00290 {
00291   const DiscreteFunction* df 
00292     = dynamic_cast<const DiscreteFunction*>(u.ptr().get());
00293 
00294   
00295   if (df != 0)
00296   {
00297     return df->getVector();
00298   }
00299 
00300   
00301 
00302   const DiscreteFuncElement* dfe 
00303     = dynamic_cast<const DiscreteFuncElement*>(u.ptr().get());
00304   TEUCHOS_TEST_FOR_EXCEPTION(dfe!=0 && u.size() > 1, runtime_error,
00305     "attempt to access vector of a single element of a multicomponent "
00306     "DiscreteFunction");
00307   if (dfe != 0)
00308   {
00309     return DiscreteFunctionData::getData(dfe)->getVector();
00310   }
00311 
00312   
00313   TEUCHOS_TEST_FOR_EXCEPTION(df==0 && u.size()==1, runtime_error,
00314     "non-block vector should be a discrete function in getDiscreteFunctionVector()");
00315   Array<Vector<double> > vec(u.size());
00316   for (int b=0; b<u.size(); b++)
00317   {
00318     vec[b] = getDiscreteFunctionVector(u[b]);
00319   }
00320   return blockVector(vec);
00321 }
00322 
00323 
00324 Mesh getDiscreteFunctionMesh(const Expr& u)
00325 {
00326   const DiscreteFunction* df 
00327     = dynamic_cast<const DiscreteFunction*>(u.ptr().get());
00328 
00329   
00330   if (df != 0)
00331   {
00332     return df->mesh();
00333   }
00334 
00335   
00336 
00337   const DiscreteFuncElement* dfe 
00338     = dynamic_cast<const DiscreteFuncElement*>(u.ptr().get());
00339   TEUCHOS_TEST_FOR_EXCEPTION(dfe!=0 && u.size() > 1, runtime_error,
00340     "attempt to access vector of a single element of a multicomponent "
00341     "DiscreteFunction");
00342   if (dfe != 0)
00343   {
00344     return DiscreteFunctionData::getData(dfe)->mesh();
00345   }
00346 
00347   
00348   TEUCHOS_TEST_FOR_EXCEPTION(df==0 && u.size()==1, runtime_error,
00349     "non-block vector should be a discrete function in getDiscreteFunctionVector()");
00350   return getDiscreteFunctionMesh(u[0]);
00351 }
00352 
00353 
00354 DiscreteSpace getDiscreteSpace(const Expr& u)
00355 {
00356   const DiscreteFunction* df 
00357     = dynamic_cast<const DiscreteFunction*>(u.ptr().get());
00358 
00359   
00360   if (df != 0)
00361   {
00362     return df->discreteSpace();
00363   }
00364 
00365   
00366 
00367   const DiscreteFuncElement* dfe 
00368     = dynamic_cast<const DiscreteFuncElement*>(u.ptr().get());
00369   TEUCHOS_TEST_FOR_EXCEPTION(dfe!=0 && u.size() > 1, runtime_error,
00370     "attempt to access vector of a single element of a multicomponent "
00371     "DiscreteFunction");
00372   if (dfe != 0)
00373   {
00374     return DiscreteFunctionData::getData(dfe)->discreteSpace();
00375   }
00376 
00377   
00378   TEUCHOS_TEST_FOR_EXCEPTION(df==0 && u.size()==1, runtime_error,
00379     "non-block vector should be a discrete function in getDiscreteFunctionVector()");
00380   return getDiscreteSpace(u[0]);
00381 }
00382 
00383 
00384 }
00385