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>
75 template <
size_t numCompIn,
typename Shape,
typename... Mixins>
78 static const size_t numComp = numCompIn;
80 constexpr
static auto Order = Shape::Order;
86 : meshInfo(meshInfoIn), Mixins( std::forward<Mixins>(mixins) )... {};
110 template <
typename VtxAccessor,
typename EdgeAccessor>
112 constexpr
static const Mesh_Topology topo[2] = {Vertex, Edge};
113 VtxAccessor vtxField;
114 EdgeAccessor edgeField;
115 using BaseType =
typename VtxAccessor::BaseType;
118 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
119 if (t != Vertex && t != Edge) {
120 Kokkos::printf(
"%d is not a support topology\n", t);
123 return (t == Vertex) ? vtxField(entity, node, component)
124 : edgeField(entity, node, component);
145 constexpr
static const Mesh_Topology topo[1] = {Vertex};
146 VtxAccessor vtxField;
147 using BaseType =
typename VtxAccessor::BaseType;
150 auto &operator()(
int entity,
int node,
int component, Mesh_Topology t)
const {
152 Kokkos::printf(
"%d is not a support topology\n", t);
155 return vtxField(entity, node, component);
180 template <
typename ExecutionSpace,
181 template <
typename...>
182 typename Controller = MeshField::KokkosController,
183 typename DataType,
size_t order,
size_t dim,
size_t numComp>
184 auto CreateLagrangeField(
const MeshInfo &meshInfo) {
185 static_assert((std::is_same_v<Real4, DataType> ==
true ||
186 std::is_same_v<Real8, DataType> ==
true),
187 "CreateLagrangeField only supports single and double precision "
188 "floating point fields\n");
190 (order == 1 || order == 2),
191 "CreateLagrangeField only supports linear and quadratic fields\n");
192 static_assert((dim == 1 || dim == 2 || dim == 3),
193 "CreateLagrangeField only supports 1d, 2d, and 3d meshes\n");
194 using MemorySpace =
typename ExecutionSpace::memory_space;
195 if constexpr (order == 1 && (dim == 1 || dim == 2 || dim == 3)) {
196 if (meshInfo.numVtx <= 0) {
197 fail(
"mesh has no vertices\n");
199 #ifdef MESHFIELDS_ENABLE_CABANA
200 using Ctrlr = std::conditional_t<
202 Controller<ExecutionSpace, MemorySpace, DataType>,
203 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
204 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp]>,
205 Controller<MemorySpace, ExecutionSpace, DataType ***>>;
207 auto createController = [](
auto numVtx) {
208 if constexpr (std::is_same_v<
209 Controller<ExecutionSpace, MemorySpace, DataType>,
210 MeshField::CabanaController<ExecutionSpace, MemorySpace,
212 return Ctrlr({numVtx});
214 return Ctrlr({ numVtx, 1, numComp});
217 Ctrlr kk_ctrl = createController(meshInfo.numVtx);
219 using Ctrlr = Controller<MemorySpace, ExecutionSpace, DataType ***>;
220 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp});
222 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
223 using LA = LinearAccessor<decltype(vtxField)>;
225 using LinearLagrangeShapeField = std::conditional_t<
227 ShapeField<numComp, LinearTetrahedronShape, LA>,
228 ShapeField<numComp, LinearTriangleShape, LA>>;
230 LinearLagrangeShapeField llsf(meshInfo, {vtxField});
231 return FieldWithController<Ctrlr, LinearLagrangeShapeField>{kk_ctrl, llsf};
232 }
else if constexpr (order == 2 && (dim == 2 || dim == 3)) {
234 if (meshInfo.numVtx <= 0) {
235 fail(
"mesh has no vertices\n");
237 if (meshInfo.numEdge <= 0) {
238 fail(
"mesh has no edges\n");
240 #ifdef MESHFIELDS_ENABLE_CABANA
241 using Ctrlr = std::conditional_t<
243 Controller<ExecutionSpace, MemorySpace, DataType>,
244 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
245 Controller<ExecutionSpace, MemorySpace, DataType[1][numComp],
246 DataType[1][numComp]>,
247 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>>;
249 auto createController = [](
auto numVtx,
auto numEdge) {
250 if constexpr (std::is_same_v<
251 Controller<ExecutionSpace, MemorySpace, DataType>,
252 MeshField::CabanaController<ExecutionSpace, MemorySpace,
254 return Ctrlr({numVtx, numEdge});
256 return Ctrlr({ numVtx, 1, numComp,
257 numEdge, 1, numComp});
260 Ctrlr kk_ctrl = createController(meshInfo.numVtx, meshInfo.numEdge);
263 Controller<MemorySpace, ExecutionSpace, DataType ***, DataType ***>;
264 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp,
265 meshInfo.numEdge, 1, numComp});
267 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
268 auto edgeField = MeshField::makeField<Ctrlr, 1>(kk_ctrl);
269 using QA = QuadraticAccessor<decltype(vtxField), decltype(edgeField)>;
271 using QuadraticLagrangeShapeField = std::conditional_t<
273 ShapeField<numComp, QuadraticTetrahedronShape, QA>,
274 ShapeField<numComp, QuadraticTriangleShape, QA>>;
276 QuadraticLagrangeShapeField qlsf(meshInfo, {vtxField, edgeField});
277 return FieldWithController<Ctrlr, QuadraticLagrangeShapeField>{kk_ctrl,
281 fail(
"CreateLagrangeField does not support the specified "
282 "combination of order %d and dimension %d.\n",
284 return FieldWithController<int, std::nullptr_t>{};
305 template <
typename ExecutionSpace,
306 template <
typename...>
307 typename Controller = MeshField::KokkosController,
309 auto CreateCoordinateField(
const MeshInfo &meshInfo) {
310 if (meshInfo.numVtx <= 0) {
311 fail(
"mesh has no vertices\n");
313 using DataType = Real;
314 using MemorySpace =
typename ExecutionSpace::memory_space;
315 const int numComp = meshInfo.dim;
316 #ifdef MESHFIELDS_ENABLE_CABANA
317 using Ctrlr = std::conditional_t<
319 Controller<ExecutionSpace, MemorySpace, DataType>,
320 MeshField::CabanaController<ExecutionSpace, MemorySpace, DataType>>,
321 Controller<ExecutionSpace, MemorySpace, DataType[1][dim]>,
322 Controller<MemorySpace, ExecutionSpace, DataType ***>>;
323 auto createController = [](
const int numComp,
auto numVtx) {
324 if constexpr (std::is_same_v<
325 Controller<ExecutionSpace, MemorySpace, DataType>,
326 MeshField::CabanaController<ExecutionSpace, MemorySpace,
328 return Ctrlr({numVtx});
330 return Ctrlr({ numVtx, 1, numComp});
333 Ctrlr kk_ctrl = createController(numComp, meshInfo.numVtx);
335 using Ctrlr = Controller<MemorySpace, ExecutionSpace, DataType ***>;
336 Ctrlr kk_ctrl({ meshInfo.numVtx, 1, numComp});
338 auto vtxField = MeshField::makeField<Ctrlr, 0>(kk_ctrl);
339 using LA = LinearAccessor<decltype(vtxField)>;
340 using LinearLagrangeShapeField =
341 ShapeField<dim, LinearTriangleShape, LA>;
342 LinearLagrangeShapeField llsf(meshInfo, {vtxField});
343 return FieldWithController<Ctrlr, LinearLagrangeShapeField>{kk_ctrl, llsf};
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.
Enable definition of field classes with multiple inheritance.