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 Controller,
typename... Mixins>
101 static const size_t numComp = numCompIn;
103 constexpr
static auto Order = Shape::Order;
104 using Ctrlr=Controller;
110 : meshInfo(meshInfoIn), Mixins( std::forward<Mixins>(mixins) )... {};
134 template <
typename VtxAccessor,
typename EdgeAccessor>
136 constexpr
static const Mesh_Topology topo[2] = {Vertex, Edge};
137 VtxAccessor vtxField;
138 EdgeAccessor edgeField;
139 using BaseType =
typename VtxAccessor::BaseType;
142 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
143 if (t != Vertex && t != Edge) {
144 Kokkos::printf(
"%d is not a support topology\n", t);
147 return (t == Vertex) ? vtxField(entity, node, component)
148 : edgeField(entity, node, component);
169 constexpr
static const Mesh_Topology topo[1] = {Vertex};
170 VtxAccessor vtxField;
171 using BaseType =
typename VtxAccessor::BaseType;
174 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
176 Kokkos::printf(
"%d is not a support topology\n", t);
179 return vtxField(entity, node, component);
204 template <
typename ExecutionSpace,
205 template <
typename...>
206 typename Controller = MeshField::KokkosController,
207 typename DataType,
size_t order,
size_t dim,
size_t numComp>
208 auto CreateLagrangeField(
const MeshInfo &meshInfo) {
209 static_assert((std::is_same_v<Real4, DataType> ==
true ||
210 std::is_same_v<Real8, DataType> ==
true),
211 "CreateLagrangeField only supports single and double precision "
212 "floating point fields\n");
214 (order == 1 || order == 2),
215 "CreateLagrangeField only supports linear and quadratic fields\n");
216 static_assert((dim == 1 || dim == 2 || dim == 3),
217 "CreateLagrangeField only supports 1d, 2d, and 3d meshes\n");
218 using MemorySpace =
typename ExecutionSpace::memory_space;
219 if constexpr (order == 1 && (dim == 1 || dim == 2 || dim == 3)) {
220 if (meshInfo.numVtx <= 0) {
221 fail(
"mesh has no vertices\n");
223 #ifdef MESHFIELDS_ENABLE_CABANA
224 using Ctrlr = std::conditional_t<
226 Controller<ExecutionSpace, MemorySpace, DataType>,
227 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
228 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp]>,
229 Controller<MemorySpace, ExecutionSpace, DataType ***>>;
231 auto createController = [](
auto numVtx) {
232 if constexpr (std::is_same_v<
233 Controller<ExecutionSpace, MemorySpace, DataType>,
234 MeshField::CabanaController<ExecutionSpace, MemorySpace,
236 return Ctrlr({numVtx});
238 return Ctrlr({ numVtx, 1, numComp});
241 Ctrlr kk_ctrl = createController(meshInfo.numVtx);
243 using Ctrlr = Controller<MemorySpace, ExecutionSpace, DataType ***>;
244 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp});
246 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
247 using LA = LinearAccessor<decltype(vtxField)>;
249 using LinearLagrangeShapeField = std::conditional_t<
251 ShapeField<numComp, LinearTetrahedronShape, Ctrlr, LA>,
252 ShapeField<numComp, LinearTriangleShape, Ctrlr, LA>>;
254 LinearLagrangeShapeField llsf(meshInfo, {vtxField});
255 return FieldWithController<Ctrlr, LinearLagrangeShapeField>{kk_ctrl, llsf};
256 }
else if constexpr (order == 2 && (dim == 2 || dim == 3)) {
258 if (meshInfo.numVtx <= 0) {
259 fail(
"mesh has no vertices\n");
261 if (meshInfo.numEdge <= 0) {
262 fail(
"mesh has no edges\n");
264 #ifdef MESHFIELDS_ENABLE_CABANA
265 using Ctrlr = std::conditional_t<
267 Controller<ExecutionSpace, MemorySpace, DataType>,
268 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
269 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp],
270 DataType[1][numComp]>,
271 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>>;
273 auto createController = [](
auto numVtx,
auto numEdge) {
274 if constexpr (std::is_same_v<
275 Controller<ExecutionSpace, MemorySpace, DataType>,
276 MeshField::CabanaController<ExecutionSpace, MemorySpace,
278 return Ctrlr({numVtx, numEdge});
280 return Ctrlr({ numVtx, 1, numComp,
281 numEdge, 1, numComp});
284 Ctrlr kk_ctrl = createController(meshInfo.numVtx, meshInfo.numEdge);
287 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>;
288 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp,
289 meshInfo.numEdge, 1, numComp});
291 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
292 auto edgeField = MeshField::makeField<Ctrlr, 1>(kk_ctrl);
293 using QA = QuadraticAccessor<decltype(vtxField), decltype(edgeField)>;
295 using QuadraticLagrangeShapeField = std::conditional_t<
297 ShapeField<numComp, QuadraticTetrahedronShape, Ctrlr, QA>,
298 ShapeField<numComp, QuadraticTriangleShape, Ctrlr, QA>>;
300 QuadraticLagrangeShapeField qlsf(meshInfo, {vtxField, edgeField});
301 return FieldWithController<Ctrlr, QuadraticLagrangeShapeField>{kk_ctrl,
305 fail(
"CreateLagrangeField does not support the specified "
306 "combination of order %d and dimension %d.\n",
308 return FieldWithController<int, std::nullptr_t>{};
329 template <
typename ExecutionSpace,
330 template <
typename...>
331 typename Controller = MeshField::KokkosController,
333 auto CreateCoordinateField(
const MeshInfo &meshInfo) {
335 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.