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 "SundanceMaximalQuadratureIntegral.hpp"
00043 #include "SundanceGaussianQuadrature.hpp"
00044 #include "SundanceSpatialDerivSpecifier.hpp"
00045 #include "SundanceOut.hpp"
00046 #include "PlayaTabs.hpp"
00047 #include "Teuchos_TimeMonitor.hpp"
00048
00049 using namespace Sundance;
00050 using namespace Teuchos;
00051
00052 using std::endl;
00053 using std::setw;
00054 using std::setprecision;
00055
00056 extern "C"
00057 {
00058 int dgemm_(const char* transA, const char* transB,
00059 const int* M, const int *N, const int* K,
00060 const double* alpha,
00061 const double* A, const int* ldA,
00062 const double* B, const int* ldB,
00063 const double* beta,
00064 double* C, const int* ldC);
00065 }
00066
00067 static Time& maxCellQuadrature0Timer()
00068 {
00069 static RCP<Time> rtn
00070 = TimeMonitor::getNewTimer("max cell 0-form quadrature");
00071 return *rtn;
00072 }
00073
00074 static Time& maxCellQuadrature1Timer()
00075 {
00076 static RCP<Time> rtn
00077 = TimeMonitor::getNewTimer("max cell 1-form quadrature");
00078 return *rtn;
00079 }
00080
00081 static Time& maxCellQuadrature2Timer()
00082 {
00083 static RCP<Time> rtn
00084 = TimeMonitor::getNewTimer("max cell 2-form quadrature");
00085 return *rtn;
00086 }
00087
00088
00089 MaximalQuadratureIntegral::MaximalQuadratureIntegral(
00090 const CellType& cellType,
00091 const QuadratureFamily& quad,
00092 const ParametrizedCurve& globalCurve,
00093 const Mesh& mesh,
00094 int verb)
00095 : ElementIntegral(dimension(cellType), cellType, dimension(cellType),
00096 cellType, true, globalCurve, mesh, verb),
00097 quad_(quad),
00098 quadPts_(),
00099 quadWeights_(),
00100 W_(),
00101 useSumFirstMethod_(true)
00102 {
00103 Tabs tab0(0);
00104
00105 SUNDANCE_MSG1(setupVerb(), tab0 << "MaximalQuadratureIntegral ctor for 0-form");
00106 if (setupVerb()) describe(Out::os());
00107
00108 SUNDANCE_MSG1(setupVerb(), tab0 << "quadrature family=" << quad);
00109
00110
00111 quad.getPoints(cellType, quadPts_, quadWeights_);
00112 int nQuad = quadPts_.size();
00113
00114 W_.resize(nQuad);
00115
00116 for (int q=0; q<nQuad; q++)
00117 {
00118 W_[q] = quadWeights_[q];
00119 }
00120 }
00121
00122
00123 MaximalQuadratureIntegral::MaximalQuadratureIntegral(
00124 const CellType& cellType,
00125 const BasisFamily& testBasis,
00126 int alpha,
00127 int testDerivOrder,
00128 const QuadratureFamily& quad,
00129 const ParametrizedCurve& globalCurve,
00130 const Mesh& mesh,
00131 int verb)
00132 : ElementIntegral(dimension(cellType), cellType, dimension(cellType),
00133 cellType, testBasis,
00134 alpha, testDerivOrder, true, globalCurve, mesh, verb),
00135 quad_(quad),
00136 quadPts_(),
00137 quadWeights_(),
00138 W_(),
00139 useSumFirstMethod_(true)
00140 {
00141 Tabs tab0(0);
00142
00143 SUNDANCE_MSG1(setupVerb(), tab0 << "MaximalQuadratureIntegral ctor for 1-form");
00144 if (setupVerb()) describe(Out::os());
00145 assertLinearForm();
00146
00147
00148 SUNDANCE_MSG1(setupVerb(), tab0 << "quadrature family=" << quad);
00149
00150 quad.getPoints(cellType, quadPts_, quadWeights_);
00151 int nQuad = quadPts_.size();
00152
00153 W_.resize(nQuad * nRefDerivTest() * nNodesTest());
00154
00155 SUNDANCE_MSG1(setupVerb(), tab0 << "num nodes for test function " << nNodesTest());
00156
00157 Array<Array<Array<Array<double> > > > testBasisVals(nRefDerivTest());
00158
00159 for (int r=0; r<nRefDerivTest(); r++)
00160 {
00161 Tabs tab3;
00162 SUNDANCE_MSG1(setupVerb(), tab3
00163 << "evaluating basis functions for ref deriv direction " << r);
00164 MultiIndex mi;
00165 testBasisVals[r].resize(testBasis.dim());
00166 if (testDerivOrder==1) mi[r] = 1;
00167 SpatialDerivSpecifier deriv(mi);
00168 testBasis.refEval(evalCellType(), quadPts_, deriv,
00169 testBasisVals[r], setupVerb());
00170 }
00171
00172 int vecComp = 0;
00173 W_ACI_F1_.resize(nQuad);
00174 for (int q=0; q<nQuad; q++)
00175 {
00176 W_ACI_F1_[q].resize(nRefDerivTest());
00177 for (int t=0; t<nRefDerivTest(); t++)
00178 {
00179 W_ACI_F1_[q][t].resize(nNodesTest());
00180 for (int nt=0; nt<nNodesTest(); nt++)
00181 {
00182 wValue(q, t, nt)
00183 = chop(quadWeights_[q] * testBasisVals[t][vecComp][q][nt]) ;
00184 W_ACI_F1_[q][t][nt] = chop(testBasisVals[t][vecComp][q][nt]);
00185 }
00186 }
00187 }
00188
00189 addFlops(2*nQuad*nRefDerivTest()*nNodesTest());
00190 }
00191
00192
00193
00194
00195 MaximalQuadratureIntegral::MaximalQuadratureIntegral(
00196 const CellType& cellType,
00197 const BasisFamily& testBasis,
00198 int alpha,
00199 int testDerivOrder,
00200 const BasisFamily& unkBasis,
00201 int beta,
00202 int unkDerivOrder,
00203 const QuadratureFamily& quad,
00204 const ParametrizedCurve& globalCurve,
00205 const Mesh& mesh,
00206 int verb)
00207 : ElementIntegral(dimension(cellType), cellType, dimension(cellType),
00208 cellType, testBasis,
00209 alpha, testDerivOrder, unkBasis, beta, unkDerivOrder, true,
00210 globalCurve, mesh,
00211 verb),
00212 quad_(quad),
00213 quadPts_(),
00214 quadWeights_(),
00215 W_(),
00216 useSumFirstMethod_(true)
00217 {
00218 Tabs tab0(0);
00219
00220 SUNDANCE_MSG1(setupVerb(), tab0 << "MaximalQuadratureIntegral ctor for 2-form");
00221 if (setupVerb()) describe(Out::os());
00222 assertBilinearForm();
00223
00224
00225 quad.getPoints(cellType, quadPts_, quadWeights_);
00226 int nQuad = quadPts_.size();
00227
00228 W_.resize(nQuad * nRefDerivTest() * nNodesTest()
00229 * nRefDerivUnk() * nNodesUnk());
00230
00231
00232
00233 Array<Array<Array<Array<double> > > > testBasisVals(nRefDerivTest());
00234 Array<Array<Array<Array<double> > > > unkBasisVals(nRefDerivUnk());
00235
00236
00237 for (int r=0; r<nRefDerivTest(); r++)
00238 {
00239 testBasisVals[r].resize(testBasis.dim());
00240 MultiIndex mi;
00241 if (testDerivOrder==1) mi[r] = 1;
00242 SpatialDerivSpecifier deriv(mi);
00243 testBasis.refEval(evalCellType(), quadPts_, deriv,
00244 testBasisVals[r], setupVerb());
00245 }
00246
00247 for (int r=0; r<nRefDerivUnk(); r++)
00248 {
00249 unkBasisVals[r].resize(unkBasis.dim());
00250 MultiIndex mi;
00251 if (unkDerivOrder==1) mi[r] = 1;
00252 SpatialDerivSpecifier deriv(mi);
00253 unkBasis.refEval(evalCellType(),
00254 quadPts_, deriv, unkBasisVals[r], setupVerb());
00255 }
00256
00257
00258 int vecComp = 0;
00259
00260 W_ACI_F2_.resize(nQuad);
00261 for (int q=0; q<nQuad; q++)
00262 {
00263 W_ACI_F2_[q].resize(nRefDerivTest());
00264 for (int t=0; t<nRefDerivTest(); t++)
00265 {
00266 W_ACI_F2_[q][t].resize(nNodesTest());
00267 for (int nt=0; nt<nNodesTest(); nt++)
00268 {
00269 W_ACI_F2_[q][t][nt].resize(nRefDerivUnk());
00270 for (int u=0; u<nRefDerivUnk(); u++)
00271 {
00272 W_ACI_F2_[q][t][nt][u].resize(nNodesUnk());
00273 for (int nu=0; nu<nNodesUnk(); nu++)
00274 {
00275 wValue(q, t, nt, u, nu)
00276 = chop(quadWeights_[q] * testBasisVals[t][vecComp][q][nt]
00277 * unkBasisVals[u][vecComp][q][nu]);
00278 W_ACI_F2_[q][t][nt][u][nu] =
00279 chop(testBasisVals[t][vecComp][q][nt] * unkBasisVals[u][vecComp][q][nu]);
00280 }
00281 }
00282 }
00283 }
00284 }
00285
00286 addFlops(3*nQuad*nRefDerivTest()*nNodesTest()*nRefDerivUnk()*nNodesUnk()
00287 + W_.size());
00288 for (int i=0; i<W_.size(); i++) W_[i] = chop(W_[i]);
00289
00290 }
00291
00292
00293 void MaximalQuadratureIntegral
00294 ::transformZeroForm(const CellJacobianBatch& JTrans,
00295 const CellJacobianBatch& JVol,
00296 const Array<int>& isLocalFlag,
00297 const Array<int>& facetIndex,
00298 const RCP<Array<int> >& cellLIDs,
00299 const double* const coeff,
00300 RCP<Array<double> >& A) const
00301 {
00302 TimeMonitor timer(maxCellQuadrature0Timer());
00303 Tabs tabs;
00304 SUNDANCE_MSG1(integrationVerb(), tabs << "doing zero form by quadrature");
00305
00306 TEUCHOS_TEST_FOR_EXCEPTION(order() != 0, std::logic_error,
00307 "MaximalQuadratureIntegral::transformZeroForm() called "
00308 "for form of order " << order());
00309
00310 TEUCHOS_TEST_FOR_EXCEPTION( (int) isLocalFlag.size() != 0
00311 && (int) isLocalFlag.size() != JVol.numCells(),
00312 std::runtime_error,
00313 "mismatch between isLocalFlag.size()=" << isLocalFlag.size()
00314 << " and JVol.numCells()=" << JVol.numCells());
00315
00316 bool checkLocalFlag = (int) isLocalFlag.size() != 0;
00317
00318 const Array<int>* cellLID = cellLIDs.get();
00319 int nQuad = quadWeights_.size();
00320
00321
00322 double& a = (*A)[0];
00323 SUNDANCE_MSG5(integrationVerb(), tabs << "input A=");
00324 if (integrationVerb() >= 5) writeTable(Out::os(), tabs, *A, 6);
00325 double* coeffPtr = (double*) coeff;
00326 const Array<double>& w = W_;
00327
00328 if (globalCurve().isCurveValid())
00329 {
00330 Array<double> quadWeightsTmp = quadWeights_;
00331 Array<Point> quadPointsTmp = quadPts_;
00332 int fc = 0;
00333 bool isCutByCurve;
00334
00335 for (int c=0; c<JVol.numCells(); c++)
00336 {
00337 if (checkLocalFlag && !isLocalFlag[c])
00338 {
00339 coeffPtr += nQuad;
00340 continue;
00341 }
00342 double detJ = fabs(JVol.detJ()[c]);
00343
00344 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c], fc ,mesh(),
00345 globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00346
00347 if (isCutByCurve)
00348 {
00349 for (int q=0; q<nQuad; q++, coeffPtr++)
00350 {
00351 a += quadWeightsTmp[q]*(*coeffPtr)*detJ;
00352 }
00353 }
00354 else
00355 {
00356 for (int q=0; q<nQuad; q++, coeffPtr++)
00357 {
00358 a += w[q]*(*coeffPtr)*detJ;
00359 }
00360 }
00361 }
00362 }
00363 else
00364 {
00365 for (int c=0; c<JVol.numCells(); c++)
00366 {
00367 if (checkLocalFlag && !isLocalFlag[c])
00368 {
00369 coeffPtr += nQuad;
00370 continue;
00371 }
00372 double detJ = fabs(JVol.detJ()[c]);
00373
00374 for (int q=0; q<nQuad; q++, coeffPtr++)
00375 {
00376 a += w[q]*(*coeffPtr)*detJ;
00377 }
00378 }
00379 }
00380 SUNDANCE_MSG5(integrationVerb(), tabs << "output A = ");
00381 if (integrationVerb() >= 5) writeTable(Out::os(), tabs, *A, 6);
00382
00383 SUNDANCE_MSG1(integrationVerb(), tabs << "done zero form");
00384 }
00385
00386
00387 void MaximalQuadratureIntegral::transformOneForm(const CellJacobianBatch& JTrans,
00388 const CellJacobianBatch& JVol,
00389 const Array<int>& facetIndex,
00390 const RCP<Array<int> >& cellLIDs,
00391 const double* const coeff,
00392 RCP<Array<double> >& A) const
00393 {
00394 TimeMonitor timer(maxCellQuadrature1Timer());
00395 Tabs tabs;
00396 TEUCHOS_TEST_FOR_EXCEPTION(order() != 1, std::logic_error,
00397 "MaximalQuadratureIntegral::transformOneForm() called for form "
00398 "of order " << order());
00399 SUNDANCE_MSG2(integrationVerb(), tabs << "doing one form by quadrature");
00400 int flops = 0;
00401 const Array<int>* cellLID = cellLIDs.get();
00402
00403 int nQuad = quadWeights_.size();
00404
00405
00406
00407
00408 if (testDerivOrder() == 0)
00409 {
00410 double* aPtr = &((*A)[0]);
00411 SUNDANCE_MSG5(integrationVerb(), tabs << "input A = ");
00412 if (integrationVerb() >= 5) writeTable(Out::os(), tabs, *A, 6);
00413
00414 double* coeffPtr = (double*) coeff;
00415 int offset = 0 ;
00416 const Array<double>& w = W_;
00417
00418 if (globalCurve().isCurveValid())
00419 {
00420 Array<double> quadWeightsTmp = quadWeights_;
00421 Array<Point> quadPointsTmp = quadPts_;
00422 bool isCutByCurve;
00423
00424 for (int c=0; c<JVol.numCells(); c++, offset+=nNodes())
00425 {
00426 Tabs tab2;
00427 double detJ = fabs(JVol.detJ()[c]);
00428 int fc = 0;
00429
00430 SUNDANCE_MSG4(integrationVerb(), tab2 << "c=" << c << " detJ=" << detJ);
00431
00432
00433 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c] , fc ,
00434 mesh() , globalCurve() , quadPointsTmp , quadWeightsTmp , isCutByCurve );
00435 if (isCutByCurve)
00436 {
00437 Array<double> wi;
00438 wi.resize(nQuad * nNodes());
00439 for (int ii = 0 ; ii < wi.size() ; ii++ ) wi[ii] = 0.0;
00440 for (int n = 0 ; n < nNodes() ; n++)
00441 {
00442 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00443 {
00444
00445 wi[n + nNodes()*q] +=
00446 chop(quadWeightsTmp[q] * W_ACI_F1_[q][0][n]);
00447 }
00448 }
00449
00450 for (int q=0; q<nQuad; q++, coeffPtr++)
00451 {
00452 double f = (*coeffPtr)*detJ;
00453 for (int n=0; n<nNodes(); n++)
00454 {
00455 aPtr[offset+n] += f*wi[n + nNodes()*q];
00456 }
00457 }
00458 }
00459 else
00460 {
00461 for (int q=0; q<nQuad; q++, coeffPtr++)
00462 {
00463 double f = (*coeffPtr)*detJ;
00464 for (int n=0; n<nNodes(); n++)
00465 {
00466 aPtr[offset+n] += f*w[n + nNodes()*q];
00467 }
00468 }
00469 }
00470
00471 if (integrationVerb() >= 4)
00472 {
00473 Out::os() << tab2 << "integration results on cell:" << std::endl;
00474 Out::os() << tab2 << setw(10) << "n" << setw(12) << "I_n" << std::endl;
00475 for (int n=0; n<nNodes(); n++)
00476 {
00477 Out::os() << tab2 << setw(10) << n
00478 << setw(12) << setprecision(6) << aPtr[offset+n] << std::endl;
00479 }
00480 }
00481 }
00482 }
00483 else
00484 {
00485 for (int c=0; c<JVol.numCells(); c++, offset+=nNodes())
00486 {
00487 Tabs tab2;
00488 double detJ = fabs(JVol.detJ()[c]);
00489 SUNDANCE_MSG4(integrationVerb(), tab2 << "c=" << c << " detJ=" << detJ);
00490
00491 for (int q=0; q<nQuad; q++, coeffPtr++)
00492 {
00493 Tabs tab3;
00494 double f = (*coeffPtr)*detJ;
00495 SUNDANCE_MSG4(integrationVerb(), tab3 << "q=" << q << " coeff=" <<
00496 *coeffPtr << " coeff*detJ=" << f);
00497 for (int n=0; n<nNodes(); n++)
00498 {
00499 Tabs tab4;
00500 SUNDANCE_MSG4(integrationVerb(), tab4 << "n=" << n << " w=" <<
00501 w[n + nNodes()*q]);
00502 aPtr[offset+n] += f*w[n + nNodes()*q];
00503 }
00504 }
00505
00506 if (integrationVerb() >= 4)
00507 {
00508 Out::os() << tab2 << "integration results on cell:" << std::endl;
00509 Out::os() << tab2 << setw(10) << "n" << setw(12) << "I_n" << std::endl;
00510 for (int n=0; n<nNodes(); n++)
00511 {
00512 Out::os() << tab2 << setw(10) << n
00513 << setw(12) << setprecision(6) << aPtr[offset+n] << std::endl;
00514 }
00515 }
00516
00517 }
00518 }
00519
00520 SUNDANCE_MSG5(integrationVerb(), tabs << "output A = ");
00521 if (integrationVerb() >= 5) writeTable(Out::os(), tabs, *A, 6);
00522 }
00523 else
00524 {
00525
00526
00527 createOneFormTransformationMatrix(JTrans, JVol);
00528
00529 SUNDANCE_MSG4(transformVerb(),
00530 Tabs() << "transformation matrix=" << G(alpha()));
00531
00532 double* GPtr = &(G(alpha())[0]);
00533
00534 transformSummingFirst(JVol.numCells(), facetIndex, cellLIDs, GPtr, coeff, A);
00535 }
00536 addFlops(flops);
00537 }
00538
00539
00540 void MaximalQuadratureIntegral::transformTwoForm(const CellJacobianBatch& JTrans,
00541 const CellJacobianBatch& JVol,
00542 const Array<int>& facetIndex,
00543 const RCP<Array<int> >& cellLIDs,
00544 const double* const coeff,
00545 RCP<Array<double> >& A) const
00546 {
00547 TimeMonitor timer(maxCellQuadrature2Timer());
00548 Tabs tabs;
00549 TEUCHOS_TEST_FOR_EXCEPTION(order() != 2, std::logic_error,
00550 "MaximalQuadratureIntegral::transformTwoForm() called for form "
00551 "of order " << order());
00552 SUNDANCE_MSG2(integrationVerb(), tabs << "doing one form by quadrature");
00553
00554 int nQuad = quadWeights_.size();
00555 const Array<int>* cellLID = cellLIDs.get();
00556
00557
00558
00559
00560
00561 if (testDerivOrder() == 0 && unkDerivOrder() == 0)
00562 {
00563 double* aPtr = &((*A)[0]);
00564 double* coeffPtr = (double*) coeff;
00565 int offset = 0 ;
00566 const Array<double>& w = W_;
00567 if (globalCurve().isCurveValid())
00568 {
00569 int fc = 0;
00570 Array<double> quadWeightsTmp = quadWeights_;
00571 Array<Point> quadPointsTmp = quadPts_;
00572 bool isCutByCurve;
00573
00574 for (int c=0; c<JVol.numCells(); c++, offset+=nNodes())
00575 {
00576 double detJ = fabs(JVol.detJ()[c]);
00577 quadWeightsTmp = quadWeights_;
00578 quadPointsTmp = quadPts_;
00579
00580 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c] , fc ,
00581 mesh() , globalCurve() , quadPointsTmp , quadWeightsTmp , isCutByCurve );
00582 if (isCutByCurve)
00583 {
00584 Array<double> wi;
00585 wi.resize(nQuad * nNodesTest() *nNodesUnk() );
00586 for (int ii = 0 ; ii < wi.size() ; ii++ ) wi[ii] = 0.0;
00587
00588
00589
00590 for (int nt = 0 ; nt < nNodesTest() ; nt++)
00591 {
00592 for (int nu=0; nu<nNodesUnk(); nu++)
00593 {
00594 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00595 {
00596
00597 wi[nu + nNodesUnk()*(nt + nNodesTest()*q)] +=
00598 chop(quadWeightsTmp[q] * W_ACI_F2_[q][0][nt][0][nu]);
00599 }
00600 }
00601 }
00602 for (int q=0; q<nQuad; q++, coeffPtr++)
00603 {
00604 double f = (*coeffPtr)*detJ;
00605 for (int n=0; n<nNodes(); n++)
00606 {
00607 aPtr[offset+n] += f*wi[n + nNodes()*q];
00608 }
00609 }
00610 }
00611 else
00612 {
00613 for (int q=0; q<nQuad; q++, coeffPtr++)
00614 {
00615 double f = (*coeffPtr)*detJ;
00616 for (int n=0; n<nNodes(); n++)
00617 {
00618 aPtr[offset+n] += f*w[n + nNodes()*q];
00619 }
00620 }
00621 }
00622 }
00623 }
00624 else
00625 {
00626 for (int c=0; c<JVol.numCells(); c++, offset+=nNodes())
00627 {
00628 double detJ = fabs(JVol.detJ()[c]);
00629 for (int q=0; q<nQuad; q++, coeffPtr++)
00630 {
00631 double f = (*coeffPtr)*detJ;
00632 for (int n=0; n<nNodes(); n++)
00633 {
00634 aPtr[offset+n] += f*w[n + nNodes()*q];
00635 }
00636 }
00637 }
00638 }
00639
00640 addFlops( JVol.numCells() * (1 + nQuad * (1 + 2*nNodes())) );
00641 }
00642 else
00643 {
00644 createTwoFormTransformationMatrix(JTrans, JVol);
00645 double* GPtr;
00646
00647 if (testDerivOrder() == 0)
00648 {
00649 GPtr = &(G(beta())[0]);
00650 SUNDANCE_MSG2(transformVerb(),
00651 Tabs() << "transformation matrix=" << G(beta()));
00652 }
00653 else if (unkDerivOrder() == 0)
00654 {
00655 GPtr = &(G(alpha())[0]);
00656 SUNDANCE_MSG2(transformVerb(),
00657 Tabs() << "transformation matrix=" << G(alpha()));
00658 }
00659 else
00660 {
00661 GPtr = &(G(alpha(), beta())[0]);
00662 SUNDANCE_MSG2(transformVerb(),
00663 Tabs() << "transformation matrix="
00664 << G(alpha(),beta()));
00665 }
00666
00667
00668 transformSummingFirst(JTrans.numCells(), facetIndex, cellLIDs, GPtr, coeff, A);
00669 }
00670 }
00671
00672 void MaximalQuadratureIntegral
00673 ::transformSummingFirst(int nCells,
00674 const Array<int>& facetIndex,
00675 const RCP<Array<int> >& cellLIDs,
00676 const double* const GPtr,
00677 const double* const coeff,
00678 RCP<Array<double> >& A) const
00679 {
00680 double* aPtr = &((*A)[0]);
00681 double* coeffPtr = (double*) coeff;
00682 const Array<int>* cellLID = cellLIDs.get();
00683 int nQuad = quadWeights_.size();
00684
00685 int transSize = 0;
00686 if (order()==2)
00687 {
00688 transSize = nRefDerivTest() * nRefDerivUnk();
00689 }
00690 else
00691 {
00692 transSize = nRefDerivTest();
00693 }
00694
00695
00696 static Array<double> sumWorkspace;
00697
00698 int swSize = transSize * nNodes();
00699 sumWorkspace.resize(swSize);
00700 const Array<double>& w = W_;
00701
00702
00703
00704
00705
00706
00707
00708
00709 if (globalCurve().isCurveValid())
00710 {
00711 Array<double> quadWeightsTmp = quadWeights_;
00712 Array<Point> quadPointsTmp = quadPts_;
00713 bool isCutByCurve;
00714
00715 for (int c=0; c<nCells; c++)
00716 {
00717
00718 for (int i=0; i<swSize; i++) sumWorkspace[i]=0.0;
00719 int fc = 0;
00720
00721
00722 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c] , fc ,
00723 mesh() , globalCurve() , quadPointsTmp , quadWeightsTmp , isCutByCurve );
00724 if (isCutByCurve)
00725 {
00726 Array<double> wi;
00727 if (order()==1)
00728 {
00729 wi.resize(nQuad * nRefDerivTest() * nNodesTest());
00730 for (int ii = 0 ; ii < wi.size() ; ii++ ) wi[ii] = 0.0;
00731
00732 for (int n = 0 ; n < nNodes() ; n++)
00733 {
00734 for (int t=0; t<nRefDerivTest(); t++)
00735 {
00736 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00737 {
00738
00739 wi[n + nNodes()*(t + nRefDerivTest()*q)] +=
00740 chop(quadWeightsTmp[q] * W_ACI_F1_[q][t][n]);
00741 }
00742 }
00743 }
00744 }
00745 else
00746 {
00747 wi.resize(nQuad * nRefDerivTest() * nNodesTest()
00748 * nRefDerivUnk() * nNodesUnk() );
00749 for (int ii = 0 ; ii < wi.size() ; ii++ ) wi[ii] = 0.0;
00750
00751 for (int t=0; t<nRefDerivTest(); t++)
00752 {
00753 for (int nt = 0 ; nt < nNodesTest() ; nt++)
00754 {
00755 for (int u=0; u<nRefDerivUnk(); u++)
00756 {
00757 for (int nu=0; nu<nNodesUnk(); nu++)
00758 {
00759 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00760 {
00761
00762
00763 wi[nu + nNodesUnk()*(nt + nNodesTest()*(u + nRefDerivUnk()*(t + nRefDerivTest()*q)))] +=
00764 chop(quadWeightsTmp[q] * W_ACI_F2_[q][t][nt][u][nu]);
00765 }
00766 }
00767 }
00768 }
00769 }
00770 }
00771
00772 for (int q=0; q<nQuad; q++, coeffPtr++)
00773 {
00774 double f = (*coeffPtr);
00775 for (int n=0; n<swSize; n++)
00776 {
00777 sumWorkspace[n] += f*wi[n + q*swSize];
00778 }
00779 }
00780
00781 }
00782 else
00783 {
00784 for (int q=0; q<nQuad; q++, coeffPtr++)
00785 {
00786 double f = (*coeffPtr);
00787 for (int n=0; n<swSize; n++)
00788 {
00789 sumWorkspace[n] += f*w[n + q*swSize];
00790 }
00791 }
00792 }
00793
00794
00795 const double * const gCell = &(GPtr[transSize*c]);
00796 double* aCell = aPtr + nNodes()*c;
00797 for (int i=0; i<nNodes(); i++)
00798 {
00799 for (int j=0; j<transSize; j++)
00800 {
00801 aCell[i] += sumWorkspace[nNodes()*j + i] * gCell[j];
00802 }
00803 }
00804 }
00805 }
00806 else
00807 {
00808
00809 for (int c=0; c<nCells; c++)
00810 {
00811
00812 for (int i=0; i<swSize; i++) sumWorkspace[i]=0.0;
00813
00814 for (int q=0; q<nQuad; q++, coeffPtr++)
00815 {
00816 double f = (*coeffPtr);
00817 for (int n=0; n<swSize; n++)
00818 {
00819 sumWorkspace[n] += f*w[n + q*swSize];
00820 }
00821 }
00822
00823
00824 const double * const gCell = &(GPtr[transSize*c]);
00825 double* aCell = aPtr + nNodes()*c;
00826 for (int i=0; i<nNodes(); i++)
00827 {
00828 for (int j=0; j<transSize; j++)
00829 {
00830 aCell[i] += sumWorkspace[nNodes()*j + i] * gCell[j];
00831 }
00832 }
00833 }
00834 }
00835 }
00836