SundanceTrivialGrouper.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 "SundanceTrivialGrouper.hpp"
00032 #include "SundanceRefIntegral.hpp"
00033 #include "SundanceQuadratureIntegral.hpp"
00034 #include "SundanceReducedIntegral.hpp"
00035 #include "SundanceMaximalQuadratureIntegral.hpp"
00036 #include "SundanceCurveQuadratureIntegral.hpp"
00037 #include "SundanceEquationSet.hpp"
00038 #include "SundanceIntegralGroup.hpp"
00039 #include "SundanceBasisFamily.hpp"
00040 #include "SundanceSparsitySuperset.hpp"
00041 #include "SundanceQuadratureFamily.hpp"
00042 #include "SundanceReducedQuadrature.hpp"
00043 #include "SundanceMap.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "PlayaTabs.hpp"
00046 
00047 using namespace Sundance;
00048 using namespace Teuchos;
00049 
00050 
00051 
00052 void TrivialGrouper::findGroups(const EquationSet& eqn,
00053   const CellType& maxCellType,
00054   int spatialDim,
00055   const CellType& cellType,
00056   int cellDim,
00057   const QuadratureFamily& quad,
00058   const RCP<SparsitySuperset>& sparsity,
00059   bool isInternalBdry,
00060   Array<RCP<IntegralGroup> >& groups,
00061   const ParametrizedCurve& globalCurve,
00062   const Mesh& mesh) const
00063 {
00064   Tabs tab(0);
00065 
00066   SUNDANCE_MSG1(setupVerb(),
00067     tab << "in TrivialGrouper::findGroups(), num derivs = " 
00068     << sparsity->numDerivs());
00069   SUNDANCE_MSG1(setupVerb(), 
00070     tab << "cell type = " << cellType);
00071   SUNDANCE_MSG1(setupVerb(), 
00072     tab << "sparsity = " << std::endl << *sparsity << std::endl);
00073 
00074   const ReducedQuadrature* rq = dynamic_cast<const ReducedQuadrature*>(quad.ptr(
00075 ).get());
00076   bool useReducedQuad = (rq != 0);
00077   SUNDANCE_MSG1(setupVerb(), tab << "using reduced quadrature: " 
00078     << useReducedQuad);
00079 
00080 
00081   int vecCount=0;
00082   int constCount=0;
00083 
00084   bool isMaximal = cellType == maxCellType;
00085   bool useMaxIntegral = isMaximal;
00086   
00087   /* turn off grouping for submaximal cells. This works around 
00088    * a bug detected by Rob Kirby that
00089    * shows up with Nitsche BCs in mixed-element discretizations */
00090   bool doGroups = true;
00091   if (!isMaximal) doGroups = false;
00092 
00093 
00094   typedef Sundance::Map<OrderedQuartet<int, BasisFamily, int, BasisFamily>, Array<RCP<ElementIntegral> > > twoFormMap;
00095   typedef Sundance::Map<OrderedTriple<int,int,BasisFamily>, Array<RCP<ElementIntegral> > > oneFormMap;
00096   Sundance::Map<OrderedQuartet<int, BasisFamily, int, BasisFamily>, Array<RCP<ElementIntegral> > > twoForms;
00097   Sundance::Map<OrderedQuartet<int, BasisFamily, int, BasisFamily>, Array<int> > twoFormResultIndices;
00098   Sundance::Map<OrderedTriple<int,int,BasisFamily>, Array<RCP<ElementIntegral> > > oneForms;
00099   Sundance::Map<OrderedTriple<int,int,BasisFamily>, Array<int> > oneFormResultIndices;
00100 
00101   for (int i=0; i<sparsity->numDerivs(); i++)
00102   {
00103     const MultipleDeriv& d = sparsity->deriv(i);
00104     SUNDANCE_MSG3(setupVerb(),
00105       tab << "--------------------------------------------------");
00106     SUNDANCE_MSG3(setupVerb(),
00107       tab << "defining integration policy for " << d);
00108     SUNDANCE_MSG3(setupVerb(),
00109       tab << "--------------------------------------------------");
00110       
00111     if (d.order()==0) 
00112     {
00113       RCP<ElementIntegral> integral ;
00114       int resultIndex;
00115       if (sparsity->isConstant(i))
00116       {
00117         if (globalCurve.isCurveValid() && globalCurve.isCurveIntegral() && isMaximal )
00118         { // ----- curve Integral ------
00119           integral = rcp(new CurveQuadratureIntegral( maxCellType, true ,
00120               quad, globalCurve , mesh , setupVerb() ) );
00121         }
00122         else
00123         { // --- no curve integral ---
00124           integral = rcp(new RefIntegral(spatialDim, maxCellType,
00125               cellDim, cellType, quad , isInternalBdry, globalCurve , mesh , setupVerb()));
00126         }
00127         resultIndex = constCount++;
00128       }
00129       else
00130       {
00131         if (useReducedQuad)
00132         { 
00133           integral = rcp(new ReducedIntegral(spatialDim, maxCellType,
00134               cellDim, cellType, quad , isInternalBdry, globalCurve , mesh , setupVerb()));
00135         }
00136         else if (useMaxIntegral)
00137         {
00138           if (globalCurve.isCurveValid() && globalCurve.isCurveIntegral() && isMaximal )
00139           { // ----- curve Integral ------
00140             integral = rcp(new CurveQuadratureIntegral(maxCellType, false ,
00141                 quad, globalCurve , mesh , setupVerb()));
00142           }
00143           else
00144           { // --- no curve integral ---
00145             integral = rcp(new MaximalQuadratureIntegral(maxCellType,
00146                 quad, globalCurve , mesh , setupVerb()));
00147           }
00148         }
00149         else // no maxCell Integral
00150         {
00151           integral = rcp(new QuadratureIntegral(spatialDim, maxCellType, 
00152               cellDim, cellType, quad, isInternalBdry, globalCurve , mesh ,
00153               setupVerb()));
00154         }
00155         resultIndex = vecCount++;
00156       }
00157       integral->setVerb(integrationVerb(), transformVerb());
00158       SUNDANCE_MSG3(setupVerb(), tab << "is zero-form");
00159       groups.append(rcp(new IntegralGroup(tuple(integral),
00160             tuple(resultIndex), setupVerb())));
00161     }
00162     else
00163     {
00164       BasisFamily testBasis;
00165       BasisFamily unkBasis;
00166       MultiIndex miTest;
00167       MultiIndex miUnk;
00168       int rawTestID = -1;
00169       int rawUnkID = -1;
00170       int rawParamID = -1;
00171       int testID = -1;
00172       int unkID = -1;
00173       int paramID = -1;
00174       int testBlock = -1;
00175       int unkBlock = -1;
00176       bool isOneForm;
00177       bool hasParam;
00178       extractWeakForm(eqn, d, testBasis, unkBasis, miTest, miUnk, 
00179         rawTestID, rawUnkID,
00180         testID, unkID,
00181         testBlock, unkBlock,
00182         rawParamID, paramID,
00183         isOneForm, hasParam);
00184       
00185       TEUCHOS_TEST_FOR_EXCEPT(hasParam && !isOneForm);
00186 
00187       /* The parameter index acts as an index into a multivector. If
00188        * this one-form is not a parametric derivative, we use zero as
00189        * the multivector index */
00190       int mvIndex = 0;
00191       if (hasParam) mvIndex = paramID; 
00192       
00193       /* In variational problems we might have (u,v) and (v,u). Because 
00194        * the derivative is stored as an unordered multiset it can't 
00195        * distinguish between the two cases. We need to check the equation 
00196        * set to see if the two functions show up as variations and 
00197        * unknowns. If so, then we need to produce the transposed integral.
00198        */
00199       bool transposeNeeded = false;
00200       if (!isOneForm && rawTestID!=rawUnkID 
00201         && eqn.hasVarID(rawUnkID) && eqn.hasUnkID(rawTestID))
00202       {
00203         transposeNeeded = true;
00204       }
00205 
00206 
00207       if (isOneForm)
00208       {
00209         SUNDANCE_MSG3(setupVerb(), tab << "is one-form");
00210       }
00211       else
00212       {
00213         SUNDANCE_MSG3(setupVerb(), tab << "is two-form");
00214       }
00215 
00216 
00217       if (hasParam)
00218       {
00219         SUNDANCE_MSG3(setupVerb(), tab << "is a parametric derivative");
00220       }
00221       else
00222       {
00223         SUNDANCE_MSG3(setupVerb(), tab << "is not a parametric derivative");
00224       }
00225 
00226       SUNDANCE_MSG3(setupVerb(), 
00227         tab << "test ID: " << testID << " block=" << testBlock);
00228 
00229       if (!isOneForm)
00230       {
00231         SUNDANCE_MSG3(setupVerb(), tab << "unk funcID: " << unkID << " block=" << unkBlock);
00232       }
00233 
00234       if (hasParam)
00235       {
00236         SUNDANCE_MSG3(setupVerb(), tab << "paramID=" << paramID);
00237       }
00238                    
00239       SUNDANCE_MSG3(setupVerb(), tab << "deriv = " << d);
00240       if (sparsity->isConstant(i))
00241       {
00242         SUNDANCE_MSG3(setupVerb(), tab << "coeff is constant");
00243       }
00244       else
00245       {
00246         SUNDANCE_MSG3(setupVerb(), tab << "coeff is non-constant");
00247       }
00248 
00249       RCP<ElementIntegral> integral;
00250       RCP<ElementIntegral> transposedIntegral;
00251       int resultIndex;
00252       if (sparsity->isConstant(i))
00253       {
00254         if (isOneForm)
00255         {
00256           int alpha=0;
00257           if (miTest.order()==1)
00258           {
00259             alpha = miTest.firstOrderDirection();
00260           }
00261           // test if we need to make curve Integral
00262           if (globalCurve.isCurveValid() && globalCurve.isCurveIntegral() && isMaximal )
00263           { // ----- curve Integral ------
00264             integral = rcp(new CurveQuadratureIntegral(maxCellType, true ,
00265                 testBasis, alpha,
00266                 miTest.order(), quad, globalCurve , mesh ,setupVerb()));
00267           }
00268           else
00269           { // --- no curve integral ---
00270             integral = rcp(new RefIntegral(spatialDim, maxCellType,
00271                 cellDim, cellType,
00272                 testBasis, alpha,
00273                 miTest.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00274           }
00275         }
00276         else
00277         {
00278           int alpha=0;
00279           int beta=0;
00280           if (miTest.order()==1)
00281           {
00282             alpha = miTest.firstOrderDirection();
00283           }
00284           if (miUnk.order()==1)
00285           {
00286             beta = miUnk.firstOrderDirection();
00287           }
00288           // test if we need to make curve Integral
00289           if (globalCurve.isCurveValid() && globalCurve.isCurveIntegral() && isMaximal )
00290           { // ----- curve Integral ------
00291             integral = rcp(new CurveQuadratureIntegral(maxCellType, true ,
00292                 testBasis, alpha,
00293                 miTest.order(),
00294                 unkBasis, beta,
00295                 miUnk.order(), quad, globalCurve , mesh ,setupVerb()));
00296           }
00297           else // --- no curve integral ---
00298           {
00299             integral = rcp(new RefIntegral(spatialDim, maxCellType,
00300                 cellDim, cellType,
00301                 testBasis, alpha, miTest.order(),
00302                 unkBasis, beta, miUnk.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00303           }
00304           if (transposeNeeded)
00305           {
00306             if (globalCurve.isCurveValid() && globalCurve.isCurveIntegral() && isMaximal )
00307             { // ----- curve Integral ------
00308               transposedIntegral = rcp(new CurveQuadratureIntegral(maxCellType, true ,
00309                   unkBasis, beta,
00310                   miUnk.order(),
00311                   testBasis, alpha,
00312                   miTest.order(),
00313                   quad, globalCurve , mesh ,setupVerb()));
00314             }
00315             else // --- no curve integral ---
00316             {
00317               transposedIntegral = rcp(new RefIntegral(spatialDim, maxCellType,
00318                   cellDim, cellType,
00319                   unkBasis, beta,
00320                   miUnk.order(),
00321                   testBasis, alpha,
00322                   miTest.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00323             }
00324           }
00325         }
00326         resultIndex = constCount++;
00327       }
00328       else /* sparsity->isVector(i) */
00329       {
00330         if (isOneForm)
00331         {
00332           int alpha=0;
00333           if (miTest.order()==1)
00334           {
00335             alpha = miTest.firstOrderDirection();
00336           }
00337           if (useReducedQuad)
00338           {
00339             integral = rcp(new ReducedIntegral(spatialDim, maxCellType,
00340                 cellDim, cellType,
00341                 testBasis, alpha,
00342                 miTest.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00343           }
00344           else if (useMaxIntegral)
00345           {
00346             if ( globalCurve.isCurveValid() && globalCurve.isCurveIntegral() )
00347             { // ----- curve Integral ------
00348               integral = rcp(new CurveQuadratureIntegral(maxCellType, false ,
00349                   testBasis, alpha,
00350                   miTest.order(), quad, globalCurve , mesh ,setupVerb()));
00351             }
00352             else
00353             {// --- no curve integral ---
00354               integral = rcp(new MaximalQuadratureIntegral(maxCellType,
00355                   testBasis, alpha,
00356                   miTest.order(), quad, globalCurve , mesh ,setupVerb()));
00357             }
00358           }
00359           else // no maxCell Integral
00360           {
00361             integral = rcp(new QuadratureIntegral(spatialDim, maxCellType,
00362                 cellDim, cellType,
00363                 testBasis, alpha, 
00364                 miTest.order(), quad, isInternalBdry, globalCurve , mesh ,setupVerb()));
00365           }
00366         }
00367         else /* two-form */
00368         {
00369           int alpha=0;
00370           int beta=0;
00371           if (miTest.order()==1)
00372           {
00373             alpha = miTest.firstOrderDirection();
00374           }
00375           if (miUnk.order()==1)
00376           {
00377             beta = miUnk.firstOrderDirection();
00378           }
00379           if (useReducedQuad)
00380           {
00381             integral = rcp(new ReducedIntegral(spatialDim, maxCellType,
00382                 cellDim, cellType,
00383                 testBasis, alpha, miTest.order(),
00384                 unkBasis, beta, miUnk.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00385             if (transposeNeeded)
00386             {
00387               transposedIntegral = rcp(new ReducedIntegral(spatialDim, maxCellType,
00388                   cellDim, cellType,
00389                   unkBasis, beta,
00390                   miUnk.order(),
00391                   testBasis, alpha,
00392                   miTest.order(), quad , isInternalBdry, globalCurve , mesh ,setupVerb()));
00393             }
00394           }
00395           else if (useMaxIntegral)
00396           {
00397             if ( globalCurve.isCurveValid() && globalCurve.isCurveIntegral() )
00398             { // ----- curve Integral ------
00399               integral = rcp(new CurveQuadratureIntegral(maxCellType, false ,
00400                   testBasis, alpha,
00401                   miTest.order(),
00402                   unkBasis, beta,
00403                   miUnk.order(), quad, globalCurve , mesh ,setupVerb()));
00404             }
00405             else
00406             {// --- no curve integral ---
00407               integral = rcp(new MaximalQuadratureIntegral(maxCellType,
00408                   testBasis, alpha,
00409                   miTest.order(),
00410                   unkBasis, beta,
00411                   miUnk.order(), quad, globalCurve , mesh ,setupVerb()));
00412             }
00413             if (transposeNeeded)
00414             {
00415               if ( globalCurve.isCurveValid() && globalCurve.isCurveIntegral() )
00416               { // ----- curve Integral ------
00417                 transposedIntegral = rcp(new CurveQuadratureIntegral(maxCellType, false ,
00418                     unkBasis, beta, miUnk.order(),
00419                     testBasis, alpha, miTest.order(), quad,
00420                     globalCurve , mesh ,setupVerb()));
00421               }
00422               else
00423               { // --- no curve integral ---
00424                 transposedIntegral = rcp(new MaximalQuadratureIntegral(maxCellType,
00425                     unkBasis, beta, miUnk.order(),
00426                     testBasis, alpha, miTest.order(), quad,
00427                     globalCurve , mesh ,setupVerb()));
00428               }
00429             }
00430           }
00431           else // no MaxCell integral
00432           {
00433             integral = rcp(new QuadratureIntegral(spatialDim, maxCellType,
00434                 cellDim, cellType,
00435                 testBasis, alpha, 
00436                 miTest.order(),
00437                 unkBasis, beta, 
00438                 miUnk.order(), quad, isInternalBdry, globalCurve , mesh ,setupVerb()));
00439             if (transposeNeeded)
00440             {
00441               transposedIntegral = rcp(new QuadratureIntegral(spatialDim, maxCellType,
00442                   cellDim, cellType,
00443                   unkBasis, beta, miUnk.order(),
00444                   testBasis, alpha, miTest.order(), quad, 
00445                   isInternalBdry, globalCurve , mesh ,setupVerb()));
00446             }
00447           }
00448         }
00449         resultIndex = vecCount++;
00450       }
00451 
00452       /* Set the verbosity for the integrals */
00453       integral->setVerb(integrationVerb(), transformVerb());
00454       if (transposeNeeded)
00455       {
00456         transposedIntegral->setVerb(integrationVerb(), transformVerb());
00457       }
00458           
00459       
00460       if (isOneForm)
00461       {
00462         if (doGroups)
00463         {
00464           OrderedTriple<int,int,BasisFamily> testKey(rawTestID, mvIndex, testBasis);
00465           if (!oneForms.containsKey(testKey))
00466           {
00467             oneForms.put(testKey, tuple(integral));
00468             oneFormResultIndices.put(testKey, tuple(resultIndex));
00469           }
00470           else
00471           {
00472             oneForms[testKey].append(integral);
00473             oneFormResultIndices[testKey].append(resultIndex);
00474           }
00475         }
00476         else
00477         {
00478           groups.append(rcp(new IntegralGroup(tuple(testID), tuple(testBlock),
00479                 tuple(mvIndex),
00480                 tuple(integral),
00481                 tuple(resultIndex), tuple(d), setupVerb())));
00482         }
00483       }
00484       else
00485       {
00486         if (!doGroups)
00487         {
00488           groups.append(rcp(new IntegralGroup(tuple(testID), tuple(testBlock),
00489                 tuple(unkID), tuple(unkBlock),
00490                 tuple(integral),
00491                 tuple(resultIndex), tuple(d), setupVerb())));
00492           if (transposeNeeded)
00493           {
00494             groups.append(rcp(new IntegralGroup(tuple(unkID), tuple(unkBlock),
00495                   tuple(testID), tuple(testBlock),
00496                   tuple(transposedIntegral),
00497                   tuple(resultIndex), tuple(d), setupVerb())));
00498           }
00499         }
00500         else
00501         {
00502           Tabs tab3;
00503           OrderedQuartet<int, BasisFamily, int, BasisFamily> testUnkKey(rawTestID, testBasis, rawUnkID, unkBasis);
00504 
00505 
00506           SUNDANCE_MSG2(setupVerb(), tab3 << "key=" << testUnkKey);
00507           if (!twoForms.containsKey(testUnkKey))
00508           {
00509             Tabs tab4;
00510             SUNDANCE_MSG2(setupVerb(), tab4 << "key not found");
00511             twoForms.put(testUnkKey, tuple(integral));
00512             twoFormResultIndices.put(testUnkKey, tuple(resultIndex));
00513           }
00514           else
00515           {
00516             Tabs tab4;
00517             SUNDANCE_MSG2(setupVerb(), tab4 << "key found");
00518             twoForms[testUnkKey].append(integral);
00519             twoFormResultIndices[testUnkKey].append(resultIndex);
00520           }
00521           if (transposeNeeded)
00522           {
00523             OrderedQuartet<int, BasisFamily, int, BasisFamily> unkTestKey(rawUnkID, unkBasis, rawTestID, testBasis);
00524             
00525             if (!twoForms.containsKey(unkTestKey))
00526             {
00527               Tabs tab4;
00528               SUNDANCE_MSG2(setupVerb(), tab4 << "key not found");
00529               twoForms.put(unkTestKey, tuple(transposedIntegral));
00530               twoFormResultIndices.put(unkTestKey, tuple(resultIndex));
00531             }
00532             else
00533             {
00534               Tabs tab4;
00535               SUNDANCE_MSG2(setupVerb(), tab4 << "key found");
00536               twoForms[unkTestKey].append(transposedIntegral);
00537               twoFormResultIndices[unkTestKey].append(resultIndex);
00538             }
00539           }
00540         }
00541       }
00542     }
00543   }
00544 
00545   if (doGroups)
00546   {
00547     Tabs tab;
00548     SUNDANCE_MSG2(setupVerb(), tab << "creating integral groups");
00549     for (twoFormMap::const_iterator i=twoForms.begin(); i!=twoForms.end(); i++)
00550     {
00551       Tabs tab3;
00552       SUNDANCE_MSG2(setupVerb(), tab3 << "integral group number="
00553         << groups.size());
00554       int rawTestID = i->first.a();
00555       BasisFamily testBasis = i->first.b();
00556       int rawUnkID = i->first.c();
00557       BasisFamily unkBasis = i->first.d();
00558       int testID = eqn.reducedVarID(rawTestID);
00559       int unkID = eqn.reducedUnkID(rawUnkID);
00560       int testBlock = eqn.blockForVarID(rawTestID);
00561       int unkBlock = eqn.blockForUnkID(rawUnkID);
00562       const Array<RCP<ElementIntegral> >& integrals = i->second;
00563       const Array<int>& resultIndices 
00564         = twoFormResultIndices.get(i->first);
00565       SUNDANCE_MSG2(setupVerb(), tab3 << "creating two-form integral group" << std::endl
00566         << tab3 << "testID=" << rawTestID << std::endl
00567         << tab3 << "unkID=" << rawUnkID << std::endl
00568         << tab3 << "testBlock=" << testBlock << std::endl
00569         << tab3 << "unkBlock=" << unkBlock << std::endl
00570         << tab3 << "testBasis=" << testBasis << std::endl
00571         << tab3 << "unkBasis=" << unkBasis << std::endl
00572         << tab3 << "resultIndices=" << resultIndices);
00573       Array<MultipleDeriv> grpDerivs;
00574       for (int j=0; j<resultIndices.size(); j++)
00575       {
00576         MultipleDeriv d = sparsity->deriv(resultIndices[j]);
00577         SUNDANCE_MSG2(setupVerb(), tab3 << "deriv " << j << " " 
00578           << d);
00579         grpDerivs.append(d);
00580       }
00581       groups.append(rcp(new IntegralGroup(tuple(testID), tuple(testBlock), 
00582             tuple(unkID), tuple(unkBlock),
00583             integrals, resultIndices, grpDerivs, setupVerb())));
00584     }
00585 
00586     for (oneFormMap::const_iterator i=oneForms.begin(); i!=oneForms.end(); i++)
00587     {
00588       Tabs tab3;
00589       SUNDANCE_MSG2(setupVerb(), tab3 << "integral group number="
00590         << groups.size());
00591       int rawTestID = i->first.a();
00592       int mvIndex = i->first.b();
00593       int testID = eqn.reducedVarID(rawTestID);
00594       int testBlock = eqn.blockForVarID(rawTestID);
00595       const Array<RCP<ElementIntegral> >& integrals = i->second;
00596       const Array<int>& resultIndices 
00597         = oneFormResultIndices.get(i->first);
00598       SUNDANCE_MSG2(setupVerb(), tab3 << "creating one-form integral group" << std::endl
00599         << tab3 << "testID=" << testID << std::endl
00600         << tab3 << "resultIndices=" << resultIndices);
00601       Array<MultipleDeriv> grpDerivs;
00602       for (int j=0; j<resultIndices.size(); j++)
00603       {
00604         MultipleDeriv d = sparsity->deriv(resultIndices[j]);
00605         SUNDANCE_MSG2(setupVerb(), tab3 << "deriv " << j << " " 
00606           << d);
00607         grpDerivs.append(d);
00608       }
00609       groups.append(rcp(new IntegralGroup(tuple(testID), tuple(testBlock),
00610             tuple(mvIndex),
00611             integrals, resultIndices, grpDerivs, setupVerb())));
00612     }
00613   }
00614   
00615   
00616 }
00617 

Site Contact