svMultiPhysics
Loading...
Searching...
No Matches
NodeOrderingConventions.h
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_BASIS_NODEORDERINGCONVENTIONS_H
5#define SVMP_FE_BASIS_NODEORDERINGCONVENTIONS_H
6
7#include "BasisTraits.h"
8#include "Math/Vector.h"
9#include "Types.h"
10
11#include <array>
12#include <cstddef>
13#include <span>
14#include <vector>
15
16namespace svmp::FE::basis {
17
18/**
19 * @defgroup FE_BasisNodeOrdering Reference-node generation (internal)
20 * @ingroup FE_Basis
21 * @brief Reference-node generators that the basis families build on.
22 *
23 * @warning Internal implementation detail. Do not use these directly: obtain a
24 * basis through basis_factory and read its nodes via BasisFunction::nodes().
25 * These declarations are part of the internal node-ordering machinery and their
26 * interface may change without notice.
27 *
28 * @details This is the reference-node generator the basis families build on, not
29 * a consumer entry point. It is documented for FE core developers; model-level
30 * code never calls it directly.
31 * @{
32 */
33
34/**
35 * @brief The i-th 1D tensor-axis reference node on [-1, 1] at the given order.
36 *
37 * @details Returns the Gauss-Lobatto-Legendre (GLL) node of index @p i for a
38 * degree-@p order distribution: the endpoints are -1 and +1 and the interior
39 * nodes are the roots of @f$P'_{order}@f$, so high-order tensor interpolation
40 * stays well-conditioned (a logarithmic Lebesgue constant instead of the
41 * exponential growth of equispaced nodes). At order 1 the nodes are
42 * @f$\{-1, +1\}@f$ and at order 2 @f$\{-1, 0, +1\}@f$, so they coincide with the
43 * equispaced layout for the production orders and differ only for order >= 3.
44 * Returns 0 for order <= 0 when @p i is 0. Invalid indices throw.
45 *
46 * This is the single definition of the tensor-axis node distribution: the
47 * reference-node layout generators, the Lagrange tensor-axis initialization, and
48 * the serendipity edge/face/interior strata all source their 1D nodes here. The
49 * LagrangeBasis and SerendipityBasis docs point back to this description of the
50 * GLL distribution and its conditioning rather than restating it.
51 *
52 * @param i Node index in [0, order] for positive orders, or 0 for order <= 0.
53 * @param order Polynomial order of the 1D distribution.
54 * @return GLL node coordinate on [-1, 1].
55 * @throws BasisNodeOrderingException If @p i is outside the valid range.
56 */
57[[nodiscard]] double line_coord_pm_one(int i, int order);
58
59/**
60 * @brief Reference Lagrange node coordinates paired with their integer lattice
61 * index.
62 *
63 * @details `lattice[n]` is the exact integer index of `coords[n]` in the
64 * element's natural index space, with every component in `[0, order]`:
65 * - tensor topologies (line/quad/hex): axis indices `(i, j, k)`, unused axes `0`;
66 * - simplex topologies (triangle/tetra): off-origin barycentric indices
67 * `(i, j, k)` (with `k = 0` for triangles) satisfying `i + j + k <= order`;
68 * - wedge: triangle lattice `(i, j)` in the first two components and the
69 * through-axis index `r` in the third.
70 *
71 * Emitting the lattice alongside the coordinate lets callers consume the integer
72 * index directly instead of reconstructing it from the floating-point coordinate.
73 */
75 std::vector<math::Vector<double, 3>> coords; ///< Reference node coordinates, one per node.
76 std::vector<std::array<int, 3>> lattice; ///< Integer lattice index of each node (see details above).
77};
78
79/**
80 * @brief Reference-node coordinate and count lookups for an element type.
81 */
83public:
84 /**
85 * @brief One reference node coordinate by local index. Regenerates the full
86 * layout per call; prefer node_coords() when more than one node is needed.
87 *
88 * @param elem_type Element type to look up.
89 * @param local_node Local node index in [0, num_nodes(elem_type)).
90 * @return Reference coordinate of the requested node.
91 */
93 std::size_t local_node);
94
95 /**
96 * @brief Number of reference nodes in an element type's public layout.
97 * @param elem_type Element type to look up.
98 * @return Node count.
99 */
100 static std::size_t num_nodes(ElementType elem_type);
101
102 /**
103 * @brief All reference node coordinates for an element type, in public layout order.
104 *
105 * @details Returns the complete public reference layout for @p elem_type
106 * (the same coordinates node_coord_at() returns one at a time), including
107 * the serendipity layouts. Prefer this single call when the whole layout is
108 * needed: node_coord_at() regenerates the full list on every call.
109 *
110 * @param elem_type Element type to look up.
111 * @return Reference node coordinates, one per node.
112 */
113 static std::vector<math::Vector<double, 3>> node_coords(ElementType elem_type);
114
115 /**
116 * @brief Reference Lagrange node coordinates for a canonical type and order.
117 * @param canonical_type Canonical Lagrange element type (or Point1).
118 * @param order Polynomial order.
119 * @return Reference node coordinates, one per node, in basis order.
120 */
121 static std::vector<math::Vector<double, 3>>
122 get_lagrange_node_coords(ElementType canonical_type, int order);
123
124 /**
125 * @brief Reference Lagrange nodes with their integer lattice indices.
126 *
127 * @details Returns the same coordinates as get_lagrange_node_coords(), paired
128 * with the integer lattice index of each node (see LagrangeNodeLayout). The
129 * structural invariants in the contract (size match, components in
130 * `[0, order]`, simplex/wedge sum bounds) are validated before returning.
131 *
132 * @param canonical_type Canonical Lagrange element type (or Point1).
133 * @param order Polynomial order.
134 * @return Coordinates and matching lattice indices, one entry per node.
135 * @throws BasisConstructionException If a structural invariant is violated.
136 */
137 static LagrangeNodeLayout
138 get_lagrange_lattice(ElementType canonical_type, int order);
139
140 /**
141 * @brief Reference nodes for an arbitrary-order serendipity layout.
142 *
143 * @details Generates the stratified serendipity node set for the
144 * quadrilateral or hexahedral family at the requested order: the
145 * corner+edge skeleton (the leading prefix of the complete Lagrange layout
146 * of the same order, in VTK boundary order) followed by the reduced face
147 * and volume interior. This is the single source of serendipity node
148 * geometry -- SerendipityBasis builds its mode space and coefficient table
149 * on top of these coordinates for both the arbitrary-order path and the
150 * named Quad8/Hex20 layouts (the order-2 instances). Wedge serendipity
151 * (Wedge15) is a fixed named layout and is not generated here.
152 *
153 * @param topology BasisTopology::Quadrilateral or BasisTopology::Hexahedron.
154 * @param order Polynomial order; must be >= 1.
155 * @return Reference node coordinates in stratified (skeleton-then-interior) order.
156 * @throws BasisConstructionException If @p order is below 1.
157 * @throws BasisElementCompatibilityException If @p topology is not Quadrilateral or Hexahedron.
158 */
159 static std::vector<math::Vector<double, 3>>
161};
162
163/** @} */
164
165} // namespace svmp::FE::basis
166
167#endif // SVMP_FE_BASIS_NODEORDERINGCONVENTIONS_H
Reference-topology vocabulary (BasisTopology) and the internal ElementType/topology/order maps.
Fixed-size vector types for FE computations, backed by Eigen.
Fundamental type definitions for the finite element library.
Reference-node coordinate and count lookups for an element type.
Definition NodeOrderingConventions.h:82
static LagrangeNodeLayout get_lagrange_lattice(ElementType canonical_type, int order)
Reference Lagrange nodes with their integer lattice indices.
static std::vector< math::Vector< double, 3 > > get_lagrange_node_coords(ElementType canonical_type, int order)
Reference Lagrange node coordinates for a canonical type and order.
static std::size_t num_nodes(ElementType elem_type)
Number of reference nodes in an element type's public layout.
static std::vector< math::Vector< double, 3 > > serendipity_node_coords(BasisTopology topology, int order)
Reference nodes for an arbitrary-order serendipity layout.
static math::Vector< double, 3 > node_coord_at(ElementType elem_type, std::size_t local_node)
One reference node coordinate by local index. Regenerates the full layout per call; prefer node_coord...
static std::vector< math::Vector< double, 3 > > node_coords(ElementType elem_type)
All reference node coordinates for an element type, in public layout order.
BasisTopology
Reference-cell topology of a basis (the shape, independent of order).
Definition BasisTraits.h:28
double line_coord_pm_one(int i, int order)
The i-th 1D tensor-axis reference node on [-1, 1] at the given order.
ElementType
Reference element types supported by the FE library.
Definition Types.h:215
Eigen::Matrix< T, static_cast< int >(N), 1 > Vector
Fixed-size column vector for element-level computations.
Definition Vector.h:51
Reference Lagrange node coordinates paired with their integer lattice index.
Definition NodeOrderingConventions.h:74
std::vector< math::Vector< double, 3 > > coords
Reference node coordinates, one per node.
Definition NodeOrderingConventions.h:75
std::vector< std::array< int, 3 > > lattice
Integer lattice index of each node (see details above).
Definition NodeOrderingConventions.h:76