SundanceVectorFillingAssemblyKernel.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 "SundanceOut.hpp"
00032 #include "SundanceTabs.hpp"
00033 #include "SundanceVectorFillingAssemblyKernel.hpp"
00034 #include "Teuchos_Time.hpp"
00035 #include "Teuchos_TimeMonitor.hpp"
00036 #include "TSFLoadableBlockVector.hpp"
00037 
00038 
00039 
00040 using namespace Sundance;
00041 using namespace Sundance;
00042 using namespace Sundance;
00043 using namespace Teuchos;
00044 using namespace TSFExtended;
00045 using std::setw;
00046 using std::endl;
00047       
00048 static Time& vecInsertTimer() 
00049 {
00050   static RCP<Time> rtn 
00051     = TimeMonitor::getNewTimer("vector insertion"); 
00052   return *rtn;
00053 }
00054 
00055 VectorFillingAssemblyKernel::VectorFillingAssemblyKernel(
00056   const Array<RCP<DOFMapBase> >& dofMap,
00057   const Array<RCP<Array<int> > >& isBCIndex,
00058   const Array<int>& lowestLocalIndex,
00059   Array<Vector<double> >& b,
00060   bool partitionBCs,
00061   int verbosity
00062   )
00063   : AssemblyKernelBase(verbosity),
00064     b_(b),
00065     vec_(b.size()),
00066     mapBundle_(dofMap, isBCIndex, lowestLocalIndex, partitionBCs, verbosity)
00067 {
00068   Tabs tab0;
00069 
00070   SUNDANCE_MSG1(verb(), tab0 << "VectorFillingAssemblyKernel ctor");
00071   
00072   int numBlocks = dofMap.size();
00073 
00074   for (int i=0; i<b_.size(); i++)
00075   {
00076     vec_[i].resize(numBlocks);
00077     for (int block=0; block<numBlocks; block++)
00078     {
00079       Tabs tab1;
00080       SUNDANCE_MSG1(verb(), tab1 << "getting vector for block b=" 
00081         << block << " of " << numBlocks);
00082       Vector<double> vecBlock; 
00083       if (partitionBCs && numBlocks == 1)
00084       {
00085         Tabs tab2;
00086         SUNDANCE_MSG1(verb(), tab2 << "making loadable block vector");
00087         vecBlock = b[i];
00088         int lowestRow = mapBundle_.lowestLocalIndex(block) ;
00089         int highestRow = lowestRow + mapBundle_.dofMap(block)->numLocalDOFs();
00090         vec_[i][block] = 
00091           rcp(new LoadableBlockVector(vecBlock, lowestRow,
00092               highestRow, mapBundle_.isBCIndex(block)));
00093       }
00094       else
00095       {
00096         vecBlock = b[i].getBlock(block);
00097         vec_[i][block] = rcp_dynamic_cast<LoadableVector<double> >(vecBlock.ptr());
00098       }
00099       TEST_FOR_EXCEPTION(vec_[i][block].get()==0, RuntimeError,
00100         "vector block " << block << " is not loadable");
00101       vecBlock.zero();
00102     }
00103   }
00104   SUNDANCE_MSG1(verb(), tab0 << "done VectorFillingAssemblyKernel ctor");
00105 }
00106 
00107 
00108 void VectorFillingAssemblyKernel::buildLocalDOFMaps(
00109   const RCP<StdFwkEvalMediator>& mediator,
00110   IntegrationCellSpecifier intCellSpec,
00111   const Array<Set<int> >& requiredFuncs) 
00112 {
00113   mapBundle_.buildLocalDOFMaps(mediator, intCellSpec, requiredFuncs,
00114     verb());
00115 }
00116 
00117 
00118 void VectorFillingAssemblyKernel::insertLocalVectorBatch(
00119   bool isBCRqc,
00120   bool useCofacetCells,
00121   const Array<int>& funcID,  
00122   const Array<int>& funcBlock, 
00123   const Array<int>& mvIndices, 
00124   const Array<double>& localValues) const
00125 {
00126   TimeMonitor timer(vecInsertTimer());
00127   Tabs tab0;
00128 
00129   SUNDANCE_MSG1(verb(), tab0 << "inserting local vector batch");
00130   SUNDANCE_MSG4(verb(), tab0 << "vector values are " << localValues);
00131 
00132   const MapBundle& mb = mapBundle_;
00133   int nCells = mb.nCells();
00134 
00135   for (int i=0; i<funcID.size(); i++)
00136   {
00137     Tabs tab1;
00138     SUNDANCE_MSG2(verb(), tab1 << "function ID = "<< funcID[i] 
00139       << " of " << funcID.size());
00140     SUNDANCE_MSG2(verb(), tab1 << "is BC eqn = " << isBCRqc);
00141     SUNDANCE_MSG2(verb(), tab1 << "num cells = " << nCells);
00142     SUNDANCE_MSG2(verb(), tab1 << "using cofacet cells = " << useCofacetCells);
00143     SUNDANCE_MSG2(verb(), tab1 << "multivector index = " 
00144       << mvIndices[i]);
00145 
00146     /* First, find the block associated with the current function
00147      * so that we can find the appropriate DOF information */
00148     int block = funcBlock[i];
00149 
00150     const RCP<DOFMapBase>& dofMap = mb.dofMap(block);
00151     int lowestLocalRow = mb.lowestLocalIndex(block);
00152 
00153     int chunk = mb.mapStruct(block, useCofacetCells)->chunkForFuncID(funcID[i]);
00154     SUNDANCE_MSG2(verb(), tab1 << "chunk = " << chunk);
00155 
00156     int funcIndex = mb.mapStruct(block, useCofacetCells)->indexForFuncID(funcID[i]);
00157     SUNDANCE_MSG2(verb(), tab1 << "func offset into local DOF map = " 
00158       << funcIndex);
00159 
00160     const Array<int>& dofs = mb.localDOFs(block, useCofacetCells, chunk);
00161     SUNDANCE_MSG4(verb(), tab1 << "local dofs = " << dofs);    
00162 
00163     int nFuncs = mb.mapStruct(block, useCofacetCells)->numFuncs(chunk);
00164     SUNDANCE_MSG2(verb(), tab1 << "num funcs in chunk = " << nFuncs);
00165 
00166     int nNodes = mb.nNodesInChunk(block, useCofacetCells, chunk);
00167     SUNDANCE_MSG2(verb(), tab1 << "num nodes in chunk = " << nNodes);
00168 
00169     const Array<int>& isBCIndex = *(mb.isBCIndex(block));
00170 
00171     /* At this point, we can start to load the elements */
00172     int r=0;
00173     RCP<TSFExtended::LoadableVector<double> > vecBlock 
00174       = vec_[mvIndices[i]][block];
00175 
00176     FancyOStream& os = Out::os();
00177 
00178     for (int c=0; c<nCells; c++)
00179     {
00180       Tabs tab2;
00181       SUNDANCE_MSG2(verb(), tab2 << "cell = " << c << " of " << nCells);
00182       for (int n=0; n<nNodes; n++, r++)
00183       {
00184         Tabs tab3;
00185         int rowIndex = dofs[(c*nFuncs + funcIndex)*nNodes + n];
00186         int localRowIndex = rowIndex - lowestLocalRow;
00187         if (verb() >= 2) os << tab3 << "n=" << setw(4) << n 
00188                             << " G=" << setw(8) << rowIndex 
00189                             << " L=" << setw(8) << localRowIndex;
00190         if (!(dofMap->isLocalDOF(rowIndex))
00191           || isBCRqc!=isBCIndex[localRowIndex]) 
00192         {
00193           if (verb() >= 2)
00194           {
00195             if (!dofMap->isLocalDOF(rowIndex)) 
00196             {
00197               os << " --- skipping (is non-local) ---" << std::endl;
00198             }
00199             else if (!isBCRqc && isBCIndex[localRowIndex])
00200             {
00201               os << " --- skipping (is BC row) ---" << std::endl;
00202             }
00203             else
00204             {
00205               os << " --- skipping (is non-BC row) ---" << std::endl;
00206             }
00207           }
00208         }
00209         else
00210         {
00211           if (verb() >= 2) os << setw(15) << localValues[r] << std::endl;
00212           vecBlock->addToElement(rowIndex, localValues[r]);
00213         }
00214       }
00215     }
00216   }
00217   SUNDANCE_MSG1(verb(), tab0 << "...done vector insertion");
00218 }
00219 
00220 

Site Contact