00001 #include "EpetraExt_ConfigDefs.h"
00002 #ifdef HAVE_MPI
00003 #include "Epetra_MpiComm.h"
00004 #include "mpi.h"
00005 #else
00006 #include "Epetra_SerialComm.h"
00007 #endif
00008 #include "EpetraExt_XMLReader.h"
00009 #include "Teuchos_ParameterList.hpp"
00010 #include "Teuchos_RefCountPtr.hpp"
00011 #include "Teuchos_XMLObject.hpp"
00012 #include "Teuchos_StringInputSource.hpp"
00013 #include "Teuchos_FileInputSource.hpp"
00014 #include "Teuchos_ParameterList.hpp"
00015 #include "Teuchos_XMLParameterListReader.hpp"
00016 #include "Teuchos_TestForException.hpp"
00017 #include "Epetra_Map.h"
00018 #include "Epetra_CrsGraph.h"
00019 #include "Epetra_FECrsGraph.h"
00020 #include "Epetra_RowMatrix.h"
00021 #include "Epetra_CrsMatrix.h"
00022 #include "Epetra_FECrsMatrix.h"
00023 #include "Epetra_MultiVector.h"
00024 #include "Epetra_Import.h"
00025
00026
00027 static void Tokenize(const string& str, vector<string>& tokens,
00028 const string& delimiters = " ")
00029 {
00030
00031 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
00032
00033 string::size_type pos = str.find_first_of(delimiters, lastPos);
00034
00035 while (string::npos != pos || string::npos != lastPos)
00036 {
00037
00038 tokens.push_back(str.substr(lastPos, pos - lastPos));
00039
00040 lastPos = str.find_first_not_of(delimiters, pos);
00041
00042 pos = str.find_first_of(delimiters, lastPos);
00043 }
00044 }
00045 using namespace Teuchos;
00046
00047
00048 EpetraExt::XMLReader::XMLReader(const Epetra_Comm& comm, const string& FileName) :
00049 Comm_(comm)
00050 {
00051 #ifdef HAVE_TEUCHOS_EXPAT
00052 FileInputSource fileSrc(FileName);
00053 fileXML_ = rcp(new XMLObject(fileSrc.getObject()));
00054 IsOpen_ = true;
00055 #else
00056 cerr << "Teuchos was not configured with support for expat." << endl;
00057 cerr << "Please reconfigure teuchos with --enable-teuchos-expat." << endl;
00058 exit(EXIT_FAILURE);
00059 #endif
00060 }
00061
00062
00063 void EpetraExt::XMLReader::
00064 Read(const string& Label, Epetra_CrsGraph*& Graph)
00065 {
00066 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00067 "No file has been opened");
00068
00069 Graph = 0;
00070
00071 for (int i = 0; i < fileXML_->numChildren(); ++i)
00072 {
00073 const XMLObject& child = fileXML_->getChild(i);
00074 string tag = child.getTag();
00075
00076 if (tag == "Graph")
00077 {
00078 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00079 {
00080 bool debug = false;
00081 int NumGlobalRows = child.getRequiredInt("Rows");
00082 int NumGlobalCols = child.getRequiredInt("Columns");
00083 int NumGlobalEntries = child.getRequiredInt("Entries");
00084 int Offset = child.getRequiredInt("StartingIndex");
00085 if (debug) std::cout << NumGlobalCols << NumGlobalEntries << Offset << endl;
00086
00087 Epetra_Map map(NumGlobalRows, 0, Comm_);
00088 Graph = new Epetra_CrsGraph(Copy, map, 0);
00089
00090 for (int j = 0; j < child.numContentLines(); ++j)
00091 {
00092 vector<string> tokens;
00093 const string& line = child.getContentLine(j);
00094 Tokenize(line, tokens, " \n\r\t");
00095 if (tokens.size() < 2) continue;
00096
00097 int row, col;
00098 row = atoi((char*)tokens[0].c_str());
00099 col = atoi((char*)tokens[1].c_str());
00100
00101 if (map.LID(row) != -1)
00102 Graph->InsertGlobalIndices(row, 1, &col);
00103 }
00104 Graph->FillComplete();
00105 }
00106 }
00107 }
00108 }
00109
00110
00111 void EpetraExt::XMLReader::
00112 Read(const string& Label, Epetra_CrsMatrix*& matrix)
00113 {
00114 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00115 "No file has been opened");
00116
00117 matrix = 0;
00118
00119 for (int i = 0; i < fileXML_->numChildren(); ++i)
00120 {
00121 const XMLObject& child = fileXML_->getChild(i);
00122 string tag = child.getTag();
00123
00124 if (tag == "PointMatrix")
00125 {
00126 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00127 {
00128 bool debug = false;
00129 int NumGlobalRows = child.getRequiredInt("Rows");
00130 int NumGlobalCols = child.getRequiredInt("Columns");
00131 int NumGlobalNonzeros = child.getRequiredInt("Nonzeros");
00132 int Offset = child.getRequiredInt("StartingIndex");
00133 if (debug) std::cout << NumGlobalCols << NumGlobalNonzeros << Offset << endl;
00134
00135 Epetra_Map map(NumGlobalRows, 0, Comm_);
00136 matrix = new Epetra_CrsMatrix(Copy, map, 0);
00137
00138 for (int j = 0; j < child.numContentLines(); ++j)
00139 {
00140 vector<string> tokens;
00141 const string& line = child.getContentLine(j);
00142 Tokenize(line, tokens, " \n\r\t");
00143 if (tokens.size() < 3) continue;
00144
00145 int row, col;
00146 double val;
00147 row = atoi((char*)tokens[0].c_str());
00148 col = atoi((char*)tokens[1].c_str());
00149 sscanf((char*)tokens[2].c_str(), "%lg", &val);
00150
00151
00152 if (map.LID(row) != -1)
00153 matrix->InsertGlobalValues(row, 1, &val, &col);
00154 }
00155 matrix->FillComplete();
00156 }
00157 }
00158 }
00159 }
00160
00161
00162 void EpetraExt::XMLReader::
00163 Read(const string& Label, Epetra_MultiVector*& MultiVector)
00164 {
00165 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00166 "No file has been opened");
00167
00168 MultiVector = 0;
00169
00170
00171 for (int i = 0; i < fileXML_->numChildren(); ++i)
00172 {
00173 const XMLObject& child = fileXML_->getChild(i);
00174 string tag = child.getTag();
00175
00176 if (tag == "MultiVector")
00177 {
00178 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00179 {
00180 int GlobalLength = child.getRequiredInt("Length");
00181 int NumVectors = child.getRequiredInt("NumVectors");
00182
00183 Epetra_Map Map(GlobalLength, 0, Comm_);
00184 MultiVector = new Epetra_MultiVector(Map, NumVectors);
00185
00186 int count = 0;
00187 double val;
00188 for (int j = 0; j < child.numContentLines(); ++j)
00189 {
00190 vector<string> tokens;
00191
00192 const string& line = child.getContentLine(j);
00193
00194 Tokenize(line, tokens, " \n\r\t");
00195
00196 if (tokens.size() == 0) continue;
00197
00198 TEST_FOR_EXCEPTION(tokens.size() != (unsigned) NumVectors, std::logic_error,
00199 "wrong number of tokens in line; "
00200 << "tokens.size() = " << tokens.size()
00201 << ", NumVectors = " << NumVectors);
00202 int tsize = (int) tokens.size();
00203 for (int k = 0; k < tsize; ++k)
00204 {
00205 if (Map.LID(count) != -1)
00206 {
00207 sscanf((char*)(tokens[k].c_str()), "%lf", &val);
00208
00209 (*MultiVector)[k][Map.LID(count)] = val;
00210 }
00211 }
00212 ++count;
00213 }
00214 }
00215 }
00216 }
00217 }
00218
00219
00220 void EpetraExt::XMLReader::
00221 Read(const string& Label, Epetra_Map*& Map)
00222 {
00223 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00224 "No file has been opened");
00225
00226 Map = 0;
00227
00228
00229 for (int i = 0; i < fileXML_->numChildren(); ++i)
00230 {
00231 const XMLObject& child = fileXML_->getChild(i);
00232 string tag = child.getTag();
00233
00234 if (tag == "Map")
00235 {
00236 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00237 {
00238 int NumGlobalElements = child.getRequiredInt("NumElements");
00239 int IndexBase = child.getRequiredInt("IndexBase");
00240 int NumProc = child.getRequiredInt("NumProc");
00241
00242 TEST_FOR_EXCEPTION(NumProc != Comm_.NumProc(), std::logic_error,
00243 "Requested map defined with different number of processors, "
00244 << "NumProc = " << NumProc << " while "
00245 << "Comm.NumProc() = " << Comm_.NumProc());
00246
00247 char str[80];
00248 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
00249 int NumMyElements = child.getRequiredInt(str);
00250
00251 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
00252
00253 vector<int> MyGlobalElements(NumMyElements);
00254
00255 for (int iproc = 0; iproc < child.numChildren(); ++iproc)
00256 {
00257 const XMLObject& newChild = child.getChild(iproc);
00258 int count = 0;
00259
00260 if (newChild.hasAttribute("ID") &&
00261 newChild.getRequiredInt("ID") == Comm_.MyPID())
00262 {
00263 for (int j = 0; j < newChild.numContentLines(); ++j)
00264 {
00265 vector<string> tokens;
00266
00267 const string& line = newChild.getContentLine(j);
00268
00269 Tokenize(line, tokens, " \n\r\t");
00270 int tsize = (int) tokens.size();
00271 for (int k = 0; k < tsize; ++k)
00272 {
00273 MyGlobalElements[count++] = atoi((char*)tokens[k].c_str());
00274 }
00275 }
00276 }
00277 }
00278
00279 Map = new Epetra_Map(NumGlobalElements, NumMyElements,
00280 &MyGlobalElements[0], IndexBase, Comm_);
00281 }
00282 }
00283 }
00284 }
00285
00286
00287 void EpetraExt::XMLReader::
00288 Read(const string& Label, vector<string>& Content)
00289 {
00290 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00291 "No file has been opened");
00292
00293 for (int i = 0; i < fileXML_->numChildren(); ++i)
00294 {
00295 const XMLObject& child = fileXML_->getChild(i);
00296 string tag = child.getTag();
00297
00298 if (tag == "Text")
00299 {
00300 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00301 {
00302 for (int j = 0; j < child.numContentLines(); ++j)
00303 {
00304 const string& line = child.getContentLine(j);
00305 if (line == "\n") continue;
00306 Content.push_back(line);
00307 }
00308 }
00309 }
00310 }
00311 }
00312
00313
00314 void EpetraExt::XMLReader::
00315 Read(const string& Label, Teuchos::ParameterList& List)
00316 {
00317 TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
00318 "No file has been opened");
00319
00320 for (int i = 0; i < fileXML_->numChildren(); ++i)
00321 {
00322 const XMLObject& child = fileXML_->getChild(i);
00323 string tag = child.getTag();
00324
00325 if (tag == "List")
00326 {
00327 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
00328 {
00329 Teuchos::XMLParameterListReader ListReader;
00330 List = ListReader.toParameterList(child.getChild(0));
00331 }
00332 }
00333 }
00334 }