5#include "preconditioner/fine_grid.h"
6#include "common/macros.h"
7#include "preconditioner/mat_a.h"
11 fine_grid::fine_grid(
const model& model, domain&& domain)
13 point_idcs_(std::move(domain.point_indices)),
14 grad_point_idcs_(std::move(domain.grad_point_indices)),
15 inner_point_(std::move(domain.inner_point)),
16 inner_grad_point_(std::move(domain.inner_grad_point)),
17 dim_(model.poly_dimension()),
18 l_(model.poly_basis_size()),
19 mu_(static_cast<index_t>(point_idcs_.size())),
20 sigma_(static_cast<index_t>(grad_point_idcs_.size())),
21 m_(mu_ + dim_ * sigma_) {
22 RSMESH_ASSERT(mu_ > l_);
25 void fine_grid::clear() {
26 me_ = Eigen::MatrixXd();
27 ldlt_of_qtaq_ = Eigen::LDLT<Eigen::MatrixXd>();
30 void fine_grid::setup(
const geometry::points3d& points_full,
31 const Eigen::MatrixXd& lagrange_pt_full) {
32 setup(points_full, geometry::points3d(0, 3), lagrange_pt_full);
35 void fine_grid::setup(
const geometry::points3d& points_full,
36 const geometry::points3d& grad_points_full,
37 const Eigen::MatrixXd& lagrange_pt_full) {
38 auto points = points_full(point_idcs_, Eigen::all);
39 auto grad_points = grad_points_full(grad_point_idcs_, Eigen::all);
42 auto a = mat_a(model_, points, grad_points);
45 std::vector<index_t> flat_indices(point_idcs_);
46 flat_indices.reserve(mu_ + dim_ * sigma_);
47 for (
auto i : grad_point_idcs_) {
48 for (index_t j = 0; j < dim_; j++) {
49 flat_indices.push_back(mu_ + dim_ * i + j);
54 auto lagrange_pt = lagrange_pt_full(Eigen::all, flat_indices);
55 me_ = -lagrange_pt.rightCols(m_ - l_);
58 ldlt_of_qtaq_ = (me_.transpose() * a.topLeftCorner(l_, l_) * me_ +
59 me_.transpose() * a.topRightCorner(l_, m_ - l_) +
60 a.bottomLeftCorner(m_ - l_, l_) * me_ + a.bottomRightCorner(m_ - l_, m_ - l_))
63 ldlt_of_qtaq_ = a.ldlt();
66 mu_full_ = points_full.rows();
67 sigma_full_ = grad_points_full.rows();
70 void fine_grid::set_solution_to(valuesd& weights_full)
const {
71 for (index_t i = 0; i < mu_; i++) {
72 if (inner_point_.at(i)) {
73 weights_full(point_idcs_.at(i)) = lambda_(i);
77 for (index_t i = 0; i < sigma_; i++) {
78 if (inner_grad_point_.at(i)) {
79 weights_full.segment(mu_full_ + dim_ * grad_point_idcs_.at(i), dim_) =
80 lambda_.segment(mu_ + dim_ * i, dim_);
85 void fine_grid::solve(
const valuesd& values_full) {
87 values.head(mu_) = values_full(point_idcs_);
88 values.tail(dim_ * sigma_).reshaped<Eigen::RowMajor>(sigma_, dim_) =
89 values_full.tail(dim_ * sigma_full_)
90 .reshaped<Eigen::RowMajor>(sigma_full_, dim_)(grad_point_idcs_, Eigen::all);
94 valuesd qtd = me_.transpose() * values.head(l_) + values.tail(m_ - l_);
97 valuesd gamma = ldlt_of_qtaq_.solve(qtd);
100 lambda_ = valuesd(m_);
101 lambda_.head(l_) = me_ * gamma;
102 lambda_.tail(m_ - l_) = gamma;
104 lambda_ = ldlt_of_qtaq_.solve(values);
该命名空间下主要定义了关于krylov子空间方法的预处理相关的类和函数