SundanceDiscreteFunction.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
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   /* Case 1: u is a discrete function */
00220   if (df != 0)
00221   {
00222     Vector<double> dfVec = df->getVector().copy();
00223     return new DiscreteFunction(df->discreteSpace(), dfVec, name);
00224   }
00225 
00226   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00227    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00258   if (df != 0)
00259   {
00260     df->setVector(v);
00261     return;
00262   }
00263 
00264   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00265    * wrapper has gotten lost in list element dereferencing. */
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   /* At this point, the vector should be a block vector */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00295   if (df != 0)
00296   {
00297     return df->getVector();
00298   }
00299 
00300   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00301    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00330   if (df != 0)
00331   {
00332     return df->mesh();
00333   }
00334 
00335   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00336    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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   /* Case 1: u is a discrete function */
00360   if (df != 0)
00361   {
00362     return df->discreteSpace();
00363   }
00364 
00365   /* Case 2: u is an element of a length-one expression whose DiscreteFunction
00366    * wrapper has gotten lost in dereferencing. */
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   /* Case 3: u is a list of discrete functions */
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 

Site Contact