Skip to content

Commit d9f3138

Browse files
committed
dof_handler stored by copy in int_exp_ and grad_int_exp_, discretize() and analyze_data() semantic for fe_de_elliptic. core submodule update
1 parent fe94db8 commit d9f3138

File tree

2 files changed

+33
-35
lines changed

2 files changed

+33
-35
lines changed

fdaPDE/core

fdaPDE/src/solvers/fe_de_elliptic.h

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,40 @@ struct fe_de_elliptic {
8080
requires(is_valid_info_t<InfoT>::value)
8181
fe_de_elliptic(const GeoFrame& gf, InfoT&& info) {
8282
fdapde_static_assert(GeoFrame::Order == 1, THIS_CLASS_IS_FOR_ORDER_ONE_GEOFRAMES_ONLY);
83-
using BilinearForm = std::tuple_element_t<0, std::decay_t<decltype(info.penalty)>>;
83+
discretize(gf, info.penalty);
84+
analyze_data(gf);
85+
}
86+
87+
// perform finite element based numerical discretization
88+
template <typename GeoFrame, typename Penalty> void discretize(const GeoFrame& gf, Penalty&& penalty) {
89+
fdapde_static_assert(internals::is_valid_penalty_pair_v<Penalty>, INVALID_PENALTY_DESCRIPTION);
90+
using BilinearForm = std::tuple_element_t<0, std::decay_t<Penalty>>;
91+
using LinearForm = std::tuple_element_t<1, std::decay_t<Penalty>>;
8492
using FeSpace = typename BilinearForm::TrialSpace;
8593
using DofHandler = typename FeSpace::DofHandlerType;
8694
using Triangulation = typename FeSpace::Triangulation;
8795
constexpr int embed_dim = Triangulation::embed_dim;
88-
const Triangulation& triangulation = gf.template triangulation<0>();
89-
const FeSpace& fe_space = std::get<0>(info.penalty).trial_space();
90-
const DofHandler& dof_handler = fe_space.dof_handler();
9196

92-
discretize(info.penalty);
97+
// discretization
98+
const FeSpace& fe_space = std::get<0>(penalty).trial_space();
99+
const Triangulation& triangulation = gf.template triangulation<0>();
100+
const DofHandler& dof_handler = fe_space.dof_handler();
101+
const BilinearForm& bilinear_form = std::get<0>(penalty);
102+
const LinearForm& linear_form = std::get<1>(penalty);
103+
n_dofs_ = bilinear_form.n_dofs(); // number of basis functions over physical domain
104+
internals::fe_mass_assembly_loop<FeSpace> mass_assembler(bilinear_form.trial_space());
105+
R0_ = mass_assembler.assemble();
106+
R1_ = bilinear_form.assemble();
107+
u_ = linear_form.assemble();
108+
109+
// penalty matrix
110+
sparse_solver_t invR0;
111+
invR0.compute(R0_);
112+
P_ = R1_.transpose() * invR0.solve(R1_);
113+
// store handles for basis system evaluation at locations
114+
point_eval_ = [fe_space = bilinear_form.trial_space()](const matrix_t& locs) -> decltype(auto) {
115+
return internals::point_basis_eval(fe_space, locs);
116+
};
93117
// eval reference basis at quadrature nodes, store de_quadrature weights
94118
de_quadrature_t<embed_dim> quad_rule;
95119
int n_quad_nodes = quad_rule.order;
@@ -103,15 +127,15 @@ struct fe_de_elliptic {
103127
w[i] = quad_rule.weights[i];
104128
}
105129
// store handle for approximation of \int_D (e^g)
106-
int_exp_ = [&, PsiQuad, w](const vector_t& g) {
130+
int_exp_ = [&, dof_handler, PsiQuad, w](const vector_t& g) {
107131
double val_ = 0;
108132
for (auto it = triangulation.cells_begin(); it != triangulation.cells_end(); ++it) {
109133
val_ += w.dot((PsiQuad * g(dof_handler.dofs().row(it->id()))).array().exp().matrix()) * it->measure();
110134
}
111135
return val_;
112136
};
113137
// store handle for approximation of \nabla_g(\int_D (e^g))
114-
grad_int_exp_ = [&, PsiQuad, w](const vector_t& g) {
138+
grad_int_exp_ = [&, dof_handler, PsiQuad, w](const vector_t& g) {
115139
vector_t grad = vector_t::Zero(g.rows());
116140
for (auto it = triangulation.cells_begin(); it != triangulation.cells_end(); ++it) {
117141
grad(dof_handler.dofs().row(it->id())) +=
@@ -120,33 +144,7 @@ struct fe_de_elliptic {
120144
it->measure();
121145
}
122146
return grad;
123-
};
124-
125-
analyze_data(gf);
126-
}
127-
128-
// perform finite element based numerical discretization
129-
template <typename Penalty> void discretize(Penalty&& penalty) {
130-
fdapde_static_assert(internals::is_valid_penalty_pair_v<Penalty>, INVALID_PENALTY_DESCRIPTION);
131-
using BilinearForm = std::tuple_element_t<0, std::decay_t<Penalty>>;
132-
using LinearForm = std::tuple_element_t<1, std::decay_t<Penalty>>;
133-
using FeSpace = typename BilinearForm::TrialSpace;
134-
// discretization
135-
const BilinearForm& bilinear_form = std::get<0>(penalty);
136-
const LinearForm& linear_form = std::get<1>(penalty);
137-
n_dofs_ = bilinear_form.n_dofs(); // number of basis functions over physical domain
138-
internals::fe_mass_assembly_loop<FeSpace> mass_assembler(bilinear_form.trial_space());
139-
R0_ = mass_assembler.assemble();
140-
R1_ = bilinear_form.assemble();
141-
u_ = linear_form.assemble();
142-
// penalty matrix
143-
sparse_solver_t invR0;
144-
invR0.compute(R0_);
145-
P_ = R1_.transpose() * invR0.solve(R1_);
146-
// store handles for basis system evaluation at locations
147-
point_eval_ = [fe_space = bilinear_form.trial_space()](const matrix_t& locs) -> decltype(auto) {
148-
return internals::point_basis_eval(fe_space, locs);
149-
};
147+
};
150148
return;
151149
}
152150
// fit from geoframe

0 commit comments

Comments
 (0)