|
Teko Version of the Day
|
00001 /* 00002 // @HEADER 00003 // 00004 // *********************************************************************** 00005 // 00006 // Teko: A package for block and physics based preconditioning 00007 // Copyright 2010 Sandia Corporation 00008 // 00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00010 // the U.S. Government retains certain rights in this software. 00011 // 00012 // Redistribution and use in source and binary forms, with or without 00013 // modification, are permitted provided that the following conditions are 00014 // met: 00015 // 00016 // 1. Redistributions of source code must retain the above copyright 00017 // notice, this list of conditions and the following disclaimer. 00018 // 00019 // 2. Redistributions in binary form must reproduce the above copyright 00020 // notice, this list of conditions and the following disclaimer in the 00021 // documentation and/or other materials provided with the distribution. 00022 // 00023 // 3. Neither the name of the Corporation nor the names of the 00024 // contributors may be used to endorse or promote products derived from 00025 // this software without specific prior written permission. 00026 // 00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 // 00039 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) 00040 // 00041 // *********************************************************************** 00042 // 00043 // @HEADER 00044 00045 */ 00046 00047 #include "Teko_BlockingEpetra.hpp" 00048 00049 #include "Epetra_IntVector.h" 00050 #include "Epetra_LocalMap.h" 00051 00052 using Teuchos::RCP; 00053 using Teuchos::rcp; 00054 00055 namespace Teko { 00056 namespace Epetra { 00057 namespace Blocking { 00058 00072 const MapPair buildSubMap(const std::vector< int > & gid, const Epetra_Comm &comm) 00073 { 00074 Teuchos::RCP<Epetra_Map> gidMap = rcp(new Epetra_Map(-1,gid.size(),&gid[0],0,comm)); 00075 Teuchos::RCP<Epetra_Map> contigMap = rcp(new Epetra_Map(-1,gid.size(),0,comm)); 00076 00077 return std::make_pair(gidMap,contigMap); 00078 } 00079 00089 const ImExPair buildExportImport(const Epetra_Map & baseMap,const MapPair & maps) 00090 { 00091 return std::make_pair(rcp(new Epetra_Import(*maps.first,baseMap)), 00092 rcp(new Epetra_Export(*maps.first,baseMap))); 00093 } 00094 00102 void buildSubVectors(const std::vector<MapPair> & maps, 00103 std::vector<RCP<Epetra_MultiVector> > & vectors,int count) 00104 { 00105 std::vector<MapPair>::const_iterator mapItr; 00106 00107 // loop over all maps 00108 for(mapItr=maps.begin();mapItr!=maps.end();mapItr++) { 00109 // add new elements to vectors 00110 RCP<Epetra_MultiVector> mv = rcp(new Epetra_MultiVector(*(*mapItr).second,count)); 00111 vectors.push_back(mv); 00112 } 00113 } 00114 00121 void one2many(std::vector<RCP<Epetra_MultiVector> > & many, const Epetra_MultiVector & single, 00122 const std::vector<RCP<Epetra_Import> > & subImport) 00123 { 00124 // std::vector<RCP<Epetra_Vector> >::const_iterator vecItr; 00125 std::vector<RCP<Epetra_MultiVector> >::const_iterator vecItr; 00126 std::vector<RCP<Epetra_Import> >::const_iterator impItr; 00127 00128 // using Importers fill the sub vectors from the mama vector 00129 for(vecItr=many.begin(),impItr=subImport.begin(); 00130 vecItr!=many.end();++vecItr,++impItr) { 00131 // for ease of access to the destination 00132 RCP<Epetra_MultiVector> destVec = *vecItr; 00133 00134 // extract the map with global indicies from the current vector 00135 const Epetra_BlockMap & globalMap = (*impItr)->TargetMap(); 00136 00137 // build the import vector as a view on the destination 00138 Epetra_MultiVector importVector(View,globalMap,destVec->Values(),destVec->Stride(),destVec->NumVectors()); 00139 00140 // perform the import 00141 importVector.Import(single,**impItr,Insert); 00142 } 00143 } 00144 00154 void many2one(Epetra_MultiVector & one, const std::vector<RCP<const Epetra_MultiVector> > & many, 00155 const std::vector<RCP<Epetra_Export> > & subExport) 00156 { 00157 // std::vector<RCP<const Epetra_Vector> >::const_iterator vecItr; 00158 std::vector<RCP<const Epetra_MultiVector> >::const_iterator vecItr; 00159 std::vector<RCP<Epetra_Export> >::const_iterator expItr; 00160 00161 // using Exporters fill the empty vector from the sub-vectors 00162 for(vecItr=many.begin(),expItr=subExport.begin(); 00163 vecItr!=many.end();++vecItr,++expItr) { 00164 00165 // for ease of access to the source 00166 RCP<const Epetra_MultiVector> srcVec = *vecItr; 00167 00168 // extract the map with global indicies from the current vector 00169 const Epetra_BlockMap & globalMap = (*expItr)->SourceMap(); 00170 00171 // build the export vector as a view of the destination 00172 Epetra_MultiVector exportVector(View,globalMap,srcVec->Values(),srcVec->Stride(),srcVec->NumVectors()); 00173 one.Export(exportVector,**expItr,Insert); 00174 } 00175 } 00176 00182 RCP<Epetra_IntVector> getSubBlockColumnGIDs(const Epetra_CrsMatrix & A,const MapPair & mapPair) 00183 { 00184 RCP<const Epetra_Map> blkGIDMap = mapPair.first; 00185 RCP<const Epetra_Map> blkContigMap = mapPair.second; 00186 00187 // fill index vector for rows 00188 Epetra_IntVector rIndex(A.RowMap(),true); 00189 for(int i=0;i<A.NumMyRows();i++) { 00190 // LID is need to get to contiguous map 00191 int lid = blkGIDMap->LID(A.GRID(i)); // this LID makes me nervous 00192 if(lid>-1) 00193 rIndex[i] = blkContigMap->GID(lid); 00194 else 00195 rIndex[i] = -1; 00196 } 00197 00198 // get relavant column indices 00199 Epetra_Import import(A.ColMap(),A.RowMap()); 00200 RCP<Epetra_IntVector> cIndex = rcp(new Epetra_IntVector(A.ColMap(),true)); 00201 cIndex->Import(rIndex,import,Insert); 00202 00203 return cIndex; 00204 } 00205 00206 // build a single subblock Epetra_CrsMatrix 00207 RCP<Epetra_CrsMatrix> buildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector<MapPair> & subMaps) 00208 { 00209 // get the number of variables families 00210 int numVarFamily = subMaps.size(); 00211 00212 TEUCHOS_ASSERT(i>=0 && i<numVarFamily); 00213 TEUCHOS_ASSERT(j>=0 && j<numVarFamily); 00214 00215 const Epetra_Map & gRowMap = *subMaps[i].first; // new GIDs 00216 const Epetra_Map & gColMap = *subMaps[j].first; 00217 const Epetra_Map & rowMap = *subMaps[i].second; // contiguous GIDs 00218 const Epetra_Map & colMap = *subMaps[j].second; 00219 00220 const RCP<Epetra_IntVector> plocal2ContigGIDs = getSubBlockColumnGIDs(A,subMaps[j]); 00221 Epetra_IntVector & local2ContigGIDs = *plocal2ContigGIDs; 00222 00223 RCP<Epetra_CrsMatrix> mat = rcp(new Epetra_CrsMatrix(Copy,rowMap,0)); 00224 00225 // get entry information 00226 int numMyRows = rowMap.NumMyElements(); 00227 int maxNumEntries = A.MaxNumEntries(); 00228 00229 // for extraction 00230 std::vector<int> indices(maxNumEntries); 00231 std::vector<double> values(maxNumEntries); 00232 00233 // for insertion 00234 std::vector<int> colIndices(maxNumEntries); 00235 std::vector<double> colValues(maxNumEntries); 00236 00237 // insert each row into subblock 00238 // let FillComplete handle column distribution 00239 for(int localRow=0;localRow<numMyRows;localRow++) { 00240 int numEntries = -1; 00241 int globalRow = gRowMap.GID(localRow); 00242 int lid = A.RowMap().LID(globalRow); 00243 int contigRow = rowMap.GID(localRow); 00244 TEUCHOS_ASSERT(lid>-1); 00245 00246 int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); 00247 TEUCHOS_ASSERT(err==0); 00248 00249 int numOwnedCols = 0; 00250 for(int localCol=0;localCol<numEntries;localCol++) { 00251 TEUCHOS_ASSERT(indices[localCol]>-1); 00252 00253 // if global id is not owned by this column 00254 int gid = local2ContigGIDs[indices[localCol]]; 00255 if(gid==-1) continue; // in contiguous row 00256 00257 colIndices[numOwnedCols] = gid; 00258 colValues[numOwnedCols] = values[localCol]; 00259 numOwnedCols++; 00260 } 00261 00262 // insert it into the new matrix 00263 mat->InsertGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); 00264 } 00265 00266 // fill it and automagically optimize the storage 00267 mat->FillComplete(colMap,rowMap); 00268 00269 return mat; 00270 } 00271 00272 // build a single subblock Epetra_CrsMatrix 00273 void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector<MapPair> & subMaps,Epetra_CrsMatrix & mat) 00274 { 00275 // get the number of variables families 00276 int numVarFamily = subMaps.size(); 00277 00278 TEUCHOS_ASSERT(i>=0 && i<numVarFamily); 00279 TEUCHOS_ASSERT(j>=0 && j<numVarFamily); 00280 00281 const Epetra_Map & gRowMap = *subMaps[i].first; // new GIDs 00282 const Epetra_Map & gColMap = *subMaps[j].first; 00283 const Epetra_Map & rowMap = *subMaps[i].second; // contiguous GIDs 00284 const Epetra_Map & colMap = *subMaps[j].second; 00285 00286 const RCP<Epetra_IntVector> plocal2ContigGIDs = getSubBlockColumnGIDs(A,subMaps[j]); 00287 Epetra_IntVector & local2ContigGIDs = *plocal2ContigGIDs; 00288 00289 mat.PutScalar(0.0); 00290 00291 // get entry information 00292 int numMyRows = rowMap.NumMyElements(); 00293 int maxNumEntries = A.MaxNumEntries(); 00294 00295 // for extraction 00296 std::vector<int> indices(maxNumEntries); 00297 std::vector<double> values(maxNumEntries); 00298 00299 // for insertion 00300 std::vector<int> colIndices(maxNumEntries); 00301 std::vector<double> colValues(maxNumEntries); 00302 00303 // insert each row into subblock 00304 // let FillComplete handle column distribution 00305 for(int localRow=0;localRow<numMyRows;localRow++) { 00306 int numEntries = -1; 00307 int globalRow = gRowMap.GID(localRow); 00308 int lid = A.RowMap().LID(globalRow); 00309 int contigRow = rowMap.GID(localRow); 00310 TEUCHOS_ASSERT(lid>-1); 00311 00312 int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); 00313 TEUCHOS_ASSERT(err==0); 00314 00315 int numOwnedCols = 0; 00316 for(int localCol=0;localCol<numEntries;localCol++) { 00317 TEUCHOS_ASSERT(indices[localCol]>-1); 00318 00319 // if global id is not owned by this column 00320 int gid = local2ContigGIDs[indices[localCol]]; 00321 if(gid==-1) continue; // in contiguous row 00322 00323 colIndices[numOwnedCols] = gid; 00324 colValues[numOwnedCols] = values[localCol]; 00325 numOwnedCols++; 00326 } 00327 00328 // insert it into the new matrix 00329 mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); 00330 } 00331 } 00332 00333 } // end Blocking 00334 } // end Epetra 00335 } // end Teko
1.7.4