diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt index 07dd8e2895db7d981471265a0d01159980be19bd..38907f9f81ff5d74a304efadffda83c6d9abcb68 100644 --- a/Applications/CMakeLists.txt +++ b/Applications/CMakeLists.txt @@ -1,3 +1,5 @@ +include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake) + add_subdirectory(ApplicationsLib) if(OGS_BUILD_UTILS AND NOT IS_SUBPROJECT) diff --git a/AssemblerLib/CMakeLists.txt b/AssemblerLib/CMakeLists.txt index ff62c445190b7a274db79f79b2fc446e3e08b1ea..bf04b9b5ede969a54418e5779886b31a7b6ba150 100644 --- a/AssemblerLib/CMakeLists.txt +++ b/AssemblerLib/CMakeLists.txt @@ -1,3 +1,5 @@ +include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake) + #Source files grouped by a directory GET_SOURCE_FILES(SOURCES_ASSEMBLERLIB) set(SOURCES ${SOURCES_ASSEMBLERLIB}) diff --git a/AssemblerLib/LocalDataInitializer.h b/AssemblerLib/LocalDataInitializer.h index 2a3bde8026e6e1e57671cfabb7f38d0ed27f5108..46f69d426960b4194af1976edd1956cff138b14a 100644 --- a/AssemblerLib/LocalDataInitializer.h +++ b/AssemblerLib/LocalDataInitializer.h @@ -19,22 +19,97 @@ #include "NumLib/Fem/Integration/GaussIntegrationPolicy.h" -#include "NumLib/Fem/ShapeFunction/ShapeHex20.h" -#include "NumLib/Fem/ShapeFunction/ShapeHex8.h" +#ifndef OGS_MAX_ELEMENT_DIM +static_assert(false, "The macro OGS_MAX_ELEMENT_DIM is undefined."); +#endif + +#ifndef OGS_MAX_ELEMENT_ORDER +static_assert(false, "The macro OGS_MAX_ELEMENT_ORDER is undefined."); +#endif + +// The following macros decide which element types will be compiled, i.e. +// which element types will be available for use in simulations. + +#ifdef OGS_ENABLE_ELEMENT_SIMPLEX +#define ENABLED_ELEMENT_TYPE_SIMPLEX 1u +#else +#define ENABLED_ELEMENT_TYPE_SIMPLEX 0u +#endif + +#ifdef OGS_ENABLE_ELEMENT_CUBOID +#define ENABLED_ELEMENT_TYPE_CUBOID 1u << 1 +#else +#define ENABLED_ELEMENT_TYPE_CUBOID 0u +#endif + +#ifdef OGS_ENABLE_ELEMENT_PRISM +#define ENABLED_ELEMENT_TYPE_PRISM 1u << 2 +#else +#define ENABLED_ELEMENT_TYPE_PRISM 0u +#endif + +#ifdef OGS_ENABLE_ELEMENT_PYRAMID +#define ENABLED_ELEMENT_TYPE_PYRAMID 1u << 3 +#else +#define ENABLED_ELEMENT_TYPE_PYRAMID 0u +#endif + +// Dependent element types. +// Faces of tets, pyramids and prisms are triangles +#define ENABLED_ELEMENT_TYPE_TRI ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_PYRAMID) \ + |(ENABLED_ELEMENT_TYPE_PRISM)) +// Faces of hexes, pyramids and prisms are quads +#define ENABLED_ELEMENT_TYPE_QUAD ((ENABLED_ELEMENT_TYPE_CUBOID) | (ENABLED_ELEMENT_TYPE_PYRAMID) \ + |(ENABLED_ELEMENT_TYPE_PRISM)) +// Faces of triangles and quads are lines +#define ENABLED_ELEMENT_TYPE_LINE ((ENABLED_ELEMENT_TYPE_TRI) | (ENABLED_ELEMENT_TYPE_QUAD)) + +// All enabled element types +#define OGS_ENABLED_ELEMENTS \ + ( (ENABLED_ELEMENT_TYPE_SIMPLEX) \ + | (ENABLED_ELEMENT_TYPE_CUBOID ) \ + | (ENABLED_ELEMENT_TYPE_PYRAMID) \ + | (ENABLED_ELEMENT_TYPE_PRISM ) ) + + +// Include only what is needed (Well, the conditions are not sharp). +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 #include "NumLib/Fem/ShapeFunction/ShapeLine2.h" #include "NumLib/Fem/ShapeFunction/ShapeLine3.h" #include "NumLib/Fem/ShapeFunction/ShapePoint1.h" -#include "NumLib/Fem/ShapeFunction/ShapePrism15.h" -#include "NumLib/Fem/ShapeFunction/ShapePrism6.h" -#include "NumLib/Fem/ShapeFunction/ShapePyra13.h" -#include "NumLib/Fem/ShapeFunction/ShapePyra5.h" -#include "NumLib/Fem/ShapeFunction/ShapeQuad4.h" -#include "NumLib/Fem/ShapeFunction/ShapeQuad8.h" -#include "NumLib/Fem/ShapeFunction/ShapeQuad9.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 #include "NumLib/Fem/ShapeFunction/ShapeTet10.h" #include "NumLib/Fem/ShapeFunction/ShapeTet4.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 #include "NumLib/Fem/ShapeFunction/ShapeTri3.h" #include "NumLib/Fem/ShapeFunction/ShapeTri6.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 +#include "NumLib/Fem/ShapeFunction/ShapeHex20.h" +#include "NumLib/Fem/ShapeFunction/ShapeHex8.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 +#include "NumLib/Fem/ShapeFunction/ShapeQuad4.h" +#include "NumLib/Fem/ShapeFunction/ShapeQuad8.h" +#include "NumLib/Fem/ShapeFunction/ShapeQuad9.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 +#include "NumLib/Fem/ShapeFunction/ShapePrism15.h" +#include "NumLib/Fem/ShapeFunction/ShapePrism6.h" +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 +#include "NumLib/Fem/ShapeFunction/ShapePyra13.h" +#include "NumLib/Fem/ShapeFunction/ShapePyra5.h" +#endif + namespace AssemblerLib { @@ -66,38 +141,110 @@ class LocalDataInitializer public: LocalDataInitializer() { - _builder[std::type_index(typeid(MeshLib::Hex20))] = - [](){ return new LAData<NumLib::ShapeHex20>; }; - _builder[std::type_index(typeid(MeshLib::Hex))] = - [](){ return new LAData<NumLib::ShapeHex8>; }; + // /// Lines and points /////////////////////////////////// + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 0 && OGS_MAX_ELEMENT_ORDER >= 1 + _builder[std::type_index(typeid(MeshLib::Point))] = + [](){ return new LAData<NumLib::ShapePoint1>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 1 _builder[std::type_index(typeid(MeshLib::Line))] = [](){ return new LAData<NumLib::ShapeLine2>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 2 _builder[std::type_index(typeid(MeshLib::Line3))] = [](){ return new LAData<NumLib::ShapeLine3>; }; - _builder[std::type_index(typeid(MeshLib::Point))] = - [](){ return new LAData<NumLib::ShapePoint1>; }; - _builder[std::type_index(typeid(MeshLib::Prism15))] = - [](){ return new LAData<NumLib::ShapePrism15>; }; - _builder[std::type_index(typeid(MeshLib::Prism))] = - [](){ return new LAData<NumLib::ShapePrism6>; }; - _builder[std::type_index(typeid(MeshLib::Pyramid13))] = - [](){ return new LAData<NumLib::ShapePyra13>; }; - _builder[std::type_index(typeid(MeshLib::Pyramid))] = - [](){ return new LAData<NumLib::ShapePyra5>; }; +#endif + + + // /// Quads and Hexahedra /////////////////////////////////// + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1 _builder[std::type_index(typeid(MeshLib::Quad))] = [](){ return new LAData<NumLib::ShapeQuad4>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1 + _builder[std::type_index(typeid(MeshLib::Hex))] = + [](){ return new LAData<NumLib::ShapeHex8>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2 _builder[std::type_index(typeid(MeshLib::Quad8))] = [](){ return new LAData<NumLib::ShapeQuad8>; }; _builder[std::type_index(typeid(MeshLib::Quad9))] = [](){ return new LAData<NumLib::ShapeQuad9>; }; - _builder[std::type_index(typeid(MeshLib::Tet10))] = - [](){ return new LAData<NumLib::ShapeTet10>; }; - _builder[std::type_index(typeid(MeshLib::Tet))] = - [](){ return new LAData<NumLib::ShapeTet4>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2 + _builder[std::type_index(typeid(MeshLib::Hex20))] = + [](){ return new LAData<NumLib::ShapeHex20>; }; +#endif + + + // /// Simplices //////////////////////////////////////////////// + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1 _builder[std::type_index(typeid(MeshLib::Tri))] = [](){ return new LAData<NumLib::ShapeTri3>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1 + _builder[std::type_index(typeid(MeshLib::Tet))] = + [](){ return new LAData<NumLib::ShapeTet4>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2 _builder[std::type_index(typeid(MeshLib::Tri6))] = [](){ return new LAData<NumLib::ShapeTri6>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2 + _builder[std::type_index(typeid(MeshLib::Tet10))] = + [](){ return new LAData<NumLib::ShapeTet10>; }; +#endif + + + // /// Prisms //////////////////////////////////////////////////// + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1 + _builder[std::type_index(typeid(MeshLib::Prism))] = + [](){ return new LAData<NumLib::ShapePrism6>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2 + _builder[std::type_index(typeid(MeshLib::Prism15))] = + [](){ return new LAData<NumLib::ShapePrism15>; }; +#endif + + // /// Pyramids ////////////////////////////////////////////////// + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1 + _builder[std::type_index(typeid(MeshLib::Pyramid))] = + [](){ return new LAData<NumLib::ShapePyra5>; }; +#endif + +#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 \ + && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2 + _builder[std::type_index(typeid(MeshLib::Pyramid13))] = + [](){ return new LAData<NumLib::ShapePyra13>; }; +#endif } /// Sets the provided data_ptr to the newly created local assembler data and @@ -106,8 +253,18 @@ public: void operator()(const MeshLib::Element& e, LocalAssemblerDataInterface_<GlobalMatrix_, GlobalVector_>*& data_ptr, Args_&&... args) { - data_ptr = _builder[std::type_index(typeid(e))](); - data_ptr->init(e, std::forward<Args_>(args)...); + auto const type_idx = std::type_index(typeid(e)); + auto it = _builder.find(type_idx); + + if (it != _builder.end()) { + data_ptr = it->second(); + data_ptr->init(e, std::forward<Args_>(args)...); + } else { + ERR("You are trying to build a local assembler for an unknown mesh element type (%s)." + " Maybe you have disabled this mesh element type in your build configuration.", + type_idx.name()); + std::abort(); + } } private: @@ -120,4 +277,14 @@ private: } // namespace AssemblerLib + +#undef ENABLED_ELEMENT_TYPE_SIMPLEX +#undef ENABLED_ELEMENT_TYPE_CUBOID +#undef ENABLED_ELEMENT_TYPE_PYRAMID +#undef ENABLED_ELEMENT_TYPE_PRISM +#undef ENABLED_ELEMENT_TYPE_LINE +#undef ENABLED_ELEMENT_TYPE_TRI +#undef ENABLED_ELEMENT_TYPE_QUAD +#undef OGS_ENABLED_ELEMENTS + #endif // ASSEMBLER_LIB_LOCALDATAINITIALIZER_H_ diff --git a/CMakeLists.txt b/CMakeLists.txt index aded93597f610ef468250d9551beb44c129115c5..d3ac9ed761922d197531513d7dd983a1774eca9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,14 @@ set_property(CACHE OGS_LIB_EIGEN PROPERTY STRINGS "Default" "System" "Local") +# Options controlling which FEM elements will be compiled +set(OGS_MAX_ELEMENT_DIM 3 CACHE STRING "Maximum dimension of FEM elements to be built.") +set(OGS_MAX_ELEMENT_ORDER 2 CACHE STRING "Maximum order of FEM elements to be built.") +option(OGS_ENABLE_ELEMENT_SIMPLEX "Build FEM elements for simplices (triangles, tetrahedra)." ON) +option(OGS_ENABLE_ELEMENT_CUBOID "Build FEM elements for cuboids (quads, hexahedra)." ON) +option(OGS_ENABLE_ELEMENT_PRISM "Build FEM elements for prisms." ON) +option(OGS_ENABLE_ELEMENT_PYRAMID "Build FEM elements for pyramids." ON) + ################### ### Definitions ### ################### diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt index 0b680154fd2fcdbd813a610c67074fb4ce0f4554..9ebfdfb669cd194a59433c1edecdd4a1f7e411b6 100644 --- a/FileIO/CMakeLists.txt +++ b/FileIO/CMakeLists.txt @@ -49,6 +49,8 @@ if(OGS_USE_PETSC) set(SOURCES ${SOURCES} ${SOURCES_MPI_IO}) endif() +include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake) + # Create the library add_library(FileIO STATIC ${SOURCES}) diff --git a/ProcessLib/CMakeLists.txt b/ProcessLib/CMakeLists.txt index af6c480143a09351b371ecabb7cdf922a8459fc4..d9c60892dc0031b347a11b4ee421f989d4835e92 100644 --- a/ProcessLib/CMakeLists.txt +++ b/ProcessLib/CMakeLists.txt @@ -1,3 +1,5 @@ +include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake) + # Source files GET_SOURCE_FILES(SOURCES) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 33e6b3514974137da0e68473111a26286a0b4cb9..f0880be09ecd2830194c0b53948a9411f2fe7eca 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1,3 +1,5 @@ +include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake) + # VS2012 doesn't support correctly the tuples yet # See http://code.google.com/p/googletest/issues/detail?id=412 if(MSVC) diff --git a/scripts/cmake/OGSEnabledElements.cmake b/scripts/cmake/OGSEnabledElements.cmake new file mode 100644 index 0000000000000000000000000000000000000000..c805f16b38ba86562602b9142073b88ca244a181 --- /dev/null +++ b/scripts/cmake/OGSEnabledElements.cmake @@ -0,0 +1,24 @@ +# Definitions controlling which FEM elements will be compiled +if(NOT OGS_MAX_ELEMENT_DIM MATCHES "^[0-3]$") + message(FATAL_ERROR "OGS_MAX_ELEMENT_DIM must be an integer between 0 and 3.") +endif() +add_definitions(-DOGS_MAX_ELEMENT_DIM=${OGS_MAX_ELEMENT_DIM}) + +if(NOT OGS_MAX_ELEMENT_ORDER MATCHES "^[0-9]$") + message(FATAL_ERROR "OGS_MAX_ELEMENT_ORDER must be an integer.") +endif() +add_definitions(-DOGS_MAX_ELEMENT_ORDER=${OGS_MAX_ELEMENT_ORDER}) + + +if(OGS_ENABLE_ELEMENT_SIMPLEX) + add_definitions(-DOGS_ENABLE_ELEMENT_SIMPLEX) +endif() +if(OGS_ENABLE_ELEMENT_CUBOID) + add_definitions(-DOGS_ENABLE_ELEMENT_CUBOID) +endif() +if(OGS_ENABLE_ELEMENT_PRISM) + add_definitions(-DOGS_ENABLE_ELEMENT_PRISM) +endif() +if(OGS_ENABLE_ELEMENT_PYRAMID) + add_definitions(-DOGS_ENABLE_ELEMENT_PYRAMID) +endif()