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

Site Contact