Skip to content

Commit 2123527

Browse files
committed
address comments
1 parent 7152c5d commit 2123527

File tree

7 files changed

+100
-112
lines changed

7 files changed

+100
-112
lines changed

doc/sphinx/references.bib

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12202,6 +12202,20 @@ @article{vankeken:etal:2008
1220212202
doi = {10.1016/j.pepi.2008.04.015}
1220312203
}
1220412204

12205+
@Article{munch:globalcoarsening:2023,
12206+
author = {Peter Munch and Timo Heister and Laura Prieto Saavedra and Martin Kronbichler},
12207+
title = {Efficient Distributed Matrix-free Multigrid Methods on Locally Refined Meshes for {FEM} Computations},
12208+
journal = {{ACM} Transactions on Parallel Computing},
12209+
year = {2023},
12210+
volume = {10},
12211+
number = {1},
12212+
pages = {1--38},
12213+
month = mar,
12214+
doi = {10.1145/3580314},
12215+
publisher = {Association for Computing Machinery ({ACM})},
12216+
url = {https://arxiv.org/abs/2203.12292},
12217+
}
12218+
1220512219
@article{mulyukova:bercovici:2018,
1220612220
title={Collapse of passive margins by lithospheric damage and plunging grain size},
1220712221
author={Mulyukova, Elvira and Bercovici, David},

include/aspect/simulator/solver/matrix_free_operators.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,14 +358,16 @@ namespace aspect
358358
void clear () override;
359359

360360
/**
361-
*
361+
* Initialize the MatrixFree object given in @p mf_storage and use that to
362+
* initialize this operator.
362363
*/
363364
void reinit(const Mapping<dim> &mapping,
364365
const DoFHandler<dim> &dof_handler_v,
365366
const DoFHandler<dim> &dof_handler_p,
366367
const AffineConstraints<number> &constraints_v,
367368
const AffineConstraints<number> &constraints_p,
368-
std::shared_ptr<MatrixFree<dim,double>> mf_storage);
369+
std::shared_ptr<MatrixFree<dim,double>> mf_storage,
370+
const unsigned int level = numbers::invalid_unsigned_int);
369371

370372
/**
371373
* Pass in a reference to the problem data.
@@ -432,13 +434,16 @@ namespace aspect
432434
void clear () override;
433435

434436
/**
435-
*
437+
* Initialize the MatrixFree object given in @p mf_storage and use that to
438+
* initialize this operator.
436439
*/
437440
void reinit(const Mapping<dim> &mapping,
438-
const DoFHandler<dim> &dof_handler,
439-
const DoFHandler<dim> &dof_handler_other,
440-
const AffineConstraints<number> &constraints,
441-
std::shared_ptr<MatrixFree<dim,double>> mf_storage);
441+
const DoFHandler<dim> &dof_handler_v,
442+
const DoFHandler<dim> &dof_handler_p,
443+
const AffineConstraints<number> &constraints_v,
444+
const AffineConstraints<number> &constraints_p,
445+
std::shared_ptr<MatrixFree<dim,double>> mf_storage,
446+
const unsigned int level = numbers::invalid_unsigned_int);
442447
/**
443448
* Pass in a reference to the problem data.
444449
*/

source/simulator/core.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ namespace aspect
125125

126126
template <int dim>
127127
typename Triangulation<dim>::MeshSmoothing
128-
smoothing_flags(bool global_coarsening)
128+
smoothing_flags(const bool global_coarsening)
129129
{
130130
if (global_coarsening)
131131
return Triangulation<dim>::limit_level_difference_at_vertices;

source/simulator/parameters.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ namespace aspect
435435

436436
prm.declare_entry ("Stokes GMG type", "local smoothing",
437437
Patterns::Selection(StokesGMGType::pattern()),
438-
"local smoothing or global coarsening");
438+
"The choice of geometric multigrid, either 'local smoothing' (the default) "
439+
" or 'global coarsening'. Local smoothing (\\cite{clevenger:heister:2021}) "
440+
"has been extensively tested and works in many more situations, while "
441+
"global coarsening is shown to be up to 3x faster (\\cite{munch:globalcoarsening:2023}).");
439442

440443
prm.declare_entry ("Use direct solver for Stokes system", "false",
441444
Patterns::Bool(),
@@ -1117,7 +1120,7 @@ namespace aspect
11171120
prm.declare_entry ("Stabilization method", "entropy viscosity",
11181121
Patterns::Selection("entropy viscosity|SUPG"),
11191122
"Select the method for stabilizing the advection equation. The original "
1120-
"method implemented is 'entropy viscosity' as described in \\cite {kronbichler:etal:2012}. "
1123+
"method implemented is 'entropy viscosity' as described in \\cite{kronbichler:etal:2012}. "
11211124
"SUPG is currently experimental.");
11221125

11231126
prm.declare_entry ("List of compositional fields with disabled boundary entropy viscosity", "",

source/simulator/solver/matrix_free_operators.cc

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,13 @@ namespace aspect
483483
const DoFHandler<dim> &dof_handler_p,
484484
const AffineConstraints<number> &constraints_v,
485485
const AffineConstraints<number> &constraints_p,
486-
std::shared_ptr<MatrixFree<dim,double>> mf_storage)
486+
std::shared_ptr<MatrixFree<dim,double>> mf_storage,
487+
const unsigned int level)
487488
{
488489
typename MatrixFree<dim, number>::AdditionalData data;
489490
data.mapping_update_flags =
490491
update_quadrature_points /*| update_gradients*/ | update_values;
491-
data.mg_level = numbers::invalid_unsigned_int;
492+
data.mg_level = level;
492493

493494
data.tasks_parallel_scheme =
494495
MatrixFree<dim,double>::AdditionalData::none;
@@ -663,15 +664,16 @@ namespace aspect
663664
template <int dim, int degree_v, typename number>
664665
void
665666
MatrixFreeStokesOperators::ABlockOperator<dim,degree_v,number>::reinit(const Mapping<dim> &mapping,
666-
const DoFHandler<dim> &dof_handler,
667-
const DoFHandler<dim> &dof_handler_other,
668-
const AffineConstraints<number> &constraints,
669-
std::shared_ptr<MatrixFree<dim,double>> mf_storage)
667+
const DoFHandler<dim> &dof_handler_v,
668+
const DoFHandler<dim> &dof_handler_p,
669+
const AffineConstraints<number> &constraints_v,
670+
const AffineConstraints<number> &constraints_p,
671+
std::shared_ptr<MatrixFree<dim,double>> mf_storage,
672+
const unsigned int level)
670673
{
671674
typename MatrixFree<dim, number>::AdditionalData data;
672-
data.mapping_update_flags =
673-
update_quadrature_points | update_gradients | update_values;
674-
data.mg_level = numbers::invalid_unsigned_int;
675+
data.mapping_update_flags = update_quadrature_points | update_gradients | update_values;
676+
data.mg_level = level;
675677

676678
typename MatrixFree<dim,double>::AdditionalData additional_data;
677679
additional_data.tasks_parallel_scheme =
@@ -681,8 +683,8 @@ namespace aspect
681683

682684
AffineConstraints<number> dummy;
683685
mf_storage->reinit(mapping,
684-
std::vector< const DoFHandler< dim > *> {&dof_handler, &dof_handler_other},
685-
std::vector< const AffineConstraints< number > *> {&constraints, &dummy} ,
686+
std::vector< const DoFHandler< dim > *> {&dof_handler_v, &dof_handler_p},
687+
std::vector< const AffineConstraints< number > *> {&constraints_v, &constraints_p} ,
686688
QGauss<1>(degree_v+1), additional_data);
687689

688690
this->initialize(mf_storage, std::vector< unsigned int > {0}, std::vector< unsigned int > {0});

source/simulator/solver/stokes_matrix_free_global_coarsening.cc

Lines changed: 54 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ namespace aspect
145145
std::string
146146
StokesMatrixFreeHandlerGlobalCoarseningImplementation<dim, velocity_degree>::name () const
147147
{
148-
return "GC-GMG";
148+
return "GMG-GC";
149149
}
150150

151151

@@ -173,11 +173,10 @@ namespace aspect
173173
template <int dim, int velocity_degree>
174174
void StokesMatrixFreeHandlerGlobalCoarseningImplementation<dim, velocity_degree>::evaluate_material_model ()
175175
{
176-
sim.pcout << "evaluate_material_model()" << std::endl;
177176
const auto &dof_handler_projection = dofhandlers_projection.back();
178177

179178
dealii::LinearAlgebra::distributed::Vector<double> active_viscosity_vector(dof_handler_projection.locally_owned_dofs(),
180-
this->get_triangulation().get_communicator());
179+
this->get_mpi_communicator());
181180

182181
const Quadrature<dim> &quadrature_formula = this->introspection().quadratures.velocities;
183182

@@ -248,8 +247,8 @@ namespace aspect
248247
active_viscosity_vector.compress(VectorOperation::insert);
249248
}
250249

251-
minimum_viscosity = dealii::Utilities::MPI::min(minimum_viscosity_local, this->get_triangulation().get_communicator());
252-
maximum_viscosity = dealii::Utilities::MPI::max(maximum_viscosity_local, this->get_triangulation().get_communicator());
250+
minimum_viscosity = dealii::Utilities::MPI::min(minimum_viscosity_local, this->get_mpi_communicator());
251+
maximum_viscosity = dealii::Utilities::MPI::max(maximum_viscosity_local, this->get_mpi_communicator());
253252

254253
FEValues<dim> fe_values_projection (this->get_mapping(),
255254
fe_projection,
@@ -369,7 +368,7 @@ namespace aspect
369368
AffineConstraints<double> cs;
370369
std::shared_ptr<MatrixFree<dim,double>>
371370
mf(new MatrixFree<dim,double>());
372-
mf->reinit(*sim.mapping, dofhandlers_projection[l], cs, QGauss<1>(degree+1));
371+
mf->reinit(this->get_mapping(), dofhandlers_projection[l], cs, QGauss<1>(degree+1));
373372
temp_ops[l].initialize(mf);
374373
}
375374

@@ -380,9 +379,9 @@ namespace aspect
380379
temp_ops[l].initialize_dof_vector(vec);
381380
});
382381

383-
transfer.template interpolate_to_mg(dof_handler_projection,
384-
level_viscosity_vector,
385-
active_viscosity_vector);
382+
transfer.interpolate_to_mg(dof_handler_projection,
383+
level_viscosity_vector,
384+
active_viscosity_vector);
386385

387386
for (unsigned int level=min_level; level<=max_level; ++level)
388387
{
@@ -1454,14 +1453,6 @@ namespace aspect
14541453
if (solve_newton_system == false)
14551454
outputs.pressure_normalization_adjustment = this->normalize_pressure(solution_vector);
14561455

1457-
// convert melt pressures
1458-
// TODO: We assert in the StokesMatrixFreeHandler constructor that we
1459-
// are not including melt transport.
1460-
// TODO: We have to const_cast, because the compute_melt_variables
1461-
// function assembles and solves an equation. To avoid this we either
1462-
// have to hand over non-const references to the current function, or
1463-
// call the compute_melt_variables function after finishing the current function.
1464-
14651456
return outputs;
14661457
}
14671458

@@ -1489,16 +1480,16 @@ namespace aspect
14891480
}
14901481
}
14911482

1492-
have_periodic_hanging_nodes = (dealii::Utilities::MPI::max(have_periodic_hanging_nodes ? 1 : 0, this->get_triangulation().get_communicator())) == 1;
1483+
have_periodic_hanging_nodes = (dealii::Utilities::MPI::max(have_periodic_hanging_nodes ? 1 : 0, this->get_mpi_communicator())) == 1;
14931484
AssertThrow(have_periodic_hanging_nodes==false, ExcNotImplemented());
14941485
}
14951486

1496-
const Mapping<dim> &mapping = *sim.mapping;
1487+
const Mapping<dim> &mapping = this->get_mapping();
14971488

14981489
// This vector will be refilled with the new MatrixFree objects below:
14991490
matrix_free_objects.clear();
15001491

1501-
trias = dealii::MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence (sim.triangulation);
1492+
trias = dealii::MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence (this->get_triangulation());
15021493
min_level = 0;
15031494
max_level = trias.size() - 1;
15041495
constraints_v.resize(min_level, max_level);
@@ -1540,38 +1531,57 @@ namespace aspect
15401531
constraint.reinit(locally_relevant_dofs);
15411532
#endif
15421533

1543-
sim.compute_initial_velocity_boundary_constraints(constraint); // TODO: this can't work
1544-
sim.compute_current_velocity_boundary_constraints(constraint); // TODO: this can't work
15451534

1546-
for (const auto &p : sim.boundary_velocity_manager.get_zero_boundary_velocity_indicators())
1535+
std::set<types::boundary_id> dirichlet_boundary = this->get_boundary_velocity_manager().get_zero_boundary_velocity_indicators();
1536+
for (const auto boundary_id: this->get_boundary_velocity_manager().get_prescribed_boundary_velocity_indicators())
1537+
{
1538+
const ComponentMask component_mask = this->get_boundary_velocity_manager().get_component_mask(boundary_id);
1539+
1540+
if (component_mask != ComponentMask(this->introspection().n_components, false))
1541+
{
1542+
ComponentMask velocity_mask(fe_v.n_components(), false);
1543+
1544+
for (unsigned int i=0; i<dim; ++i)
1545+
velocity_mask.set(i, component_mask[this->introspection().component_indices.velocities[i]]);
1546+
1547+
VectorTools::interpolate_boundary_values (mapping,
1548+
dof_handler,
1549+
boundary_id,
1550+
Functions::ZeroFunction<dim>(dim),
1551+
constraint,
1552+
velocity_mask);
1553+
}
1554+
else
1555+
{
1556+
// no mask given: add at the end
1557+
dirichlet_boundary.insert(boundary_id);
1558+
}
1559+
}
1560+
1561+
1562+
for (const auto id : dirichlet_boundary)
15471563
{
15481564
VectorTools::interpolate_boundary_values (mapping,
15491565
dof_handler,
1550-
p,
1566+
id,
15511567
Functions::ZeroFunction<dim>(dim),
15521568
constraint);
1553-
15541569
}
15551570

15561571

1557-
// VectorTools::interpolate_boundary_values(
1558-
// mapping,
1559-
// dof_handler,
1560-
// 0,
1561-
// Functions::ZeroFunction<dim, typename LevelOperatorType::value_type>(
1562-
// dof_handler_in.get_fe().n_components()),
1563-
// constraint);
1564-
Assert(sim.boundary_velocity_manager.get_active_plugins().size() == 0,
1572+
Assert(this->get_boundary_velocity_manager().get_active_plugins().size() == 0,
15651573
ExcNotImplemented());
15661574

1567-
Assert(sim.boundary_velocity_manager.get_tangential_boundary_velocity_indicators().size() == 0,
1568-
ExcNotImplemented());
1569-
// VectorTools::compute_no_normal_flux_constraints (dof_handler_v,
1570-
// /* first_vector_component= */
1571-
// 0,
1572-
// sim.boundary_velocity_manager.get_tangential_boundary_velocity_indicators(),
1573-
// constraints_v,
1574-
// *sim.mapping);
1575+
if (this->get_boundary_velocity_manager().get_tangential_boundary_velocity_indicators().size() > 0)
1576+
{
1577+
Assert(false, dealii::StandardExceptions::ExcNotImplemented("This is not tested."));
1578+
VectorTools::compute_no_normal_flux_constraints (dof_handler,
1579+
0 /* first_vector_component */,
1580+
this->get_boundary_velocity_manager().get_tangential_boundary_velocity_indicators(),
1581+
constraint,
1582+
mapping);
1583+
1584+
}
15751585

15761586
DoFTools::make_hanging_node_constraints(dof_handler, constraint);
15771587
constraint.close();
@@ -1607,7 +1617,7 @@ namespace aspect
16071617

16081618
matrix_free = std::make_shared<MatrixFree<dim,double>>();
16091619
matrix_free_objects.push_back(matrix_free);
1610-
mg_matrices_A_block[l].reinit(mapping, dofhandlers_v[l], dofhandlers_p[l], constraints_v[l], matrix_free);
1620+
mg_matrices_A_block[l].reinit(mapping, dofhandlers_v[l], dofhandlers_p[l], constraints_v[l], constraints_p[l], matrix_free);
16111621

16121622
matrix_free = std::make_shared<MatrixFree<dim,double>>();
16131623
matrix_free_objects.push_back(matrix_free);
@@ -1625,52 +1635,6 @@ namespace aspect
16251635
}
16261636
}
16271637

1628-
1629-
1630-
// Multigrid DoF setup
1631-
#if 0
1632-
{
1633-
//Ablock GMG
1634-
dof_handler_v.distribute_mg_dofs();
1635-
1636-
mg_constrained_dofs_A_block.clear();
1637-
mg_constrained_dofs_A_block.initialize(dof_handler_v);
1638-
1639-
std::set<types::boundary_id> dirichlet_boundary = this->get_boundary_velocity_manager().get_zero_boundary_velocity_indicators();
1640-
for (const auto boundary_id: this->get_boundary_velocity_manager().get_prescribed_boundary_velocity_indicators())
1641-
{
1642-
const ComponentMask component_mask = this->get_boundary_velocity_manager().get_component_mask(boundary_id);
1643-
1644-
if (component_mask != ComponentMask(this->introspection().n_components, false))
1645-
{
1646-
ComponentMask velocity_mask(fe_v.n_components(), false);
1647-
1648-
for (unsigned int i=0; i<dim; ++i)
1649-
velocity_mask.set(i, component_mask[this->introspection().component_indices.velocities[i]]);
1650-
1651-
mg_constrained_dofs_A_block.make_zero_boundary_constraints(dof_handler_v, {boundary_id}, velocity_mask);
1652-
}
1653-
else
1654-
{
1655-
// no mask given: add at the end
1656-
dirichlet_boundary.insert(boundary_id);
1657-
}
1658-
}
1659-
1660-
// Unconditionally call this function, even if the set is empty. Otherwise, the data structure
1661-
// for boundary indices will not be created (if mesh has no Dirichlet conditions).
1662-
mg_constrained_dofs_A_block.make_zero_boundary_constraints(dof_handler_v, dirichlet_boundary);
1663-
1664-
//Schur complement matrix GMG
1665-
dof_handler_p.distribute_mg_dofs();
1666-
1667-
mg_constrained_dofs_Schur_complement.clear();
1668-
mg_constrained_dofs_Schur_complement.initialize(dof_handler_p);
1669-
1670-
dof_handler_projection.distribute_mg_dofs();
1671-
}
1672-
#endif
1673-
16741638
// Setup the matrix-free operators
16751639
std::shared_ptr<MatrixFree<dim,double>> matrix_free = std::make_shared<MatrixFree<dim,double>>();
16761640
matrix_free_objects.push_back(matrix_free);
@@ -1758,13 +1722,14 @@ namespace aspect
17581722
template <int dim, int velocity_degree>
17591723
void StokesMatrixFreeHandlerGlobalCoarseningImplementation<dim, velocity_degree>::build_preconditioner()
17601724
{
1761-
TimerOutput::Scope timer (this->get_computing_timer(), "Build Stokes preconditioner");
1725+
this->get_computing_timer().enter_subsection("Build Stokes preconditioner");
17621726

17631727
for (auto l = min_level; l <= max_level; ++l)
17641728
{
17651729
mg_matrices_Schur_complement[l].compute_diagonal();
17661730
mg_matrices_A_block[l].compute_diagonal();
17671731
}
1732+
this->get_computing_timer().leave_subsection("Build Stokes preconditioner");
17681733
}
17691734

17701735

0 commit comments

Comments
 (0)