Reduced Lagrange Multipliers
 
Loading...
Searching...
No Matches
matrix_free_utils.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2024 by Luca Heltai
4//
5// This file is part of the reduced_lagrange_multipliers application, based on
6// the deal.II library.
7//
8// The reduced_lagrange_multipliers application is free software; you can use
9// it, redistribute it, and/or modify it under the terms of the Apache-2.0
10// License WITH LLVM-exception as published by the Free Software Foundation;
11// either version 3.0 of the License, or (at your option) any later version. The
12// full text of the license can be found in the file LICENSE.md at the top level
13// of the reduced_lagrange_multipliers distribution.
14//
15// ---------------------------------------------------------------------
16
17/* ---------------------------------------------------------------------
18 *
19 * Copyright (C) 2000 - 2020 by the deal.II authors
20 *
21 * This file is part of the deal.II library.
22 *
23 * The deal.II library is free software; you can use it, redistribute
24 * it, and/or modify it under the terms of the GNU Lesser General
25 * Public License as published by the Free Software Foundation; either
26 * version 2.1 of the License, or (at your option) any later version.
27 * The full text of the license can be found in the file LICENSE.md at
28 * the top level directory of deal.II.
29 */
30
31
32
33#include <matrix_free_utils.h>
34
35
36template <int dim, typename number, int n_components>
38 const Inclusions<dim> &inclusions_,
39 const DoFHandler<dim> &dof_handler_,
40 const AffineConstraints<number> &constraints_,
41 const MappingQ<dim> &mapping_,
42 const FiniteElement<dim> &fe_)
43 : rpe{{1e-9, true, inclusions_.rtree_extraction_level, {}}}
44 , n_coefficients{inclusions_.n_coefficients}
45{
46 [[maybe_unused]] auto parallel_triangulation =
48 &dof_handler_.get_triangulation());
49 Assert((parallel_triangulation != nullptr),
50 ExcMessage("Only p::d::T triangulations are supported."));
51
52 mapping = &mapping_;
53 fe = &fe_;
54 constraints = &constraints_;
55 dof_handler = &dof_handler_;
56 inclusions = &inclusions_;
57
58 // Get all locally owned support points from the inclusions
59 std::vector<Point<dim>> locations(
60 inclusions->inclusions_as_particles.n_locally_owned_particles());
62 inclusions->inclusions_as_particles)
63 .get_particle_positions(locations);
64
65 rpe.reinit(locations, dof_handler->get_triangulation(), *mapping);
66
67 // We should make sure all points have been found. Do this only in debug mode
68 Assert(rpe.all_points_found(),
69 ExcInternalError("Not all points have been"
70 "found during the geometric search procedure."));
71}
72
73
74
75template <int dim, typename number, int n_components>
76void
82
83
84
85template <int dim, typename number, int n_components>
86void
88 const VectorType &src) const
89{
90 Assert(rpe.is_ready(),
91 ExcInternalError("Remote evaluator has not been initialized."));
92
94 dst = 0.;
95
96 std::vector<number> integration_values;
97 const unsigned int n_dofs_per_cell = fe->n_dofs_per_cell();
98
99 // collect
100 std::vector<types::global_dof_index> inclusion_dof_indices(
101 inclusions->n_coefficients);
102
103 auto particle = inclusions->inclusions_as_particles.begin();
104 while (particle != inclusions->inclusions_as_particles.end())
105 {
106 const auto id = particle->get_id();
107 inclusion_dof_indices = inclusions->get_dof_indices(id);
108 const auto &inclusion_fe_values = inclusions->get_fe_values(id);
109
110 double value_per_particle = 0.;
111 for (unsigned int j = 0; j < inclusions->n_coefficients; ++j)
112 {
113 value_per_particle +=
114 inclusion_fe_values[j] * src(inclusion_dof_indices[j]);
115 }
116 integration_values.push_back(value_per_particle);
117 ++particle;
118 }
119
120
121 const auto integration_function = [&](const auto &values,
122 const auto &cell_data) {
124
125 std::vector<double> local_values;
126 std::vector<types::global_dof_index> local_dof_indices;
127
128 for (const auto cell : cell_data.cell_indices())
129 {
130 const auto cell_dh =
131 cell_data.get_active_cell_iterator(cell)->as_dof_handler_iterator(
132 *dof_handler);
133
134
135 const auto unit_points = cell_data.get_unit_points(cell);
136 const auto inclusion_values = cell_data.get_data_view(cell, values);
137
138 phi_force.reinit(cell_dh, unit_points);
139
140 for (const auto q : phi_force.quadrature_point_indices())
141 phi_force.submit_value(inclusion_values[q], q);
142
143 local_values.resize(n_dofs_per_cell);
144 phi_force.test_and_sum(local_values, EvaluationFlags::values);
145
146 local_dof_indices.resize(n_dofs_per_cell);
147 cell_dh->get_dof_indices(local_dof_indices);
148 constraints->distribute_local_to_global(local_values,
149 local_dof_indices,
150 dst);
151 }
152 };
153
154 rpe.template process_and_evaluate<number>(integration_values,
155 integration_function);
157}
158
159
160
161template <int dim, typename number, int n_components>
162void
164 const VectorType &src) const
165{
166 Assert(rpe.is_ready(),
167 ExcInternalError("Remote evaluator has not been initialized."));
168
170 dst = 0.;
171
172 const auto evaluation_function = [&](const auto &values,
173 const auto &cell_data) {
175 *fe,
177
178 std::vector<double> local_values;
179 const unsigned int n_dofs_per_cell = fe->n_dofs_per_cell();
180
181 for (const auto cell : cell_data.cell_indices())
182 {
183 const auto cell_dh =
184 cell_data.get_active_cell_iterator(cell)->as_dof_handler_iterator(
185 *dof_handler);
186
187 const auto unit_points = cell_data.get_unit_points(cell);
188 const auto local_value = cell_data.get_data_view(cell, values);
189
190 local_values.resize(n_dofs_per_cell);
191 cell_dh->get_dof_values(*constraints,
192 src,
193 local_values.begin(),
194 local_values.end());
195
196 evaluator.reinit(cell_dh, unit_points);
197 evaluator.evaluate(local_values, EvaluationFlags::values);
198
199 for (unsigned int q = 0; q < unit_points.size(); ++q)
200 local_value[q] = evaluator.get_value(q);
201 }
202 };
203
204
205 const std::vector<number> output =
206 rpe.template evaluate_and_process<number>(evaluation_function);
207
208 std::vector<types::global_dof_index> inclusion_dof_indices(
209 inclusions->n_coefficients);
210
211 auto particle = inclusions->inclusions_as_particles.begin();
212 while (particle != inclusions->inclusions_as_particles.end())
213 {
214 const auto id = particle->get_id();
215 const auto local_id = particle->get_local_index();
216 inclusion_dof_indices = inclusions->get_dof_indices(id);
217 const auto &inclusion_fe_values = inclusions->get_fe_values(id);
218
219 for (unsigned int j = 0; j < inclusions->n_coefficients; ++j)
220 dst(inclusion_dof_indices[j]) +=
221 inclusion_fe_values[j] * output[local_id];
222
223 ++particle;
224 }
225
227}
228
229
230
231template <int dim, typename number, int n_components>
232void
234 VectorType &dst,
235 const VectorType &src) const
236{
237 Assert(rpe.is_ready(),
238 ExcInternalError("Remote evaluator has not been initialized."));
239 VectorType tmp_vector;
240 tmp_vector.reinit(dst, true);
241 vmult(tmp_vector, src);
242 dst += tmp_vector;
243}
244
245template <int dim, typename number, int n_components>
246void
248 VectorType &dst,
249 const VectorType &src) const
250{
251 Assert(rpe.is_ready(),
252 ExcInternalError("Remote evaluator has not been initialized."));
253 VectorType tmp_vector;
254 tmp_vector.reinit(dst, true);
255 Tvmult(tmp_vector, src);
256 dst += tmp_vector;
257}
258
259
260
261// Template instantiations
262template class CouplingOperator<2, double, 1>;
263template class CouplingOperator<3, double, 1>;
264template class CouplingOperator<2, float, 1>;
265template class CouplingOperator<3, float, 1>;
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
const value_type & get_value(const unsigned int point_index) const
void submit_value(const value_type &value, const unsigned int point_index)
void evaluate(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
void test_and_sum(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ArrayView< const Point< dim > > &unit_points)
void compress(VectorOperation::values operation)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
void initialize_dof_vector(VectorType &vec) const
void vmult(VectorType &dst, const VectorType &src) const
void vmult_add(VectorType &dst, const VectorType &src) const
ObserverPointer< const FiniteElement< dim > > fe
void Tvmult_add(VectorType &dst, const VectorType &src) const
ObserverPointer< const Inclusions< dim > > inclusions
ObserverPointer< const Mapping< dim > > mapping
LinearAlgebra::distributed::Vector< number > VectorType
void Tvmult(VectorType &dst, const VectorType &src) const
ObserverPointer< const AffineConstraints< number > > constraints
CouplingOperator(const Inclusions< dim > &inclusions, const DoFHandler< dim > &dof_handler, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const MappingQ< dim > &mapping=MappingQ1< dim >(), const FiniteElement< dim > &fe=FE_Q< dim >(1))
Utilities::MPI::RemotePointEvaluation< dim > rpe
ObserverPointer< const DoFHandler< dim > > dof_handler
Class for handling inclusions in an immersed boundary method.
Definition inclusions.h:65
unsigned int rtree_extraction_level
#define Assert(cond, exc)
update_values
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)