From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/io/xmlReader.cpp | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 src/io/xmlReader.cpp (limited to 'src/io/xmlReader.cpp') diff --git a/src/io/xmlReader.cpp b/src/io/xmlReader.cpp new file mode 100644 index 0000000..302a93c --- /dev/null +++ b/src/io/xmlReader.cpp @@ -0,0 +1,329 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2010 Jonas Latt, Jonas Fietz, Mathias Krause + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +/** \file + * Input/Output in XML format -- non-generic code. + */ + +#include "io/xmlReader.h" +#include +#include +#include +#include "communication/mpiManager.h" + + +namespace olb { + +XMLreader XMLreader::_notFound; + +XMLreader::XMLreader() + : clout(std::cout,"XMLreader") +{ + _name = "XML node not found"; + _warningsOn = true; +} + +XMLreader::XMLreader( TiXmlNode* pParent) + : clout(std::cout,"XMLreader") +{ + _warningsOn = true; + if (singleton::mpi().isMainProcessor()) { + mainProcessorIni(pParent); + } else { + slaveProcessorIni(); + } +} + +XMLreader::XMLreader(const std::string& fName) + : clout("XMLreader") +{ + _warningsOn = true; + TiXmlDocument* doc = nullptr; + int loadOK = false; +#ifdef PARALLEL_MODE_MPI // parallel program execution + if (singleton::mpi().isMainProcessor()) { +#endif + doc = new TiXmlDocument(fName.c_str()); + loadOK = doc->LoadFile(); + if (!loadOK) { + clout << std::string("Problem processing input XML file ") << fName << std::endl; + } +#ifdef PARALLEL_MODE_MPI // parallel program execution + } + if (singleton::mpi().isMainProcessor()) { +#endif + mainProcessorIni(doc); + delete doc; +#ifdef PARALLEL_MODE_MPI // parallel program execution + } else { + slaveProcessorIni(); + } +#endif +} + +XMLreader::~XMLreader() +{ + for (unsigned int iNode=0; iNode<_children.size(); ++iNode) { + delete _children[iNode]; + } +} + +void XMLreader::mainProcessorIni( TiXmlNode* pParent ) +{ + assert (pParent->Type()==TiXmlNode::TINYXML_DOCUMENT || pParent->Type()==TiXmlNode::TINYXML_ELEMENT ); + if (pParent->Type() == TiXmlNode::TINYXML_DOCUMENT) { + // ignore the surrounding PARAM-block + pParent = pParent->FirstChildElement(); + } + + _name = pParent->ValueStr(); +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&_name,1); +#endif + + TiXmlAttribute* attr = pParent->ToElement()->FirstAttribute(); + while (attr != nullptr) { +#ifdef PARALLEL_MODE_MPI // parallel program execution + int size = 0; + std::string* key = const_cast(&attr->NameTStr()); + singleton::mpi().bCast(key, size); + std::string* value = const_cast(&attr->ValueStr()); + singleton::mpi().bCast(value, size); +#endif + _attributes[attr->NameTStr()] = attr->ValueStr(); + attr = attr->Next(); + } +#ifdef PARALLEL_MODE_MPI // parallel program execution + std::string tmpstr = ""; + int size = 0; + singleton::mpi().bCast(&tmpstr, size); + singleton::mpi().bCast(&tmpstr, size); +#endif + + + TiXmlNode * pChild; + int type = 0; + for ( pChild = pParent->FirstChild(); pChild != nullptr; pChild = pChild->NextSibling()) { + type = pChild->Type(); +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&type, 1); +#endif + if ( type==TiXmlNode::TINYXML_ELEMENT ) { + _children.push_back( new XMLreader( pChild ) ); + } else if ( type==TiXmlNode::TINYXML_TEXT ) { + _text = pChild->ToText()->ValueStr(); +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&_text,1); +#endif + } + } + type = TiXmlNode::TINYXML_UNKNOWN; +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&type, 1); +#endif +} + +void XMLreader::slaveProcessorIni() +{ +#ifdef PARALLEL_MODE_MPI // parallel program execution + + singleton::mpi().bCast(&_name,1); + std::string key = ""; + std::string value = ""; + int size = int(); + do { + singleton::mpi().bCast(&key, size); + singleton::mpi().bCast(&value, size); + _attributes[key] = value; + } while (key != ""); +#endif + + int type=0; + do { +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&type, 1); +#endif + if ( type==TiXmlNode::TINYXML_ELEMENT ) { + _children.push_back( new XMLreader( nullptr ) ); + } else if ( type==TiXmlNode::TINYXML_TEXT ) { +#ifdef PARALLEL_MODE_MPI // parallel program execution + singleton::mpi().bCast(&_text,1); +#endif + } + } while (type != TiXmlNode::TINYXML_UNKNOWN); +} + +void XMLreader::print(int indent) const +{ + std::string indentStr(indent, ' '); + clout << indentStr << "[" << _name << "]" << std::endl; + if (!_text.empty()) { + clout << indentStr << " " << _text << std::endl; + } + for (unsigned int iNode=0; iNode<_children.size(); ++iNode) { + _children[iNode]->print(indent+2); + } +} + +XMLreader const& XMLreader::operator[] (std::string fName) const +{ + for (unsigned int iNode=0; iNode<_children.size(); ++iNode) { + if (_children[iNode]->_name == fName) { + return *_children[iNode]; + } + } + if ( _warningsOn ) { + clout << "Warning: cannot read value from node \"" << _name << "\"" << ", \"" << fName <<"\"" << std::endl; + } + return _notFound; +} + +std::vector::const_iterator XMLreader::begin() const +{ + return _children.begin(); +} + +std::vector::const_iterator XMLreader::end() const +{ + return _children.end(); +} + +std::string XMLreader::getName() const +{ + return _name; +} + +void XMLreader::setWarningsOn(bool warnings) const +{ + _warningsOn = warnings; + for (unsigned int iNode=0; iNode<_children.size(); ++iNode) { + _children[iNode]->setWarningsOn(warnings); + } +} + +// template specialization for T=bool +template <> +bool XMLreader::read(bool& value, bool verboseOn, bool exitIfMissing) const +{ + std::stringstream valueStr(_text); + std::string word; + valueStr >> word; + // Transform to lower-case, so that "true" and "false" are case-insensitive. + std::transform(word.begin(), word.end(), word.begin(), ::tolower); + if (!word.compare("true") || (word=="1")) { + value = true; + return true; + } else if (!word.compare("false") || (word=="0")) { + value=false; + return true; + } else { + if ( verboseOn ) { + std::stringstream ss; + ss << ( value ? "true" : "false" ); + printWarning("bool", ss.str(), verboseOn, exitIfMissing); + } + } + return false; +} + +// template specialization for T=int +template <> +bool XMLreader::read(int& value, bool verboseOn, bool exitIfMissing) const +{ + std::stringstream valueStr(_text); + int tmp = int(); + if (!(valueStr >> tmp)) { + std::stringstream ss; + ss << value; + printWarning("int", ss.str(), verboseOn, exitIfMissing); + return false; + } + value = tmp; + return true; +} + +// template specialization for T=double +template <> +bool XMLreader::read(double& value, bool verboseOn, bool exitIfMissing) const +{ + std::stringstream valueStr(_text); + double tmp = double(); + if (!(valueStr >> tmp)) { + std::stringstream ss; + ss << value; + printWarning("double", ss.str(), verboseOn, exitIfMissing); + return false; + } + value = tmp; + return true; +} + +template <> +bool XMLreader::read(std::string& entry, bool verboseOn, bool exitIfMissing) const +{ + if (_name == "XML node not found") { + return false; + } + std::stringstream valueStr(_text); + std::string tmp = std::string(); + if (!(valueStr >> tmp)) { + std::stringstream ss; + ss << entry; + printWarning("string", ss.str(), verboseOn, exitIfMissing); + return false; + } + + entry = _text; + return true; +} + +std::string XMLreader::getAttribute(const std::string& aName) const +{ + std::map::const_iterator it = _attributes.find(aName); + if ( it == _attributes.end()) { + return "Attribute not found."; + } + return it->second; + //return attributes[aName]; +} + + +/// print warning if verbose mode is on and exit, if exItMissing is true +void XMLreader::printWarning(std::string typeName, std::string value, bool verboseOn, bool exitIfMissing) const +{ + + if ( verboseOn ) { + clout << "Warning: Cannot read " << typeName << " value from XML element " << _name << "." << std::endl; + if ( ! value.empty() ) { + clout << " Setting default value = " << value << std::endl; + } + } + if ( exitIfMissing ) { + clout << "Error: This program cannot continue without \"" << _name << "\". Optimization aborted." << std::endl; + exit(1); + } +} + + + +} // namespace olb -- cgit v1.2.3