|
EpetraExt
Development
|
00001 /* 00002 //@HEADER 00003 // *********************************************************************** 00004 // 00005 // EpetraExt: Epetra Extended - Linear Algebra Services Package 00006 // Copyright (2011) Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 //@HEADER 00042 */ 00043 00044 #include "EpetraExt_ConfigDefs.h" 00045 #ifdef HAVE_MPI 00046 #include "Epetra_MpiComm.h" 00047 #include "mpi.h" 00048 #else 00049 #include "Epetra_SerialComm.h" 00050 #endif 00051 #include "EpetraExt_XMLReader.h" 00052 #include "Teuchos_ParameterList.hpp" 00053 #include "Teuchos_RefCountPtr.hpp" 00054 #include "Teuchos_XMLObject.hpp" 00055 #include "Teuchos_StringInputSource.hpp" 00056 #include "Teuchos_FileInputSource.hpp" 00057 #include "Teuchos_ParameterList.hpp" 00058 #include "Teuchos_XMLParameterListReader.hpp" 00059 #include "Teuchos_Assert.hpp" 00060 #include "Epetra_Map.h" 00061 #include "Epetra_CrsGraph.h" 00062 #include "Epetra_FECrsGraph.h" 00063 #include "Epetra_RowMatrix.h" 00064 #include "Epetra_CrsMatrix.h" 00065 #include "Epetra_FECrsMatrix.h" 00066 #include "Epetra_MultiVector.h" 00067 #include "Epetra_Import.h" 00068 00069 // ============================================================================ 00070 static void Tokenize(const std::string& str, std::vector<std::string>& tokens, 00071 const std::string& delimiters = " ") 00072 { 00073 // Skip delimiters at beginning. 00074 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); 00075 // Find first "non-delimiter". 00076 std::string::size_type pos = str.find_first_of(delimiters, lastPos); 00077 00078 while (std::string::npos != pos || std::string::npos != lastPos) 00079 { 00080 // Found a token, add it to the std::vector. 00081 tokens.push_back(str.substr(lastPos, pos - lastPos)); 00082 // Skip delimiters. Note the "not_of" 00083 lastPos = str.find_first_not_of(delimiters, pos); 00084 // Find next "non-delimiter" 00085 pos = str.find_first_of(delimiters, lastPos); 00086 } 00087 } 00088 using namespace Teuchos; 00089 00090 // ============================================================================ 00091 EpetraExt::XMLReader::XMLReader(const Epetra_Comm& comm, const std::string& FileName) : 00092 Comm_(comm) 00093 { 00094 #ifdef HAVE_TEUCHOS_EXPAT 00095 FileInputSource fileSrc(FileName); 00096 fileXML_ = rcp(new XMLObject(fileSrc.getObject())); 00097 IsOpen_ = true; 00098 #else 00099 std::cerr << "Teuchos was not configured with support for expat." << std::endl; 00100 std::cerr << "Please reconfigure teuchos with --enable-teuchos-expat." << std::endl; 00101 exit(EXIT_FAILURE); 00102 #endif 00103 } 00104 00105 // ============================================================================ 00106 void EpetraExt::XMLReader:: 00107 Read(const std::string& Label, Epetra_CrsGraph*& Graph) 00108 { 00109 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00110 "No file has been opened"); 00111 00112 Graph = 0; 00113 00114 for (int i = 0; i < fileXML_->numChildren(); ++i) 00115 { 00116 const XMLObject& child = fileXML_->getChild(i); 00117 std::string tag = child.getTag(); 00118 00119 if (tag == "Graph") 00120 { 00121 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00122 { 00123 bool debug = false; 00124 int NumGlobalRows = child.getRequiredInt("Rows"); 00125 int NumGlobalCols = child.getRequiredInt("Columns"); 00126 int NumGlobalEntries = child.getRequiredInt("Entries"); 00127 int Offset = child.getRequiredInt("StartingIndex"); 00128 if (debug) std::cout << NumGlobalCols << NumGlobalEntries << Offset << std::endl; 00129 00130 Epetra_Map map(NumGlobalRows, 0, Comm_); 00131 Graph = new Epetra_CrsGraph(Copy, map, 0); 00132 00133 for (int j = 0; j < child.numContentLines(); ++j) 00134 { 00135 std::vector<std::string> tokens; 00136 const std::string& line = child.getContentLine(j); 00137 Tokenize(line, tokens, " \n\r\t"); 00138 if (tokens.size() < 2) continue; 00139 00140 int row, col; 00141 row = atoi((char*)tokens[0].c_str()); 00142 col = atoi((char*)tokens[1].c_str()); 00143 00144 if (map.LID(row) != -1) 00145 Graph->InsertGlobalIndices(row, 1, &col); 00146 } 00147 Graph->FillComplete(); 00148 } 00149 } 00150 } 00151 } 00152 00153 // ============================================================================ 00154 void EpetraExt::XMLReader:: 00155 Read(const std::string& Label, Epetra_CrsMatrix*& matrix) 00156 { 00157 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00158 "No file has been opened"); 00159 00160 matrix = 0; 00161 00162 for (int i = 0; i < fileXML_->numChildren(); ++i) 00163 { 00164 const XMLObject& child = fileXML_->getChild(i); 00165 std::string tag = child.getTag(); 00166 00167 if (tag == "PointMatrix") 00168 { 00169 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00170 { 00171 bool debug = false; 00172 int NumGlobalRows = child.getRequiredInt("Rows"); 00173 int NumGlobalCols = child.getRequiredInt("Columns"); 00174 int NumGlobalNonzeros = child.getRequiredInt("Nonzeros"); 00175 int Offset = child.getRequiredInt("StartingIndex"); 00176 if (debug) std::cout << NumGlobalCols << NumGlobalNonzeros << Offset << std::endl; 00177 00178 Epetra_Map map(NumGlobalRows, 0, Comm_); 00179 matrix = new Epetra_CrsMatrix(Copy, map, 0); 00180 00181 for (int j = 0; j < child.numContentLines(); ++j) 00182 { 00183 std::vector<std::string> tokens; 00184 const std::string& line = child.getContentLine(j); 00185 Tokenize(line, tokens, " \n\r\t"); 00186 if (tokens.size() < 3) continue; 00187 00188 int row, col; 00189 double val; 00190 row = atoi((char*)tokens[0].c_str()); 00191 col = atoi((char*)tokens[1].c_str()); 00192 sscanf((char*)tokens[2].c_str(), "%lg", &val); 00193 //val = atof((char*)tokens[2].c_str()); 00194 00195 if (map.LID(row) != -1) 00196 matrix->InsertGlobalValues(row, 1, &val, &col); 00197 } 00198 matrix->FillComplete(); 00199 } 00200 } 00201 } 00202 } 00203 00204 // ============================================================================ 00205 void EpetraExt::XMLReader:: 00206 Read(const std::string& Label, Epetra_MultiVector*& MultiVector) 00207 { 00208 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00209 "No file has been opened"); 00210 00211 MultiVector = 0; 00212 00213 // read all file and create all objects in memory. 00214 for (int i = 0; i < fileXML_->numChildren(); ++i) 00215 { 00216 const XMLObject& child = fileXML_->getChild(i); 00217 std::string tag = child.getTag(); 00218 00219 if (tag == "MultiVector") 00220 { 00221 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00222 { 00223 int GlobalLength = child.getRequiredInt("Length"); 00224 int NumVectors = child.getRequiredInt("NumVectors"); 00225 00226 Epetra_Map Map(GlobalLength, 0, Comm_); 00227 MultiVector = new Epetra_MultiVector(Map, NumVectors); 00228 00229 int count = 0; 00230 double val; 00231 for (int j = 0; j < child.numContentLines(); ++j) 00232 { 00233 std::vector<std::string> tokens; 00234 00235 const std::string& line = child.getContentLine(j); 00236 00237 Tokenize(line, tokens, " \n\r\t"); 00238 00239 if (tokens.size() == 0) continue; 00240 00241 TEUCHOS_TEST_FOR_EXCEPTION(tokens.size() != (unsigned) NumVectors, std::logic_error, 00242 "wrong number of tokens in line; " 00243 << "tokens.size() = " << tokens.size() 00244 << ", NumVectors = " << NumVectors); 00245 int tsize = (int) tokens.size(); 00246 for (int k = 0; k < tsize; ++k) 00247 { 00248 if (Map.LID(count) != -1) 00249 { 00250 sscanf((char*)(tokens[k].c_str()), "%lf", &val); 00251 00252 (*MultiVector)[k][Map.LID(count)] = val; 00253 } 00254 } 00255 ++count; 00256 } 00257 } 00258 } 00259 } 00260 } 00261 00262 // ============================================================================ 00263 void EpetraExt::XMLReader:: 00264 Read(const std::string& Label, Epetra_Map*& Map) 00265 { 00266 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00267 "No file has been opened"); 00268 00269 Map = 0; 00270 00271 // read all file and create all objects in memory. 00272 for (int i = 0; i < fileXML_->numChildren(); ++i) 00273 { 00274 const XMLObject& child = fileXML_->getChild(i); 00275 std::string tag = child.getTag(); 00276 00277 if (tag == "Map") 00278 { 00279 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00280 { 00281 int NumGlobalElements = child.getRequiredInt("NumElements"); 00282 int IndexBase = child.getRequiredInt("IndexBase"); 00283 int NumProc = child.getRequiredInt("NumProc"); 00284 00285 TEUCHOS_TEST_FOR_EXCEPTION(NumProc != Comm_.NumProc(), std::logic_error, 00286 "Requested map defined with different number of processors, " 00287 << "NumProc = " << NumProc << " while " 00288 << "Comm.NumProc() = " << Comm_.NumProc()); 00289 00290 char str[80]; 00291 sprintf(str, "ElementsOnProc%d", Comm_.MyPID()); 00292 int NumMyElements = child.getRequiredInt(str); 00293 00294 sprintf(str, "ElementsOnProc%d", Comm_.MyPID()); 00295 00296 std::vector<int> MyGlobalElements(NumMyElements); 00297 00298 for (int iproc = 0; iproc < child.numChildren(); ++iproc) 00299 { 00300 const XMLObject& newChild = child.getChild(iproc); 00301 int count = 0; 00302 00303 if (newChild.hasAttribute("ID") && 00304 newChild.getRequiredInt("ID") == Comm_.MyPID()) 00305 { 00306 for (int j = 0; j < newChild.numContentLines(); ++j) 00307 { 00308 std::vector<std::string> tokens; 00309 00310 const std::string& line = newChild.getContentLine(j); 00311 00312 Tokenize(line, tokens, " \n\r\t"); 00313 int tsize = (int) tokens.size(); 00314 for (int k = 0; k < tsize; ++k) 00315 { 00316 MyGlobalElements[count++] = atoi((char*)tokens[k].c_str()); 00317 } 00318 } 00319 } 00320 } 00321 00322 Map = new Epetra_Map(NumGlobalElements, NumMyElements, 00323 &MyGlobalElements[0], IndexBase, Comm_); 00324 } 00325 } 00326 } 00327 } 00328 00329 // ============================================================================ 00330 void EpetraExt::XMLReader:: 00331 Read(const std::string& Label, std::vector<std::string>& Content) 00332 { 00333 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00334 "No file has been opened"); 00335 00336 for (int i = 0; i < fileXML_->numChildren(); ++i) 00337 { 00338 const XMLObject& child = fileXML_->getChild(i); 00339 std::string tag = child.getTag(); 00340 00341 if (tag == "Text") 00342 { 00343 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00344 { 00345 for (int j = 0; j < child.numContentLines(); ++j) 00346 { 00347 const std::string& line = child.getContentLine(j); 00348 if (line == "\n") continue; 00349 Content.push_back(line); 00350 } 00351 } 00352 } 00353 } 00354 } 00355 00356 // ============================================================================ 00357 void EpetraExt::XMLReader:: 00358 Read(const std::string& Label, Teuchos::ParameterList& List) 00359 { 00360 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, 00361 "No file has been opened"); 00362 00363 for (int i = 0; i < fileXML_->numChildren(); ++i) 00364 { 00365 const XMLObject& child = fileXML_->getChild(i); 00366 std::string tag = child.getTag(); 00367 00368 if (tag == "List") 00369 { 00370 if (child.hasAttribute("Label") && child.getRequired("Label") == Label) 00371 { 00372 Teuchos::XMLParameterListReader ListReader; 00373 List = ListReader.toParameterList(child.getChild(0)); 00374 } 00375 } 00376 } 00377 }
1.7.6.1