SundanceDiscreteFunction.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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   /* Case 1: u is a discrete function */
00231   if (df != 0)
00232   {
00233     Vector<double> dfVec = df->getVector().copy();
00234     return new DiscreteFunction(df->discreteSpace(), dfVec, name);
00235   }
00236 
00237   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00238    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00269   if (df != 0)
00270   {
00271     df->setVector(v);
00272     return;
00273   }
00274 
00275   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00276    * wrapper has gotten lost in list element dereferencing. */
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   /* At this point, the vector should be a block vector */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00306   if (df != 0)
00307   {
00308     return df->getVector();
00309   }
00310 
00311   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00312    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00341   if (df != 0)
00342   {
00343     return df->mesh();
00344   }
00345 
00346   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00347    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00371   if (df != 0)
00372   {
00373     return df->discreteSpace();
00374   }
00375 
00376   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00377    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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 

Site Contact