diff --git a/src/SIM/NonLinSIM.h b/src/SIM/NonLinSIM.h index 6ecbb46a..d2b310da 100644 --- a/src/SIM/NonLinSIM.h +++ b/src/SIM/NonLinSIM.h @@ -171,9 +171,8 @@ public: //! \param is The file stream to read from virtual bool parse(char* keyWord, std::istream& is); - //! \brief Parses a data section from an input stream. - //! \param[in] keyWord Keyword of current data section to read - //! \param is The file stream to read from + //! \brief Parses a data section from an XML document. + //! \param[in] elem The XML element to parse virtual bool parse(const TiXmlElement* elem); private: diff --git a/src/SIM/SIM1D.h b/src/SIM/SIM1D.h index e5ad2c71..dd36b0ac 100644 --- a/src/SIM/SIM1D.h +++ b/src/SIM/SIM1D.h @@ -34,24 +34,28 @@ public: //! \param[in] ng Number of Gauss points in each parameter direction virtual void setQuadratureRule(size_t ng); +private: + //! \brief Parses subtags of the \a geometry XML-tag. + bool parseGeometryTag(const TiXmlElement* elem); + protected: + //! \brief Parses a data section from an XML document. + //! \param[in] elem The XML element to parse + virtual bool parse(const TiXmlElement* elem); + //! \brief Parses a data section from an input stream. //! \param[in] keyWord Keyword of current data section to read //! \param is The file stream to read from virtual bool parse(char* keyWord, std::istream& is); - //! \brief Read patches from given stream - //! \param[in] isp The stream to read from + //! \brief Reads patches from given input stream. + //! \param[in] isp The input stream to read from virtual bool readPatches(std::istream& isp); - //! \brief Reads a patch from given input file. - //! \param[in] isp The stream to read from + //! \brief Reads a patch from given input stream. + //! \param[in] isp The input stream to read from //! \param[in] pchInd 0-based index of the patch to read virtual bool readPatch(std::istream& isp, int pchInd); - //! \brief Parses a data section from an XML document. - //! \param[in] elem The XML element to parse - virtual bool parse(const TiXmlElement* elem); - //! \brief Preprocesses a user-defined Dirichlet boundary property. //! \param[in] patch 1-based index of the patch to receive the property //! \param[in] lndx Local index of the boundary item to receive the property @@ -63,9 +67,6 @@ protected: protected: unsigned char nf; //!< Number of scalar fields -private: - //! \brief Parse subtags of the block from the input file - bool parseGeometryTag(const TiXmlElement* elem); }; #endif diff --git a/src/SIM/SIM2D.h b/src/SIM/SIM2D.h index a0442624..2f6a05e2 100644 --- a/src/SIM/SIM2D.h +++ b/src/SIM/SIM2D.h @@ -42,16 +42,20 @@ public: //! \param[in] g2ln Global-to-local node number mapping for the borrowed grid void clonePatches(const FEModelVec& patches, const std::map& g2ln); +private: + //! \brief Parses subtags of the \a geometry XML-tag. + bool parseGeometryTag(const TiXmlElement* elem); + protected: + //! \brief Parses a data section from an XML document. + //! \param[in] elem The XML element to parse + virtual bool parse(const TiXmlElement* elem); + //! \brief Parses a data section from an input stream. //! \param[in] keyWord Keyword of current data section to read //! \param is The file stream to read from virtual bool parse(char* keyWord, std::istream& is); - //! \brief Parses a data section from an XML document. - //! \param[in] elem The XML element to parse - virtual bool parse(const TiXmlElement* elem); - //! \brief Reads patches from given input stream. //! \param[in] isp The input stream to read from virtual bool readPatches(std::istream& isp); @@ -91,8 +95,6 @@ protected: private: bool isRefined; //!< If \e true, the model has been adaptively refined - //! \brief Parse subtags of the block from the input file - bool parseGeometryTag(const TiXmlElement* elem); protected: unsigned char nf[2]; //!< Number of scalar fields diff --git a/src/SIM/SIM3D.h b/src/SIM/SIM3D.h index 5296c22a..b408b035 100644 --- a/src/SIM/SIM3D.h +++ b/src/SIM/SIM3D.h @@ -38,11 +38,15 @@ public: //! \param[in] ng Number of Gauss points in each parameter direction virtual void setQuadratureRule(size_t ng); - //! \brief Reads node numbers from given input stream. - //! \param[in] isn The file stream to read from - void readNodes(std::istream& isn); +private: + //! \brief Parses subtags of the \a geometry XML-tag. + bool parseGeometryTag(const TiXmlElement* elem); protected: + //! \brief Parses a data section from an XML document. + //! \param[in] elem The XML element to parse + virtual bool parse(const TiXmlElement* elem); + //! \brief Parses a data section from an input stream. //! \param[in] keyWord Keyword of current data section to read //! \param is The file stream to read from @@ -60,14 +64,13 @@ protected: //! \param[in] pchInd 0-based index of the patch to read node data for //! \param[in] basis The basis to read node data for (mixed FEM) //! \param[in] oneBased If \e true the read node numbers are assumed - //! one-based. If \e false they are assumed to be zero-based + //! one-based. If \e false they are assumed to be zero-based. virtual bool readNodes(std::istream& isn, int pchInd, int basis = 0, bool oneBased = false); - //! \brief Parses a data section from an XML element - //! \param[in] elem The XML element to parse - ////! \param is The file stream to read from - virtual bool parse(const TiXmlElement* elem); + //! \brief Reads node numbers from given input stream. + //! \param[in] isn The file stream to read from + void readNodes(std::istream& isn); //! \brief Preprocesses a user-defined Dirichlet boundary property. //! \param[in] patch 1-based index of the patch to receive the property @@ -88,11 +91,7 @@ protected: protected: unsigned char nf[2]; //!< Number of scalar fields - - bool checkRHSys; //!< Check if all patches are in a right-hand system -private: - //! \brief Parse subtags of the block from the input file - bool parseGeometryTag(const TiXmlElement* elem); + bool checkRHSys; //!< Check if all patches are in a right-hand system }; #endif diff --git a/src/SIM/SIMbase.h b/src/SIM/SIMbase.h index 939e8be3..cf093285 100644 --- a/src/SIM/SIMbase.h +++ b/src/SIM/SIMbase.h @@ -101,6 +101,15 @@ public: //! \param[in] elem The XML element to parse virtual bool parse(const TiXmlElement* elem); +private: + //! \brief Parses a subelement of the \a geometry XML-tag. + bool parseGeometryTag(const TiXmlElement* elem); + //! \brief Parses a subelement of the \a resultoutput XML-tag. + bool parseOutputTag(const TiXmlElement* elem); + //! \brief Parses a subelement of the \a boundaryconditions XML-tag. + bool parseBCTag(const TiXmlElement* elem); + +public: //! \brief Refines a list of elements. virtual bool refine(const std::vector&, const std::vector&, const char* = 0) { return false; } @@ -491,9 +500,6 @@ protected: //! \brief Creates the computational FEM model from the spline patches. bool createFEMmodel(); - //! \brief Reads node numbers from given input stream. - //! \param[in] isp The file stream to read from - virtual void readNodes(std::istream& isp) {} public: //! \brief Returns the local patch index for the given global patch number. //! \details For serial applications this is an identity mapping only, whereas @@ -559,12 +565,14 @@ protected: //! one-based. If \e false they are assumed to be zero-based. virtual bool readNodes(std::istream& isn, int pchInd, int basis = 0, bool oneBased = false) { return false; } + //! \brief Reads node numbers from given input stream. + //! \param[in] isn The input stream to read from + virtual void readNodes(std::istream& isn) {} //! \brief Reads a LinSolParams object from the given stream. //! \details This method helps with encapsulating PETSc in libIFEM. void readLinSolParams(std::istream& is, int npar); - - //! \brief Reads a LinSolParams object from the given XML element + //! \brief Reads a LinSolParams object from the given XML element. //! \details This method helps with encapsulating PETSc in libIFEM. void readLinSolParams(const TiXmlElement* elem); @@ -621,14 +629,6 @@ protected: private: size_t nIntGP; //!< Number of interior integration points in the whole model size_t nBouGP; //!< Number of boundary integration points in the whole model - - //! \brief Parses a subelement of the tag from input file - //! \param[in] elem The XML element to parse - bool parseGeometryTag(const TiXmlElement* elem); - //! \brief Parses a subelement of the tag from input file - //! \param[in] elem The XML element to parse - bool parseOutputTag(const TiXmlElement* elem); - bool parseBCTag(const TiXmlElement* elem); }; #endif diff --git a/src/SIM/SIMinput.C b/src/SIM/SIMinput.C index 57bc9c8a..af3093bd 100644 --- a/src/SIM/SIMinput.C +++ b/src/SIM/SIMinput.C @@ -13,13 +13,12 @@ #include "SIMinput.h" #include "Utilities.h" +#include "tinyxml.h" #ifdef PARALLEL_PETSC #include "petscsys.h" #endif #include -#include "tinyxml.h" - int SIMinput::msgLevel = 2; @@ -36,12 +35,12 @@ SIMinput::SIMinput () } -bool SIMinput::read(const char* fileName) +bool SIMinput::read (const char* fileName) { if (strcasestr(fileName,".xinp")) - return readXML(fileName); - - return readFlat(fileName); + return this->readXML(fileName); + else + return this->readFlat(fileName); } @@ -71,23 +70,26 @@ bool SIMinput::readFlat (const char* fileName) } -static void injectIncludeFiles(TiXmlElement* tag) +/*! + \brief Recursive helper method for processing the \a include XML-tags. +*/ + +static void injectIncludeFiles (TiXmlElement* tag) { TiXmlElement* elem = tag->FirstChildElement(); while (elem) { - if (!strcasecmp(elem->Value(),"include")) { - if (elem->FirstChild() && elem->FirstChild()->Value()) { - TiXmlDocument doc; - if (doc.LoadFile(elem->FirstChild()->Value())) - tag->ReplaceChild(elem,*doc.RootElement()); - else { - std::cerr << __PRETTY_FUNCTION__ << ": Failed to load " << elem->FirstChild()->Value() << std::endl; - std::cerr << "\t Error at line " << doc.ErrorRow() << ": " << doc.ErrorDesc() << std::endl; - } - } - } else + if (strcasecmp(elem->Value(),"include")) injectIncludeFiles(elem); - + else if (elem->FirstChild() && elem->FirstChild()->Value()) { + TiXmlDocument doc; + if (doc.LoadFile(elem->FirstChild()->Value())) + tag->ReplaceChild(elem,*doc.RootElement()); + else + std::cerr << __PRETTY_FUNCTION__ <<": Failed to load " + << elem->FirstChild()->Value() + <<"\n\tError at line "<< doc.ErrorRow() <<": " + << doc.ErrorDesc() << std::endl; + } elem = elem->NextSiblingElement(); } } @@ -97,25 +99,26 @@ bool SIMinput::readXML (const char* fileName) { TiXmlDocument doc; if (!doc.LoadFile(fileName)) { - std::cerr << __PRETTY_FUNCTION__ << ": Failed to load " << fileName << std::endl; - std::cerr << "\t Error at line " << doc.ErrorRow() << ": " << doc.ErrorDesc() << std::endl; + std::cerr << __PRETTY_FUNCTION__ <<": Failed to load "<< fileName + <<"\n\tError at line "<< doc.ErrorRow() <<": " + << doc.ErrorDesc() << std::endl; return false; } - - if (!doc.RootElement() || - strcmp(doc.RootElement()->Value(),"simulation")) { - std::cerr << __PRETTY_FUNCTION__ << ": Malformatted input file " << fileName << std::endl; + + if (!doc.RootElement() || strcmp(doc.RootElement()->Value(),"simulation")) { + std::cerr << __PRETTY_FUNCTION__ <<": Malformatted input file "<< fileName + << std::endl; return false; } injectIncludeFiles(doc.RootElement()); - + std::vector parsed = handlePriorityTags(doc.RootElement()); // now parse the rest TiXmlElement* elem = doc.RootElement()->FirstChildElement(); while (elem) { - if (find(parsed.begin(),parsed.end(),elem) == parsed.end()) { - if (!parse(elem)) { + if (std::find(parsed.begin(),parsed.end(),elem) == parsed.end()) { + if (!this->parse(elem)) { std::cerr <<" *** SIMinput::read: Failure occured while parsing \"" << elem->Value() <<"\""<< std::endl; return false; @@ -137,10 +140,9 @@ std::vector SIMinput::handlePriorityTags(const TiXmlElement for (size_t i=0;iFirstChildElement(special[i]); if (elem) { - if (!parse(elem)) { + if (!this->parse(elem)) std::cerr <<" *** SIMinput::read: Failure occured while parsing \"" << elem->Value() <<"\""<< std::endl; - } parsed.push_back(elem); } } diff --git a/src/SIM/SIMinput.h b/src/SIM/SIMinput.h index aab4d243..0715acd2 100644 --- a/src/SIM/SIMinput.h +++ b/src/SIM/SIMinput.h @@ -17,13 +17,13 @@ #include #include +class TiXmlElement; + /*! \brief Base class for NURBS-based FEM simulators with input file parsing. */ -class TiXmlElement; - class SIMinput { protected: @@ -36,10 +36,14 @@ public: //! \brief Reads model data from the specified input file \a *fileName. virtual bool read(const char* fileName); - //! \brief Reads a flat text input file - virtual bool readFlat(const char* fileName); - //! \brief Reads an XML input file + +private: + //! \brief Reads a flat text input file. + bool readFlat(const char* fileName); + //! \brief Reads an XML input file. bool readXML(const char* fileName); + +public: //! \brief Parses a data section from an input stream. virtual bool parse(char* keyWord, std::istream& is) = 0; //! \brief Parses a data section from an XML element. @@ -51,11 +55,13 @@ protected: int myPid; //!< Processor ID in parallel simulations int nProc; //!< Number of processors in parallel simulations - //! \brief Certain tags needs to be parsed before others. This function takes care of this + //! \brief Handles the parsing order for certain XML-tags. //! \param[in] base The base tag containing the elements to be prioritized //! \returns A vector with elements that was handled - //! \details This function needs to be called in the app specific SIM classes - // prior parsing its app specific block. + //! + //! \details Certain tags needs to be parsed before others. This method takes + //! care of this. It needs to be called in the application-specific SIM class + //! prior to parsing its application-specific data block. std::vector handlePriorityTags(const TiXmlElement* base); };