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.
177 lines
7.0 KiB
177 lines
7.0 KiB
#ifndef MEDUSA_BITS_APPROXIMATIONS_RBFFD_FWD_HPP_
|
|
#define MEDUSA_BITS_APPROXIMATIONS_RBFFD_FWD_HPP_
|
|
|
|
/**
|
|
* @file
|
|
* Declaration of Radial Basis Function Finite Difference approximation.
|
|
*
|
|
* @example test/approximations/RBFFD_test.cpp
|
|
*/
|
|
|
|
#include <medusa/Config.hpp>
|
|
#include <medusa/bits/types/Range_fwd.hpp>
|
|
#include <Eigen/Core>
|
|
#include "RBFBasis_fwd.hpp"
|
|
#include "Monomials_fwd.hpp"
|
|
#include "ScaleFunction.hpp"
|
|
#include "RBFInterpolant_fwd.hpp"
|
|
|
|
namespace mm {
|
|
|
|
/**
|
|
* Computes a RBF-FD approximation of given operator over local neighbourhood.
|
|
*
|
|
* @tparam RBFType Type of RBF used in approximation. Must satisfy the @ref rbf-concept.
|
|
* @tparam vec_t Vector type used in calculations.
|
|
* @tparam scale_t Scale function to be used in approximation. Must satisfy the @ref scale-concept.
|
|
* @tparam solver_t Which linear solver to use in weight computations. Must satisfy the
|
|
* @ref linsolve-concept. Default: LU with partial pivoting.
|
|
*
|
|
* This class satisfies the @ref approx-concept.
|
|
*
|
|
* Usage example:
|
|
* @snippet approximations/RBFFD_test.cpp RBFFD usage example
|
|
* @ingroup approximations
|
|
*/
|
|
template <class RBFType, class vec_t, class scale_t = NoScale, class solver_t =
|
|
Eigen::PartialPivLU<Eigen::Matrix<typename vec_t::scalar_t, Eigen::Dynamic, Eigen::Dynamic>>>
|
|
class RBFFD {
|
|
static_assert(std::is_same<typename vec_t::scalar_t, typename RBFType::scalar_t>::value,
|
|
"Basis and underlying RBF must have the same scalar type.");
|
|
public:
|
|
typedef RBFType rbf_t; ///< Radial basis function type.
|
|
typedef vec_t vector_t; ///< Vector type.
|
|
typedef typename vector_t::scalar_t scalar_t; ///< Scalar type.
|
|
/// Store dimension of the domain.
|
|
enum { /** Dimensionality of the function domain. */ dim = vec_t::dim };
|
|
|
|
private:
|
|
rbf_t rbf_; ///< RBF used in the approximation.
|
|
Monomials<vec_t> mon_; ///< Monomials used in the approximation.
|
|
solver_t solver_; ///< Linear solver used in the approximation.
|
|
|
|
vector_t point_; ///< Saved point.
|
|
scalar_t scale_; ///< Saved scale.
|
|
Range<vec_t> support_; ///< Saved support scaled to local coordinate system.
|
|
|
|
public:
|
|
/// Construct a RBFFD engine from given RBF using no monomial augmentation.
|
|
explicit RBFFD(rbf_t rbf) : rbf_(rbf), mon_(), point_(NaN) {}
|
|
|
|
/// Construct a RBFFD engine from given RBF with additional monomial augmentation.
|
|
RBFFD(rbf_t rbf, const Monomials<vec_t>& mon) : rbf_(rbf), mon_(mon), point_(NaN) {}
|
|
|
|
/// Return the RBF used in this approximation.
|
|
const rbf_t& rbf() const { return rbf_; }
|
|
|
|
/// Return the augmenting monomial basis.
|
|
const Monomials<vec_t>& monomials() const { return mon_; }
|
|
|
|
/// Returns minimal support size required for this approximation to be performed.
|
|
int requiredSupportSize() const { return mon_.size(); }
|
|
|
|
/**
|
|
* Setup this engine to approximate operators at given point over given local neighbourhood.
|
|
* @param point At which point to construct the approximation.
|
|
* @param support Coordinates of local support points.
|
|
*/
|
|
void compute(const vector_t& point, const std::vector<vector_t>& support);
|
|
|
|
/// Return shape function (stencil weights) for value approximation.
|
|
Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> getShape() const;
|
|
|
|
/// Return shape function (stencil weights) for given derivative operator.
|
|
template <class operator_t>
|
|
Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> getShape(const operator_t& op) const;
|
|
|
|
/**
|
|
* Returns weights for approximation with a given right hand side, which is expected to
|
|
* contains the values of an operator applied to your basis functions (both RBFs and monomials).
|
|
* This method is useful if values of the operator are computed differently to the procedure
|
|
* used by @ref getShape.
|
|
* @param Lb The right hand side of the approximation system representing an values of
|
|
* an operator applied to basis functions (both RBFs and monomials) at the point where
|
|
* @ref compute was called.
|
|
* @sa getShape
|
|
*/
|
|
template <typename Derived>
|
|
Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> getShapeFromRhs(
|
|
const Eigen::MatrixBase<Derived>& Lb) const;
|
|
|
|
private:
|
|
/// Returns the augmented collocation matrix.
|
|
Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic> getMatrix(
|
|
const std::vector<vector_t>& local_coordinates) const;
|
|
|
|
public:
|
|
/**
|
|
* Return the center point of the approximation.
|
|
* Only initialized after the first call to @ref compute.
|
|
*/
|
|
vec_t center() const { return point_; }
|
|
|
|
/// Return the scaling factor. Only initialized after the first call to @ref compute.
|
|
scalar_t scale() const { return scale_; }
|
|
|
|
/**
|
|
* Returns the local (translated and scaled) coordinates of the support nodes.
|
|
* Only initialized after the first call to @ref compute.
|
|
*/
|
|
Range<vec_t> localCoordinates() const { return support_; }
|
|
|
|
/**
|
|
* Returns the augmented collocation matrix.
|
|
* Only initialized after the first call to @ref compute.
|
|
*/
|
|
Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic> getMatrix() const {
|
|
return getMatrix(support_);
|
|
}
|
|
|
|
/**
|
|
* Returns the stored decomposition of the augmented collocation matrix.
|
|
* Only initialized after the first call to @ref compute.
|
|
*/
|
|
const solver_t& solver() const { return solver_; }
|
|
|
|
/**
|
|
* Construct a RBF interpolant of form
|
|
* @f[
|
|
* u(p) = \sum_{i=1}^n \alpha_i \phi\left(\left\|\frac{p - p_i}{s}\right\|\right) +
|
|
* \sum_{i=1}^s \beta_i q_i\left(\frac{p - p_c}{s} \right),
|
|
* @f]
|
|
* where @f$\phi@f$ is the RBF and @f$q_i@f$ are monomials. Additionally, @f$s@f$
|
|
* constraints are imposed for @f$\beta_i@f$, @f$\sum_{i=1}^n q_j(p_i) = 0@f$, for
|
|
* @f$j = 1, \ldots, s@f$.
|
|
* @param point Center point @f$p@f$.
|
|
* @param support Support values @f$p_i@f$.
|
|
* @param values Function values @f$u_i@f$ at @f$p_i@f$.
|
|
* @return An object representing the interpolant.
|
|
*/
|
|
template <typename Derived>
|
|
RBFInterpolant<rbf_t, vec_t> getApproximant(const vector_t& point,
|
|
const std::vector<vector_t>& support, const Eigen::MatrixBase<Derived>& values) const;
|
|
|
|
/// Output basic info about given approximation engine.
|
|
template <class R, class V, class S, class L>
|
|
friend std::ostream& operator<<(std::ostream& os, const RBFFD<R, V, S, L>& e);
|
|
};
|
|
|
|
/// Output basic info about given approximation engine.
|
|
template <class R, class V, class S, class L>
|
|
std::ostream& operator<<(std::ostream& os, const RBFFD<R, V, S, L>& e) {
|
|
os << "RBFFD approximation engine:\n"
|
|
<< " dimension: " << e.dim << '\n';
|
|
if (e.point_[0] != e.point_[0]) {
|
|
os << " last point: not used yet\n";
|
|
} else {
|
|
os << " last point: " << e.point_ << '\n';
|
|
}
|
|
os << " RBF: " << e.rbf_ << '\n'
|
|
<< " Augmentation: " << e.mon_ << '\n'
|
|
<< " scale: " << S();
|
|
return os;
|
|
}
|
|
|
|
} // namespace mm
|
|
|
|
#endif // MEDUSA_BITS_APPROXIMATIONS_RBFFD_FWD_HPP_
|
|
|