OGS
GenericLocalAssemblerFactory.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <functional>
7#include <memory>
8#include <typeindex>
9#include <unordered_map>
10
13
14namespace ProcessLib
15{
22template <typename T>
25 std::same_as<T, NumLib::IntegrationOrder>;
26
29template <typename LocalAssemblerInterface,
30 NumLib::IntegrationMethodProvider IntegrationMethodProvider,
31 typename... ConstructorArgs>
33{
34 using LocAsmIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
35 using LocAsmBuilder = std::function<LocAsmIntfPtr(
36 MeshLib::Element const& e,
37 std::size_t const local_matrix_size,
38 IntegrationMethodProvider const& integration_method_provider,
39 ConstructorArgs&&...)>;
40
41protected: // only allow instances of subclasses
43 NumLib::LocalToGlobalIndexMap const& dof_table,
44 IntegrationMethodProvider const& integration_method_provider)
45 : _dof_table{dof_table},
46 _integration_method_provider{integration_method_provider}
47 {
48 }
49
50public:
56 LocAsmIntfPtr operator()(std::size_t const id,
57 MeshLib::Element const& mesh_item,
58 ConstructorArgs&&... args) const
59 {
60 auto const type_idx = std::type_index(typeid(mesh_item));
61 auto const it = _builders.find(type_idx);
62
63 if (it != _builders.end())
64 {
65 auto const num_local_dof = _dof_table.getNumberOfElementDOF(id);
66 return it->second(mesh_item, num_local_dof,
68 std::forward<ConstructorArgs>(args)...);
69 }
71 "You are trying to build a local assembler for an unknown mesh "
72 "element type ({:s})."
73 " Maybe you have disabled this mesh element type in your build "
74 "configuration, or a mesh element order does not match shape "
75 "function order given in the project file.",
76 type_idx.name());
77 }
78
79private:
81 IntegrationMethodProvider const& _integration_method_provider;
82
83protected:
85 std::unordered_map<std::type_index, LocAsmBuilder> _builders;
86};
87
88template <typename ShapeFunction, typename LocalAssemblerInterface,
89 template <typename /* shp fct */, int /* global dim */>
90 class LocalAssemblerImplementation,
91 NumLib::IntegrationMethodProvider IntegrationMethodProvider,
92 int GlobalDim, typename... ConstructorArgs>
94{
96 LocalAssemblerInterface, IntegrationMethodProvider, ConstructorArgs...>;
99
100 using LocAsmImpl = LocalAssemblerImplementation<ShapeFunction, GlobalDim>;
101
103
104public:
107 template <typename MeshElement>
109 {
110 return [](MeshLib::Element const& e,
111 std::size_t const local_matrix_size,
112 IntegrationMethodProvider const& integration_method_provider,
113 ConstructorArgs&&... args)
114 {
115 auto const& integration_method =
116 integration_method_provider
117 .template getIntegrationMethod<MeshElement>(e);
118
119 static_assert(!std::is_abstract_v<LocAsmImpl>,
120 "The given local assembler implementation is an "
121 "abstract class, which cannot be instantiated. Make "
122 "sure to implement all virtual methods!");
123
124 static_assert(
125 std::is_constructible_v<
126 LocAsmImpl, MeshLib::Element const&, std::size_t,
127 decltype(integration_method), ConstructorArgs&&...>,
128 "The given local assembler implementation is not "
129 "constructible from the provided arguments.");
130
131 return std::make_unique<LocAsmImpl>(
132 e, local_matrix_size, integration_method,
133 std::forward<ConstructorArgs>(args)...);
134 };
135 }
136};
137
138} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
GenericLocalAssemblerFactory(NumLib::LocalToGlobalIndexMap const &dof_table, IntegrationMethodProvider const &integration_method_provider)
std::function< LocAsmIntfPtr(MeshLib::Element const &e, std::size_t const local_matrix_size, IntegrationMethodProvider const &integration_method_provider, ConstructorArgs &&...)> LocAsmBuilder
LocAsmIntfPtr operator()(std::size_t const id, MeshLib::Element const &mesh_item, ConstructorArgs &&... args) const