EpetraExt Development
EpetraExt_XMLReader.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines