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