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 "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
00147
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
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