EpetraExt Development
Loading...
Searching...
No Matches
EpetraExt_XMLReader.cpp
Go to the documentation of this file.
1/*
2//@HEADER
3// ***********************************************************************
4//
5// EpetraExt: Epetra Extended - Linear Algebra Services Package
6// Copyright (2011) Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41//@HEADER
42*/
43
45#ifdef HAVE_MPI
46#include "Epetra_MpiComm.h"
47#include "mpi.h"
48#else
49#include "Epetra_SerialComm.h"
50#endif
51#include "EpetraExt_XMLReader.h"
52#include "Teuchos_ParameterList.hpp"
53#include "Teuchos_RCP.hpp"
54#include "Teuchos_XMLObject.hpp"
55#include "Teuchos_StringInputSource.hpp"
56#include "Teuchos_FileInputSource.hpp"
57#include "Teuchos_ParameterList.hpp"
58#include "Teuchos_XMLParameterListReader.hpp"
59#include "Teuchos_Assert.hpp"
60#include "Epetra_ConfigDefs.h"
61#include "Epetra_Map.h"
62#include "Epetra_CrsGraph.h"
63#include "Epetra_FECrsGraph.h"
64#include "Epetra_RowMatrix.h"
65#include "Epetra_CrsMatrix.h"
66#include "Epetra_FECrsMatrix.h"
67#include "Epetra_MultiVector.h"
68#include "Epetra_Import.h"
69
70#if defined(__PGI)
71#include <sstream>
72#endif
73
74// ============================================================================
75static void Tokenize(const std::string& str, std::vector<std::string>& tokens,
76 const std::string& delimiters = " ")
77{
78 // Skip delimiters at beginning.
79 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
80 // Find first "non-delimiter".
81 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
82
83 while (std::string::npos != pos || std::string::npos != lastPos)
84 {
85 // Found a token, add it to the std::vector.
86 tokens.push_back(str.substr(lastPos, pos - lastPos));
87 // Skip delimiters. Note the "not_of"
88 lastPos = str.find_first_not_of(delimiters, pos);
89 // Find next "non-delimiter"
90 pos = str.find_first_of(delimiters, lastPos);
91 }
92}
93using namespace Teuchos;
94
95// ============================================================================
96EpetraExt::XMLReader::XMLReader(const Epetra_Comm& comm, const std::string& FileName) :
97 Comm_(comm)
98{
99#ifdef HAVE_TEUCHOS_EXPAT
100 FileInputSource fileSrc(FileName);
101 fileXML_ = rcp(new XMLObject(fileSrc.getObject()));
102 IsOpen_ = true;
103#else
104 (void)FileName;
105 std::cerr << "Teuchos was not configured with support for expat." << std::endl;
106 std::cerr << "Please reconfigure teuchos with --enable-teuchos-expat." << std::endl;
107 exit(EXIT_FAILURE);
108#endif
109}
110
111// ============================================================================
112#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
114Read(const std::string& Label, Epetra_CrsGraph*& Graph)
115{
116 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
117 "No file has been opened");
118
119 Graph = 0;
120
121 for (int i = 0; i < fileXML_->numChildren(); ++i)
122 {
123 const XMLObject& child = fileXML_->getChild(i);
124 std::string tag = child.getTag();
125
126 if (tag == "Graph")
127 {
128 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
129 {
130 bool debug = false;
131 int NumGlobalRows = child.getRequiredInt("Rows");
132 int NumGlobalCols = child.getRequiredInt("Columns");
133 int NumGlobalEntries = child.getRequiredInt("Entries");
134 int Offset = child.getRequiredInt("StartingIndex");
135 if (debug) std::cout << NumGlobalCols << NumGlobalEntries << Offset << std::endl;
136
137 Epetra_Map map(NumGlobalRows, 0, Comm_);
138 Graph = new Epetra_CrsGraph(Copy, map, 0);
139
140 for (int j = 0; j < child.numContentLines(); ++j)
141 {
142 std::vector<std::string> tokens;
143 const std::string& line = child.getContentLine(j);
144 Tokenize(line, tokens, " \n\r\t");
145 if (tokens.size() < 2) continue;
146
147 int row, col;
148 row = atoi((char*)tokens[0].c_str());
149 col = atoi((char*)tokens[1].c_str());
150
151 if (map.LID(row) != -1)
152 Graph->InsertGlobalIndices(row, 1, &col);
153 }
154 Graph->FillComplete();
155 }
156 }
157 }
158}
159#endif
160
161#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
163Read64(const std::string& Label, Epetra_CrsGraph*& Graph)
164{
165 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
166 "No file has been opened");
167
168 Graph = 0;
169
170 for (int i = 0; i < fileXML_->numChildren(); ++i)
171 {
172 const XMLObject& child = fileXML_->getChild(i);
173 std::string tag = child.getTag();
174
175 if (tag == "Graph")
176 {
177 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
178 {
179 bool debug = false;
180 long long NumGlobalRows = child.getRequired<long long>("Rows");
181 long long NumGlobalCols = child.getRequired<long long>("Columns");
182 long long NumGlobalEntries = child.getRequired<long long>("Entries");
183 int Offset = child.getRequiredInt("StartingIndex");
184 if (debug) std::cout << NumGlobalCols << NumGlobalEntries << Offset << std::endl;
185
186 Epetra_Map map(NumGlobalRows, 0, Comm_);
187 Graph = new Epetra_CrsGraph(Copy, map, 0);
188
189 for (int j = 0; j < child.numContentLines(); ++j)
190 {
191 std::vector<std::string> tokens;
192 const std::string& line = child.getContentLine(j);
193 Tokenize(line, tokens, " \n\r\t");
194 if (tokens.size() < 2) continue;
195
196 long long row, col;
197 char *endp;
198 const int base = 10;
199#if defined(_MSC_VER)
200 row = _strtoi64((char*)tokens[0].c_str(), &endp, base);
201 col = _strtoi64((char*)tokens[1].c_str(), &endp, base);
202#else
203#if defined(__PGI)
204 std::istringstream ss_row(tokens[0]);
205 ss_row >> row;
206 std::istringstream ss_col(tokens[1]);
207 ss_col >> col;
208#else
209 row = strtoll((char*)tokens[0].c_str(), &endp, base);
210 col = strtoll((char*)tokens[1].c_str(), &endp, base);
211#endif
212#endif
213
214 if (map.LID(row) != -1)
215 Graph->InsertGlobalIndices(row, 1, &col);
216 }
217 Graph->FillComplete();
218 }
219 }
220 }
221}
222#endif
223
224// ============================================================================
225#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
227Read(const std::string& Label, Epetra_CrsMatrix*& matrix)
228{
229 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
230 "No file has been opened");
231
232 matrix = 0;
233
234 for (int i = 0; i < fileXML_->numChildren(); ++i)
235 {
236 const XMLObject& child = fileXML_->getChild(i);
237 std::string tag = child.getTag();
238
239 if (tag == "PointMatrix")
240 {
241 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
242 {
243 bool debug = false;
244 int NumGlobalRows = child.getRequiredInt("Rows");
245 int NumGlobalCols = child.getRequiredInt("Columns");
246 int NumGlobalNonzeros = child.getRequiredInt("Nonzeros");
247 int Offset = child.getRequiredInt("StartingIndex");
248 if (debug) std::cout << NumGlobalCols << NumGlobalNonzeros << Offset << std::endl;
249
250 Epetra_Map map(NumGlobalRows, 0, Comm_);
251 matrix = new Epetra_CrsMatrix(Copy, map, 0);
252
253 for (int j = 0; j < child.numContentLines(); ++j)
254 {
255 std::vector<std::string> tokens;
256 const std::string& line = child.getContentLine(j);
257 Tokenize(line, tokens, " \n\r\t");
258 if (tokens.size() < 3) continue;
259
260 int row, col;
261 double val;
262 row = atoi((char*)tokens[0].c_str());
263 col = atoi((char*)tokens[1].c_str());
264 sscanf((char*)tokens[2].c_str(), "%lg", &val);
265 //val = atof((char*)tokens[2].c_str());
266
267 if (map.LID(row) != -1)
268 matrix->InsertGlobalValues(row, 1, &val, &col);
269 }
270 matrix->FillComplete();
271 }
272 }
273 }
274}
275#endif
276
277#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
279Read64(const std::string& Label, Epetra_CrsMatrix*& matrix)
280{
281 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
282 "No file has been opened");
283
284 matrix = 0;
285
286 for (int i = 0; i < fileXML_->numChildren(); ++i)
287 {
288 const XMLObject& child = fileXML_->getChild(i);
289 std::string tag = child.getTag();
290
291 if (tag == "PointMatrix")
292 {
293 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
294 {
295 bool debug = false;
296 long long NumGlobalRows = child.getRequiredInt("Rows");
297 long long NumGlobalCols = child.getRequiredInt("Columns");
298 long long NumGlobalNonzeros = child.getRequiredInt("Nonzeros");
299 int Offset = child.getRequiredInt("StartingIndex");
300 if (debug) std::cout << NumGlobalCols << NumGlobalNonzeros << Offset << std::endl;
301
302 Epetra_Map map(NumGlobalRows, 0, Comm_);
303 matrix = new Epetra_CrsMatrix(Copy, map, 0);
304
305 for (int j = 0; j < child.numContentLines(); ++j)
306 {
307 std::vector<std::string> tokens;
308 const std::string& line = child.getContentLine(j);
309 Tokenize(line, tokens, " \n\r\t");
310 if (tokens.size() < 3) continue;
311
312 long long row, col;
313 double val;
314 char *endp;
315 const int base = 10;
316#if defined(_MSC_VER)
317 row = _strtoi64((char*)tokens[0].c_str(), &endp, base);
318 col = _strtoi64((char*)tokens[1].c_str(), &endp, base);
319#else
320#if defined(__PGI)
321 std::istringstream ss_row(tokens[0]);
322 ss_row >> row;
323 std::istringstream ss_col(tokens[1]);
324 ss_col >> col;
325#else
326 row = strtoll((char*)tokens[0].c_str(), &endp, base);
327 col = strtoll((char*)tokens[1].c_str(), &endp, base);
328#endif
329#endif
330 sscanf((char*)tokens[2].c_str(), "%lg", &val);
331 //val = atof((char*)tokens[2].c_str());
332
333 if (map.LID(row) != -1)
334 matrix->InsertGlobalValues(row, 1, &val, &col);
335 }
336 matrix->FillComplete();
337 }
338 }
339 }
340}
341#endif
342// ============================================================================
343#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
345Read(const std::string& Label, Epetra_MultiVector*& MultiVector)
346{
347 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
348 "No file has been opened");
349
350 MultiVector = 0;
351
352 // read all file and create all objects in memory.
353 for (int i = 0; i < fileXML_->numChildren(); ++i)
354 {
355 const XMLObject& child = fileXML_->getChild(i);
356 std::string tag = child.getTag();
357
358 if (tag == "MultiVector")
359 {
360 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
361 {
362 int GlobalLength = child.getRequiredInt("Length");
363 int NumVectors = child.getRequiredInt("NumVectors");
364
365 Epetra_Map Map(GlobalLength, 0, Comm_);
366 MultiVector = new Epetra_MultiVector(Map, NumVectors);
367
368 int count = 0;
369 double val;
370 for (int j = 0; j < child.numContentLines(); ++j)
371 {
372 std::vector<std::string> tokens;
373
374 const std::string& line = child.getContentLine(j);
375
376 Tokenize(line, tokens, " \n\r\t");
377
378 if (tokens.size() == 0) continue;
379
380 TEUCHOS_TEST_FOR_EXCEPTION(tokens.size() != (unsigned) NumVectors, std::logic_error,
381 "wrong number of tokens in line; "
382 << "tokens.size() = " << tokens.size()
383 << ", NumVectors = " << NumVectors);
384 int tsize = (int) tokens.size();
385 for (int k = 0; k < tsize; ++k)
386 {
387 if (Map.LID(count) != -1)
388 {
389 sscanf((char*)(tokens[k].c_str()), "%lf", &val);
390
391 (*MultiVector)[k][Map.LID(count)] = val;
392 }
393 }
394 ++count;
395 }
396 }
397 }
398 }
399}
400#endif
401
402#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
404Read64(const std::string& Label, Epetra_MultiVector*& MultiVector)
405{
406 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
407 "No file has been opened");
408
409 MultiVector = 0;
410
411 // read all file and create all objects in memory.
412 for (int i = 0; i < fileXML_->numChildren(); ++i)
413 {
414 const XMLObject& child = fileXML_->getChild(i);
415 std::string tag = child.getTag();
416
417 if (tag == "MultiVector")
418 {
419 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
420 {
421 long long GlobalLength = child.getRequired<long long>("Length");
422 int NumVectors = child.getRequiredInt("NumVectors");
423
424 Epetra_Map Map(GlobalLength, 0, Comm_);
425 MultiVector = new Epetra_MultiVector(Map, NumVectors);
426
427 long long count = 0;
428 double val;
429 for (long long j = 0; j < child.numContentLines(); ++j)
430 {
431 std::vector<std::string> tokens;
432
433 const std::string& line = child.getContentLine(j);
434
435 Tokenize(line, tokens, " \n\r\t");
436
437 if (tokens.size() == 0) continue;
438
439 TEUCHOS_TEST_FOR_EXCEPTION(tokens.size() != (unsigned) NumVectors, std::logic_error,
440 "wrong number of tokens in line; "
441 << "tokens.size() = " << tokens.size()
442 << ", NumVectors = " << NumVectors);
443 int tsize = (int) tokens.size();
444 for (int k = 0; k < tsize; ++k)
445 {
446 if (Map.LID(count) != -1)
447 {
448 sscanf((char*)(tokens[k].c_str()), "%lf", &val);
449
450 (*MultiVector)[k][Map.LID(count)] = val;
451 }
452 }
453 ++count;
454 }
455 }
456 }
457 }
458}
459#endif
460// ============================================================================
461#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
463Read(const std::string& Label, Epetra_Map*& Map)
464{
465 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
466 "No file has been opened");
467
468 Map = 0;
469
470 // read all file and create all objects in memory.
471 for (int i = 0; i < fileXML_->numChildren(); ++i)
472 {
473 const XMLObject& child = fileXML_->getChild(i);
474 std::string tag = child.getTag();
475
476 if (tag == "Map")
477 {
478 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
479 {
480 int NumGlobalElements = child.getRequiredInt("NumElements");
481 int IndexBase = child.getRequiredInt("IndexBase");
482 int NumProc = child.getRequiredInt("NumProc");
483
484 TEUCHOS_TEST_FOR_EXCEPTION(NumProc != Comm_.NumProc(), std::logic_error,
485 "Requested map defined with different number of processors, "
486 << "NumProc = " << NumProc << " while "
487 << "Comm.NumProc() = " << Comm_.NumProc());
488
489 char str[80];
490 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
491 int NumMyElements = child.getRequiredInt(str);
492
493 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
494
495 std::vector<int> MyGlobalElements(NumMyElements);
496
497 for (int iproc = 0; iproc < child.numChildren(); ++iproc)
498 {
499 const XMLObject& newChild = child.getChild(iproc);
500 int count = 0;
501
502 if (newChild.hasAttribute("ID") &&
503 newChild.getRequiredInt("ID") == Comm_.MyPID())
504 {
505 for (int j = 0; j < newChild.numContentLines(); ++j)
506 {
507 std::vector<std::string> tokens;
508
509 const std::string& line = newChild.getContentLine(j);
510
511 Tokenize(line, tokens, " \n\r\t");
512 int tsize = (int) tokens.size();
513 for (int k = 0; k < tsize; ++k)
514 {
515 MyGlobalElements[count++] = atoi((char*)tokens[k].c_str());
516 }
517 }
518 }
519 }
520
521 Map = new Epetra_Map(NumGlobalElements, NumMyElements,
522 &MyGlobalElements[0], IndexBase, Comm_);
523 }
524 }
525 }
526}
527#endif
528
529#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
531Read64(const std::string& Label, Epetra_Map*& Map)
532{
533 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
534 "No file has been opened");
535
536 Map = 0;
537
538 // read all file and create all objects in memory.
539 for (int i = 0; i < fileXML_->numChildren(); ++i)
540 {
541 const XMLObject& child = fileXML_->getChild(i);
542 std::string tag = child.getTag();
543
544 if (tag == "Map")
545 {
546 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
547 {
548 long long NumGlobalElements = child.getRequired<long long>("NumElements");
549 long long IndexBase = child.getRequired<long long>("IndexBase");
550 int NumProc = child.getRequiredInt("NumProc");
551
552 TEUCHOS_TEST_FOR_EXCEPTION(NumProc != Comm_.NumProc(), std::logic_error,
553 "Requested map defined with different number of processors, "
554 << "NumProc = " << NumProc << " while "
555 << "Comm.NumProc() = " << Comm_.NumProc());
556
557 char str[80];
558 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
559 int NumMyElements = child.getRequiredInt(str);
560
561 sprintf(str, "ElementsOnProc%d", Comm_.MyPID());
562
563 std::vector<long long> MyGlobalElements(NumMyElements);
564
565 for (int iproc = 0; iproc < child.numChildren(); ++iproc)
566 {
567 const XMLObject& newChild = child.getChild(iproc);
568 int count = 0;
569
570 if (newChild.hasAttribute("ID") &&
571 newChild.getRequiredInt("ID") == Comm_.MyPID())
572 {
573 for (int j = 0; j < newChild.numContentLines(); ++j)
574 {
575 std::vector<std::string> tokens;
576
577 const std::string& line = newChild.getContentLine(j);
578
579 Tokenize(line, tokens, " \n\r\t");
580 int tsize = (int) tokens.size();
581 for (int k = 0; k < tsize; ++k)
582 {
583 char *endp;
584 const int base = 10;
585#if defined(_MSC_VER)
586 MyGlobalElements[count++] = _strtoi64((char*)tokens[k].c_str(), &endp, base);
587#else
588#if defined(__PGI)
589 std::istringstream ss(tokens[k]);
590 ss >> MyGlobalElements[count++];
591#else
592 MyGlobalElements[count++] = strtoll((char*)tokens[k].c_str(), &endp, base);
593#endif
594#endif
595 }
596 }
597 }
598 }
599
600 Map = new Epetra_Map(NumGlobalElements, NumMyElements,
601 &MyGlobalElements[0], IndexBase, Comm_);
602 }
603 }
604 }
605}
606#endif
607
608// ============================================================================
610Read(const std::string& Label, std::vector<std::string>& Content)
611{
612 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
613 "No file has been opened");
614
615 for (int i = 0; i < fileXML_->numChildren(); ++i)
616 {
617 const XMLObject& child = fileXML_->getChild(i);
618 std::string tag = child.getTag();
619
620 if (tag == "Text")
621 {
622 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
623 {
624 for (int j = 0; j < child.numContentLines(); ++j)
625 {
626 const std::string& line = child.getContentLine(j);
627 if (line == "\n") continue;
628 Content.push_back(line);
629 }
630 }
631 }
632 }
633}
634
635// ============================================================================
637Read(const std::string& Label, Teuchos::ParameterList& List)
638{
639 TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error,
640 "No file has been opened");
641
642 for (int i = 0; i < fileXML_->numChildren(); ++i)
643 {
644 const XMLObject& child = fileXML_->getChild(i);
645 std::string tag = child.getTag();
646
647 if (tag == "List")
648 {
649 if (child.hasAttribute("Label") && child.getRequired("Label") == Label)
650 {
651 Teuchos::XMLParameterListReader ListReader;
652 List = ListReader.toParameterList(child.getChild(0));
653 }
654 }
655 }
656}
static void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
Copy
void Read64(const std::string &Label, Epetra_Map *&Map)
Reads the Epetra_Map stored with label Label. Long Long version.
void Read(const std::string &Label, Epetra_Map *&Map)
Reads the Epetra_Map stored with label Label.
XMLReader(const Epetra_Comm &Comm, const std::string &FileName)
ctor
int LID(int GID) const
int InsertGlobalIndices(int GlobalRow, int NumIndices, int *Indices)