68 {
return decltype(tr)::paramSpace; });
85 {
return decltype(tr)::numElevNodes; });
91 {
return decltype(tr)::elevatedType; });
98 using T =
decltype(tr);
99 if constexpr (T::numElevNodes > 0)
100 return T::elevNodeSpanTypes[ine];
115 using T =
decltype(tr);
116 if constexpr (T::order == 2)
127 using T =
decltype(tr);
128 if constexpr (T::order == 2)
129 return T::GetBisectElemType(i);
142 return x * __iipow(
x, y - 1);
146 return 1. /
x * __iipow(
x, y + 1);
162 template <
int diffOrder,
class TPo
int,
class TArray>
165 static_assert(diffOrder == 0 || diffOrder == 1 || diffOrder == 2 || diffOrder == 3);
169 constexpr ElemType eType =
decltype(traits)::elemType;
170 if constexpr (diffOrder == 0)
172 else if constexpr (diffOrder == 1)
174 else if constexpr (diffOrder == 2)
176 else if constexpr (diffOrder == 3)
181 using tNj = Eigen::RowVector<t_real, Eigen::Dynamic>;
182 using tD1Nj = Eigen::Matrix<t_real, 3, Eigen::Dynamic>;
183 using tD01Nj = Eigen::Matrix<t_real, 4, Eigen::Dynamic>;
184 using tDiNj = Eigen::Matrix<t_real, Eigen::Dynamic, Eigen::Dynamic>;
200 {
return decltype(tr)::dim; });
206 {
return decltype(tr)
::order; });
212 {
return decltype(tr)::numVertices; });
218 {
return decltype(tr)::numNodes; });
224 {
return decltype(tr)::numFaces; });
246 template <
class TIn,
class TOut>
252 using T =
decltype(tr);
253 if constexpr (T::numFaces > 0)
256 faceNodesOut[i] = nodes[T::faceNodes[iFace][i]];
283 template <
class TIn,
class TOut>
289 using T =
decltype(tr);
290 if constexpr (T::numElevNodes > 0)
292 auto spanElem =
Element{T::elevNodeSpanTypes[iNodeElev]};
293 for (
t_index i = 0; i < spanElem.GetNumNodes(); i++)
294 spanNodes[i] = nodes[T::elevSpans[iNodeElev][i]];
299 template <
class TIn,
class TOut>
305 using T =
decltype(tr);
306 if constexpr (T::order == 2)
309 t_index offset = iSubElem + T::numBisect * iVariant;
310 auto subElem =
Element{T::GetBisectElemType(iSubElem)};
311 for (
t_index i = 0; i < subElem.GetNumNodes(); i++)
312 subNodes[i] = nodes[T::bisectElements[offset][i]];
323 ShapeFunc_DiNj<0>(
type, pParam, Nj);
332 ShapeFunc_DiNj<1>(
type, pParam, D1Nj);
342 this->
GetNj(pParam, Nj);
346 D01Nj(0, EigenAll) = Nj;
347 D01Nj({1, 2, 3}, EigenAll) = D1Nj;
356 int nDiffCur = Base::ndiffSizC2D.at(maxOrder);
358 for (; maxOrder >= 0; maxOrder--)
364 Eigen::seq(Base::ndiffSizC2D.at(2), Base::ndiffSizC2D.at(3) - 1),
370 Eigen::seq(Base::ndiffSizC2D.at(1), Base::ndiffSizC2D.at(2) - 1),
376 Eigen::seq(Base::ndiffSizC2D.at(0), Base::ndiffSizC2D.at(1) - 1),
386 else if (this->
GetDim() == 3)
388 int nDiffCur = Base::ndiffSizC.at(maxOrder);
390 for (; maxOrder >= 0; maxOrder--)
396 Eigen::seq(Base::ndiffSizC.at(2), Base::ndiffSizC.at(3) - 1),
402 Eigen::seq(Base::ndiffSizC.at(1), Base::ndiffSizC.at(2) - 1),
408 Eigen::seq(Base::ndiffSizC.at(0), Base::ndiffSizC.at(1) - 1),
418 else if (this->
GetDim() == 1)
420 int nDiffCur = maxOrder + 1;
422 for (; maxOrder >= 0; maxOrder--)
459 const std::vector<DNDS::index> &nodes_A,
460 const std::vector<DNDS::index> &nodes_B,
466 std::vector<DNDS::index> nodes_B_Vert{nodes_B.begin(), nodes_B.begin() + eB.
GetNumVertices()};
467 std::sort(nodes_B_Vert.begin(), nodes_B_Vert.end());
471 std::vector<DNDS::index> fNodes(eF.GetNumNodes());
473 std::sort(fNodes.begin(), fNodes.begin() + eF.GetNumVertices());
475 nodes_B_Vert.begin(), nodes_B_Vert.end(),
476 fNodes.begin(), fNodes.begin() + eF.GetNumVertices()))
483 const std::vector<DNDS::index> &verts_A,
484 const std::vector<DNDS::index> &nodes_B)
490 template <
class tCoordsIn>
493 return cs * DiNj({1, 2, 3}, EigenAll).transpose();
496 template <
class tCoordsIn>
499 return cs * DiNj(0, EigenAll).transpose();
505 static_assert(dim == 2 || dim == 3);
506 if constexpr (dim == 2)
507 return J(EigenAll, 0).stableNorm();
509 return J(EigenAll, 0).cross(J(EigenAll, 1)).stableNorm();
515 tPoint c = coords.rowwise().mean();
517 tPoint ve0 = coordsC(EigenAll, 1) - coordsC(EigenAll, 0);
518 tJacobi inertia = coordsC * coordsC.transpose();
520 if (cond01 < 1 + 1e-6)
521 inertia += ve0 * ve0.transpose() * 1e-4;
523 coordsC = decRet.transpose() * coordsC;
524 tPoint ret = coordsC.rowwise().maxCoeff() - coordsC.rowwise().minCoeff();
525 std::sort(ret.begin(), ret.end(), std::greater_equal<real>());
537 Eigen::Vector<real, 3> lengths{
538 (coords(EigenAll, 5 - 1) - coords(EigenAll, 10 - 1)).norm(),
539 (coords(EigenAll, 6 - 1) - coords(EigenAll, 8 - 1)).norm(),
540 (coords(EigenAll, 7 - 1) - coords(EigenAll, 9 - 1)).norm(),
542 Eigen::Index iMin{-1};
543 real minLen = lengths.minCoeff(&iMin);
550 Eigen::Vector<real, 2> lengths{
551 (coords(EigenAll, 10 - 1) - coords(EigenAll, 12 - 1)).norm(),
552 (coords(EigenAll, 11 - 1) - coords(EigenAll, 13 - 1)).norm(),
554 Eigen::Index iMin{-1};
555 real minLen = lengths.minCoeff(&iMin);
570 using T = decltype(tr);
571 constexpr int nOut = static_cast<int>(
572 std::tuple_size<decltype(T::vtkNodeOrder)>::value);
573 std::vector<index> v(nOut);
574 for (int i = 0; i < nOut; i++)
575 v[i] = vin[T::vtkNodeOrder[i]];
576 return {T::vtkCellType, std::move(v)};
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self)
#define DNDS_DEVICE_CALLABLE
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Robust linear-algebra primitives for small / moderately-sized Eigen matrices that are more numericall...
Eigen::Matrix< t_real, Eigen::Dynamic, Eigen::Dynamic > tDiNj
Eigen::Matrix< t_real, 3, Eigen::Dynamic > tD1Nj
tJacobi ShapeJacobianCoordD01Nj(const tCoordsIn &cs, Eigen::Ref< const tD01Nj > DiNj)
DNDS_DEVICE_CALLABLE constexpr ParamSpace ElemType_to_ParamSpace(const ElemType t)
DNDS_DEVICE_CALLABLE constexpr ElemType GetElemO1(ParamSpace ps)
DNDS_DEVICE_CALLABLE constexpr decltype(auto) DispatchElementType(ElemType t, Func &&func)
Static dispatch over element types at compile time.
DNDS_DEVICE_CALLABLE constexpr int GetElemElevation_O1O2_NumNode(ElemType t)
DNDS_DEVICE_CALLABLE constexpr t_index GetO2ElemBisectNum(ElemType t)
DNDS_DEVICE_CALLABLE constexpr ElemType GetO2ElemBisectElem(ElemType t, t_index i)
DNDS_DEVICE_CALLABLE constexpr ElemType GetElemElevation_O1O2_ElevatedType(ElemType t)
DNDS_DEVICE_CALLABLE constexpr t_real ParamSpaceVolume(ParamSpace ps)
Get the volume of a parametric space.
Eigen::Matrix< t_real, 4, Eigen::Dynamic > tD01Nj
bool cellsAreFaceConnected(const std::vector< DNDS::index > &nodes_A, const std::vector< DNDS::index > &nodes_B, Element eA, Element eB)
std::pair< int, std::vector< index > > ToVTKVertsAndData(Element e, const TIn &vin)
DNDS_DEVICE_CALLABLE void ShapeFunc_DiNj(ElemType t, const TPoint &p, TArray &&v)
Dispatch to per-element shape function code via ShapeFuncImpl<T>.
tPoint GetElemNodeMajorSpan(const tSmallCoords &coords)
real JacobiDetFace(Eigen::Ref< const tJacobi > J)
DNDS_DEVICE_CALLABLE constexpr t_real ParamSpaceVol(ParamSpace ps)
DNDS_DEVICE_CALLABLE constexpr ElemType GetElemElevation_O1O2_NodeSpanType(ElemType t, t_index ine)
DNDS_DEVICE_CALLABLE constexpr ElemType GetFaceType(ElemType t_v, t_index iFace)
DNDS_DEVICE_CALLABLE constexpr ElemType ParamSpaceO1Elem(ParamSpace ps)
Get the order-1 (linear) element type for a parametric space.
Eigen::Matrix< t_real, 3, Eigen::Dynamic > GetStandardCoord(ElemType t)
Eigen::RowVector< t_real, Eigen::Dynamic > tNj
tPoint PPhysicsCoordD01Nj(const tCoordsIn &cs, Eigen::Ref< const tD01Nj > DiNj)
t_index GetO2ElemBisectVariant(Element e, const tSmallCoords &coords)
Eigen::Matrix< real, 3, Eigen::Dynamic > tSmallCoords
real Eigen3x3RealSymEigenDecompositionGetCond01(const Eigen::Matrix3d &A)
Like Eigen3x3RealSymEigenDecompositionGetCond but returns lambda0 / lambda1 only (ignores the smalles...
Eigen::Matrix3d Eigen3x3RealSymEigenDecompositionNormalized(const Eigen::Matrix3d &A)
Eigen-decomposition with eigenvector columns normalised to unit length.
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
constexpr Element ObtainO1Elem() const
void ExtractO2BisectElemNodes(t_index iSubElem, t_index iVariant, const TIn &nodes, TOut &subNodes)
DNDS_DEVICE_CALLABLE constexpr ParamSpace GetParamSpace() const
constexpr Element ObtainElevNodeSpan(t_index iNodeElev) const
DNDS_DEVICE_CALLABLE void GetNj(const tPoint &pParam, tNj &Nj) const
DNDS_DEVICE_CALLABLE constexpr Element ObtainFace(t_index iFace) const
DNDS_DEVICE_CALLABLE t_index GetO2NumBisect() const
constexpr Element ObtainElevatedElem() const
DNDS_DEVICE_CALLABLE constexpr t_index GetNumElev_O1O2() const
DNDS_DEVICE_CALLABLE constexpr t_index GetNumVertices() const
DNDS_DEVICE_CALLABLE constexpr t_index GetNumFaces() const
DNDS_DEVICE_CALLABLE void GetD1Nj(const tPoint &pParam, tD1Nj &D1Nj) const
void GetD01Nj(const tPoint &pParam, tD01Nj &D01Nj) const
void ExtractFaceNodes(t_index iFace, const TIn &nodes, TOut &faceNodesOut)
void GetDiNj(const tPoint &pParam, tDiNj &DiNj, int maxOrder) const
Element ObtainO2BisectElem(t_index iSubElem) const
DNDS_DEVICE_CALLABLE constexpr t_index GetDim() const
void ExtractElevNodeSpanNodes(t_index iNodeElev, const TIn &nodes, TOut &spanNodes)
DNDS_DEVICE_CALLABLE constexpr t_index GetOrder() const
DNDS_DEVICE_CALLABLE constexpr t_index GetNumNodes() const
Eigen::Matrix< real, 5, 1 > v