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