diff --git a/ProcessLib/BoundaryConditionAndSourceTerm/Utils/LocalDataInitializer.h b/ProcessLib/BoundaryConditionAndSourceTerm/Utils/LocalDataInitializer.h index 204b949d2ca33e8293303ad4e05c25b2c1043ad4..8f28dba451b4fc1ba6c9a86c19ea673c2fdf8ebb 100644 --- a/ProcessLib/BoundaryConditionAndSourceTerm/Utils/LocalDataInitializer.h +++ b/ProcessLib/BoundaryConditionAndSourceTerm/Utils/LocalDataInitializer.h @@ -10,32 +10,34 @@ #pragma once -#include <functional> -#include <memory> -#include <type_traits> -#include <typeindex> -#include <typeinfo> -#include <unordered_map> - -#include "MeshLib/Elements/Elements.h" -#include "NumLib/DOF/LocalToGlobalIndexMap.h" -#include "NumLib/Fem/Integration/GaussLegendreIntegrationPolicy.h" #include "ProcessLib/Utils/EnabledElements.h" +#include "ProcessLib/Utils/GenericLocalDataInitializer.h" namespace ProcessLib { namespace BoundaryConditionAndSourceTerm { -/// The LocalDataInitializer is a functor creating a local assembler data with -/// corresponding to the mesh element type shape functions and calling -/// initialization of the new local assembler data. -/// For example for MeshLib::Quad a local assembler data with template argument -/// NumLib::ShapeQuad4 is created. template <typename LocalAssemblerInterface, - template <typename, typename, int> class LocalAssemblerData, - int GlobalDim, typename... ConstructorArgs> + template <typename, typename, int> + class LocalAssemblerImplementation, + int GlobalDim, + typename... ConstructorArgs> class LocalDataInitializer final + : public ProcessLib::GenericLocalDataInitializer<LocalAssemblerInterface, + ConstructorArgs...> { + using Base = + ProcessLib::GenericLocalDataInitializer<LocalAssemblerInterface, + ConstructorArgs...>; + + template <typename ShapeFunction> + using LocAsmBuilderFactory = + ProcessLib::LocalAssemblerBuilderFactory<ShapeFunction, + LocalAssemblerInterface, + LocalAssemblerImplementation, + GlobalDim, + ConstructorArgs...>; + struct HasSuitableDimension { template <typename ElementTraits> @@ -62,11 +64,9 @@ class LocalDataInitializer final }; public: - using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>; - LocalDataInitializer(NumLib::LocalToGlobalIndexMap const& dof_table, const unsigned shapefunction_order) - : _dof_table(dof_table) + : Base(dof_table) { if (shapefunction_order < 1 || 2 < shapefunction_order) { @@ -90,7 +90,7 @@ public: using LowerOrderShapeFunction = typename ET::LowerOrderShapeFunction; _builder[std::type_index(typeid(MeshElement))] = - makeLocalAssemblerBuilder<LowerOrderShapeFunction>(); + LocAsmBuilderFactory<LowerOrderShapeFunction>::create(); }); } else if (shapefunction_order == 2) @@ -106,74 +106,10 @@ public: using MeshElement = typename ET::Element; using ShapeFunction2ndOrder = typename ET::ShapeFunction; _builder[std::type_index(typeid(MeshElement))] = - makeLocalAssemblerBuilder<ShapeFunction2ndOrder>(); + LocAsmBuilderFactory<ShapeFunction2ndOrder>::create(); }); } } - - /// Returns data pointer to the newly created local assembler data. - /// - /// \attention - /// The index \c id is not necessarily the mesh item's id. Especially when - /// having multiple meshes it will differ from the latter. - LADataIntfPtr operator()(std::size_t const id, - MeshLib::Element const& mesh_item, - ConstructorArgs&&... args) const - { - auto const type_idx = std::type_index(typeid(mesh_item)); - auto const it = _builder.find(type_idx); - - if (it != _builder.end()) - { - auto const num_local_dof = _dof_table.getNumberOfElementDOF(id); - return it->second(mesh_item, num_local_dof, - std::forward<ConstructorArgs>(args)...); - } - OGS_FATAL( - "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, or a mesh element order does not match shape " - "function order given in the project file.", - type_idx.name()); - } - -private: - using LADataBuilder = - std::function<LADataIntfPtr(MeshLib::Element const& e, - std::size_t const local_matrix_size, - ConstructorArgs&&...)>; - - template <typename ShapeFunction> - using IntegrationMethod = typename NumLib::GaussLegendreIntegrationPolicy< - typename ShapeFunction::MeshElement>::IntegrationMethod; - - template <typename ShapeFunction> - using LAData = - LocalAssemblerData<ShapeFunction, IntegrationMethod<ShapeFunction>, - GlobalDim>; - - /// Generates a function that creates a new LocalAssembler of type - /// LAData<ShapeFunction>. Only functions with shape function's dimension - /// less or equal to the global dimension are instantiated, e.g. following - /// combinations of shape functions and global dimensions: (Line2, 1), - /// (Line2, 2), (Line2, 3), (Hex20, 3) but not (Hex20, 2) or (Hex20, 1). - template <typename ShapeFunction> - static LADataBuilder makeLocalAssemblerBuilder() - { - return [](MeshLib::Element const& e, - std::size_t const local_matrix_size, - ConstructorArgs&&... args) - { - return LADataIntfPtr{new LAData<ShapeFunction>{ - e, local_matrix_size, std::forward<ConstructorArgs>(args)...}}; - }; - } - - /// Mapping of element types to local assembler constructors. - std::unordered_map<std::type_index, LADataBuilder> _builder; - - NumLib::LocalToGlobalIndexMap const& _dof_table; }; } // namespace BoundaryConditionAndSourceTerm diff --git a/ProcessLib/Utils/GenericLocalDataInitializer.h b/ProcessLib/Utils/GenericLocalDataInitializer.h index a3aa6553f33f580579a581ad32af25ead61dd6ee..9a64bdd4ee2e9884694db72f27af62d7d052b19d 100644 --- a/ProcessLib/Utils/GenericLocalDataInitializer.h +++ b/ProcessLib/Utils/GenericLocalDataInitializer.h @@ -22,8 +22,7 @@ namespace ProcessLib { /// A functor creating a local assembler with shape functions corresponding to /// the mesh element type. -template <typename LocalAssemblerInterface, int GlobalDim, - typename... ConstructorArgs> +template <typename LocalAssemblerInterface, typename... ConstructorArgs> struct GenericLocalDataInitializer { using LocAsmIntfPtr = std::unique_ptr<LocalAssemblerInterface>; @@ -82,7 +81,7 @@ template <typename ShapeFunction, typename LocalAssemblerInterface, int GlobalDim, typename... ConstructorArgs> class LocalAssemblerBuilderFactory { - using GLDI = GenericLocalDataInitializer<LocalAssemblerInterface, GlobalDim, + using GLDI = GenericLocalDataInitializer<LocalAssemblerInterface, ConstructorArgs...>; using LocAsmIntfPtr = typename GLDI::LocAsmIntfPtr; using LocAsmBuilder = typename GLDI::LocAsmBuilder; @@ -99,7 +98,7 @@ class LocalAssemblerBuilderFactory public: /// Generates a function that creates a new local assembler of type /// \c LocAsmImpl. - static LocAsmBuilder newInstance() + static LocAsmBuilder create() { return [](MeshLib::Element const& e, std::size_t const local_matrix_size, diff --git a/ProcessLib/Utils/LocalDataInitializerForDimGeN.h b/ProcessLib/Utils/LocalDataInitializerForDimGeN.h index 2a2c71cadb12966ac04f61de2c4f976997437c47..a39b5a292c92c1e66e284dda14d74db56feec674 100644 --- a/ProcessLib/Utils/LocalDataInitializerForDimGeN.h +++ b/ProcessLib/Utils/LocalDataInitializerForDimGeN.h @@ -23,11 +23,9 @@ template <int MinElementDim, typename... ConstructorArgs> class LocalDataInitializerForDimGeN final : public GenericLocalDataInitializer<LocalAssemblerInterface, - GlobalDim, ConstructorArgs...> { using Base = GenericLocalDataInitializer<LocalAssemblerInterface, - GlobalDim, ConstructorArgs...>; struct IsElementEnabled @@ -59,12 +57,11 @@ public: using Elt = typename ET::Element; using Shp = typename ET::ShapeFunction; Base::_builders[std::type_index(typeid(Elt))] = - LocalAssemblerBuilderFactory< - Shp, - LocalAssemblerInterface, - LocalAssemblerImplementation, - GlobalDim, - ConstructorArgs...>::newInstance(); + LocalAssemblerBuilderFactory<Shp, + LocalAssemblerInterface, + LocalAssemblerImplementation, + GlobalDim, + ConstructorArgs...>::create(); }); } };