svMultiPhysics
Loading...
Searching...
No Matches
Types.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef SVMP_FE_TYPES_H
5#define SVMP_FE_TYPES_H
6
7/**
8 * @file Types.h
9 * @brief Fundamental type definitions for the finite element library
10 *
11 * This header provides core type aliases, enumerations, and strong type
12 * definitions used throughout the FE library. It establishes a consistent
13 * type system that integrates with the Mesh library while maintaining
14 * independence from backend-specific types.
15 */
16
17// The Mesh library is an optional, external module. When the build enables it
18// (SVMP_FE_WITH_MESH), FE imports the Mesh scalar/index types so the two libraries
19// share a vocabulary; otherwise FE compiles standalone using the fallback
20// definitions below (e.g. svmp::CellFamily and the Mesh* aliases). The Mesh
21// headers are not part of this repository.
22#if defined(SVMP_FE_WITH_MESH) && SVMP_FE_WITH_MESH
23# include "Mesh/Core/MeshTypes.h"
24/** Nonzero when FE shares scalar/index types with the Mesh library. */
25# define SVMP_FE_HAS_MESH_TYPES 1
26#else
27// Build FE without Mesh types unless explicitly enabled.
28/** Nonzero when FE shares scalar/index types with the Mesh library. */
29# define SVMP_FE_HAS_MESH_TYPES 0
30#endif
31
32#if !SVMP_FE_HAS_MESH_TYPES
33namespace svmp {
34#ifndef SVMP_CELL_FAMILY_DEFINED
35/** Guard marking that svmp::CellFamily has been defined. */
36#define SVMP_CELL_FAMILY_DEFINED 1
37/**
38 * @brief Minimal fallback for svmp::CellFamily when the Mesh library is unavailable
39 * @ingroup FE_CommonTypes
40 *
41 * Keeps FE compilation self-contained while preserving the same namespace
42 * and enumerator set as the Mesh library's cell-family classification.
43 */
44enum class CellFamily {
45 Point,
46 Line,
47 Triangle,
48 Quad,
49 Tetra,
50 Hex,
51 Wedge,
52 Pyramid,
53 Polygon,
54 Polyhedron
55};
56#endif
57} // namespace svmp
58#endif
59#include <array>
60#include <cstddef>
61#include <cstdint>
62#include <string>
63#include <type_traits>
64#include <limits>
65
66/**
67 * @defgroup FE_Common Common
68 * @ingroup FE
69 * @brief Shared vocabulary types, constants, and exception infrastructure used by every FE module.
70 *
71 * @details The Common module collects the foundational definitions that the
72 * rest of the FE library builds on: index and scalar type aliases; shared
73 * enumerations and strong types; sentinel constants; and the FE exception
74 * hierarchy together with its argument-checking helpers.
75 */
76
77namespace svmp::FE {
78
79/**
80 * @defgroup FE_CommonTypes Types
81 * @ingroup FE_Common
82 * @brief Core type aliases, enumerations, constants, geometric types, and compile-time traits.
83 *
84 * @details This group documents the index and identifier types used for
85 * element-local and global numbering, the enumerations shared across modules,
86 * sentinel constants, reference- and physical-space geometric aliases, and
87 * the strong-type utilities that prevent accidental mixing of conceptually
88 * distinct values.
89 * @{
90 */
91
92// ============================================================================
93// Index Types
94// ============================================================================
95
96/**
97 * @brief Local index type for element-level operations
98 *
99 * Used for local node numbering within elements, local DOF indices,
100 * and other element-local indexing. Unsigned for safety.
101 */
102using LocalIndex = std::uint32_t;
103
104/**
105 * @brief Global index type for distributed DOF numbering
106 *
107 * Signed 64-bit for compatibility with PETSc and Trilinos.
108 * Negative values can indicate special conditions or invalid indices.
109 *
110 * @note Kept as a plain integer alias rather than a StrongType wrapper: this is
111 * the raw interop type handed directly to PETSc/Trilinos, where a wrapper would
112 * force an unwrap at every call. Type safety for DOF indices is provided by
113 * DofIndex (below), the strong wrapper around a GlobalIndex.
114 */
115using GlobalIndex = std::int64_t;
116
117/**
118 * @brief Field identifier type
119 *
120 * Used to distinguish between different physical fields in multi-field problems.
121 */
122using FieldId = std::uint16_t;
123
124/**
125 * @brief Block identifier for block-structured systems
126 */
127using BlockId = std::uint16_t;
128
129// Import mesh library scalar/index types when available (optional dependency).
130#if SVMP_FE_HAS_MESH_TYPES
131using MeshIndex = svmp::index_t; ///< Local mesh entity index, shared with the Mesh library.
132using MeshOffset = svmp::offset_t; ///< Offset type for mesh connectivity arrays.
133using MeshGlobalId = svmp::gid_t; ///< Global mesh entity identifier.
134#else
135using MeshIndex = std::int32_t; ///< Local mesh entity index, shared with the Mesh library.
136using MeshOffset = std::int64_t; ///< Offset type for mesh connectivity arrays.
137using MeshGlobalId = std::int64_t; ///< Global mesh entity identifier.
138#endif
139
140// ============================================================================
141// Constants
142// ============================================================================
143
144/** Sentinel for an unset or out-of-range local index. */
145constexpr LocalIndex INVALID_LOCAL_INDEX = std::numeric_limits<LocalIndex>::max();
146/** Sentinel for an unset or out-of-range global index. */
148/** Sentinel FieldId meaning "uninitialized / no field". */
149constexpr FieldId INVALID_FIELD_ID = std::numeric_limits<FieldId>::max();
150/**
151 * Sentinel FieldId for geometry-only quantities (no DOF dependence).
152 * Uses first registered field's space for quadrature, but logically decoupled
153 * from any specific field's DOFs.
154 */
155constexpr FieldId GEOMETRY_FIELD_ID = std::numeric_limits<FieldId>::max() - 1;
156/** Sentinel for an unset or out-of-range block identifier. */
157constexpr BlockId INVALID_BLOCK_ID = std::numeric_limits<BlockId>::max();
158
159/**
160 * @brief Sentinel FieldId representing "the current solution state" in tangent forms.
161 *
162 * When differentiating a residual form to obtain the tangent (Jacobian), undifferentiated
163 * TrialFunction occurrences are rewritten to StateField nodes. Those that represent the
164 * block's own primary unknown (rather than a named external field) use this sentinel
165 * FieldId. The assembler maps it to the current solution coefficients at each quadrature
166 * point, regardless of which physics or field variables are involved.
167 *
168 * This is distinct from INVALID_FIELD_ID, which means "uninitialized / no field."
169 * CURRENT_SOLUTION_FIELD_ID uses the same numeric value for backward compatibility
170 * with existing KernelIR encodings, but carries explicit semantic intent.
171 */
172constexpr FieldId CURRENT_SOLUTION_FIELD_ID = std::numeric_limits<FieldId>::max();
173
174/** Preferred cache-line/SIMD alignment for performance-critical arrays. */
175inline constexpr std::size_t kFEPreferredAlignmentBytes = 64u;
176
177/** Alignment for small fixed-size math objects that are commonly passed by value. */
178inline constexpr std::size_t kFEFixedObjectAlignmentBytes = 32u;
179
180// ============================================================================
181// Field Value Entry (for point evaluation of field-dependent expressions)
182// ============================================================================
183
184/** Maximum number of components in a FieldValueEntry (3x3 tensor). */
186
187/**
188 * @brief Field value at an evaluation point — scalar, vector, or tensor.
189 *
190 * Used by PointEvaluator and the auxiliary assembly path to supply FE
191 * field values at entity locations (e.g., nodal DOF values for
192 * Node-scoped auxiliary models with Lagrange Kronecker delta).
193 */
195 FieldId field{INVALID_FIELD_ID}; ///< Field this value belongs to.
196 int n_components{0}; ///< Number of valid entries in components.
197 double components[MAX_FIELD_VALUE_COMPONENTS]{}; ///< Component values, row-major for tensors.
198};
199
200// ============================================================================
201// Element Type Enumerations
202// ============================================================================
203
204/**
205 * @brief Reference element types supported by the FE library
206 *
207 * Maps to svmp::CellFamily from the Mesh library but provides
208 * FE-specific categorization including higher-order variants.
209 *
210 * @note The enum is consumed by name (the switches in to_mesh_family() and
211 * element_dimension() and the basis classifiers); nothing depends on the
212 * underlying numeric values, so they are left implicit. Entries are grouped by
213 * polynomial order (linear, quadratic) plus a special section.
214 */
215enum class ElementType : std::uint8_t {
216 // Linear elements
217 Line2, ///< 2-node line
218 Triangle3, ///< 3-node triangle
219 Quad4, ///< 4-node quadrilateral
220 Tetra4, ///< 4-node tetrahedron
221 Hex8, ///< 8-node hexahedron
222 Wedge6, ///< 6-node wedge/prism
223 Pyramid5, ///< 5-node pyramid
224
225 // Quadratic elements
226 Line3, ///< 3-node line
227 Triangle6, ///< 6-node triangle
228 Quad9, ///< 9-node quadrilateral (bi-quadratic)
229 Quad8, ///< 8-node quadrilateral (serendipity)
230 Tetra10, ///< 10-node tetrahedron
231 Hex27, ///< 27-node hexahedron (tri-quadratic)
232 Hex20, ///< 20-node hexahedron (serendipity)
233 Wedge15, ///< 15-node wedge
234 Wedge18, ///< 18-node wedge (complete quadratic)
235 Pyramid13, ///< 13-node pyramid
236 Pyramid14, ///< 14-node pyramid
237
238 // Special elements
239 Point1, ///< 1-node point element
240
241 Unknown ///< Unrecognized or uninitialized element type
242};
243
244/**
245 * @brief Basis function families
246 */
247enum class BasisType : std::uint8_t {
248 Lagrange, ///< Standard nodal Lagrange basis
249 NURBS, ///< Non-uniform rational B-splines (reserved; not yet implemented)
250 Serendipity, ///< Serendipity elements
251 Custom ///< User-defined basis
252};
253
254/**
255 * @brief Field types for function spaces
256 */
257enum class FieldType : std::uint8_t {
258 Scalar, ///< Scalar field (temperature, pressure)
259 Vector, ///< Vector field (velocity, displacement)
260 Tensor, ///< Tensor field (stress, strain)
261 SymmetricTensor, ///< Symmetric tensor field
262 Mixed ///< Mixed/composite field
263};
264
265/**
266 * @brief Continuity requirements for function spaces
267 */
268enum class Continuity : std::uint8_t {
269 C0, ///< Continuous (standard FEM)
270 C1, ///< C1 continuous (for plates/shells)
271 L2, ///< L2 (discontinuous)
272 H_div, ///< H(div) conforming
273 H_curl, ///< H(curl) conforming
274 Custom ///< User-defined continuity requirement
275};
276
277/**
278 * @brief Assembly strategies
279 */
280enum class AssemblyStrategy : std::uint8_t {
281 ElementByElement, ///< Traditional element loop
282 Vectorized, ///< SIMD vectorized assembly
283 MatrixFree, ///< Matrix-free operators
284 Hybrid ///< Mixed strategy
285};
286
287// ============================================================================
288// Geometric Types
289// ============================================================================
290
291/**
292 * @brief Point in reference element coordinates
293 * @tparam Dim Reference-space dimension
294 */
295template<int Dim>
296using ReferencePoint = std::array<double, static_cast<std::size_t>(Dim)>;
297
298/**
299 * @brief Point in physical coordinates
300 */
301using PhysicalPoint = std::array<double, 3>;
302
303/**
304 * @brief Jacobian matrix type
305 * @tparam SpatialDim Physical-space dimension (rows)
306 * @tparam ReferenceDim Reference-space dimension (columns)
307 */
308template<int SpatialDim, int ReferenceDim = SpatialDim>
309using Jacobian = std::array<std::array<double, static_cast<std::size_t>(ReferenceDim)>, static_cast<std::size_t>(SpatialDim)>;
310
311// ============================================================================
312// Strong Type Wrappers (C++17 idiom for type safety)
313// ============================================================================
314
315/**
316 * @brief Strong type wrapper template for type-safe programming
317 *
318 * Prevents accidental mixing of conceptually different types that have
319 * the same underlying representation.
320 *
321 * @tparam T Underlying value type
322 * @tparam Tag Empty tag type that distinguishes otherwise identical wrappers
323 */
324template<typename T, typename Tag>
326public:
327 /** @brief Underlying value type. */
328 using ValueType = T;
329
330 /** @brief Value-initialize the wrapped value. */
331 constexpr StrongType() noexcept(std::is_nothrow_default_constructible_v<T>)
332 : value_{} {}
333
334 /**
335 * @brief Wrap an explicit value.
336 * @param value Value to store.
337 */
338 constexpr explicit StrongType(T value) noexcept(std::is_nothrow_move_constructible_v<T>)
339 : value_(std::move(value)) {}
340
341 /**
342 * @brief Access the wrapped value.
343 * @return Reference to the wrapped value.
344 */
345 constexpr T& get() noexcept { return value_; }
346 /**
347 * @brief Access the wrapped value.
348 * @return Reference to the wrapped value.
349 */
350 constexpr const T& get() const noexcept { return value_; }
351
352 /**
353 * @brief Explicitly convert back to the underlying type.
354 * @return Copy of the wrapped value.
355 */
356 constexpr explicit operator T() const noexcept { return value_; }
357
358 /**
359 * @brief Compare wrapped values for equality.
360 * @param other Wrapper to compare against.
361 * @return True when the wrapped values are equal.
362 */
363 constexpr bool operator==(const StrongType& other) const noexcept {
364 return value_ == other.value_;
365 }
366 /**
367 * @brief Compare wrapped values for inequality.
368 * @param other Wrapper to compare against.
369 * @return True when the wrapped values differ.
370 */
371 constexpr bool operator!=(const StrongType& other) const noexcept {
372 return value_ != other.value_;
373 }
374 /**
375 * @brief Order by wrapped value.
376 * @param other Wrapper to compare against.
377 * @return True when this wrapped value orders before the other.
378 */
379 constexpr bool operator<(const StrongType& other) const noexcept {
380 return value_ < other.value_;
381 }
382
383private:
384 T value_;
385};
386
387// Specific strong types for common use cases
388struct QuadraturePointTag {}; ///< Tag type for quadrature-point indices.
389struct QuadratureWeightTag {}; ///< Tag type for quadrature weights.
390struct BasisValueTag {}; ///< Tag type for basis-function values.
391struct BasisGradientTag {}; ///< Tag type for basis-function gradients.
392struct DofTag {}; ///< Tag type for global DOF indices.
393
394/** Type-safe index of a quadrature point within a rule. */
396/** Type-safe quadrature weight value. */
398
399/**
400 * @brief DOF-specific index type
401 *
402 * @details A StrongType over GlobalIndex that prevents mixing DOF indices with
403 * other indices: conversion back to GlobalIndex is explicit (via get()), so a
404 * DofIndex cannot silently decay to a raw integer. Over the base StrongType it
405 * adds two DOF-specific conveniences -- it default-constructs to the invalid
406 * sentinel (-1) and exposes is_valid() -- for distributed DOF numbering where a
407 * negative value marks an unset or non-local DOF.
408 */
409class DofIndex : public StrongType<GlobalIndex, DofTag> {
410public:
412
413 /** @brief Construct an invalid DOF index (the negative sentinel). */
414 constexpr DofIndex() noexcept : StrongType(GlobalIndex{-1}) {}
415
416 /**
417 * @brief Check whether this index refers to a valid DOF.
418 * @return True when the stored value is non-negative.
419 */
420 constexpr bool is_valid() const noexcept { return get() >= 0; }
421};
422
423// ============================================================================
424// Type Traits
425// ============================================================================
426
427/**
428 * @brief Check if a type is a valid index type
429 */
430template<typename T>
431struct is_index_type : std::false_type {};
432
433template<>
434struct is_index_type<LocalIndex> : std::true_type {};
435
436template<>
437struct is_index_type<GlobalIndex> : std::true_type {};
438
439template<>
440struct is_index_type<DofIndex> : std::true_type {};
441
442/** Convenience variable template for is_index_type. */
443template<typename T>
445
446/**
447 * @brief Check if a type represents a field type
448 */
449template<typename T>
450struct is_field_type : std::false_type {};
451
452template<>
453struct is_field_type<FieldType> : std::true_type {};
454
455/** Convenience variable template for is_field_type. */
456template<typename T>
458
459// ============================================================================
460// Utility Functions
461// ============================================================================
462
463/**
464 * @brief Convert FE ElementType to Mesh CellFamily
465 * @param elem Element type to classify.
466 * @return Cell family of the element's linear topology; Point for unknown types.
467 */
469 switch(elem) {
472 return svmp::CellFamily::Line;
473
476 return svmp::CellFamily::Triangle;
477
481 return svmp::CellFamily::Quad;
482
485 return svmp::CellFamily::Tetra;
486
490 return svmp::CellFamily::Hex;
491
495 return svmp::CellFamily::Wedge;
496
500 return svmp::CellFamily::Pyramid;
501
503 return svmp::CellFamily::Point;
504
505 default:
506 return svmp::CellFamily::Point; // Fallback
507 }
508}
509
510/**
511 * @brief Get spatial dimension of element type
512 * @param elem Element type to query.
513 * @return Reference dimension from 0 (point) to 3 (volume); -1 for unknown types.
514 */
515constexpr int element_dimension(ElementType elem) noexcept {
516 switch(elem) {
518 return 0;
521 return 1;
527 return 2;
539 return 3;
540 default:
541 return -1;
542 }
543}
544
545/** @} */
546
547} // namespace svmp::FE
548
549#endif // SVMP_FE_TYPES_H
DOF-specific index type.
Definition Types.h:409
constexpr bool is_valid() const noexcept
Check whether this index refers to a valid DOF.
Definition Types.h:420
constexpr DofIndex() noexcept
Construct an invalid DOF index (the negative sentinel).
Definition Types.h:414
Strong type wrapper template for type-safe programming.
Definition Types.h:325
constexpr bool operator!=(const StrongType &other) const noexcept
Compare wrapped values for inequality.
Definition Types.h:371
constexpr bool operator<(const StrongType &other) const noexcept
Order by wrapped value.
Definition Types.h:379
constexpr T & get() noexcept
Access the wrapped value.
Definition Types.h:345
constexpr const T & get() const noexcept
Access the wrapped value.
Definition Types.h:350
constexpr StrongType() noexcept(std::is_nothrow_default_constructible_v< T >)
Value-initialize the wrapped value.
Definition Types.h:331
T ValueType
Underlying value type.
Definition Types.h:328
constexpr bool operator==(const StrongType &other) const noexcept
Compare wrapped values for equality.
Definition Types.h:363
constexpr StrongType(T value) noexcept(std::is_nothrow_move_constructible_v< T >)
Wrap an explicit value.
Definition Types.h:338
constexpr bool is_field_type_v
Definition Types.h:457
constexpr GlobalIndex INVALID_GLOBAL_INDEX
Definition Types.h:147
BasisType
Basis function families.
Definition Types.h:247
std::uint16_t FieldId
Field identifier type.
Definition Types.h:122
constexpr FieldId CURRENT_SOLUTION_FIELD_ID
Sentinel FieldId representing "the current solution state" in tangent forms.
Definition Types.h:172
FieldType
Field types for function spaces.
Definition Types.h:257
constexpr LocalIndex INVALID_LOCAL_INDEX
Definition Types.h:145
std::int64_t MeshGlobalId
Global mesh entity identifier.
Definition Types.h:137
std::array< double, 3 > PhysicalPoint
Point in physical coordinates.
Definition Types.h:301
Continuity
Continuity requirements for function spaces.
Definition Types.h:268
constexpr svmp::CellFamily to_mesh_family(ElementType elem) noexcept
Convert FE ElementType to Mesh CellFamily.
Definition Types.h:468
constexpr int element_dimension(ElementType elem) noexcept
Get spatial dimension of element type.
Definition Types.h:515
constexpr std::size_t kFEPreferredAlignmentBytes
Definition Types.h:175
std::uint16_t BlockId
Block identifier for block-structured systems.
Definition Types.h:127
constexpr bool is_index_type_v
Definition Types.h:444
AssemblyStrategy
Assembly strategies.
Definition Types.h:280
constexpr FieldId GEOMETRY_FIELD_ID
Definition Types.h:155
constexpr int MAX_FIELD_VALUE_COMPONENTS
Definition Types.h:185
ElementType
Reference element types supported by the FE library.
Definition Types.h:215
CellFamily
Minimal fallback for svmp::CellFamily when the Mesh library is unavailable.
Definition Types.h:44
constexpr BlockId INVALID_BLOCK_ID
Definition Types.h:157
std::int32_t MeshIndex
Local mesh entity index, shared with the Mesh library.
Definition Types.h:135
std::int64_t MeshOffset
Offset type for mesh connectivity arrays.
Definition Types.h:136
constexpr std::size_t kFEFixedObjectAlignmentBytes
Definition Types.h:178
std::array< std::array< double, static_cast< std::size_t >(ReferenceDim)>, static_cast< std::size_t >(SpatialDim)> Jacobian
Jacobian matrix type.
Definition Types.h:309
constexpr FieldId INVALID_FIELD_ID
Definition Types.h:149
std::array< double, static_cast< std::size_t >(Dim)> ReferencePoint
Point in reference element coordinates.
Definition Types.h:296
std::int64_t GlobalIndex
Global index type for distributed DOF numbering.
Definition Types.h:115
std::uint32_t LocalIndex
Local index type for element-level operations.
Definition Types.h:102
@ Lagrange
Standard nodal Lagrange basis.
@ Custom
User-defined basis.
@ Serendipity
Serendipity elements.
@ NURBS
Non-uniform rational B-splines (reserved; not yet implemented)
@ Vector
Vector field (velocity, displacement)
Definition Vector.cpp:68
@ Mixed
Mixed/composite field.
@ Tensor
Tensor field (stress, strain)
@ Scalar
Scalar field (temperature, pressure)
@ SymmetricTensor
Symmetric tensor field.
@ C1
C1 continuous (for plates/shells)
@ H_curl
H(curl) conforming.
@ L2
L2 (discontinuous)
@ C0
Continuous (standard FEM)
@ H_div
H(div) conforming.
@ Vectorized
SIMD vectorized assembly.
@ ElementByElement
Traditional element loop.
@ MatrixFree
Matrix-free operators.
@ Hybrid
Mixed strategy.
@ Triangle3
3-node triangle
@ Quad9
9-node quadrilateral (bi-quadratic)
@ Pyramid14
14-node pyramid
@ Pyramid5
5-node pyramid
@ Wedge6
6-node wedge/prism
@ Wedge15
15-node wedge
@ Quad4
4-node quadrilateral
@ Quad8
8-node quadrilateral (serendipity)
@ Unknown
Unrecognized or uninitialized element type.
@ Wedge18
18-node wedge (complete quadratic)
@ Hex27
27-node hexahedron (tri-quadratic)
@ Point1
1-node point element
@ Triangle6
6-node triangle
@ Hex20
20-node hexahedron (serendipity)
@ Pyramid13
13-node pyramid
@ Tetra10
10-node tetrahedron
@ Hex8
8-node hexahedron
@ Tetra4
4-node tetrahedron
Tag type for basis-function gradients.
Definition Types.h:391
Tag type for basis-function values.
Definition Types.h:390
Tag type for global DOF indices.
Definition Types.h:392
Field value at an evaluation point — scalar, vector, or tensor.
Definition Types.h:194
double components[MAX_FIELD_VALUE_COMPONENTS]
Component values, row-major for tensors.
Definition Types.h:197
int n_components
Number of valid entries in components.
Definition Types.h:196
FieldId field
Field this value belongs to.
Definition Types.h:195
Tag type for quadrature-point indices.
Definition Types.h:388
Tag type for quadrature weights.
Definition Types.h:389
Check if a type represents a field type.
Definition Types.h:450
Check if a type is a valid index type.
Definition Types.h:431