SundanceIntegralGroup.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 "SundanceIntegralGroup.hpp"
00032 #include "SundanceRefIntegral.hpp"
00033 #include "SundanceQuadratureIntegral.hpp"
00034 #include "SundanceMaximalQuadratureIntegral.hpp"
00035 #include "SundanceCurveQuadratureIntegral.hpp"
00036 #include "SundanceOut.hpp"
00037 #include "SundanceTabs.hpp"
00038 #include "Teuchos_TimeMonitor.hpp"
00039 
00040 using namespace Sundance;
00041 using namespace Teuchos;
00042 
00043 
00044 static Time& integrationTimer() 
00045 {
00046   static RCP<Time> rtn 
00047     = TimeMonitor::getNewTimer("integration"); 
00048   return *rtn;
00049 }
00050 
00051 
00052 IntegralGroup
00053 ::IntegralGroup(const Array<RCP<ElementIntegral> >& integrals,
00054   const Array<int>& resultIndices,
00055   int verb)
00056   : integrationVerb_(findIntegrationVerb(integrals)),
00057     transformVerb_(findTransformVerb(integrals)),
00058     order_(0),
00059     nTestNodes_(0),
00060     nUnkNodes_(0),
00061     testID_(),
00062     unkID_(),
00063     testBlock_(),
00064     unkBlock_(),
00065     mvIndices_(),
00066     integrals_(integrals),
00067     resultIndices_(resultIndices),
00068     termUsesMaximalCofacets_(integrals_.size()),
00069     requiresMaximalCofacet_(SomeTermsNeedCofacets),
00070     derivs_()
00071 {
00072   Tabs tab;
00073   SUNDANCE_MSG2(verb, tab << "forming 0-form integral group");
00074   bool allReqMaximalCofacets = true;
00075   bool noneReqMaximalCofacets = true;
00076   bool someReqMaximalCofacets = false;
00077 
00078   for (int i=0; i<integrals_.size(); i++)
00079   {
00080     Tabs tab1;
00081     SUNDANCE_MSG2(verb, tab1 << "integral #" << i << ", numFacetCases="
00082       << integrals[i]->nFacetCases());
00083     if (integrals[i]->nFacetCases() > 1) 
00084     {
00085       Tabs tab2;
00086       someReqMaximalCofacets = true;
00087       noneReqMaximalCofacets = false;
00088       termUsesMaximalCofacets_[i] = true;
00089       SUNDANCE_MSG2(verb, tab2 << "I need maximal cofacets");
00090     }
00091     else
00092     {
00093       Tabs tab2;
00094       allReqMaximalCofacets = false;
00095       termUsesMaximalCofacets_[i] = false;
00096       SUNDANCE_MSG2(verb, tab2 << "I do not need maximal cofacets");
00097     }
00098   }
00099 
00100   if (allReqMaximalCofacets) 
00101   {
00102     requiresMaximalCofacet_ = AllTermsNeedCofacets;
00103   }
00104   else if (noneReqMaximalCofacets) 
00105   {
00106     requiresMaximalCofacet_ = NoTermsNeedCofacets;
00107   }
00108   
00109   Tabs tab1;
00110   SUNDANCE_MSG2(verb, tab1 << "result=" << requiresMaximalCofacet_);
00111 }
00112 
00113 
00114 
00115 
00116 IntegralGroup
00117 ::IntegralGroup(const Array<int>& testID,
00118   const Array<int>& testBlock,
00119   const Array<int>& mvIndices,
00120   const Array<RCP<ElementIntegral> >& integrals,
00121   const Array<int>& resultIndices,
00122   const Array<MultipleDeriv>& derivs,
00123   int verb)
00124   : integrationVerb_(findIntegrationVerb(integrals)),
00125     transformVerb_(findTransformVerb(integrals)),
00126     order_(1),
00127     nTestNodes_(0),
00128     nUnkNodes_(0),
00129     testID_(testID),
00130     unkID_(),
00131     testBlock_(testBlock),
00132     unkBlock_(),
00133     mvIndices_(mvIndices),
00134     integrals_(integrals),
00135     resultIndices_(resultIndices),
00136     termUsesMaximalCofacets_(integrals_.size()),
00137     requiresMaximalCofacet_(SomeTermsNeedCofacets),
00138     derivs_(derivs)
00139 {
00140   Tabs tab;
00141   SUNDANCE_MSG2(verb, tab << "forming 1-form integral group");
00142   bool allReqMaximalCofacets = true;
00143   bool noneReqMaximalCofacets = true;
00144   bool someReqMaximalCofacets = false;
00145 
00146   for (int i=0; i<integrals.size(); i++)
00147   {
00148     int nt = integrals[i]->nNodesTest();
00149     if (i > 0) 
00150     {
00151       TEST_FOR_EXCEPTION(nt != nTestNodes_, InternalError,
00152         "IntegralGroup ctor detected integrals with inconsistent numbers of test nodes");
00153     }
00154     Tabs tab1;
00155     SUNDANCE_MSG2(verb, tab1 << "integral #" << i << ", numFacetCases="
00156       << integrals[i]->nFacetCases());
00157     nTestNodes_ = nt;
00158     if (integrals[i]->nFacetCases() > 1) 
00159     {
00160       Tabs tab2;
00161       SUNDANCE_MSG2(verb, tab2 << "I need maximal cofacets");
00162       someReqMaximalCofacets = true;
00163       noneReqMaximalCofacets = false;
00164       termUsesMaximalCofacets_[i] = true;
00165     }
00166     else
00167     {
00168       Tabs tab2;
00169       SUNDANCE_MSG2(verb, tab2 << "I do not need maximal cofacets");
00170       allReqMaximalCofacets = false;
00171       termUsesMaximalCofacets_[i] = false;
00172     }
00173   }
00174 
00175   if (allReqMaximalCofacets) 
00176   {
00177     requiresMaximalCofacet_ = AllTermsNeedCofacets;
00178   }
00179   else if (noneReqMaximalCofacets) 
00180   {
00181     requiresMaximalCofacet_ = NoTermsNeedCofacets;
00182   }
00183   
00184   Tabs tab1;
00185   SUNDANCE_MSG2(verb, tab1 << "result=" << requiresMaximalCofacet_);
00186 }
00187 
00188 IntegralGroup
00189 ::IntegralGroup(const Array<int>& testID,
00190   const Array<int>& testBlock,
00191   const Array<int>& unkID,
00192   const Array<int>& unkBlock,
00193   const Array<RCP<ElementIntegral> >& integrals,
00194   const Array<int>& resultIndices,
00195   const Array<MultipleDeriv>& derivs,
00196   int verb)
00197   : integrationVerb_(findIntegrationVerb(integrals)),
00198     transformVerb_(findTransformVerb(integrals)),
00199     order_(2),
00200     nTestNodes_(0),
00201     nUnkNodes_(0),
00202     testID_(testID),
00203     unkID_(unkID),
00204     testBlock_(testBlock),
00205     unkBlock_(unkBlock),
00206     mvIndices_(),
00207     integrals_(integrals),
00208     resultIndices_(resultIndices),
00209     termUsesMaximalCofacets_(integrals_.size()),
00210     requiresMaximalCofacet_(SomeTermsNeedCofacets),
00211     derivs_(derivs)
00212 {
00213   Tabs tab;
00214   SUNDANCE_MSG2(verb, tab << "forming 2-form integral group");
00215   bool allReqMaximalCofacets = true;
00216   bool noneReqMaximalCofacets = true;
00217   bool someReqMaximalCofacets = false;
00218 
00219   for (int i=0; i<integrals.size(); i++)
00220   {
00221     Tabs tab1;
00222     SUNDANCE_MSG2(verb, tab1 << "integral #" << i << ", numFacetCases="
00223       << integrals[i]->nFacetCases());
00224     int nt = integrals[i]->nNodesTest();
00225     int nu = integrals[i]->nNodesUnk();
00226     if (i > 0) 
00227     {
00228       TEST_FOR_EXCEPTION(nt != nTestNodes_, InternalError,
00229         "IntegralGroup ctor detected integrals with inconsistent numbers of test nodes");
00230       TEST_FOR_EXCEPTION(nu != nUnkNodes_, InternalError,
00231         "IntegralGroup ctor detected integrals with inconsistent numbers of unk nodes");
00232     }
00233     nTestNodes_ = nt;
00234     nUnkNodes_ = nu;
00235 
00236     if (integrals[i]->nFacetCases() > 1) 
00237     {
00238       someReqMaximalCofacets = true;
00239       noneReqMaximalCofacets = false;
00240       termUsesMaximalCofacets_[i] = true;
00241       Tabs tab2;
00242       SUNDANCE_MSG2(verb, tab2 << "I need maximal cofacets");
00243     }
00244     else
00245     {
00246       allReqMaximalCofacets = false;
00247       termUsesMaximalCofacets_[i] = false;
00248       Tabs tab2;
00249       SUNDANCE_MSG2(verb, tab2 << "I do not need maximal cofacets");
00250     }
00251   }
00252 
00253   if (allReqMaximalCofacets) 
00254   {
00255     requiresMaximalCofacet_ = AllTermsNeedCofacets;
00256   }
00257   else if (noneReqMaximalCofacets) 
00258   {
00259     requiresMaximalCofacet_ = NoTermsNeedCofacets;
00260   }
00261   
00262   Tabs tab1;
00263   SUNDANCE_MSG2(verb, tab1 << "result=" << requiresMaximalCofacet_);
00264 }
00265 
00266 
00267 bool IntegralGroup
00268 ::evaluate(const CellJacobianBatch& JTrans,
00269   const CellJacobianBatch& JVol,
00270   const Array<int>& isLocalFlag, 
00271   const Array<int>& facetIndex, 
00272   const RCP<Array<int> >& cellLIDs,
00273   const Array<RCP<EvalVector> >& vectorCoeffs,
00274   const Array<double>& constantCoeffs,
00275   RCP<Array<double> >& A) const
00276 {
00277   TimeMonitor timer(integrationTimer());
00278   Tabs tab0(0);
00279 
00280 
00281   SUNDANCE_MSG1(integrationVerb(), tab0 << "evaluating integral group with "
00282     << integrals_.size() << " integrals");
00283 
00284   SUNDANCE_MSG3(integrationVerb(), 
00285     tab0 << "num integration cells = " << JVol.numCells());
00286   SUNDANCE_MSG3(integrationVerb(), 
00287     tab0 << "num nodes in output = " << integrals_[0]->nNodes());
00288 
00289   /* initialize the return vector */
00290   if (integrals_[0]->nNodes() == -1) A->resize(1);
00291   else A->resize(JVol.numCells() * integrals_[0]->nNodes());
00292   double* aPtr = &((*A)[0]);
00293   int n = A->size();
00294   for (int i=0; i<n; i++) aPtr[i] = 0.0;
00295 
00296   SUNDANCE_MSG5(integrationVerb(), tab0 << "begin A=");
00297   if (integrationVerb() >=5) writeTable(Out::os(), tab0, *A, 6);
00298 
00299   /* do the integrals */
00300   for (int i=0; i<integrals_.size(); i++)
00301   {
00302     Tabs tab1;
00303     SUNDANCE_MSG1(integrationVerb(), tab1 << "group member i=" << i 
00304       << " of " << integrals_.size());
00305     Tabs tab2;
00306 
00307     const RefIntegral* ref 
00308       = dynamic_cast<const RefIntegral*>(integrals_[i].get());
00309     const QuadratureIntegral* quad 
00310       = dynamic_cast<const QuadratureIntegral*>(integrals_[i].get());
00311     const MaximalQuadratureIntegral* maxQuad 
00312       = dynamic_cast<const MaximalQuadratureIntegral*>(integrals_[i].get());
00313     const CurveQuadratureIntegral* curveQuad
00314       = dynamic_cast<const CurveQuadratureIntegral*>(integrals_[i].get());
00315 
00316     if (ref!=0)
00317     {
00318       SUNDANCE_MSG2(integrationVerb(),
00319         tab2 << "Integrating term group " << i 
00320         << " by transformed reference integral");
00321       double f = constantCoeffs[resultIndices_[i]];
00322       SUNDANCE_MSG2(integrationVerb(),
00323         tab2 << "Coefficient is " << f);
00324       ref->transform(JTrans, JVol, isLocalFlag, facetIndex, cellLIDs , f, A);
00325     }
00326     else if (quad != 0)
00327     {
00328       SUNDANCE_MSG2(integrationVerb(),
00329         tab2 << "Integrating term group " << i 
00330         << " by quadrature");
00331           
00332       TEST_FOR_EXCEPTION(vectorCoeffs[resultIndices_[i]]->length()==0,
00333         InternalError,
00334         "zero-length coeff vector detected in "
00335         "quadrature integration branch of "
00336         "IntegralGroup::evaluate(). std::string value is ["
00337         << vectorCoeffs[resultIndices_[i]]->str()
00338         << "]");
00339 
00340       Tabs tab3;
00341       SUNDANCE_MSG3(integrationVerb(),
00342         tab3 << "coefficients are " <<  vectorCoeffs[resultIndices_[i]]->str());
00343 
00344       const double* const f = vectorCoeffs[resultIndices_[i]]->start();
00345       quad->transform(JTrans, JVol, isLocalFlag, facetIndex, cellLIDs , f, A);
00346     }
00347     else if (maxQuad != 0)
00348     {
00349       SUNDANCE_MSG2(integrationVerb(),
00350         tab2 << "Integrating term group " << i 
00351         << " by quadrature");
00352           
00353       TEST_FOR_EXCEPTION(vectorCoeffs[resultIndices_[i]]->length()==0,
00354         InternalError,
00355         "zero-length coeff vector detected in "
00356         "quadrature integration branch of "
00357         "IntegralGroup::evaluate(). std::string value is ["
00358         << vectorCoeffs[resultIndices_[i]]->str()
00359         << "]");
00360 
00361       Tabs tab3;
00362       SUNDANCE_MSG3(integrationVerb(),
00363         tab3 << "coefficients are " <<  vectorCoeffs[resultIndices_[i]]->str());
00364 
00365       const double* const f = vectorCoeffs[resultIndices_[i]]->start();
00366       maxQuad->transform(JTrans, JVol, isLocalFlag, facetIndex, cellLIDs , f, A);
00367     }
00368     else if (curveQuad != 0)
00369     {
00370         SUNDANCE_MSG2(integrationVerb(),
00371           tab2 << "Integrating term group " << i
00372           << " by curve integral (quadrature by default) , result index: " << resultIndices_[i]);
00373 
00374         double f_const = 0.0;
00375         if (constantCoeffs.size() > resultIndices_[i]){
00376           f_const = constantCoeffs[resultIndices_[i]];
00377         }
00378 
00379         SUNDANCE_MSG2(integrationVerb(),
00380           tab2 << "Coefficient is " << f_const);
00381 
00382         // set this
00383         if (vectorCoeffs.size() > resultIndices_[i]){
00384             Tabs tab3;
00385             double* const f = vectorCoeffs[resultIndices_[i]]->start();
00386           SUNDANCE_MSG3(integrationVerb(),
00387               tab3 << "coefficients are " <<  vectorCoeffs[resultIndices_[i]]->str());
00388             curveQuad->transform(JTrans, JVol, isLocalFlag, facetIndex, cellLIDs , f_const , f , A);
00389         } else{
00390             const double* f_null = 0;
00391             curveQuad->transform(JTrans, JVol, isLocalFlag, facetIndex, cellLIDs , f_const , f_null , A);
00392         }
00393 
00394     }
00395     else
00396     {
00397       TEST_FOR_EXCEPT(1);
00398     }
00399 
00400     SUNDANCE_MSG4(integrationVerb(),
00401       tab1 << "i=" << i << " integral values=");
00402     if (integrationVerb() >=4) writeTable(Out::os(), tab1, *A, 6);
00403   }
00404   SUNDANCE_MSG1(integrationVerb(), tab0 << "done integral group");
00405 
00406   return true;
00407 }
00408 
00409 
00410 int IntegralGroup::findIntegrationVerb(const Array<RCP<ElementIntegral> >& integrals) const
00411 {
00412   int rtn = 0;
00413   for (int i=0; i<integrals.size(); i++)
00414   {
00415     rtn = std::max(rtn, integrals[i]->integrationVerb());
00416   }
00417   return rtn;
00418 }
00419 
00420 
00421 int IntegralGroup::findTransformVerb(const Array<RCP<ElementIntegral> >& integrals) const
00422 {
00423   int rtn = 0;
00424   for (int i=0; i<integrals.size(); i++)
00425   {
00426     rtn = std::max(rtn, integrals[i]->transformVerb());
00427   }
00428   return rtn;
00429 }

Site Contact