@@ -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 ); \
0 commit comments