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 #include "SundanceRefIntegral.hpp"
00032 #include "SundanceGaussianQuadrature.hpp"
00033 #include "SundanceGaussianQuadratureType.hpp"
00034 #include "SundanceQuadratureType.hpp"
00035 #include "SundanceSpatialDerivSpecifier.hpp"
00036 #include "SundanceOut.hpp"
00037 #include "PlayaTabs.hpp"
00038 #include "Teuchos_TimeMonitor.hpp"
00039
00040 using namespace Sundance;
00041 using namespace Teuchos;
00042
00043 using std::ios_base;
00044 using std::setw;
00045 using std::endl;
00046
00047 extern "C"
00048 {
00049 int dgemm_(const char* transA, const char* transB,
00050 const int* M, const int *N, const int* K,
00051 const double* alpha,
00052 const double* A, const int* ldA,
00053 const double* B, const int* ldB,
00054 const double* beta,
00055 double* C, const int* ldC);
00056 }
00057
00058 static Time& refIntegrationTimer()
00059 {
00060 static RCP<Time> rtn
00061 = TimeMonitor::getNewTimer("ref integration");
00062 return *rtn;
00063 }
00064
00065
00066
00067 RefIntegral::RefIntegral(int spatialDim,
00068 const CellType& maxCellType,
00069 int dim,
00070 const CellType& cellType,
00071 const QuadratureFamily& quad_in,
00072 bool isInternalBdry,
00073 const ParametrizedCurve& globalCurve,
00074 const Mesh& mesh,
00075 int verb)
00076 : ElementIntegral(spatialDim, maxCellType, dim, cellType, isInternalBdry, globalCurve , mesh,
00077 verb), W_()
00078 {
00079 Tabs tab0(0);
00080
00081 SUNDANCE_MSG1(setupVerb(),
00082 tab0 << "************* creating reference 0-form integrals ********");
00083 if (setupVerb()) describe(Out::os());
00084
00085
00086
00087 QuadratureFamily quad = new GaussianQuadrature(2);
00088
00089
00090 if (globalCurve.isCurveValid()){
00091 quad = quad_in;
00092 Tabs tab1;
00093 SUNDANCE_MSG1(setupVerb(),tab1 << "ACI change quadrature to Quadrature of order: "<<quad.order());
00094 }
00095 quad_ = quad;
00096
00097 Array<Point> quadPts;
00098 Array<double> quadWeights;
00099
00100 W_.resize(1);
00101 W_[0].resize(1);
00102
00103 quad.getPoints(cellType, quadPts, quadWeights);
00104
00105 quadWeights_ = quadWeights;
00106
00107 for (int q=0; q<quadWeights.size(); q++) {
00108 W_[0][0] += quadWeights[q];
00109 }
00110 }
00111
00112 RefIntegral::RefIntegral(int spatialDim,
00113 const CellType& maxCellType,
00114 int dim,
00115 const CellType& cellType,
00116 const BasisFamily& testBasis,
00117 int alpha,
00118 int testDerivOrder,
00119 const QuadratureFamily& quad_in,
00120 bool isInternalBdry,
00121 const ParametrizedCurve& globalCurve,
00122 const Mesh& mesh,
00123 int verb)
00124 : ElementIntegral(spatialDim, maxCellType, dim, cellType,
00125 testBasis, alpha, testDerivOrder, isInternalBdry, globalCurve , mesh , verb), W_()
00126 {
00127 Tabs tab0(0);
00128 SUNDANCE_MSG1(setupVerb(),
00129 tab0 << "************* creating reference 1-form integrals ********");
00130 if (setupVerb()) describe(Out::os());
00131 assertLinearForm();
00132
00133 W_.resize(nFacetCases());
00134 W_ACI_F1_.resize(nFacetCases());
00135
00136
00137 QuadratureType qType = new GaussianQuadratureType();
00138 int reqOrder = qType.findValidOrder(cellType,
00139 std::max(1, testBasis.order()));
00140
00141 SUNDANCE_MSG2(setupVerb(),
00142 tab0 << "using quadrature order=" << reqOrder);
00143
00144
00145 QuadratureFamily quad = qType.createQuadFamily(reqOrder);
00146
00147
00148
00149 if (globalCurve.isCurveValid()){
00150 quad = quad_in;
00151 Tabs tab1;
00152 SUNDANCE_MSG1(setupVerb(),tab1 << "ACI change quadrature to Quadrature of order: "<<quad.order());
00153 }
00154 quad_ = quad;
00155
00156
00157
00158
00159 for (int fc=0; fc<nFacetCases(); fc++)
00160 {
00161 Tabs tab1;
00162 SUNDANCE_MSG2(setupVerb(),
00163 tab1 << "evaluation case=" << fc << " of " << nFacetCases());
00164
00165 W_[fc].resize(nRefDerivTest() * nNodesTest());
00166
00167
00168 for (int i=0; i<W_[fc].size(); i++) { W_[fc][i]=0.0; }
00169
00170 Array<Array<Array<Array<double> > > > testBasisVals(nRefDerivTest());
00171
00172
00173
00174 getQuad(quad, fc, quadPts_, quadWeights_);
00175
00176 int nQuad = quadPts_.size();
00177
00178
00179 for (int r=0; r<nRefDerivTest(); r++)
00180 {
00181 Tabs tab2;
00182 SUNDANCE_MSG2(setupVerb(), tab2 << "evaluating basis derivative "
00183 << r << " of " << nRefDerivTest());
00184
00185 testBasisVals[r].resize(testBasis.dim());
00186 MultiIndex mi;
00187 if (testDerivOrder==1) mi[r] = 1;
00188 SpatialDerivSpecifier deriv(mi);
00189 testBasis.refEval(evalCellType(), quadPts_, deriv,
00190 testBasisVals[r], setupVerb());
00191 }
00192
00193
00194 SUNDANCE_MSG2(setupVerb(), tab1 << "doing quadrature");
00195 int vecComp = 0;
00196 W_ACI_F1_[fc].resize(nQuad);
00197 for (int q=0; q<nQuad; q++)
00198 {
00199 W_ACI_F1_[fc][q].resize(nRefDerivTest());
00200 for (int t=0; t<nRefDerivTest(); t++)
00201 {
00202 W_ACI_F1_[fc][q][t].resize(nNodesTest());
00203 for (int nt=0; nt<nNodesTest(); nt++)
00204 {
00205 value(fc, t, nt)
00206 += chop(quadWeights_[q] * testBasisVals[t][vecComp][q][nt]) ;
00207 W_ACI_F1_[fc][q][t][nt] = chop(testBasisVals[t][vecComp][q][nt]);
00208 }
00209 }
00210 }
00211
00212 for (int i=0; i<W_[fc].size(); i++) W_[fc][i] = chop(W_[fc][i]);
00213
00214 addFlops(3*nQuad*nRefDerivTest()*nNodesTest() + W_[fc].size());
00215 }
00216
00217
00218 SUNDANCE_MSG4(setupVerb(), tab0 << "--------------------------------------");
00219 SUNDANCE_MSG4(setupVerb(), tab0 << "reference linear form integral results");
00220 if (setupVerb() >= 4)
00221 {
00222 for (int fc=0; fc<nFacetCases(); fc++)
00223 {
00224 Tabs tab1;
00225 SUNDANCE_MSG4(setupVerb(), tab1 << "------ evaluation case " << fc << " of "
00226 << nFacetCases() << "-------");
00227
00228 for (int r=0; r<nRefDerivTest(); r++)
00229 {
00230 Tabs tab2;
00231
00232 MultiIndex mi;
00233 if (testDerivOrder==1) mi[r] = 1;
00234 SUNDANCE_MSG1(setupVerb(), tab2 << "multiindex=" << mi);
00235
00236 ios_base::fmtflags oldFlags = Out::os().flags();
00237 Out::os().setf(ios_base::right);
00238 Out::os().setf(ios_base::showpoint);
00239 for (int nt=0; nt<nNodesTest(); nt++)
00240 {
00241 Tabs tab3;
00242 Out::os() << tab3 << setw(10) << nt
00243 << setw(12) << std::setprecision(5) << value(fc, r, nt)
00244 << std::endl;
00245 }
00246 Out::os().flags(oldFlags);
00247 }
00248 }
00249 }
00250
00251 SUNDANCE_MSG1(setupVerb(), tab0 << "done reference linear form ctor");
00252 }
00253
00254
00255
00256
00257 RefIntegral::RefIntegral(int spatialDim,
00258 const CellType& maxCellType,
00259 int dim,
00260 const CellType& cellType,
00261 const BasisFamily& testBasis,
00262 int alpha,
00263 int testDerivOrder,
00264 const BasisFamily& unkBasis,
00265 int beta,
00266 int unkDerivOrder,
00267 const QuadratureFamily& quad_in,
00268 bool isInternalBdry,
00269 const ParametrizedCurve& globalCurve,
00270 const Mesh& mesh,
00271 int verb)
00272 : ElementIntegral(spatialDim, maxCellType, dim, cellType,
00273 testBasis, alpha, testDerivOrder,
00274 unkBasis, beta, unkDerivOrder, isInternalBdry, globalCurve , mesh ,verb), W_()
00275
00276 {
00277 Tabs tab0(0);
00278 SUNDANCE_MSG1(setupVerb(),
00279 tab0 << "************* creating reference 2-form integrals ********");
00280 if (setupVerb()) describe(Out::os());
00281
00282 assertBilinearForm();
00283
00284 W_.resize(nFacetCases());
00285 W_ACI_F2_.resize(nFacetCases());
00286
00287 QuadratureType qType = new GaussianQuadratureType();
00288 int reqOrder = qType.findValidOrder(cellType,
00289 std::max(1, unkBasis.order() + testBasis.order()));
00290
00291 SUNDANCE_MSG2(setupVerb(),
00292 tab0 << "using quadrature order=" << reqOrder);
00293 QuadratureFamily quad = qType.createQuadFamily(reqOrder);
00294
00295
00296
00297 if (globalCurve.isCurveValid()){
00298 quad = quad_in;
00299 Tabs tab1;
00300 SUNDANCE_MSG1(setupVerb(),tab1 << "ACI change quadrature to Quadrature of order: "<<quad.order());
00301 }
00302 quad_ = quad;
00303
00304 SUNDANCE_MSG2(setupVerb(),
00305 tab0 << "processing evaluation cases");
00306
00307 for (int fc=0; fc<nFacetCases(); fc++)
00308 {
00309 Tabs tab1;
00310 SUNDANCE_MSG1(setupVerb(), tab1 << "------ evaluation case " << fc << " of "
00311 << nFacetCases() << "-------");
00312
00313 W_[fc].resize(nRefDerivTest() * nNodesTest() * nRefDerivUnk() * nNodesUnk());
00314 for (int i=0; i<W_[fc].size(); i++) W_[fc][i]=0.0;
00315
00316 Array<Array<Array<Array<double> > > > testBasisVals(nRefDerivTest());
00317 Array<Array<Array<Array<double> > > > unkBasisVals(nRefDerivUnk());
00318
00319 getQuad(quad, fc, quadPts_, quadWeights_);
00320 int nQuad = quadPts_.size();
00321
00322 for (int r=0; r<nRefDerivTest(); r++)
00323 {
00324 Tabs tab2;
00325 SUNDANCE_MSG2(setupVerb(), tab2
00326 << "evaluating test function basis derivative "
00327 << r << " of " << nRefDerivTest());
00328 testBasisVals[r].resize(testBasis.dim());
00329 MultiIndex mi;
00330 if (testDerivOrder==1) mi[r] = 1;
00331 SpatialDerivSpecifier deriv(mi);
00332 testBasis.refEval(evalCellType(), quadPts_, deriv,
00333 testBasisVals[r], setupVerb());
00334 }
00335
00336 for (int r=0; r<nRefDerivUnk(); r++)
00337 {
00338 Tabs tab2;
00339 SUNDANCE_MSG2(setupVerb(), tab2
00340 << "evaluating unknown function basis derivative "
00341 << r << " of " << nRefDerivUnk());
00342 unkBasisVals[r].resize(unkBasis.dim());
00343 MultiIndex mi;
00344 if (unkDerivOrder==1) mi[r] = 1;
00345 SpatialDerivSpecifier deriv(mi);
00346 unkBasis.refEval(evalCellType(),
00347 quadPts_, deriv, unkBasisVals[r], setupVerb());
00348 }
00349
00350 SUNDANCE_MSG2(setupVerb(), tab1 << "doing quadrature...");
00351 int vecComp = 0;
00352 W_ACI_F2_[fc].resize(nQuad);
00353 for (int q=0; q<nQuad; q++)
00354 {
00355 W_ACI_F2_[fc][q].resize(nRefDerivTest());
00356 for (int t=0; t<nRefDerivTest(); t++)
00357 {
00358 W_ACI_F2_[fc][q][t].resize(nNodesTest());
00359 for (int nt=0; nt<nNodesTest(); nt++)
00360 {
00361 W_ACI_F2_[fc][q][t][nt].resize(nRefDerivUnk());
00362 for (int u=0; u<nRefDerivUnk(); u++)
00363 {
00364 W_ACI_F2_[fc][q][t][nt][u].resize(nNodesUnk());
00365 for (int nu=0; nu<nNodesUnk(); nu++)
00366 {
00367 value(fc, t, nt, u, nu)
00368 += chop(quadWeights_[q] * testBasisVals[t][vecComp][q][nt]
00369 * unkBasisVals[u][vecComp][q][nu]);
00370 W_ACI_F2_[fc][q][t][nt][u][nu] = chop( testBasisVals[t][vecComp][q][nt]
00371 * unkBasisVals[u][vecComp][q][nu] );
00372 }
00373 }
00374 }
00375 }
00376 }
00377 SUNDANCE_MSG2(setupVerb(), tab1 << "...done");
00378 addFlops(4*nQuad*nRefDerivTest()*nNodesTest()*nRefDerivUnk()*nNodesUnk()
00379 + W_[fc].size());
00380 for (int i=0; i<W_[fc].size(); i++) W_[fc][i] = chop(W_[fc][i]);
00381 }
00382
00383 SUNDANCE_MSG1(setupVerb(), tab0
00384 << "----------------------------------------");
00385 SUNDANCE_MSG4(setupVerb(), tab0
00386 << "reference bilinear form integral results");
00387 if (setupVerb() >= 4)
00388 {
00389 for (int fc=0; fc<nFacetCases(); fc++)
00390 {
00391 Tabs tab1;
00392 SUNDANCE_MSG4(setupVerb(), tab1 << "evaluation case " << fc << " of "
00393 << nFacetCases());
00394
00395 for (int rt=0; rt<nRefDerivTest(); rt++)
00396 {
00397 for (int ru=0; ru<nRefDerivUnk(); ru++)
00398 {
00399 Tabs tab2;
00400 MultiIndex miTest;
00401 if (testDerivOrder==1) miTest[rt] = 1;
00402 MultiIndex miUnk;
00403 if (unkDerivOrder==1) miUnk[ru] = 1;
00404 SUNDANCE_MSG1(setupVerb(), tab2 << "test multiindex=" << miTest
00405 << " unk multiindex=" << miUnk);
00406
00407 ios_base::fmtflags oldFlags = Out::os().flags();
00408 Out::os().setf(ios_base::right);
00409 Out::os().setf(ios_base::showpoint);
00410 for (int nt=0; nt<nNodesTest(); nt++)
00411 {
00412 Tabs tab3;
00413 Out::os() << tab3 << setw(10) << nt;
00414 for (int nu=0; nu<nNodesUnk(); nu++)
00415 {
00416 Out::os() << setw(12) << std::setprecision(5)
00417 << value(fc, rt, nt, ru, nu) ;
00418 }
00419 Out::os() << std::endl;
00420 }
00421 Out::os().flags(oldFlags);
00422 }
00423 }
00424 }
00425 }
00426
00427 SUNDANCE_MSG1(setupVerb(), tab0 << "done reference bilinear form ctor");
00428 }
00429
00430
00431
00432
00433 void RefIntegral::transformZeroForm(const CellJacobianBatch& JVol,
00434 const Array<int>& isLocalFlag,
00435 const RCP<Array<int> >& cellLIDs,
00436 const double& coeff,
00437 RCP<Array<double> >& A) const
00438 {
00439 TimeMonitor timer(refIntegrationTimer());
00440
00441 TEUCHOS_TEST_FOR_EXCEPTION(order() != 0, std::logic_error,
00442 "RefIntegral::transformZeroForm() called "
00443 "for form of order " << order());
00444
00445 Tabs tabs;
00446 SUNDANCE_MSG1(integrationVerb(), tabs << "doing zero form by reference");
00447
00448 double& a = (*A)[0];
00449 int flops = 0;
00450 const Array<int>* cellLID = cellLIDs.get();
00451
00452
00453
00454
00455 double w = coeff * W_[0][0];
00456 if ((int) isLocalFlag.size()==0)
00457 {
00458 if (globalCurve().isCurveValid())
00459 {
00460
00461 Array<double> quadWeightsTmp = quadWeights_;
00462 Array<Point> quadPointsTmp = quadPts_;
00463 bool isCutByCurve;
00464
00465 for (int c=0; c<JVol.numCells(); c++)
00466 {
00467 int fc = 0;
00468
00469 quadWeightsTmp = quadWeights_;
00470 quadPointsTmp = quadPts_;
00471 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c], fc ,mesh(),
00472 globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00473
00474 if (isCutByCurve){
00475 double sumweights = 0;
00476 for (int j=0; j < quadWeightsTmp.size(); j++) sumweights += chop(quadWeightsTmp[j]);
00477 flops+=3+quadWeightsTmp.size();
00478 a += coeff * sumweights * fabs(JVol.detJ()[c]);
00479 } else {
00480 flops+=2;
00481 a += w * fabs(JVol.detJ()[c]);
00482 }
00483 }
00484 }
00485 else
00486 {
00487 for (int c=0; c<JVol.numCells(); c++)
00488 {
00489 flops+=2;
00490 a += w * fabs(JVol.detJ()[c]);
00491 }
00492 }
00493
00494 }
00495 else
00496 {
00497 TEUCHOS_TEST_FOR_EXCEPTION( (int) isLocalFlag.size() != JVol.numCells(),
00498 std::runtime_error,
00499 "mismatch between isLocalFlag.size()="
00500 << isLocalFlag.size()
00501 << " and JVol.numCells()=" << JVol.numCells());
00502
00503 int fc = 0;
00504 if (globalCurve().isCurveValid())
00505 {
00506 Array<double> quadWeightsTmp = quadWeights_;
00507 Array<Point> quadPointsTmp = quadPts_;
00508 bool isCutByCurve;
00509
00510 for (int c=0; c<JVol.numCells(); c++)
00511 {
00512 if (isLocalFlag[c])
00513 {
00514
00515
00516 quadWeightsTmp = quadWeights_;
00517 quadPointsTmp = quadPts_;
00518 quad_.getAdaptedWeights(cellType(), dim(), (*cellLID)[c], fc , mesh(),
00519 globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00520
00521 if (isCutByCurve){
00522 double sumweights = 0;
00523 for (int j=0; j < quadWeightsTmp.size(); j++) sumweights += chop(quadWeightsTmp[j]);
00524 flops+=3+quadWeightsTmp.size();
00525 a += coeff * sumweights * fabs(JVol.detJ()[c]);
00526 } else {
00527 flops+=2;
00528 a += w * fabs(JVol.detJ()[c]);
00529 }
00530 }
00531 }
00532 }
00533 else
00534 {
00535 for (int c=0; c<JVol.numCells(); c++)
00536 {
00537 if (isLocalFlag[c])
00538 {
00539 flops+=2;
00540 a += w * fabs(JVol.detJ()[c]);
00541 }
00542 }
00543 }
00544 }
00545 addFlops(flops);
00546 }
00547
00548 void RefIntegral::transformOneForm(const CellJacobianBatch& JTrans,
00549 const CellJacobianBatch& JVol,
00550 const Array<int>& facetIndex,
00551 const RCP<Array<int> >& cellLIDs,
00552 const double& coeff,
00553 RCP<Array<double> >& A) const
00554 {
00555 TimeMonitor timer(refIntegrationTimer());
00556 TEUCHOS_TEST_FOR_EXCEPTION(order() != 1, std::logic_error,
00557 "RefIntegral::transformOneForm() called for form "
00558 "of order " << order());
00559 Tabs tabs;
00560 SUNDANCE_MSG1(integrationVerb(),
00561 tabs << "doing one form by reference");
00562
00563 int nfc = nFacetCases();
00564
00565
00566
00567 if (testDerivOrder() == 0)
00568 {
00569 double* aPtr = &((*A)[0]);
00570 int count = 0;
00571 if (globalCurve().isCurveValid())
00572 {
00573
00574 Array<double> quadWeightsTmp = quadWeights_;
00575 Array<Point> quadPointsTmp = quadPts_;
00576 bool isCutByCurve = false;
00577
00578 for (int c=0; c<JVol.numCells(); c++)
00579 {
00580 double detJ = coeff * fabs(JVol.detJ()[c]);
00581 int fc = 0;
00582 if (nfc != 1) fc = facetIndex[c];
00583
00584 quadWeightsTmp = quadWeights_;
00585 quadPointsTmp = quadPts_;
00586
00587 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c] , fc ,
00588 mesh() , globalCurve() , quadPointsTmp , quadWeightsTmp , isCutByCurve );
00589 if (isCutByCurve)
00590 {
00591 Array<double> w;
00592 w.resize(nNodesTest());
00593 for (int nt = 0 ; nt < nNodesTest() ; nt++){
00594 w[nt] = 0.0;
00595 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00596 w[nt] += chop(quadWeightsTmp[q] * W_ACI_F1_[fc][q][0][nt]);
00597 }
00598
00599 for (int n=0; n<nNodes(); n++, count++)
00600 {
00601 aPtr[count] += detJ*w[n];
00602 }
00603 }
00604 else
00605 {
00606 const Array<double>& w = W_[fc];
00607 for (int n=0; n<nNodes(); n++, count++)
00608 {
00609 aPtr[count] += detJ*w[n];
00610 }
00611 }
00612 }
00613 }
00614 else
00615 {
00616 for (int c=0; c<JVol.numCells(); c++)
00617 {
00618 double detJ = coeff * fabs(JVol.detJ()[c]);
00619 int fc = 0;
00620 if (nfc != 1) fc = facetIndex[c];
00621
00622 const Array<double>& w = W_[fc];
00623 for (int n=0; n<nNodes(); n++, count++)
00624 {
00625 aPtr[count] += detJ*w[n];
00626 }
00627 }
00628 }
00629 addFlops(JVol.numCells() * (nNodes() + 1));
00630 }
00631 else
00632 {
00633
00634
00635
00636 int nCells = JVol.numCells();
00637 double one = 1.0;
00638 int nTransRows = nRefDerivTest();
00639
00640 createOneFormTransformationMatrix(JTrans, JVol);
00641
00642 SUNDANCE_MSG3(transformVerb(),
00643 Tabs() << "transformation matrix=" << G(alpha()));
00644 int nNodes0 = nNodes();
00645
00646 if (nFacetCases()==1)
00647 {
00648
00649
00650
00651 if (globalCurve().isCurveValid())
00652 {
00653
00654 Array<double> quadWeightsTmp = quadWeights_;
00655 Array<Point> quadPointsTmp = quadPts_;
00656 bool isCutByCurve = false;
00657
00658 double* aPtr_tmp = &((*A)[0]);
00659 int count = 0;
00660 const int oneI = 1;
00661 for (int c=0; c<JVol.numCells(); c++)
00662 {
00663 int fc = 0;
00664 if (nfc != 1) fc = facetIndex[c];
00665
00666 quadWeightsTmp = quadWeights_;
00667 quadPointsTmp = quadPts_;
00668 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c], fc ,
00669 mesh() , globalCurve() , quadPointsTmp , quadWeightsTmp , isCutByCurve);
00670 if (isCutByCurve){
00671 Array<double> w;
00672 w.resize(nRefDerivTest()*nNodes());
00673 for (int i = 0 ; i < nRefDerivTest()*nNodes() ; w[i] = 0.0 , i++);
00674 for (int t=0; t<nRefDerivTest(); t++)
00675 for (int nt = 0 ; nt < nNodesTest() ; nt++){
00676 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00677
00678 w[nNodesTest()*t + nt] += chop(quadWeightsTmp[q] * W_ACI_F1_[0][q][t][nt]);
00679 }
00680 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(w[0]),
00681 &nNodes0, &(G(alpha())[0]), &nTransRows, &one,
00682 &(aPtr_tmp[count]), &nNodes0);
00683 }else{
00684 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(W_[0][0]),
00685 &nNodes0, &(G(alpha())[0]), &nTransRows, &one,
00686 &(aPtr_tmp[count]), &nNodes0);
00687 }
00688 count += nNodes();
00689 }
00690 }
00691 else
00692 {
00693 ::dgemm_("N", "N", &nNodes0, &nCells, &nTransRows, &coeff, &(W_[0][0]),
00694 &nNodes0, &(G(alpha())[0]), &nTransRows, &one,
00695 &((*A)[0]), &nNodes0);
00696 }
00697 }
00698 else
00699 {
00700
00701
00702 if (globalCurve().isCurveValid())
00703 {
00704
00705 Array<double> quadWeightsTmp = quadWeights_;
00706 Array<Point> quadPointsTmp = quadPts_;
00707 bool isCutByCurve = false;
00708
00709 int N = 1;
00710 for (int c=0; c<JVol.numCells(); c++)
00711 {
00712 int fc = 0;
00713 if (nfc != 1) fc = facetIndex[c];
00714 double* aPtr = &((*A)[c*nNodes0]);
00715
00716 quadWeightsTmp = quadWeights_;
00717 quadPointsTmp = quadPts_;
00718 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c], fc ,
00719 mesh() , globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00720 if (isCutByCurve){
00721 Array<double> w;
00722 w.resize(nRefDerivTest()*nNodes());
00723 for (int i = 0 ; i < nRefDerivTest()*nNodes() ; w[i] = 0.0 , i++);
00724 for (int t=0; t<nRefDerivTest(); t++)
00725 for (int nt = 0 ; nt < nNodesTest() ; nt++){
00726 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00727
00728 w[nNodesTest()*t + nt] += chop(quadWeightsTmp[q] * W_ACI_F1_[fc][q][t][nt]);
00729 }
00730 ::dgemm_("N", "N", &nNodes0, &N , &nTransRows, &coeff, &(w[0]),
00731 &nNodes0, &(G(alpha())[0]), &nTransRows, &one,
00732 aPtr, &nNodes0);
00733 }else{
00734 ::dgemm_("N", "N", &nNodes0, &N, &nTransRows, &coeff, &(W_[fc][0]),
00735 &nNodes0, &(G(alpha())[c*nTransRows]), &nTransRows, &one,
00736 aPtr, &nNodes0);
00737 }
00738 }
00739 }
00740 else
00741 {
00742 int N = 1;
00743 for (int c=0; c<JVol.numCells(); c++)
00744 {
00745 int fc = 0;
00746 if (nfc != 1) fc = facetIndex[c];
00747 double* aPtr = &((*A)[c*nNodes0]);
00748 ::dgemm_("N", "N", &nNodes0, &N, &nTransRows, &coeff, &(W_[fc][0]),
00749 &nNodes0, &(G(alpha())[c*nTransRows]), &nTransRows, &one,
00750 aPtr, &nNodes0);
00751 }
00752 }
00753 }
00754
00755 addFlops(2 * nNodes0 * nCells * nTransRows);
00756 }
00757 }
00758
00759 void RefIntegral::transformTwoForm(const CellJacobianBatch& JTrans,
00760 const CellJacobianBatch& JVol,
00761 const Array<int>& facetIndex,
00762 const RCP<Array<int> >& cellLIDs,
00763 const double& coeff,
00764 RCP<Array<double> >& A) const
00765 {
00766 TimeMonitor timer(refIntegrationTimer());
00767 TEUCHOS_TEST_FOR_EXCEPTION(order() != 2, std::logic_error,
00768 "RefIntegral::transformTwoForm() called for form "
00769 "of order " << order());
00770
00771 Tabs tabs;
00772 SUNDANCE_MSG1(transformVerb(), tabs << "doing two form by reference");
00773
00774 int nfc = nFacetCases();
00775
00776 SUNDANCE_MSG1(transformVerb(), tabs << "doing two form by reference ... ");
00777
00778
00779 if (testDerivOrder() == 0 && unkDerivOrder() == 0)
00780 {
00781 if (globalCurve().isCurveValid())
00782 {
00783
00784 Array<double> quadWeightsTmp = quadWeights_;
00785 Array<Point> quadPointsTmp = quadPts_;
00786 bool isCutByCurve = false;
00787
00788 double* aPtr = &((*A)[0]);
00789 int count = 0;
00790 for (int c=0; c<JVol.numCells(); c++)
00791 {
00792 int fc = 0;
00793 if (nFacetCases() != 1) fc = facetIndex[c];
00794
00795
00796
00797 quadWeightsTmp = quadWeights_;
00798 quadPointsTmp = quadPts_;
00799 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c] , fc ,
00800 mesh(), globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00801 if (isCutByCurve){
00802 Array<double> w;
00803 int ci = 0;
00804 w.resize(nNodesTest()*nNodesUnk());
00805 for (int nt = 0 ; nt < nNodesTest() ; nt++)
00806 for(int nu=0 ; nu < nNodesUnk() ; nu++ , ci++){
00807 w[ci] = 0.0;
00808 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00809 w[ci] += chop( quadWeightsTmp[q] * W_ACI_F2_[fc][q][0][nt][0][nu] );
00810 }
00811
00812 double detJ = coeff * fabs(JVol.detJ()[c]);
00813 for (int n=0; n<nNodes(); n++, count++)
00814 {
00815 aPtr[count] += detJ*w[n];
00816 }
00817 }
00818 else
00819 {
00820 const Array<double>& w = W_[fc];
00821 double detJ = coeff * fabs(JVol.detJ()[c]);
00822 for (int n=0; n<nNodes(); n++, count++)
00823 {
00824 aPtr[count] += detJ*w[n];
00825 }
00826 }
00827 }
00828 }
00829 else
00830 {
00831 double* aPtr = &((*A)[0]);
00832 int count = 0;
00833 for (int c=0; c<JVol.numCells(); c++)
00834 {
00835 int fc = 0;
00836 if (nFacetCases() != 1) fc = facetIndex[c];
00837
00838 const Array<double>& w = W_[fc];
00839 double detJ = coeff * fabs(JVol.detJ()[c]);
00840 for (int n=0; n<nNodes(); n++, count++)
00841 {
00842 aPtr[count] += detJ*w[n];
00843 }
00844 }
00845 }
00846 addFlops(JVol.numCells() * (nNodes() + 1));
00847 }
00848 else
00849 {
00850
00851
00852
00853 int nCells = JVol.numCells();
00854 double one = 1.0;
00855 int nTransRows = nRefDerivUnk()*nRefDerivTest();
00856
00857 createTwoFormTransformationMatrix(JTrans, JVol);
00858
00859 double* GPtr;
00860 if (testDerivOrder() == 0)
00861 {
00862 GPtr = &(G(beta())[0]);
00863 SUNDANCE_MSG2(transformVerb(),
00864 Tabs() << "transformation matrix=" << G(beta()));
00865 }
00866 else if (unkDerivOrder() == 0)
00867 {
00868 GPtr = &(G(alpha())[0]);
00869 SUNDANCE_MSG2(transformVerb(),
00870 Tabs() << "transformation matrix=" << G(alpha()));
00871 }
00872 else
00873 {
00874 GPtr = &(G(alpha(), beta())[0]);
00875 SUNDANCE_MSG2(transformVerb(),
00876 Tabs() << "transformation matrix="
00877 << G(alpha(),beta()));
00878 }
00879
00880 int nNodes0 = nNodes();
00881
00882 if (nFacetCases()==1)
00883 {
00884
00885
00886
00887 if (globalCurve().isCurveValid())
00888 {
00889
00890 Array<double> quadWeightsTmp = quadWeights_;
00891 Array<Point> quadPointsTmp = quadPts_;
00892 bool isCutByCurve = false;
00893
00894 for (int c=0; c<JVol.numCells(); c++)
00895 {
00896 int fc = 0;
00897 if (nfc != 1) fc = facetIndex[c];
00898
00899 double* aPtr = &((*A)[c*nNodes0]);
00900 double* gPtr = &(GPtr[c*nTransRows]);
00901 int oneI = 1;
00902
00903
00904 quadWeightsTmp = quadWeights_;
00905 quadPointsTmp = quadPts_;
00906 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c], fc ,
00907 mesh(),globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00908
00909 if (isCutByCurve){
00910 Array<double> w;
00911 w.resize(nNodesUnk()*nNodesTest()*nRefDerivUnk()*nRefDerivTest());
00912 for ( int i = 0 ; i < w.size() ; i++) w[i] = 0.0;
00913
00914 for (int t=0; t<nRefDerivTest(); t++){
00915 for (int nt=0; nt<nNodesTest(); nt++)
00916 for (int u=0; u<nRefDerivUnk(); u++)
00917 for (int nu=0; nu<nNodesUnk(); nu++)
00918 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00919
00920 w[nu + nNodesUnk()*nt + nNodes()*(u + nRefDerivUnk()*t)] +=
00921 chop(quadWeightsTmp[q]*W_ACI_F2_[0][q][t][nt][u][nu]);
00922 }
00923 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(w[0]),
00924 &nNodes0, &(gPtr[0]), &nTransRows, &one,
00925 &(aPtr[0]), &nNodes0);
00926 }else{
00927 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(W_[0][0]),
00928 &nNodes0, &(gPtr[0]), &nTransRows, &one,
00929 &(aPtr[0]), &nNodes0);
00930 }
00931 }
00932 }
00933 else
00934 {
00935 ::dgemm_("N", "N", &nNodes0, &nCells, &nTransRows, &coeff, &(W_[0][0]),
00936 &nNodes0, GPtr, &nTransRows, &one,
00937 &((*A)[0]), &nNodes0);
00938 }
00939 }
00940 else
00941 {
00942
00943
00944 if (globalCurve().isCurveValid())
00945 {
00946 int oneI = 1;
00947 Array<double> quadWeightsTmp = quadWeights_;
00948 Array<Point> quadPointsTmp = quadPts_;
00949 bool isCutByCurve = false;
00950
00951 for (int c=0; c<JVol.numCells(); c++)
00952 {
00953 int fc = 0;
00954 if (nfc != 1) fc = facetIndex[c];
00955 double* aPtr = &((*A)[c*nNodes0]);
00956 double* gPtr = &(GPtr[c*nTransRows]);
00957 SUNDANCE_MSG2(integrationVerb(),
00958 tabs << "c=" << c << ", facet case=" << fc
00959 << " W=" << W_[fc]);
00960
00961
00962 quadWeightsTmp = quadWeights_;
00963 quadPointsTmp = quadPts_;
00964 quad_.getAdaptedWeights(cellType(), dim(), (*cellLIDs)[c], fc ,
00965 mesh(), globalCurve(), quadPointsTmp, quadWeightsTmp, isCutByCurve);
00966 if (isCutByCurve){
00967 Array<double> w;
00968 w.resize(nNodesUnk()*nNodesTest()*nRefDerivUnk()*nRefDerivTest());
00969 for ( int i = 0 ; i < w.size() ; i++) w[i] = 0.0;
00970
00971 for (int t=0; t<nRefDerivTest(); t++){
00972 for (int nt=0; nt<nNodesTest(); nt++)
00973 for (int u=0; u<nRefDerivUnk(); u++)
00974 for (int nu=0; nu<nNodesUnk(); nu++)
00975 for (int q=0 ; q < quadWeightsTmp.size() ; q++)
00976
00977 w[nu + nNodesUnk()*nt + nNodes()*(u + nRefDerivUnk()*t)] +=
00978 chop( quadWeightsTmp[q]*W_ACI_F2_[fc][q][t][nt][u][nu] );
00979 }
00980 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(w[0]),
00981 &nNodes0, &(gPtr[0]), &nTransRows, &one,
00982 &(aPtr[0]), &nNodes0);
00983 }else{
00984 ::dgemm_("N", "N", &nNodes0, &oneI , &nTransRows, &coeff, &(W_[fc][0]),
00985 &nNodes0, &(gPtr[0]), &nTransRows, &one,
00986 &(aPtr[0]), &nNodes0);
00987 }
00988 }
00989 }
00990 else
00991 {
00992 int N = 1;
00993 for (int c=0; c<JVol.numCells(); c++)
00994 {
00995 int fc = 0;
00996 if (nfc != 1) fc = facetIndex[c];
00997 double* aPtr = &((*A)[c*nNodes0]);
00998 double* gPtr = &(GPtr[c*nTransRows]);
00999 SUNDANCE_MSG2(integrationVerb(),
01000 tabs << "c=" << c << ", facet case=" << fc
01001 << " W=" << W_[fc]);
01002
01003 ::dgemm_("N", "N", &nNodes0, &N, &nTransRows, &coeff, &(W_[fc][0]),
01004 &nNodes0, gPtr, &nTransRows, &one,
01005 aPtr, &nNodes0);
01006 }
01007 }
01008 }
01009
01010 addFlops(2 * nNodes0 * nCells * nTransRows);
01011 }
01012 }