Skip to content

Commit 1abea21

Browse files
authored
Merge pull request #6659 from gassmoeller/iterated_advection_no_stokes
Add Iterated advection, no stokes solver scheme
2 parents e983325 + c1cef73 commit 1abea21

File tree

20 files changed

+1192
-7732
lines changed

20 files changed

+1192
-7732
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
New: Added a new nonlinear solver scheme 'iterated Advection, no Stokes'
2+
that iterates the advection equation and uses a prescribed Stokes
3+
solution.
4+
<br>
5+
(Rene Gassmoeller, 2025/09/02)

include/aspect/parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ namespace aspect
7474
single_Advection_iterated_Stokes,
7575
single_Advection_iterated_defect_correction_Stokes,
7676
single_Advection_iterated_Newton_Stokes,
77+
iterated_Advection_no_Stokes,
7778
iterated_Advection_and_Stokes,
7879
iterated_Advection_and_defect_correction_Stokes,
7980
iterated_Advection_and_Newton_Stokes

include/aspect/simulator.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,19 @@ namespace aspect
575575
*/
576576
void solve_single_advection_iterated_newton_stokes (bool use_newton_iterations);
577577

578+
/**
579+
* This function implements one scheme for the various
580+
* steps necessary to assemble and solve the nonlinear problem.
581+
*
582+
* The `iterated Advection, no Stokes' scheme iterates the temperature and other
583+
* advection systems and instead of solving for the Stokes system,
584+
* a prescribed velocity and pressure are used."
585+
*
586+
* This function is implemented in
587+
* <code>source/simulator/solver_schemes.cc</code>.
588+
*/
589+
void solve_iterated_advection_no_stokes ();
590+
578591
/**
579592
* This function implements one scheme for the various
580593
* steps necessary to assemble and solve the nonlinear problem.

source/material_model/entropy_model.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace aspect
4545
// models splits temperature diffusion from entropy advection.
4646
switch (parameters.nonlinear_solver)
4747
{
48+
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_no_Stokes:
4849
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_Stokes:
4950
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_defect_correction_Stokes:
5051
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_Newton_Stokes:
@@ -76,7 +77,9 @@ namespace aspect
7677
CitationInfo::add("entropy");
7778

7879
AssertThrow (this->get_parameters().formulation_mass_conservation ==
79-
Parameters<dim>::Formulation::MassConservation::projected_density_field,
80+
Parameters<dim>::Formulation::MassConservation::projected_density_field ||
81+
this->get_parameters().nonlinear_solver == Parameters<dim>::NonlinearSolver::single_Advection_no_Stokes ||
82+
this->get_parameters().nonlinear_solver == Parameters<dim>::NonlinearSolver::iterated_Advection_no_Stokes,
8083
ExcMessage("The 'entropy model' material model was only tested with the "
8184
"'projected density field' approximation "
8285
"for the mass conservation equation, which is not selected."));

source/simulator/core.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,17 +378,18 @@ namespace aspect
378378
boundary_velocity_manager.parse_parameters (prm);
379379

380380
// Make sure we only have a prescribed Stokes plugin if needed
381-
if (parameters.nonlinear_solver == NonlinearSolver::single_Advection_no_Stokes)
381+
if (parameters.nonlinear_solver == NonlinearSolver::single_Advection_no_Stokes ||
382+
parameters.nonlinear_solver == NonlinearSolver::iterated_Advection_no_Stokes)
382383
{
383384
AssertThrow(prescribed_stokes_solution.get()!=nullptr,
384-
ExcMessage("For the 'single Advection, no Stokes' solver scheme you need to provide a Stokes plugin!")
385+
ExcMessage("For the selected nonlinear solver scheme you need to provide a prescribed Stokes plugin!")
385386
);
386387
}
387388
else
388389
{
389390
AssertThrow(prescribed_stokes_solution.get()==nullptr,
390391
ExcMessage("The prescribed stokes plugin you selected only works with the solver "
391-
"scheme 'single Advection, no Stokes'.")
392+
"scheme 'single Advection, no Stokes' or 'iterated Advection, no Stokes'.")
392393
);
393394
}
394395

@@ -872,6 +873,7 @@ namespace aspect
872873
case Parameters<dim>::NonlinearSolver::Kind::single_Advection_iterated_Stokes:
873874
case Parameters<dim>::NonlinearSolver::Kind::single_Advection_iterated_defect_correction_Stokes:
874875
case Parameters<dim>::NonlinearSolver::Kind::single_Advection_iterated_Newton_Stokes:
876+
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_no_Stokes:
875877
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_Stokes:
876878
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_defect_correction_Stokes:
877879
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_and_Newton_Stokes:
@@ -911,6 +913,7 @@ namespace aspect
911913

912914
case Parameters<dim>::NonlinearSolver::Kind::no_Advection_no_Stokes:
913915
case Parameters<dim>::NonlinearSolver::Kind::single_Advection_no_Stokes:
916+
case Parameters<dim>::NonlinearSolver::Kind::iterated_Advection_no_Stokes:
914917
return false;
915918
}
916919
Assert(false, ExcNotImplemented());
@@ -1981,6 +1984,12 @@ namespace aspect
19811984
break;
19821985
}
19831986

1987+
case NonlinearSolver::iterated_Advection_no_Stokes:
1988+
{
1989+
solve_iterated_advection_no_stokes();
1990+
break;
1991+
}
1992+
19841993
case NonlinearSolver::iterated_Advection_and_Stokes:
19851994
{
19861995
solve_iterated_advection_and_stokes();

source/simulator/helper_functions.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,14 +2577,15 @@ namespace aspect
25772577
+
25782578
"> is listed for a boundary condition, but is not used by the geometry model."));
25792579

2580-
if (parameters.nonlinear_solver == NonlinearSolver::single_Advection_no_Stokes)
2580+
if (parameters.nonlinear_solver == NonlinearSolver::single_Advection_no_Stokes ||
2581+
parameters.nonlinear_solver == NonlinearSolver::iterated_Advection_no_Stokes)
25812582
{
25822583
// make sure that there are no listed velocity boundary conditions
25832584
for (unsigned int i=0; i<4; ++i)
25842585
AssertThrow (boundary_indicator_lists[i].empty(),
2585-
ExcMessage ("With the solver scheme `single Advection, no Stokes', "
2586-
"one cannot set boundary conditions for velocity or traction, "
2587-
"but a boundary condition has been set."));
2586+
ExcMessage ("With the solver schemes `single Advection, no Stokes' or "
2587+
"'iterated Advection, no Stokes' one cannot set boundary conditions "
2588+
"for velocity or traction, but a boundary condition has been set."));
25882589
}
25892590
}
25902591

source/simulator/parameters.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ namespace aspect
216216
"single Advection, iterated Stokes|"
217217
"single Advection, iterated defect correction Stokes|"
218218
"single Advection, iterated Newton Stokes|"
219+
"iterated Advection, no Stokes|"
219220
"iterated Advection and Stokes|"
220221
"iterated Advection and defect correction Stokes|"
221222
"iterated Advection and Newton Stokes";
@@ -254,6 +255,10 @@ namespace aspect
254255
"the temperature and composition equations once at the beginning of each time step and "
255256
"then iterates out the solution of the Stokes equation, using Newton iterations for the "
256257
"Stokes system.\n"
258+
"The `iterated Advection, no Stokes' scheme iterates the temperature and other advection "
259+
"equations, and instead of solving for the Stokes system, a prescribed "
260+
"velocity and pressure are used. This is useful for kinematic models and advection benchmarks "
261+
"with nonlinear processes in the advection equations.\n"
257262
"The `iterated Advection and Stokes' scheme iterates out the nonlinearity "
258263
"by alternating the solution of the temperature, composition and Stokes systems.\n"
259264
"The `iterated Advection and defect correction Stokes' scheme iterates by alternating the "
@@ -1595,6 +1600,8 @@ namespace aspect
15951600
nonlinear_solver = NonlinearSolver::single_Advection_iterated_defect_correction_Stokes;
15961601
else if (solver_scheme == "single Advection, iterated Newton Stokes")
15971602
nonlinear_solver = NonlinearSolver::single_Advection_iterated_Newton_Stokes;
1603+
else if (solver_scheme == "iterated Advection, no Stokes")
1604+
nonlinear_solver = NonlinearSolver::iterated_Advection_no_Stokes;
15981605
else if (solver_scheme == "iterated Advection and Stokes")
15991606
nonlinear_solver = NonlinearSolver::iterated_Advection_and_Stokes;
16001607
else if (solver_scheme == "iterated Advection and defect correction Stokes")

source/simulator/solver_schemes.cc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,120 @@ namespace aspect
12221222

12231223

12241224

1225+
template <int dim>
1226+
void Simulator<dim>::solve_iterated_advection_no_stokes ()
1227+
{
1228+
double initial_temperature_residual = 0;
1229+
std::vector<double> initial_composition_residual (introspection.n_compositional_fields,0);
1230+
1231+
const unsigned int max_nonlinear_iterations =
1232+
(pre_refinement_step < parameters.initial_adaptive_refinement)
1233+
?
1234+
std::min(parameters.max_nonlinear_iterations,
1235+
parameters.max_nonlinear_iterations_in_prerefinement)
1236+
:
1237+
parameters.max_nonlinear_iterations;
1238+
1239+
SolverControl nonlinear_solver_control(max_nonlinear_iterations,
1240+
parameters.nonlinear_tolerance);
1241+
1242+
double relative_residual = std::numeric_limits<double>::max();
1243+
nonlinear_iteration = 0;
1244+
1245+
do
1246+
{
1247+
for (auto &particle_manager : particle_managers)
1248+
{
1249+
// Restore particles through stored copy of particle handler,
1250+
// but only if they have already been displaced in a nonlinear
1251+
// iteration (in the assemble_and_solve_composition call).
1252+
if (nonlinear_iteration > 0)
1253+
particle_manager.restore_particles();
1254+
1255+
// Apply a particle update if required by the particle properties.
1256+
// Apply the update even if nonlinear_iteration == 0,
1257+
// because the signal could be used, for example, to apply operator
1258+
// splitting on the particles, and this would need to be
1259+
// applied at the beginning of the timestep and after
1260+
// every restore_particles().
1261+
signals.post_restore_particles(particle_manager);
1262+
}
1263+
1264+
const double relative_temperature_residual =
1265+
assemble_and_solve_temperature(initial_temperature_residual,
1266+
nonlinear_iteration == 0 ? &initial_temperature_residual : nullptr);
1267+
1268+
const std::vector<double> relative_composition_residual =
1269+
assemble_and_solve_composition(initial_composition_residual,
1270+
nonlinear_iteration == 0 ? &initial_composition_residual : nullptr);
1271+
1272+
// write the residual output in the same order as the solutions
1273+
pcout << " Relative nonlinear residuals (temperature"
1274+
<< (introspection.n_compositional_fields > 0 ? ", compositional fields" : "")
1275+
<< "): "
1276+
<< relative_temperature_residual;
1277+
for (unsigned int c=0; c<introspection.n_compositional_fields; ++c)
1278+
pcout << ", " << relative_composition_residual[c];
1279+
pcout << std::endl;
1280+
1281+
// Find the maximum residual of the individual equations
1282+
relative_residual = relative_temperature_residual;
1283+
for (unsigned int c=0; c<introspection.n_compositional_fields; ++c)
1284+
relative_residual = std::max(relative_composition_residual[c],relative_residual);
1285+
1286+
pcout << " Relative nonlinear residual (total system) after nonlinear iteration " << nonlinear_iteration+1
1287+
<< ": " << relative_residual
1288+
<< std::endl
1289+
<< std::endl;
1290+
1291+
if (parameters.run_postprocessors_on_nonlinear_iterations)
1292+
postprocess ();
1293+
1294+
++nonlinear_iteration;
1295+
}
1296+
while (nonlinear_solver_control.check(nonlinear_iteration, relative_residual) == SolverControl::iterate);
1297+
1298+
// Assign Stokes solution
1299+
{
1300+
TimerOutput::Scope timer (computing_timer, "Interpolate Stokes solution");
1301+
1302+
LinearAlgebra::BlockVector distributed_stokes_solution (introspection.index_sets.system_partitioning, mpi_communicator);
1303+
1304+
VectorFunctionFromVectorFunctionObject<dim> func(
1305+
[&](const Point<dim> &p, Vector<double> &result)
1306+
{
1307+
prescribed_stokes_solution->stokes_solution(p, result);
1308+
},
1309+
0,
1310+
parameters.include_melt_transport ? 2*dim+3 : dim+1, // velocity and pressure
1311+
introspection.n_components);
1312+
1313+
VectorTools::interpolate (*mapping, dof_handler, func, distributed_stokes_solution);
1314+
1315+
// distribute hanging node and other constraints
1316+
current_constraints.distribute (distributed_stokes_solution);
1317+
1318+
solution.block(introspection.block_indices.velocities) =
1319+
distributed_stokes_solution.block(introspection.block_indices.velocities);
1320+
solution.block(introspection.block_indices.pressure) =
1321+
distributed_stokes_solution.block(introspection.block_indices.pressure);
1322+
1323+
if (parameters.include_melt_transport)
1324+
{
1325+
const unsigned int block_u_f = introspection.variable("fluid velocity").block_index;
1326+
const unsigned int block_p_f = introspection.variable("fluid pressure").block_index;
1327+
solution.block(block_u_f) = distributed_stokes_solution.block(block_u_f);
1328+
solution.block(block_p_f) = distributed_stokes_solution.block(block_p_f);
1329+
}
1330+
1331+
}
1332+
1333+
AssertThrow(nonlinear_solver_control.last_check() != SolverControl::failure, ExcNonlinearSolverNoConvergence());
1334+
signals.post_nonlinear_solver(nonlinear_solver_control);
1335+
}
1336+
1337+
1338+
12251339
template <int dim>
12261340
void Simulator<dim>::solve_iterated_advection_and_stokes ()
12271341
{
@@ -1490,6 +1604,7 @@ namespace aspect
14901604
template void Simulator<dim>::solve_single_advection_iterated_stokes(); \
14911605
template void Simulator<dim>::solve_single_advection_iterated_defect_correction_stokes(); \
14921606
template void Simulator<dim>::solve_single_advection_iterated_newton_stokes(bool); \
1607+
template void Simulator<dim>::solve_iterated_advection_no_stokes(); \
14931608
template void Simulator<dim>::solve_iterated_advection_and_stokes(); \
14941609
template void Simulator<dim>::solve_iterated_advection_and_defect_correction_stokes(); \
14951610
template void Simulator<dim>::solve_iterated_advection_and_newton_stokes(bool); \

tests/entropy_multicomponent_11_edge_case.prm

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ set Use years instead of seconds = true
1111
set End time = 4e6
1212
set Maximum time step = 2e5
1313
set Output directory = output-entropy-multi-edge-case-change-adiabatic-p
14-
set Nonlinear solver scheme = iterated Advection and Stokes
14+
set Nonlinear solver scheme = iterated Advection, no Stokes
1515
set Use operator splitting = true
1616

1717
subsection Solver parameters
@@ -22,13 +22,6 @@ subsection Solver parameters
2222
end
2323
end
2424

25-
set Surface pressure = 1.2e9
26-
set Pressure normalization = volume
27-
28-
subsection Formulation
29-
set Mass conservation = projected density field
30-
end
31-
3225
subsection Geometry model
3326
set Model name = box
3427

@@ -41,14 +34,12 @@ end
4134

4235
subsection Adiabatic conditions model
4336
subsection Compute profile
44-
4537
set Use surface condition function = true
4638

4739
subsection Surface condition function
48-
set Variable names = x,t
49-
set Function expression = 1.2e9+4e2*t;0
40+
set Variable names = x,t
41+
set Function expression = 1.2e9+4e2*t;0
5042
end
51-
5243
end
5344
end
5445

@@ -65,10 +56,6 @@ subsection Compositional fields
6556
set Compositional field methods = field, field, field, prescribed field
6657
end
6758

68-
subsection Boundary velocity model
69-
set Tangential velocity boundary indicators = left, right, top, bottom
70-
end
71-
7259
subsection Gravity model
7360
set Model name = vertical
7461

@@ -81,10 +68,8 @@ subsection Initial composition model
8168
set List of model names = function
8269

8370
subsection Function
84-
8571
set Function expression = 0.3; 1610; 2006; 0.0
86-
87-
end
72+
end
8873
end
8974

9075
subsection Material model
@@ -110,6 +95,19 @@ subsection Mesh refinement
11095
set Time steps between mesh refinement = 0
11196
end
11297

98+
subsection Prescribed Stokes solution
99+
set Model name = function
100+
101+
# The same function as we use for the adiabatic pressure
102+
subsection Pressure function
103+
set Function expression = 1.2e9+4e2*t
104+
end
105+
106+
subsection Velocity function
107+
set Function expression = 0.0; 0.0
108+
end
109+
end
110+
113111
subsection Postprocess
114112
set List of postprocessors = visualization, velocity statistics, temperature statistics, mass flux statistics, composition statistics
115113

0 commit comments

Comments
 (0)