Manifold elements¶
Usually optimization problems are defined in terms of a cost function, such as:
$$ \min_{\boldsymbol{x} \in \mathcal{M}} f(\boldsymbol{x} ) $$ where \( f: \mathcal{M} \rightarrow \mathbb{R} \).
Usually \( \mathcal{M} \) is an Euclidean vector space \( \mathbb{R}^n \).
In a finite element context, for example, in 2D elasticity problems, we have a two-dimensional displacement for each node. As a result, if there are \(n \) nodes, we optimize in \( {\mathbb{R}^{2n}} \).
The nodal degrees of freedom should be wrapped in Ikarus::RealTuple<double,2> in this case.
Another case of optimization is on non-linear manifolds. These arise typically for Cosserat materials \( \mathcal{S}\mathcal{O}(3) \)1, Reissner-Mindlin shells \( \mathcal{S}^2 \)2 and micro-magnetics \( \mathcal{S}^{2} \) or incompressible materials.
Interface¶
The general interface of the manifold elements is represented by the following concept.
namespace Ikarus::Concepts {
  template <typename ManifoldType>
  concept Manifold = requires(ManifoldType var, typename ManifoldType::CorrectionType correction, std::ostream& s,
                              typename ManifoldType::CoordinateType value) {
    typename ManifoldType::ctype; // (1)!
    ManifoldType::valueSize; // (2)!
    ManifoldType::correctionSize; // (3)!
    typename ManifoldType::CoordinateType; // (4)!
    typename ManifoldType::CorrectionType; // (5)!
    { var.getValue() } -> std::convertible_to<typename ManifoldType::CoordinateType>; // (6)!
    { var.setValue(value) } -> std::same_as<void>; // (7)!
    { var+=correction };  // (8)!
    //...
  };
}  
- The type for the coordinate values, usually double.
- The number of values to store for the state of the element. E.g., the three-dimensional unit vector needs three entries to store its state.
- The size of the correction for an element. valueSizeandcorrectionSizeare the same in Euclidean space. But, for example, the three-dimensional unit vector needs a two-dimensional correction (which lives in the tangent space).
- The type to store the element coordinates is usually Eigen::Vector<double,ManifoldType::valueSize>
- The type to store the element correction type is usually Eigen::Vector<double,ManifoldType::correctionSize>
- Access the underlying coordinate vector of the manifold element.
- Directly set the value. E.g., set Ikarus::UnitVector<double,3> a; a.setValue(Eigen::Vector3d::UnitZ());
- Update the element with a correction vector. E.g.,
Implementations¶
| Name | Formal definition | Notes | Header | 
|---|---|---|---|
| \(n\)-th dimensional Euclidean space | $$ \boldsymbol{x} \in \mathbb{R}^n $$ | realTuple.hh | |
| Unit sphere | $$ \boldsymbol{x} \in \mathcal{S}^{n-1}, \quad \mathcal{S}^{n-1} = \left\{ \boldsymbol{x} \in \mathbb{R}^n : \boldsymbol{x}\cdot \boldsymbol{x} = 1 \right\} $$ | unitVector.hh | 
- 
Oliver Sander. Geodesic finite elements for cosserat rods. International Journal for Numerical Methods in Engineering, 82(13):1645–1670, 2010. doi:10.1002/nme.2814. ↩ 
- 
Alexander Müller and Manfred Bischoff. A consistent finite element formulation of the geometrically non-linear reissner-mindlin shell model. Archives of Computational Methods in Engineering, pages 1–47, 2022. doi:10.1007/s11831-021-09702-7. ↩