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