1 #ifndef MESHFIELD_SHAPEFIELD_HPP
2 #define MESHFIELD_SHAPEFIELD_HPP
4 #ifdef MESHFIELDS_ENABLE_CABANA
5 #include "CabanaController.hpp"
7 #include "KokkosController.hpp"
8 #include "MeshField_Field.hpp"
10 #include <type_traits>
98 template <
size_t numCompIn,
typename Shape,
typename... Mixins>
101 static const size_t numComp = numCompIn;
103 constexpr
static auto Order = Shape::Order;
109 : meshInfo(meshInfoIn), Mixins( std::forward<Mixins>(mixins) )... {};
133 template <
typename VtxAccessor,
typename EdgeAccessor>
135 constexpr
static const Mesh_Topology topo[2] = {Vertex, Edge};
136 VtxAccessor vtxField;
137 EdgeAccessor edgeField;
138 using BaseType =
typename VtxAccessor::BaseType;
141 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
142 if (t != Vertex && t != Edge) {
143 Kokkos::printf(
"%d is not a support topology\n", t);
146 return (t == Vertex) ? vtxField(entity, node, component)
147 : edgeField(entity, node, component);
168 constexpr
static const Mesh_Topology topo[1] = {Vertex};
169 VtxAccessor vtxField;
170 using BaseType =
typename VtxAccessor::BaseType;
173 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
175 Kokkos::printf(
"%d is not a support topology\n", t);
178 return vtxField(entity, node, component);
203 template <
typename ExecutionSpace,
204 template <
typename...>
205 typename Controller = MeshField::KokkosController,
206 typename DataType,
size_t order,
size_t dim,
size_t numComp>
207 auto CreateLagrangeField(
const MeshInfo &meshInfo) {
208 static_assert((std::is_same_v<Real4, DataType> ==
true ||
209 std::is_same_v<Real8, DataType> ==
true),
210 "CreateLagrangeField only supports single and double precision "
211 "floating point fields\n");
213 (order == 1 || order == 2),
214 "CreateLagrangeField only supports linear and quadratic fields\n");
215 static_assert((dim == 1 || dim == 2 || dim == 3),
216 "CreateLagrangeField only supports 1d, 2d, and 3d meshes\n");
217 using MemorySpace =
typename ExecutionSpace::memory_space;
218 if constexpr (order == 1 && (dim == 1 || dim == 2 || dim == 3)) {
219 if (meshInfo.numVtx <= 0) {
220 fail(
"mesh has no vertices\n");
222 #ifdef MESHFIELDS_ENABLE_CABANA
223 using Ctrlr = std::conditional_t<
225 Controller<ExecutionSpace, MemorySpace, DataType>,
226 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
227 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp]>,
228 Controller<MemorySpace, ExecutionSpace, DataType ***>>;
230 auto createController = [](
auto numVtx) {
231 if constexpr (std::is_same_v<
232 Controller<ExecutionSpace, MemorySpace, DataType>,
233 MeshField::CabanaController<ExecutionSpace, MemorySpace,
235 return Ctrlr({numVtx});
237 return Ctrlr({ numVtx, 1, numComp});
240 Ctrlr kk_ctrl = createController(meshInfo.numVtx);
242 using Ctrlr = Controller<MemorySpace, ExecutionSpace, DataType ***>;
243 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp});
245 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
246 using LA = LinearAccessor<decltype(vtxField)>;
248 using LinearLagrangeShapeField = std::conditional_t<
250 ShapeField<numComp, LinearTetrahedronShape, LA>,
251 ShapeField<numComp, LinearTriangleShape, LA>>;
253 LinearLagrangeShapeField llsf(meshInfo, {vtxField});
254 return FieldWithController<Ctrlr, LinearLagrangeShapeField>{kk_ctrl, llsf};
255 }
else if constexpr (order == 2 && (dim == 2 || dim == 3)) {
257 if (meshInfo.numVtx <= 0) {
258 fail(
"mesh has no vertices\n");
260 if (meshInfo.numEdge <= 0) {
261 fail(
"mesh has no edges\n");
263 #ifdef MESHFIELDS_ENABLE_CABANA
264 using Ctrlr = std::conditional_t<
266 Controller<ExecutionSpace, MemorySpace, DataType>,
267 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
268 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp],
269 DataType[1][numComp]>,
270 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>>;
272 auto createController = [](
auto numVtx,
auto numEdge) {
273 if constexpr (std::is_same_v<
274 Controller<ExecutionSpace, MemorySpace, DataType>,
275 MeshField::CabanaController<ExecutionSpace, MemorySpace,
277 return Ctrlr({numVtx, numEdge});
279 return Ctrlr({ numVtx, 1, numComp,
280 numEdge, 1, numComp});
283 Ctrlr kk_ctrl = createController(meshInfo.numVtx, meshInfo.numEdge);
286 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>;
287 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp,
288 meshInfo.numEdge, 1, numComp});
290 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
291 auto edgeField = MeshField::makeField<Ctrlr, 1>(kk_ctrl);
292 using QA = QuadraticAccessor<decltype(vtxField), decltype(edgeField)>;
294 using QuadraticLagrangeShapeField = std::conditional_t<
296 ShapeField<numComp, QuadraticTetrahedronShape, QA>,
297 ShapeField<numComp, QuadraticTriangleShape, QA>>;
299 QuadraticLagrangeShapeField qlsf(meshInfo, {vtxField, edgeField});
300 return FieldWithController<Ctrlr, QuadraticLagrangeShapeField>{kk_ctrl,
304 fail(
"CreateLagrangeField does not support the specified "
305 "combination of order %d and dimension %d.\n",
307 return FieldWithController<int, std::nullptr_t>{};
328 template <
typename ExecutionSpace,
329 template <
typename...>
330 typename Controller = MeshField::KokkosController,
332 auto CreateCoordinateField(
const MeshInfo &meshInfo) {
334 return CreateLagrangeField<ExecutionSpace, Controller, Real, 1, dim, dim>(meshInfo);
Shape function definitions for finite element analysis.
Provides access to individual entries of a single Field provided by MeshField::makeField and helper f...
Return type of CreateLagrangeField/CreateCoordinateField.
On-process mesh metadata.
int numEntities(Mesh_Topology topo) const
runtime map of number of entities based on topology
Enable definition of field classes with multiple inheritance.