Reduced Lagrange Multipliers
 
Loading...
Searching...
No Matches
utils.h
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#ifndef utils_h
18#define utils_h
19
21#include <deal.II/base/mpi.h>
23
26
27
28using namespace dealii;
29
31{
33 : ParameterAcceptor("Local refinement parameters")
34 {
35 this->add_parameter("Refinement strategy",
37 "",
38 this->prm,
39 Patterns::Selection("space|embedded"));
40 this->add_parameter("Space post-refinement cycles",
42 this->add_parameter("Embedded post-refinement cycles",
44 this->add_parameter("Space pre-refinement cycles",
46 this->add_parameter("Embedded pre-refinement cycles",
48 this->add_parameter("Refinement factor", refinement_factor);
49 this->add_parameter("Max refinement level", max_refinement_level);
50 }
51
52 std::string refinement_strategy = "space";
57 double refinement_factor = 1.0;
59};
60
61
62
63template <int reduced_dim, int spacedim>
64void
66 Triangulation<reduced_dim, spacedim> &embedded_triangulation,
67 const RefinementParameters &parameters = RefinementParameters())
68{
69 Assert(
71 &embedded_triangulation) == nullptr),
72 ExcMessage(
73 "The embedded triangulation must not be distributed. It will be partitioned later."));
74
75 namespace bgi = boost::geometry::index;
76
77 space_triangulation.refine_global(parameters.space_pre_refinement_cycles);
78 embedded_triangulation.refine_global(
79 parameters.embedded_pre_refinement_cycles);
80
81 // build caches so that we can get local trees
82 GridTools::Cache<spacedim, spacedim> space_cache{space_triangulation};
84 embedded_triangulation};
85
86 auto refine = [&]() {
87 bool done = false;
88 bool global_done = false;
89
90 double min_embedded = 1e10;
91 double max_embedded = 0;
92 double min_space = 1e10;
93 double max_space = 0;
94
95 // bounding box
96 const bool use_space = parameters.refinement_strategy == "space";
97 const bool use_embedded = parameters.refinement_strategy == "embedded";
98
99 AssertThrow(use_space || use_embedded,
100 ExcMessage("One of the two must be true"));
101 unsigned int n_space_cells = space_triangulation.n_global_active_cells();
102 unsigned int n_embedded_cells =
103 embedded_triangulation.n_global_active_cells();
104 while (global_done == false)
105 {
106 done = true;
107 // Bounding boxes of the space grid
108 const auto &tree =
109 space_cache.get_locally_owned_cell_bounding_boxes_rtree();
110
111 const auto &embedded_tree =
112 embedded_cache.get_cell_bounding_boxes_rtree();
113
114 unsigned int n_refs = 0;
115
116 for (const auto &[embedded_box, embedded_cell] : embedded_tree)
117 {
118 const auto &[p1, p2] = embedded_box.get_boundary_points();
119 const auto diameter = p1.distance(p2);
120 min_embedded = std::min(min_embedded, diameter);
121 max_embedded = std::max(max_embedded, diameter);
122
123 for (const auto &[space_box, space_cell] :
124 tree | bgi::adaptors::queried(bgi::intersects(embedded_box)))
125 {
126 const auto &[sp1, sp2] = space_box.get_boundary_points();
127 const auto space_diameter = sp1.distance(sp2);
128 min_space = std::min(min_space, space_diameter);
129 max_space = std::max(max_space, space_diameter);
130
131 if (use_embedded &&
132 embedded_cell->level() < parameters.max_refinement_level &&
133 parameters.refinement_factor * space_diameter < diameter)
134 {
135 embedded_cell->set_refine_flag();
136 ++n_refs;
137 done = false;
138 }
139 if (use_space &&
140 space_cell->level() < parameters.max_refinement_level &&
141 parameters.refinement_factor * diameter < space_diameter)
142 {
143 space_cell->set_refine_flag();
144 ++n_refs;
145 done = false;
146 }
147 }
148 }
149 deallog << "Cells marked for refinement: " << n_refs;
150 // Synchronize done variable across all processes, otherwise we might
151 // deadlock
152 global_done =
153 Utilities::MPI::min(static_cast<int>(done),
154 space_triangulation.get_communicator());
155
156 if (global_done == false)
157 {
158 if (use_embedded)
159 {
160 n_embedded_cells =
161 embedded_triangulation.n_global_active_cells();
162 deallog << " out of " << n_embedded_cells
163 << " (embedded) cells." << std::endl;
164 embedded_triangulation.execute_coarsening_and_refinement();
165 if (n_embedded_cells ==
166 embedded_triangulation.n_global_active_cells())
167 break;
168 }
169 if (use_space)
170 {
171 n_space_cells = space_triangulation.n_global_active_cells();
172 deallog << " out of " << n_space_cells << " (space) cells."
173 << std::endl;
174 space_triangulation.execute_coarsening_and_refinement();
175 if (n_space_cells ==
176 space_triangulation.n_global_active_cells())
177 break;
178 }
179 }
180 }
181
182 deallog << std::setw(20) << std::left << "Min space: " << std::setw(12)
183 << std::right << min_space << std::setw(20) << std::left
184 << ", max space: " << std::setw(12) << std::right << max_space
185 << std::setw(25) << std::left << ", min embedded: " << std::setw(12)
186 << std::right << min_embedded << std::setw(25) << std::left
187 << ", max embedded: " << std::setw(12) << std::right << max_embedded
188 << std::endl;
189
190 return std::make_tuple(min_space, max_space, min_embedded, max_embedded);
191 };
192
193 // Do the refinement loop once, to make sure we satisfy our criterions
194 refine();
195
196
197 // Pre refine the space grid according to the delta refinement
198 if (parameters.space_post_refinement_cycles > 0)
199 for (unsigned int i = 0; i < parameters.space_post_refinement_cycles; ++i)
200 {
201 const auto &tree =
202 space_cache.get_locally_owned_cell_bounding_boxes_rtree();
203
204 const auto &embedded_tree =
205 embedded_cache.get_cell_bounding_boxes_rtree();
206
207 for (const auto &[embedded_box, embedded_cell] : embedded_tree)
208 for (const auto &[space_box, space_cell] :
209 tree | bgi::adaptors::queried(bgi::intersects(embedded_box)))
210 space_cell->set_refine_flag();
211 space_triangulation.execute_coarsening_and_refinement();
212
213 // Make sure again we satisfy our criterion after the space
214 // refinement
215 refine();
216 }
217
218 embedded_triangulation.refine_global(
219 parameters.embedded_post_refinement_cycles);
220
221 // Check once again we satisfy our criterion, and record min/max
222 const auto [sm, sM, em, eM] = refine();
223
224
226 space_triangulation.get_communicator()) == 0)
227 std::cout << "Space local min/max diameters : " << sm << "/" << sM
228 << std::endl
229 << "Embedded space min/max diameters: " << em << "/" << eM
230 << std::endl;
231}
232
233
234
235#endif
ParameterAcceptor(const std::string &section_name="")
static ParameterHandler prm
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation="", ParameterHandler &prm_=prm, const Patterns::PatternBase &pattern=*Patterns::Tools::Convert< ParameterType >::to_pattern())
virtual types::global_cell_index n_global_active_cells() const
MPI_Comm get_communicator() const
void refine_global(const unsigned int times=1)
virtual void execute_coarsening_and_refinement()
#define Assert(cond, exc)
#define AssertThrow(cond, exc)
LogStream deallog
double diameter(const Triangulation< dim, spacedim > &tria)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned int space_pre_refinement_cycles
Definition utils.h:55
unsigned int embedded_pre_refinement_cycles
Definition utils.h:56
unsigned int space_post_refinement_cycles
Definition utils.h:53
double refinement_factor
Definition utils.h:57
int max_refinement_level
Definition utils.h:58
std::string refinement_strategy
Definition utils.h:52
unsigned int embedded_post_refinement_cycles
Definition utils.h:54
void adjust_grids(Triangulation< spacedim, spacedim > &space_triangulation, Triangulation< reduced_dim, spacedim > &embedded_triangulation, const RefinementParameters &parameters=RefinementParameters())
Definition utils.h:65