You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
9.6 KiB
193 lines
9.6 KiB
namespace mm {
|
|
|
|
/**
|
|
|
|
@page concepts Concepts
|
|
|
|
Concepts are general patterns that certain classes follow
|
|
or require their members to follow.
|
|
The most important ones are described below.
|
|
|
|
@section rbf-concept Radial Basis Function concept
|
|
This concept represents a radial basis function as
|
|
a function of squared radial distance from the origin, ie.\ a function @f$f@f$ mapping
|
|
@f[ r^2 \mapsto f(r^2) @f]
|
|
|
|
The only requirements are that the class is default constructible,
|
|
has a `scalar_t` member type, that denotes the type used for numerical computations (eg. `double`)
|
|
and has the operators:
|
|
|
|
- `scalar_t operator()(scalar_t r2) const` evaluates function at given squared radial distance
|
|
- `scalar_t operator()(scalar_t r2, int derivative) const` evaluates given derivative wrt. `r2` at given squared radial distance
|
|
- `template <int dim> scalar_t operator()(scalar_t r2, Lap<dim>) const` evaluates Laplacian wrt. `r` at given squared radial distance
|
|
|
|
Classes Gaussian, Multiquadric, InverseMultiquadric and Polyharmonic satisfy this concept.
|
|
|
|
@section scale-concept Scale function concept
|
|
This represents a scaling function that computes the appropriate scaling to the local support domain.
|
|
It requires a class to implement a single method
|
|
|
|
- `template<vec_t> static typename vec_t::scalar_t scale(const vec_t& p, const std::vector<vec_t>& support)`
|
|
|
|
which returns local scale of this neighbourhood. For a neighbourhood of `{0, -h, h}`, `h` would be the appropriate local scale.
|
|
Support nodes are assumed to be ordered by distance from `p`.
|
|
|
|
Classes NoScale, ScaleToClosest, ScaleToFarthest satisfy this concept.
|
|
|
|
@section weight-concept Weight function concept
|
|
This concept represents a weight function used for weighted least squares solving.
|
|
The function returns a non-negative scalar for all inputs.
|
|
|
|
Classes satisfying this concept must be default constructible and provide member types `scalar_t`,
|
|
`vector_t`, and static value `dim`, representing types used for numerical computation,
|
|
and dimensionality of the function domain. Additionally, this method must be provided:
|
|
|
|
- `scalar_t operator()(const vector_t& point) const`
|
|
|
|
which evaluates the weight function.
|
|
|
|
Classes NoWeight and RBFWeight satisfy this concept. Specific instance of RBFWeight,
|
|
namely GaussianWeight is defined for Gaussian RBFs, because of common usage.
|
|
|
|
@section basis-concept Basis function concept
|
|
This concept represents a (local or global) basis over a neighbourhood of points.
|
|
|
|
Classes satisfying this concept must be default constructible and provide member types `scalar_t`,
|
|
`vector_t`, and static value `dim`, representing types used for numerical computation,
|
|
and dimensionality of the function domain. Additionally, these four methods must be provided:
|
|
|
|
- `scalar_t eval(int index, const vector_t& point, const std::vector<vector_t>& support) const`
|
|
- `template <typename operator_t> scalar_t evalOp(int index, const vector_t& point, const operator_t& op, const std::vector<vector_t>& support, scalar_t scale) const`
|
|
- `scalar_t evalAt0(int index, const std::vector<vector_t>& support) const;`
|
|
- `template <typename operator_t> scalar_t evalOpAt0(int index, const operator_t& op, const std::vector<vector_t>& support) const;`
|
|
|
|
allowing evaluation of `i`-th basis member in given point or at 0 and arbitrary operators.
|
|
The special methods for evaluation at 0 are commonly used in approximation computations
|
|
and are usually simpler and faster than general methods, which are not needed in that case.
|
|
Support nodes are assumed to be ordered by distance from `p`.
|
|
|
|
Classes Monomials and RBFBasis satisfy this concept.
|
|
|
|
@section operator-family-concept Operator family concept
|
|
An operator family is a (finite) collection of operators. Each operator family
|
|
must have an `operator_t` type, defining the type of operators in the family.
|
|
For convenience when printing, methods `name` and `type_name` must be defined,
|
|
giving human readable names. Additionally, a collection of all operators
|
|
in the family must be available through `operators` method, its size is given by `size()`,
|
|
and the index of an operator in this family can be computed using the `index` method.
|
|
|
|
In summary, the following methods must be defined:
|
|
|
|
- `std::string name() const;`
|
|
- `static int size();`
|
|
- `static std::string type_name();`
|
|
- `static std::array<operator_t, size> operators();` // can return other iterables
|
|
- `static int index(operator_t o);` // can take const &
|
|
|
|
The first four are used by @ref computeShapes to compute approximations,
|
|
while the last one is used by ExplicitOperators and ImplicitOperators to get the index of operator
|
|
in storage. The `index` method must also be compatible with `operators`, in the sense that
|
|
for the list of operators `o`, returned by `operators`, it must hold that `index(o[i]) == i`
|
|
for each `i`, i.e. the operators must be given in order by the `operators` method.
|
|
|
|
The @ref computeShapes method only computes approximations for families of operators,
|
|
however, inheriting from the `Operator` class will introduce all the required methods for 1-element
|
|
families.
|
|
|
|
Classes Der1s, Der2s, Lap, Der1, Der2, Derivative, Biharmonic satisfy this concept.
|
|
|
|
@section operator-concept Operator concept
|
|
This concept represents a (differential) operator, which can be applied to basis functions (see
|
|
the @ref basis-concept above) and for which approximations can be computed using
|
|
approximation engines (see @ref approx-concept below).
|
|
|
|
The basis itself can know how to compute the given operator, but if it does not,
|
|
the appropriate one of two methods that are required by this concept will be implemented.
|
|
|
|
- <code>template \<typename basis_t> typename basis_t::scalar_t apply(
|
|
const basis_t& basis, int index, typename basis_t::vector_t point,
|
|
const std::vector<typename basis_t::vector_t>& support,
|
|
typename basis_t::scalar_t scale) const;</code>
|
|
|
|
- <code>template \<typename basis_t> typename basis_t::scalar_t applyAt0(
|
|
const basis_t& basis, int index,
|
|
const std::vector<typename basis_t::vector_t>& support,
|
|
typename basis_t::scalar_t scale) const;</code>
|
|
|
|
These methods should implement applying the operator to `i`-th member of the basis.
|
|
Support nodes are assumed to be ordered by distance from the central point (`point` or `0`).
|
|
See Operators class for more details.
|
|
Additionally, the operator must define the `std::string name() const;` method for printing.
|
|
|
|
This allows implementation of custom operators in such a way, that if you only use
|
|
`MQ` basis functions, you operator only need to know how to be applied specifically to
|
|
`MQ` basis. Custom operator approximation can be obtained using ShapeStorage::get
|
|
and used with ExplicitOperators::apply, ImplicitOperators::apply, ExplicitVectorOperators::apply,
|
|
ImplicitVectorOperators::apply.
|
|
|
|
@section approx-concept Approximation engine concept
|
|
This concept represents an approximation engine for approximating
|
|
differential operators in neighborhood of points.
|
|
|
|
Given a point @f$p@f$ with neighbours @f$p_1, \dots, p_n@f$, called _support_,
|
|
an operator @f$\mathcal{L}@f$ is approximated as
|
|
@f[ (\mathcal{L}{u})(p) \approx \sum_{i=1}^n w_i u(p_i). @f]
|
|
The weights @f$w_i@f$ are called stencil weights of the _shape function_ for operator
|
|
@f$\mathcal{L}@f$ at points @f$p@f$.
|
|
|
|
Approximation engines are classes that compute operator and function approximations.
|
|
Operator approximations are often called "stencil weights" or "shape function".
|
|
They must provide member types `scalar_t` and `vector_t`, and static value `dim`,
|
|
representing types used for numerical computation and dimensionality of the function domain.
|
|
Additionally, these three methods must be provided:
|
|
|
|
- `void compute(const vector_t& point, const std::vector<vector_t>& support)`,
|
|
- `Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> getShape() const` and
|
|
- `template <operator_t> Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> getShape(const operator_t& op) const`
|
|
- `FunctionType getApproximant(const vector_t& point, const std::vector<vector_t>& support,
|
|
const Eigen::MatrixBase<Derived>& values) const`
|
|
|
|
The compute step prepares the engine for approximation of operators around point `point`
|
|
with given support `support` and is usually computationally more intense.
|
|
Support nodes are assumed to be ordered by distance from `point`.
|
|
The `getShape()` step computes the shape for given basic differential operator or
|
|
the evaluation operator (first overload).
|
|
The `getApproximant` method returns the function approximant around given point.
|
|
|
|
Typical usage is illustrated below:
|
|
@code
|
|
ApproximationEngine engine(...);
|
|
double h = 0.1;
|
|
engine.compute({0.0, 0.0}, {{0.0, 0.0}, {-h, 0.0}, {h, 0.0}, {0.0, h}, {0.0, -h}});
|
|
VectorXd shape = engine.getShape();
|
|
VectorXd shape = engine.getShape(Lap()); // shape for Laplacian
|
|
@endcode
|
|
|
|
Classes WLS and RBFFD satisfy this concept.
|
|
|
|
@section ss-concept Shape storage concept
|
|
This concept represents classes used for storing computed shape functions for different domain nodes.
|
|
Their intention os to store the shape functions more compactly than if stored in `vector<vector<double>>`.
|
|
|
|
Classes UniformShapeStorage and RaggedShapeStorage satisfy this concept. See also
|
|
ShapeStorage for CRTP inheritable interface.
|
|
|
|
Typical usage:
|
|
@snippet UniformShapeStorage_test.cpp Uniform shape storage usage example
|
|
|
|
@section linsolve-concept Linear solver concept
|
|
This class represents a linear solver and follows the Eigen's
|
|
[Linear algebra and decompositions](https://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html).
|
|
The linear solver class must be default constructible and
|
|
have two methods
|
|
|
|
- `void compute(const Matrix& M)`
|
|
- `Vector solve(const Vector& rhs)`
|
|
|
|
The class JacobiSVDWrapper and most Eigen's decompositions follow this concept.
|
|
|
|
*/
|
|
}
|
|
|
|
// vim: set ft=php:
|
|
// vim: set spell spelllang=en:
|
|
|