From fd0e96de2964d92b893ecdcaafc5a0c3d6633ca2 Mon Sep 17 00:00:00 2001 From: rinkk <karsten.rink@ufz.de> Date: Thu, 1 Mar 2018 12:24:48 +0100 Subject: [PATCH] added data structures and read method for fem-conditions in data explorer --- .../DataHolderLib/BoundaryCondition.h | 29 +++++ Applications/DataHolderLib/Condition.cpp | 73 ++++++++++++ Applications/DataHolderLib/Condition.h | 83 ++++++++++++++ Applications/DataHolderLib/InitialCondition.h | 39 +++++++ Applications/DataHolderLib/Project.h | 16 +++ Applications/DataHolderLib/SourceTerm.h | 29 +++++ .../FileIO/XmlIO/OpenGeoSysProject.xsd | 107 ++++++++++++------ Tests/FileIO_Qt/TestQtPrjInterface.cpp | 77 +++++++++++++ scripts/cmake/CompilerSetup.cmake | 3 +- 9 files changed, 418 insertions(+), 38 deletions(-) create mode 100644 Applications/DataHolderLib/BoundaryCondition.h create mode 100644 Applications/DataHolderLib/Condition.cpp create mode 100644 Applications/DataHolderLib/Condition.h create mode 100644 Applications/DataHolderLib/InitialCondition.h create mode 100644 Applications/DataHolderLib/SourceTerm.h create mode 100644 Tests/FileIO_Qt/TestQtPrjInterface.cpp diff --git a/Applications/DataHolderLib/BoundaryCondition.h b/Applications/DataHolderLib/BoundaryCondition.h new file mode 100644 index 00000000000..90a62a8b77a --- /dev/null +++ b/Applications/DataHolderLib/BoundaryCondition.h @@ -0,0 +1,29 @@ +/** + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#pragma once +#include "Applications/DataHolderLib/Condition.h" + +namespace DataHolderLib +{ + +class BoundaryCondition : public DataHolderLib::Condition +{ +public: + BoundaryCondition(std::string const process_var, std::string const param_name, ConditionType type) + : Condition(process_var, param_name, type) + {} + +private: + +}; + + +} // namespace diff --git a/Applications/DataHolderLib/Condition.cpp b/Applications/DataHolderLib/Condition.cpp new file mode 100644 index 00000000000..564a0e05b0b --- /dev/null +++ b/Applications/DataHolderLib/Condition.cpp @@ -0,0 +1,73 @@ +/** + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#include "Condition.h" + +namespace DataHolderLib +{ + +Condition::Condition(std::string const process_var, std::string const param_name, ConditionType type) +: _type(type), _process_var(process_var), _param_name(param_name) +{}; + +Condition::Condition(Condition const& c) +: _base_type(c.getBaseObjType()), _type(c.getType()), + _process_var(c.getProcessVarName()), _param_name(c.getParamName()), + _base_obj_name(c.getBaseObjName()), _obj_name(c.getObjName()) +{} + +void Condition::setMesh(std::string const mesh_name) +{ + _base_type = BaseObjType::MESH; + _base_obj_name = mesh_name; + _obj_name = ""; +} + +void Condition::setGeoObject(std::string geo_name, std::string obj_name) +{ + _base_type = BaseObjType::GEOMETRY; + _base_obj_name = geo_name; + _obj_name = obj_name; +} + +ConditionType Condition::convertStringToType(std::string const& str) +{ + if ( str == "Dirichlet") + return ConditionType::DIRICHLET; + else if (str == "NonlinearDirichlet") + return ConditionType::NONLINEARDIRICHLET; + else if (str == "Neumann") + return ConditionType::NEUMANN; + else if (str == "NonuniformNeumann") + return ConditionType::NONLINEARNEUMANN; + else if (str == "Robin") + return ConditionType::ROBIN; + + return ConditionType::NONE; +} + +std::string Condition::convertTypeToString(ConditionType type) +{ + if (type == ConditionType::DIRICHLET) + return "Dirichlet"; + else if (type == ConditionType::NONLINEARDIRICHLET) + return "NonlinearDirichlet"; + else if (type == ConditionType::NEUMANN) + return "Neumann"; + else if (type == ConditionType::NONLINEARDIRICHLET) + return "NonlinearNeumann"; + else if (type == ConditionType::ROBIN) + return "Robin"; + + return ""; +} + + +} // namespace diff --git a/Applications/DataHolderLib/Condition.h b/Applications/DataHolderLib/Condition.h new file mode 100644 index 00000000000..b14a21b72d5 --- /dev/null +++ b/Applications/DataHolderLib/Condition.h @@ -0,0 +1,83 @@ +/** + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#pragma once + +#include <string> + +namespace DataHolderLib +{ + +enum class BaseObjType +{ + MESH = 0, + GEOMETRY = 1 +}; + +enum class ConditionType +{ + NONE = 0, + DIRICHLET, + NONLINEARDIRICHLET, + NEUMANN, + NONLINEARNEUMANN, + ROBIN +}; + +enum class ParameterType +{ + NONE, + CONSTANT, + FUNCTION +}; + +class Condition +{ +public: + Condition(std::string const process_var, std::string const param_name, ConditionType type); + + Condition(Condition const& c); + + ~Condition() {}; + + /// Returns the name of the associated process variable + std::string const getProcessVarName() const { return _process_var; } + + std::string const getParamName() const { return _param_name; } + + /// Is the condition set a geometry or on a mesh + BaseObjType getBaseObjType() const { return _base_type; } + + ///Returns the name of the base object (i.e. geometry or mesh) + std::string getBaseObjName() const { return _base_obj_name; } + + ///Returns the name of the geometric object + std::string const getObjName() const { return _obj_name; } + + ConditionType getType() const { return _type; } + + void setMesh(std::string const mesh_name); + + virtual void setGeoObject(std::string geo_name, std::string obj_name); + + static std::string convertTypeToString(ConditionType type); + + static ConditionType convertStringToType(std::string const& type_str); + +private: + BaseObjType _base_type; + ConditionType _type; + std::string _process_var; + std::string _param_name; + std::string _base_obj_name; + std::string _obj_name; +}; + +} // namespace diff --git a/Applications/DataHolderLib/InitialCondition.h b/Applications/DataHolderLib/InitialCondition.h new file mode 100644 index 00000000000..e5d4147eafd --- /dev/null +++ b/Applications/DataHolderLib/InitialCondition.h @@ -0,0 +1,39 @@ +/** + * \file + * \author Karsten Rink + * \date 2010-02-04 + * \brief Definition of the Color class. + * + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#pragma once + +#include <array> +#include <map> +#include <string> + +namespace DataHolderLib +{ +using Color = std::array<unsigned char, 4>; + +Color createColor(unsigned char r, unsigned char g, unsigned char b); + +Color createColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +/// Returns a random RGB colour. +Color getRandomColor(); + +/// Uses a color-lookup-table (in form of a map) to return a colour for a specified name. If the name is not +/// in the colortable a new entry is created with the new name and a random colour. +Color const getColor(const std::string &id, std::map<std::string, DataHolderLib::Color> &colors); + +/// Convenience function to use the getColor method with numbers as identifiers. +Color const getColor(double id, std::map<std::string, DataHolderLib::Color> &colors); +} // namespace diff --git a/Applications/DataHolderLib/Project.h b/Applications/DataHolderLib/Project.h index 8ee2edc1056..d9d9b850120 100644 --- a/Applications/DataHolderLib/Project.h +++ b/Applications/DataHolderLib/Project.h @@ -15,6 +15,10 @@ #include "MeshLib/Mesh.h" +#include "Applications/DataHolderLib/BoundaryCondition.h" + +#include "Applications/DataHolderLib/SourceTerm.h" + //namespace MeshLib { // class Mesh; //} @@ -59,6 +63,14 @@ public: /// false otherwise. bool removeMesh(const std::string &name); + void addBoundaryCondition(BoundaryCondition bc) { _boundary_conditions.push_back(bc); } + + std::vector<BoundaryCondition> const getBoundaryConditions() const { return _boundary_conditions; } + + void addSourceTerm(SourceTerm bc) { _source_terms.push_back(bc); } + + std::vector<SourceTerm> const getSourceTerms() const { return _source_terms; } + private: /// Checks if a mesh with the same name exists and provides a unique name in /// case of already existing mesh. Returns true if the mesh name is unique. @@ -77,6 +89,10 @@ private: GeoLib::GEOObjects _geoObjects; std::vector<std::unique_ptr<MeshLib::Mesh>> _mesh_vec; + + std::vector<BoundaryCondition> _boundary_conditions; + + std::vector<SourceTerm> _source_terms; }; } // namespace diff --git a/Applications/DataHolderLib/SourceTerm.h b/Applications/DataHolderLib/SourceTerm.h new file mode 100644 index 00000000000..13a74df460b --- /dev/null +++ b/Applications/DataHolderLib/SourceTerm.h @@ -0,0 +1,29 @@ +/** +* \copyright +* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) +* Distributed under a Modified BSD License. +* See accompanying file LICENSE.txt or +* http://www.opengeosys.org/project/license +* +* +*/ + +#pragma once +#include "Applications/DataHolderLib/Condition.h" + +namespace DataHolderLib +{ + + class SourceTerm : public DataHolderLib::Condition + { + public: + SourceTerm(std::string const process_var, std::string const param_name, ConditionType type) + : Condition(process_var, param_name, type) + {} + + private: + + }; + + +} // namespace diff --git a/Applications/FileIO/XmlIO/OpenGeoSysProject.xsd b/Applications/FileIO/XmlIO/OpenGeoSysProject.xsd index f721a815f9d..c39b190b12c 100644 --- a/Applications/FileIO/XmlIO/OpenGeoSysProject.xsd +++ b/Applications/FileIO/XmlIO/OpenGeoSysProject.xsd @@ -2,56 +2,89 @@ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- OpenGeoSysProject schema; initial implementation: Karsten Rink, 2010-08-20 --> + <xs:element name="name" type="xs:string" /> - <!-- object containing just a source file definition --> - <xs:complexType name="projectElement"> + <!-- definition of processes --> + <xs:complexType name="processType"> <xs:sequence> - <xs:element name="file" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element ref="name" minOccurs="1" maxOccurs="1" /> + <xs:element name="type" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="integration_order" minOccurs="1" maxOccurs="1" /> + <xs:element name="process_variables" minOccurs="1" maxOccurs="1" /> + <xs:element name="secondary_variables" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:complexType> - <!-- object containing a required reference to a geometry file --> - <xs:complexType name="geoElement"> - <xs:complexContent> - <xs:extension base="projectElement"> - <xs:sequence> - <xs:element name="geoReference" type="xs:string"/> - </xs:sequence> - </xs:extension> - </xs:complexContent> + <xs:complexType name="parameterType"> + <xs:sequence> + <xs:element ref="name" minOccurs="1" maxOccurs="1" /> + <xs:element name="type" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="value" minOccurs="0" maxOccurs="1" /> + <xs:element name="field_name" type="xs:string" minOccurs="0" maxOccurs="1" /> + </xs:sequence> </xs:complexType> - <!-- msh-object with optional geometry- and texture-reference --> - <xs:complexType name="mshElement"> - <xs:complexContent> - <xs:extension base="projectElement"> - <xs:sequence> - <xs:element name="geoReference" type="xs:string" minOccurs="0" /> - <xs:element name="texture" type="xs:string" minOccurs="0" /> - </xs:sequence> - </xs:extension> - </xs:complexContent> + <xs:complexType name="conditionType"> + <xs:sequence> + <xs:element name="geometrical_set" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="geometry" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="type" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="field_name" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="mesh" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="parameter" type="xs:string" minOccurs="0" maxOccurs="1" /> + </xs:sequence> </xs:complexType> + <xs:complexType name="conditionListType"> + <xs:sequence> + <xs:element name="boundary_condition" type="conditionType" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + <xs:complexType name="pvariableType"> + <xs:sequence> + <xs:element ref="name"/> + <xs:element name="components" type="xs:nonNegativeInteger" minOccurs="1" maxOccurs="1" /> + <xs:element name="order" type="xs:nonNegativeInteger" minOccurs="1" maxOccurs="1" /> + <xs:element name="initial_condition" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="boundary_conditions" type="conditionListType" minOccurs="0" maxOccurs="1" /> + <xs:element name="source_terms" type="conditionListType" minOccurs="0" maxOccurs="1" /> + </xs:sequence> + </xs:complexType> + <!-- definition of file content --> <xs:element name="OpenGeoSysProject"> <xs:complexType> - <xs:sequence> - <xs:element name="geo" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="msh" type="mshElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="cnd" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="mfp" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="mmp" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="msp" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="np" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="out" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="pcs" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="sim" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="tim" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="fct" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - <xs:element name="stn" type="projectElement" minOccurs="0" maxOccurs="unbounded" /> - </xs:sequence> + <xs:all> + <xs:element name="mesh" minOccurs="0"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="axially_symmetric" type="xs:boolean"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + <xs:element name="geometry" type="xs:string" minOccurs="0"/> + <xs:element name="processes" minOccurs="0"/> <!--ignore--> + <xs:element name="time_loop" minOccurs="0"/> <!--ignore--> + <xs:element name="parameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="parameter" type="parameterType" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="process_variables" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="process_variable" type="pvariableType" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="nonlinear_solvers" minOccurs="0"/> <!--ignore--> + <xs:element name="linear_solvers" minOccurs="0"/> <!--ignore--> + </xs:all> </xs:complexType> </xs:element> diff --git a/Tests/FileIO_Qt/TestQtPrjInterface.cpp b/Tests/FileIO_Qt/TestQtPrjInterface.cpp new file mode 100644 index 00000000000..66c928ecde1 --- /dev/null +++ b/Tests/FileIO_Qt/TestQtPrjInterface.cpp @@ -0,0 +1,77 @@ +/** + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#include <cstdio> + +#include "gtest/gtest.h" + +#include "BaseLib/BuildInfo.h" +#include "Applications/FileIO/XmlIO/Qt/XmlPrjInterface.h" +#include "Applications/DataHolderLib/Project.h" +#include "Applications/DataHolderLib/BoundaryCondition.h" +#include "Applications/DataHolderLib/SourceTerm.h" +#include "GeoLib/GEOObjects.h" + + +TEST(TestQtPrjInterface, QtXmlPrjReader) +{ + typedef struct + { + std::string const file_name; + std::size_t n_geo; + std::size_t n_mesh; + std::size_t n_bc; + std::size_t n_st; + } TestParams; + + std::vector<TestParams> test_files; + + std::string name = BaseLib::BuildInfo::data_path + "/Elliptic/nonuniform_bc_Groundwaterflow/neumann_nonuniform.prj"; + test_files.push_back({ name, 1, 1, 2, 0 }); + name = BaseLib::BuildInfo::data_path + "/Elliptic/nonuniform_bc_Groundwaterflow/neumann_nonuniform.prj"; + test_files.push_back({ name, 1, 1, 2, 0 }); + + for (std::size_t i=0; i<test_files.size(); ++i) + { + DataHolderLib::Project project; + FileIO::XmlPrjInterface xml(project); + int result = xml.readFile(QString::fromStdString(test_files[i].file_name)); + EXPECT_EQ(1, result); + + std::vector<std::string> geo_names; + project.getGEOObjects().getGeometryNames(geo_names); + EXPECT_EQ(test_files[i].n_geo, geo_names.size()); + EXPECT_EQ(test_files[i].n_mesh, project.getMeshObjects().size()); + + std::vector<DataHolderLib::BoundaryCondition> const bcs = project.getBoundaryConditions(); + EXPECT_EQ(test_files[i].n_bc, bcs.size()); + for (DataHolderLib::BoundaryCondition bc : bcs) + { + EXPECT_FALSE(bc.getProcessVarName().empty()); + EXPECT_FALSE(bc.getParamName().empty()); + EXPECT_FALSE(DataHolderLib::ConditionType::NONE == bc.getType()); + EXPECT_FALSE(bc.getBaseObjName().empty()); + if (bc.getBaseObjType() == DataHolderLib::BaseObjType::GEOMETRY) + EXPECT_FALSE(bc.getObjName().empty()); + } + + std::vector<DataHolderLib::SourceTerm> const sts = project.getSourceTerms(); + EXPECT_EQ(test_files[i].n_st, sts.size()); + for (DataHolderLib::SourceTerm st : sts) + { + EXPECT_FALSE(st.getProcessVarName().empty()); + EXPECT_FALSE(st.getParamName().empty()); + EXPECT_FALSE(DataHolderLib::ConditionType::NONE == st.getType()); + EXPECT_FALSE(st.getBaseObjName().empty()); + if (st.getBaseObjType() == DataHolderLib::BaseObjType::GEOMETRY) + EXPECT_FALSE(st.getObjName().empty()); + } + } +} diff --git a/scripts/cmake/CompilerSetup.cmake b/scripts/cmake/CompilerSetup.cmake index bbcd1272cab..083922fb0e8 100644 --- a/scripts/cmake/CompilerSetup.cmake +++ b/scripts/cmake/CompilerSetup.cmake @@ -135,7 +135,8 @@ if(WIN32) /wd4267 /wd4996 /bigobj") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} \ /ZI /Od /Ob0") - + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /ignore:4099") + DisableCompilerFlag(DEBUG /RTC1) # cygwin else() -- GitLab