-
Notifications
You must be signed in to change notification settings - Fork 267
Expand file tree
/
Copy pathparameters.cc
More file actions
2477 lines (2287 loc) · 161 KB
/
parameters.cc
File metadata and controls
2477 lines (2287 loc) · 161 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Copyright (C) 2011 - 2024 by the authors of the ASPECT code.
This file is part of ASPECT.
ASPECT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
ASPECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ASPECT; see the file LICENSE. If not see
<http://www.gnu.org/licenses/>.
*/
#include <aspect/simulator.h>
#include <aspect/global.h>
#include <aspect/utilities.h>
#include <aspect/melt.h>
#include <aspect/volume_of_fluid/handler.h>
#include <aspect/simulator/solver/stokes_matrix_free.h>
#include <aspect/newton.h>
#include <aspect/mesh_deformation/free_surface.h>
#include <deal.II/base/parameter_handler.h>
#include <boost/lexical_cast.hpp>
#include <cstdlib>
#include <regex>
#include <sys/stat.h>
namespace aspect
{
template <int dim>
Parameters<dim>::Parameters (ParameterHandler &prm,
const MPI_Comm mpi_communicator)
{
parse_parameters (prm, mpi_communicator);
}
template <int dim>
void
Parameters<dim>::
declare_parameters (ParameterHandler &prm, const unsigned int mpi_rank)
{
prm.declare_entry ("Dimension", "2",
Patterns::Integer (2,3),
"The number of space dimensions you want to run this program in. "
"ASPECT can run in 2 and 3 space dimensions.");
prm.declare_entry ("Additional shared libraries", "",
Patterns::List (Patterns::FileName()),
"A list of names of additional shared libraries that should be loaded "
"upon starting up the program. The names of these files can contain absolute "
"or relative paths (relative to the directory in which you call ASPECT). "
"In fact, file names that do not contain any directory "
"information (i.e., only the name of a file such as <libmyplugin.so> "
"will not be found if they are not located in one of the directories "
"listed in the \\texttt{LD_LIBRARY_PATH} environment variable. In order "
"to load a library in the current directory, use <./libmyplugin.so> "
"instead."
"\n\n"
"If you specify <./libmyplugin.so>, ASPECT will open either "
"<./libmyplugin.debug.so> or <./libmyplugin.release.so> "
"depending on the current ASPECT build type."
"\n\n"
"The typical use of this parameter is so that you can implement "
"additional plugins in your own directories, rather than in the ASPECT "
"source directories. You can then simply compile these plugins into a "
"shared library without having to re-compile all of ASPECT. See the "
"section of the manual discussing writing extensions for more "
"information on how to compile additional files into a shared "
"library.");
prm.declare_entry ("Resume computation", "false",
Patterns::Selection ("true|false|auto"),
"A flag indicating whether the computation should be resumed from "
"a previously saved state (if true) or start from scratch (if false). "
"If auto is selected, models will be resumed if there is an existing "
"checkpoint file, otherwise started from scratch.");
prm.declare_entry ("Max nonlinear iterations", "10",
Patterns::Integer (1),
"The maximal number of nonlinear iterations to be performed.");
prm.declare_entry ("Max nonlinear iterations in pre-refinement", boost::lexical_cast<std::string>(std::numeric_limits<int>::max()),
Patterns::Integer (0),
"The maximal number of nonlinear iterations to be performed in the pre-refinement "
"steps. This does not include the last refinement step before moving to timestep 1. "
"When this parameter has a larger value than max nonlinear iterations, the latter is used.");
prm.declare_entry ("Start time", "0.",
Patterns::Double (),
"The start time of the simulation. Units: Years if the "
"'Use years instead of seconds' parameter is set; "
"seconds otherwise.");
prm.declare_entry ("Timing output frequency", "100",
Patterns::Integer(0),
"How frequently in timesteps to output timing information. This is "
"generally adjusted only for debugging and timing purposes. If the "
"value is set to zero it will also output timing information at the "
"initiation timesteps.");
prm.declare_entry ("Use years instead of seconds", "true",
Patterns::Bool (),
"When computing results for mantle convection simulations, "
"it is often difficult to judge the order of magnitude of results "
"when they are stated in MKS units involving seconds. Rather, "
"some kinds of results such as velocities are often stated in "
"terms of meters per year (or, sometimes, centimeters per year). "
"On the other hand, for non-dimensional computations, one wants "
"results in their natural unit system as used inside the code. "
"If this flag is set to `true' conversion to years happens; if "
"it is `false', no such conversion happens."
"\n\n"
"Contrary to the word ``output'' in the name of this parameter, "
"a number of plugins also use this parameter to determine "
"how to interpret their \\textit{inputs}. For example, when `true', "
"several of the boundary velocity models described in Section~"
"\\ref{parameters:Boundary_20velocity_20model} interpret both "
"specific times in years instead of seconds, and velocities in "
"meters per year instead of meters per second."
"\n\n"
"For the purposes of this parameter, a year consists of "
"60*60*24*365.2425 seconds. In other words, a year is taken "
"to have 365.2425 days.");
prm.declare_alias ("Use years instead of seconds",
"Use years in output instead of seconds",
(mpi_rank == 0) ? true : false); // trigger deprecation warning
prm.declare_entry ("CFL number", "1.0",
Patterns::Double (0.),
"In computations, the time step $k$ is chosen according to "
"$k = c \\min_K \\frac {h_K} {\\|u\\|_{\\infty,K} p_T}$ where $h_K$ is the "
"diameter of cell $K$, and the denominator is the maximal magnitude "
"of the velocity on cell $K$ times the polynomial degree $p_T$ of the "
"temperature discretization. The dimensionless constant $c$ is called the "
"CFL number in this program. For time discretizations that have explicit "
"components, $c$ must be less than a constant that depends on the "
"details of the time discretization and that is no larger than one. "
"On the other hand, for implicit discretizations such as the one chosen "
"here, one can choose the time step as large as one wants (in particular, "
"one can choose $c>1$) though a CFL number significantly larger than "
"one will yield rather diffusive solutions. Units: None.");
prm.declare_entry ("Maximum time step",
/* boost::lexical_cast<std::string>(std::numeric_limits<double>::max() /
year_in_seconds) = */ "5.69e+300",
Patterns::Double (0.),
"Set a maximum time step size for the solver to use. Generally the time step "
"based on the CFL number should be sufficient, but for complicated models "
"or benchmarking it may be useful to limit the time step to some value. "
"The default value is a value so that when converted from years into seconds "
"it equals the largest number representable by a floating "
"point number, implying an unlimited time step."
"Units: Years or seconds, depending on the ``Use years instead of seconds'' parameter.");
prm.declare_entry ("Maximum first time step",
/* boost::lexical_cast<std::string>(std::numeric_limits<double>::max() /
year_in_seconds) = */ "5.69e+300",
Patterns::Double (0.),
"Set a maximum time step size for only the first timestep. Generally the time step "
"based on the CFL number should be sufficient, but for complicated models "
"or benchmarking it may be useful to limit the first time step to some value, "
"especially when using the free surface, which needs to settle to prevent "
"instabilities. This should in that case be combined with a value set for "
"``Maximum relative increase in time step''. "
"The default value is a value so that when converted from years into seconds "
"it equals the largest number representable by a floating "
"point number, implying an unlimited time step. "
"Units: Years or seconds, depending on the ``Use years instead of seconds'' parameter.");
prm.declare_entry ("Maximum relative increase in time step",
"91.0",
Patterns::Double (0.),
"Set a percentage with which the length of the time step is limited to increase. Generally the "
"time step based on the CFL number should be sufficient, but for complicated models "
"which may suddenly drastically change behavior, it may be useful to limit the increase "
"in the time step, without limiting the time step size of the whole simulation to a "
"particular number. For example, if this parameter is set to $50$, then that means that "
"the length of a time step can at most increase by 50\\% from one time step to the next, or by a "
"factor of 1.5. "
"\n\n"
"Here, the default value is set to be 91\\% because the best available step-size ratio bound "
"guaranteeing stability in the PDE context seems to be 1.91, see \\cite{Denner:2014}. "
"In that thesis, the bound was proved in the context of semilinear parabolic problem, "
"but it appears reasonable to also use this value as an upper bound in the current "
"context."
"\n\n"
"Units: \\%.");
prm.declare_entry ("Use conduction timestep", "false",
Patterns::Bool (),
"Mantle convection simulations are often focused on convection "
"dominated systems. However, these codes can also be used to "
"investigate systems where heat conduction plays a dominant role. "
"This parameter indicates whether the simulator should also use "
"heat conduction in determining the length of each time step.");
const std::string allowed_solver_schemes = "no Advection, no Stokes|"
"no Advection, single Stokes|"
"no Advection, single Stokes first timestep only|"
"first timestep only, single Stokes|" // deprecated: use "no Advection, single Stokes first timestep only" instead
"no Advection, iterated Stokes|"
"no Advection, iterated defect correction Stokes|"
"single Advection, no Stokes|"
"single Advection, single Stokes|"
"single Advection, iterated Stokes|"
"single Advection, iterated defect correction Stokes|"
"single Advection, iterated Newton Stokes|"
"iterated Advection, no Stokes|"
"iterated Advection and Stokes|"
"iterated Advection and defect correction Stokes|"
"iterated Advection and Newton Stokes";
prm.declare_entry ("Nonlinear solver scheme", "single Advection, single Stokes",
Patterns::Selection (allowed_solver_schemes),
"The kind of scheme used to resolve the nonlinearity in the system of equations:\n\n"
"The `no Advection, no Stokes' scheme solves no equations. This "
"is useful to investigate the initial and boundary conditions of the model.\n"
"The `no Advection, single Stokes' scheme only solves the Stokes system once per "
"timestep. This is mostly useful for instantaneous models and Stokes benchmarks.\n"
"The `no Advection, single Stokes first timestep only' scheme solves the Stokes equations exactly "
"once, at the first time step. No nonlinear iterations are done, and the temperature and "
"composition systems are not solved.\n"
"The `no Advection, iterated Stokes' scheme only solves the Stokes system, iterating "
"out the solution, and does not solve the compositions and the temperature equation. "
"This is mostly useful for instantaneous models and benchmarks with stress-dependent rheology.\n"
"The `no Advection, iterated defect correction Stokes' scheme solves "
"the temperature and composition equations once at the beginning of each time step and "
"then iterates out the solution of the Stokes equation, using defect correction Picard "
"iterations for the Stokes system.\n"
"The `single Advection, no Stokes' scheme solves the temperature and other advection "
"systems once per timestep, and instead of solving for the Stokes system, a prescribed "
"velocity and pressure is used. This is useful for kinematic models and advection benchmarks.\n"
"The `single Advection, single Stokes' solver scheme performs no nonlinear iterations, "
"and the temperature, compositional fields and Stokes equations are solved exactly "
"once per time step, one after the other. This is the default solver scheme.\n"
"The `single Advection, iterated Stokes' scheme solves the temperature and composition "
"equation once at the beginning of each time step and then iterates out the solution of "
"the Stokes equation.\n"
"The `single Advection, iterated defect correction Stokes' scheme solves "
"the temperature and composition equations once at the beginning of each time step and "
"then iterates out the solution of the Stokes equation, using defect correction Picard "
"iterations for the Stokes system.\n"
"The `single Advection, iterated Newton Stokes' scheme solves "
"the temperature and composition equations once at the beginning of each time step and "
"then iterates out the solution of the Stokes equation, using Newton iterations for the "
"Stokes system.\n"
"The `iterated Advection, no Stokes' scheme iterates the temperature and other advection "
"equations, and instead of solving for the Stokes system, a prescribed "
"velocity and pressure are used. This is useful for kinematic models and advection benchmarks "
"with nonlinear processes in the advection equations.\n"
"The `iterated Advection and Stokes' scheme iterates out the nonlinearity "
"by alternating the solution of the temperature, composition and Stokes systems.\n"
"The `iterated Advection and defect correction Stokes' scheme iterates by alternating the "
"solution of the temperature, composition and Stokes equations, using Picard iterations for "
"the temperature and composition, and defect correction Picard iterations for the Stokes system.\n"
"The `iterated Advection and Newton Stokes' scheme iterates by alternating the solution "
"of the temperature, composition and Stokes equations, using Picard iterations for the "
"temperature and composition, and Newton iterations for the Stokes system.");
prm.declare_entry ("Nonlinear solver failure strategy", "continue with next timestep",
Patterns::Selection("continue with next timestep|cut timestep size|abort program"),
"Select the strategy on what to do if the nonlinear solver scheme fails to "
"converge. The options are:\n"
"`continue with next timestep`: ignore error and continue to the next timestep\n"
"`cut timestep size`: reduce the current timestep size by a specified factor and redo "
"the timestep\n"
"`abort program`: abort the program with an error message.");
prm.declare_entry ("Nonlinear solver tolerance", "1e-5",
Patterns::Double(0., 1.),
"A relative tolerance up to which the nonlinear solver will iterate. "
"This parameter is only relevant if the `Nonlinear solver scheme' does nonlinear "
"iterations, in other words, if it is set to something other than "
"`single Advection, single Stokes' or `single Advection, no Stokes'.");
prm.declare_entry ("Pressure normalization", "surface",
Patterns::Selection ("surface|volume|no"),
"If and how to normalize the pressure after the solution step. "
"This is necessary because depending on boundary conditions, "
"in many cases the pressure is only determined by the model "
"up to a constant. On the other hand, we often would like to "
"have a well-determined pressure, for example for "
"table lookups of material properties in models "
"or for comparing solutions. If the given value is `surface', then "
"normalization at the end of each time steps adds a constant value "
"to the pressure in such a way that the average pressure at the surface "
"of the domain is what is set in the `Surface pressure' parameter; "
"the surface of the domain is determined by asking "
"the geometry model whether a particular face of the geometry has a zero "
"or small `depth'. If the value of this parameter is `volume' then the "
"pressure is normalized so that the domain average is zero. If `no' is "
"given, the no pressure normalization is performed.");
prm.declare_entry ("Surface pressure", "0.",
Patterns::Double(),
"The value the pressure is normalized to in each time step when "
"`Pressure normalization' is set to `surface' with default value 0. "
"This setting is ignored in all other cases."
"\n\n"
"The mathematical equations that describe thermal convection "
"only determine the pressure up to an arbitrary constant. On "
"the other hand, for comparison and for looking up material "
"parameters it is important that the pressure be normalized "
"somehow. We do this by enforcing a particular average pressure "
"value at the surface of the domain, where the geometry model "
"determines where the surface is. This parameter describes what "
"this average surface pressure value is supposed to be. By "
"default, it is set to zero, but one may want to choose a "
"different value for example for simulating only the volume "
"of the mantle below the lithosphere, in which case the surface "
"pressure should be the lithostatic pressure at the bottom "
"of the lithosphere."
"\n\n"
"For more information, see the section in the manual that discusses "
"the general mathematical model.");
prm.declare_entry ("Adiabatic surface temperature", "0.",
Patterns::Double(),
"In order to make the problem in the first time step easier to "
"solve, we need a reasonable guess for the temperature and pressure. "
"To obtain it, we use an adiabatic pressure and temperature field. "
"This parameter describes what the `adiabatic' temperature would "
"be at the surface of the domain (i.e. at depth zero). Note "
"that this value need not coincide with the boundary condition "
"posed at this point. Rather, the boundary condition may differ "
"significantly from the adiabatic value, and then typically "
"induce a thermal boundary layer."
"\n\n"
"For more information, see the section in the manual that discusses "
"the general mathematical model.");
prm.declare_entry ("Output directory", "output",
Patterns::DirectoryName(),
"The name of the directory into which all output files should be "
"placed. This may be an absolute or a relative path. ASPECT will "
"write output such as statistics files or visualization files "
"into this directory or into directories further nested within.");
prm.declare_entry ("Output directory LFS stripe count", "0",
Patterns::Integer(0),
"Many large clusters use the Lustre file system (LFS) that allows to 'stripe' "
"files, i.e., to use multiple file servers to store a single file. This is "
"useful when writing very large files from multiple MPI processes, such "
"as when creating graphical output or creating checkpoints. In those "
"cases, if all MPI processes try to route their data to a single file "
"server, that file server and the disks it manages may be saturated by "
"data and everything slows down. File striping instead ensures that the "
"data is sent to several file servers, improving performance. A "
"description of how Lustre manages file striping can be found at "
"https://doc.lustre.org/lustre_manual.xhtml#managingstripingfreespace . "
"How file striping can be configured is discussed at "
"https://wiki.lustre.org/Configuring_Lustre_File_Striping ."
"\n\n"
"When this parameter is set to anything other than zero, "
"ASPECT will call the Lustre support tool, `lst`, as follows: "
"`lst setstripe -c N OUTPUT_DIR`, where `N` is the value of the "
"input parameter discussed here, and `OUTPUT_DIR` is the directory "
"into which ASPECT writes its output. The file striping so set on "
"the output directory are also inherited by the sub-directories "
"ASPECT creates within it."
"\n\n"
"In order to use this parameter, your cluster must obviously be "
"using the Lustre file system. What the correct value for the stripe "
"count is is something you will have to find out from your cluster's "
"local documentation, or your cluster administrator. It depends on "
"the physical details and configuration of the file servers attached "
"to a cluster.");
prm.declare_entry ("Use operator splitting", "false",
Patterns::Bool(),
"If set to true, the advection and reactions of compositional fields and "
"temperature are solved separately, and can use different time steps. Note that "
"this will only work if the material/heating model fills the reaction\\_rates/"
"heating\\_reaction\\_rates structures. Operator splitting can be used with any "
"existing solver schemes that solve the temperature/composition equations.");
prm.declare_entry ("World builder file", "",
Patterns::FileName(),
"Name of the world builder file. If empty, the world builder is not initialized.");
prm.enter_subsection ("Particles");
{
prm.declare_entry ("Number of particle systems", "1",
Patterns::Integer(0, ASPECT_MAX_NUM_PARTICLE_SYSTEMS),
"The number of particle systems to be created. The maximum number of particle systems "
"is set by the CMake variable `ASPECT_MAX_NUM_PARTICLE_SYSTEMS` and is by default 2.");
}
prm.leave_subsection();
prm.enter_subsection ("Solver parameters");
{
prm.declare_entry ("Temperature solver tolerance", "1e-12",
Patterns::Double(0., 1.),
"The relative tolerance up to which the linear system for "
"the temperature system gets solved. See `Stokes solver "
"parameters/Linear solver tolerance' for more details.");
prm.declare_entry ("Composition solver tolerance", "1e-12",
Patterns::Double(0., 1.),
"The relative tolerance up to which the linear system for "
"the composition system gets solved. See `Stokes solver "
"parameters/Linear solver tolerance' for more details.");
prm.enter_subsection ("Advection solver parameters");
{
prm.declare_entry ("GMRES solver restart length", "50",
Patterns::Integer(1),
"This is the number of iterations that define the "
"GMRES solver restart length. Increasing this "
"parameter makes the solver more robust and decreases "
"the number of iterations. Be aware that "
"increasing this number increases the memory usage "
"of the advection solver, and makes individual "
"iterations more expensive.");
}
prm.leave_subsection();
prm.enter_subsection ("Stokes solver parameters");
{
prm.declare_entry ("Stokes solver type", "default solver",
Patterns::Selection(StokesSolverType::pattern()),
"This is the type of solver used on the Stokes system. The block geometric "
"multigrid solver currently has a limited implementation and therefore "
"may trigger Asserts in the code when used. If this is the case, "
"please switch to 'block AMG'. Additionally, the block GMG solver requires "
"using material model averaging. The 'default solver' chooses "
"the geometric multigrid solver if supported, otherwise the AMG solver.");
prm.declare_entry ("Stokes GMG type", "local smoothing",
Patterns::Selection(StokesGMGType::pattern()),
"The choice of geometric multigrid, either 'local smoothing' (the default) "
" or 'global coarsening'. Local smoothing (\\cite{clevenger:heister:2021}) "
"has been extensively tested and works in many more situations, while "
"global coarsening is shown to be up to 3x faster (\\cite{munch:globalcoarsening:2023}).");
prm.declare_entry ("Use direct solver for Stokes system", "false",
Patterns::Bool(),
"If set to true the linear system for the Stokes equation will "
"be solved using Trilinos klu, otherwise an iterative Schur "
"complement solver is used. The direct solver is only efficient "
"for small problems.");
prm.declare_entry ("Use weighted BFBT for Schur complement", "false",
Patterns::Bool(),
"If set to true, the Schur complement approximation in the Block preconditioner "
"uses the weighted BFBT preconditioner, otherwise a weighted mass matrix will "
"be used. The BFBT preconditioner is more expensive, but works better for large "
"viscosity variations.");
prm.declare_entry ("Krylov method for cheap solver steps", "GMRES",
Patterns::Selection(StokesKrylovType::pattern()),
"This is the Krylov method used to solve the Stokes system. Both options, GMRES "
"and IDR(s), solve non-symmetric, indefinite systems. GMRES "
"guarantees the residual will be reduced in each iteration while IDR(s) has "
"no such property. On the other hand, the vector storage requirement for GMRES is "
"dependent on the restart length and can be quite restrictive (since, for "
"the matrix-free GMG solver, memory is dominated by these vectors) whereas "
"IDR(s) has a short term recurrence. "
"Note that the IDR(s) Krylov method is not available for the AMG solver since "
"it is not a flexible method, i.e., it cannot handle a preconditioner which "
"may change in each iteration (the AMG-based preconditioner contains a CG solve "
"in the pressure space which may have different number of iterations each step).");
prm.declare_entry ("IDR(s) parameter", "2",
Patterns::Integer(1),
"This is the sole parameter for the IDR(s) Krylov solver and will dictate the "
"number of matrix-vector products and preconditioner applications per iteration (s+1) "
"and the total number of temporary vectors required (5+3*s). For s=1, this method is "
"analogous to BiCGStab. As s is increased this method is expected to converge to "
"GMRES in terms of matrix-vector/preconditioner applications to solution.");
prm.declare_entry ("Linear solver tolerance", "1e-7",
Patterns::Double(0., 1.),
"A relative tolerance up to which the linear Stokes systems in each "
"time or nonlinear step should be solved. The absolute tolerance will "
"then be $\\| M x_0 - F \\| \\cdot \\text{tol}$, where $x_0 = (0,p_0)$ "
"is the initial guess of the pressure, $M$ is the system matrix, "
"$F$ is the right-hand side, and tol is the parameter specified here. "
"We include the initial guess of the pressure "
"to remove the dependency of the tolerance on the static pressure. "
"A given tolerance value of 1 would "
"mean that a zero solution vector is an acceptable solution "
"since in that case the norm of the residual of the linear "
"system equals the norm of the right hand side. A given "
"tolerance of 0 would mean that the linear system has to be "
"solved exactly, since this is the only way to obtain "
"a zero residual."
"\n\n"
"In practice, you should choose the value of this parameter "
"to be so that if you make it smaller the results of your "
"simulation do not change any more (qualitatively) whereas "
"if you make it larger, they do. For most cases, the default "
"value should be sufficient. In fact, a tolerance of 1e-4 "
"might be accurate enough.");
prm.declare_entry ("Number of cheap Stokes solver steps", "1000",
Patterns::Integer(0),
"As explained in the paper that describes ASPECT (Kronbichler, Heister, and Bangerth, "
"2012, see \\cite{kronbichler:etal:2012}) we first try to solve the Stokes system in every "
"time step using a GMRES iteration with a poor but cheap "
"preconditioner. By default, we try whether we can converge the GMRES "
"solver in 200 such iterations before deciding that we need a better "
"preconditioner. This is sufficient for simple problems with variable "
"viscosity and we never need the second phase with the more expensive "
"preconditioner. On the other hand, for more complex problems, and in "
"particular for problems with strongly nonlinear viscosity, the 200 "
"cheap iterations don't actually do very much good and one might skip "
"this part right away. In that case, this parameter can be set to "
"zero, i.e., we immediately start with the better but more expensive "
"preconditioner.");
prm.declare_entry ("Maximum number of expensive Stokes solver steps", "1000",
Patterns::Integer(0),
"This sets the maximum number of iterations used in the expensive Stokes solver. "
"If this value is set too low for the size of the problem, the Stokes solver will "
"not converge and return an error message pointing out that the user didn't allow "
"a sufficiently large number of iterations for the iterative solver to converge.");
prm.declare_entry ("GMRES solver restart length", "100",
Patterns::Integer(1),
"This is the number of iterations that define the GMRES solver restart length. "
"Increasing this parameter helps with convergence issues arising from high localized "
"viscosity jumps in the domain. Be aware that increasing this number increases the "
"memory usage of the Stokes solver, and makes individual Stokes iterations more "
"expensive.");
prm.declare_entry ("Linear solver A block tolerance", "1e-2",
Patterns::Double(0., 1.),
"A relative tolerance up to which the approximate inverse of the $A$ block "
"of the Stokes system is computed. This approximate $A$ is used in the "
"preconditioning used in the GMRES solver. The exact definition of this "
"block preconditioner for the Stokes equation can be found in "
"\\cite{kronbichler:etal:2012}.");
prm.declare_entry ("Use full A block as preconditioner", "false",
Patterns::Bool(),
"This parameter determines whether we use an simplified approximation of the "
"$A$ block as preconditioner for the Stokes solver, or the full $A$ block. The "
"simplified approximation only contains the terms that describe the coupling of "
"identical components (plus boundary conditions) as described in "
"\\cite{kronbichler:etal:2012}. The full block is closer to the description in "
"\\cite{rudi2017weighted}."
"\n\n"
"There is no clear way to determine which preconditioner "
"performs better. The default value (simplified approximation) requires "
"more outer GMRES iterations, but is faster to apply in each iteration. The full block "
"needs less assembly time (because the block is "
"available anyway), converges in less GMRES iterations, but requires more time per "
"iteration. There are also differences in the amount of memory consumption between "
"the two approaches."
"\n\n"
"The default value should be good for relatively simple models, but in "
"particular for very strong viscosity contrasts the full $A$ block can be "
"advantageous. This parameter is always set to true when using the GMG solver.");
prm.declare_entry ("Force nonsymmetric A block solver", "false",
Patterns::Bool(),
"This parameter determines whether to enforce a solver that supports nonsymmetric "
"matrices when solving the inner $A$ block of the Stokes system. "
"By default ASPECT recognizes cases where the A block is nonsymmetric "
"automatically, and chooses an appropriate solver. However, if the "
"inner A block solver does not converge, this parameter can be set to 'true' "
"to force the use of a solver that can handle nonsymmetric matrices.");
prm.declare_entry ("Linear solver S block tolerance", "1e-6",
Patterns::Double(0., 1.),
"A relative tolerance up to which the approximate inverse of the $S$ block "
"(i.e., the Schur complement matrix $S = BA^{-1}B^{T}$) of the Stokes "
"system is computed. This approximate inverse of the $S$ block is used "
"in the preconditioning used in the GMRES solver. The exact definition of "
"this block preconditioner for the Stokes equation can be found in "
"\\cite{kronbichler:etal:2012}.");
}
prm.leave_subsection ();
prm.enter_subsection ("AMG parameters");
{
prm.declare_entry ("AMG smoother type", "Chebyshev",
Patterns::Selection ("Chebyshev|symmetric Gauss-Seidel"),
"This parameter sets the type of smoother for the AMG. "
"The default is strongly recommended for any normal runs "
"with ASPECT. There are some indications that the symmetric "
"Gauss-Seidel might be better and more stable for the Newton "
"solver. For extensive benchmarking of various settings of the "
"AMG parameters in this section for the Stokes problem and others, "
"see https://github.com/geodynamics/aspect/pull/234.");
prm.declare_entry ("AMG smoother sweeps", "2",
Patterns::Integer(0),
"Determines how many sweeps of the smoother should be performed. When the flag elliptic "
"is set to true, (which is true for ASPECT), the polynomial degree of "
"the Chebyshev smoother is set to this value. The term sweeps refers to the number of "
"matrix-vector products performed in the Chebyshev case. In the non-elliptic case, "
"this parameter sets the number of SSOR relaxation sweeps for post-smoothing to be performed. "
"The default is strongly recommended. There are indications that for the Newton solver a different "
"value might be better. For extensive benchmarking of various settings of the "
"AMG parameters in this section for the Stokes problem and others, "
"see https://github.com/geodynamics/aspect/pull/234.");
prm.declare_entry ("AMG aggregation threshold", "0.001",
Patterns::Double(0., 1.),
"This threshold tells the AMG setup how the coarsening should be performed. "
"In the AMG used by ML, all points that strongly couple with the tentative coarse-level "
"point form one aggregate. The term strong coupling is controlled by the variable "
"aggregation\\_threshold, meaning that all elements that are not smaller than "
"aggregation\\_threshold times the diagonal element do couple strongly. "
"The default is strongly recommended. There are indications that for the Newton solver a different "
"value might be better. For extensive benchmarking of various settings of the "
"AMG parameters in this section for the Stokes problem and others, "
"see https://github.com/geodynamics/aspect/pull/234.");
prm.declare_entry ("AMG output details", "false",
Patterns::Bool(),
"Turns on extra information on the AMG solver. Note that this will generate much more output.");
}
prm.leave_subsection ();
prm.enter_subsection ("Operator splitting parameters");
{
prm.declare_entry ("Reaction solver type", "ARKode",
Patterns::Selection ("ARKode|fixed step"),
"This parameter determines what solver will be used when the reactions "
"are computed within the operator splitting scheme. For reactions where "
"the reaction rate is a known, finite quantity, the appropriate choice "
"is `ARKode', which uses an ODE solver from SUNDIALs ARKode (adaptive-step "
"additive Runge Kutta ODE solver methods) to compute the solution. ARKode "
"will pick a reasonable step size based on the reaction rate and the given "
"`Reaction solver relative tolerance'. "
"However, in some cases we have instantaneous reactions, where we know the "
"new value of a compositional field (and the reaction rate would be "
"infinite), or reaction where we need to know or be able to control the step "
"size we use to compute the reactions. In theses cases, it is appropriate "
"to use the `fixed step' scheme, a method that a forward Euler scheme and a "
"fixed number of steps given by the `Reaction time step' and "
"`Reaction time steps per advection step' parameters. ");
prm.declare_entry ("Reaction solver relative tolerance", "1e-6",
Patterns::Double (0.),
"The relative solver tolerance used in the ARKode reaction solver. "
"This tolerance is used to adaptively determine the reaction step size. "
"For more details, see the ARKode documentation. This parameter is only used "
"if the `ARKode' reaction solver type is used. "
"Units: none.");
prm.declare_entry ("Reaction time step", "1000.0",
Patterns::Double (0.),
"Set a time step size for computing reactions of compositional fields and the "
"temperature field in case operator splitting is used. This is only used "
"when the parameter ``Use operator splitting'' is set to true and when the "
"`fixed step' reaction solver type is used. "
"The reaction time step must be greater than 0. "
"If you want to prescribe the reaction time step only as a relative value "
"compared to the advection time step as opposed to as an absolute value, you "
"should use the parameter ``Reaction time steps per advection step'' and set "
"this parameter to the same (or larger) value as the ``Maximum time step'' "
"(which is 5.69e+300 by default). "
"Units: Years or seconds, depending on the ``Use years instead of seconds'' "
"parameter.");
prm.declare_entry ("Reaction time steps per advection step", "0",
Patterns::Integer (0),
"The number of reaction time steps done within one advection time step "
"in case operator splitting is used. This is only used if the parameter "
"``Use operator splitting'' is set to true and when the `fixed step' "
"reaction solver type is used. If set to zero, this parameter is ignored. "
"Otherwise, the reaction time step size is chosen according to "
"this criterion and the ``Reaction time step'', whichever yields the "
"smaller time step. "
"Units: none.");
}
prm.leave_subsection ();
prm.enter_subsection ("Diffusion solver parameters");
{
prm.declare_entry ("Diffusion length scale", "1.e4",
Patterns::Double (0.),
"Set a length scale for the diffusion of advection fields if the "
"``prescribed field with diffusion'' method is selected for a field. "
"More precisely, this length scale represents the square root of the "
"product of diffusivity and time in the diffusion equation, and controls "
"the distance over which features are diffused. "
"Units: \\si{\\meter}.");
}
prm.leave_subsection ();
}
prm.leave_subsection ();
prm.enter_subsection("Formulation");
{
prm.declare_entry ("Formulation", "custom",
Patterns::Selection ("isentropic compression|custom|anelastic liquid approximation|Boussinesq approximation"),
"Select a formulation for the basic equations. Different "
"published formulations are available in ASPECT (see the list of "
"possible values for this parameter in the manual for available options). "
"Two ASPECT specific options are\n"
" * `isentropic compression': ASPECT's original "
"formulation, using the explicit compressible mass equation, "
"and the full density for the temperature equation.\n"
" * `custom': A custom selection of `Mass conservation' and "
"`Temperature equation'.\n"
":::{warning}\n"
"The `custom' option is "
"implemented for advanced users that want full control over the "
"equations solved. It is possible to choose inconsistent formulations "
"and no error checking is performed on the consistency of the resulting "
"equations.\n"
":::\n\n"
":::{note}\n"
"The `anelastic liquid approximation' option here can also be "
"used to set up the `truncated anelastic liquid approximation' as long as "
"this option is chosen together with a material model that defines a "
"density that depends on temperature and depth and not on the pressure.\n"
":::");
prm.declare_entry ("Mass conservation", "ask material model",
Patterns::Selection ("incompressible|isentropic compression|hydrostatic compression|"
"reference density profile|implicit reference density profile|"
"projected density field|"
"ask material model"),
"Possible approximations for the density derivatives in the mass "
"conservation equation. Note that this parameter is only evaluated "
"if `Formulation' is set to `custom'. Other formulations ignore "
"the value of this parameter.");
prm.declare_entry ("Temperature equation", "real density",
Patterns::Selection ("real density|reference density profile"),
"Possible approximations for the density in the temperature equation. "
"Possible approximations are `real density' and `reference density profile'. "
"Note that this parameter is only evaluated "
"if `Formulation' is set to `custom'. Other formulations ignore "
"the value of this parameter.");
prm.declare_entry ("Enable additional Stokes RHS", "false",
Patterns::Bool (),
"Whether to ask the material model for additional terms for the right-hand side "
"of the Stokes equation. This feature is likely only used when implementing force "
"vectors for manufactured solution problems and requires filling additional outputs "
"of type AdditionalMaterialOutputsStokesRHS.");
prm.declare_entry ("Enable elasticity", "false",
Patterns::Bool (),
"Whether to include the additional elastic terms on the right-hand side of "
"the Stokes equation.");
prm.declare_entry ("Enable prescribed dilation", "false",
Patterns::Bool (),
"Whether to include additional terms on the right-hand side of "
"the Stokes equation to set a given compression term specified in the "
"MaterialModel output PrescribedPlasticDilation.");
}
prm.leave_subsection();
// next declare parameters that pertain to the equations to be
// solved, along with boundary conditions etc. note that at this
// point we do not know yet which geometry model we will use, so
// we do not know which symbolic names will be valid to address individual
// parts of the boundary. we can only work around this by allowing any string
// to indicate a boundary
prm.enter_subsection ("Melt settings");
{
prm.declare_entry ("Include melt transport", "false",
Patterns::Bool (),
"Whether to include the transport of melt into the model or not. If this "
"is set to true, two additional pressures (the fluid pressure and the "
"compaction pressure) will be added to the finite element. "
"Including melt transport in the simulation also requires that there is "
"one compositional field that has the name `porosity'. This field will "
"be used for computing the additional pressures and the melt velocity, "
"and has a different advection equation than other compositional fields, "
"as it is effectively advected with the melt velocity.");
}
prm.leave_subsection();
prm.enter_subsection ("Mesh deformation");
{
prm.declare_entry ("Mesh deformation boundary indicators", "",
Patterns::List (Patterns::Anything()),
"A comma separated list of names denoting those boundaries "
"where there is some type of mesh deformation. Set to nothing to disable all "
"deformation computations."
"\n\n"
"The names of the boundaries listed here can either by "
"numbers (in which case they correspond to the numerical "
"boundary indicators assigned by the geometry object), or they "
"can correspond to any of the symbolic names the geometry object "
"may have provided for each part of the boundary. You may want "
"to compare this with the documentation of the geometry model you "
"use in your model.");
}
prm.leave_subsection();
prm.enter_subsection ("Boundary heat flux model");
{
prm.declare_entry ("Fixed heat flux boundary indicators", "",
Patterns::List (Patterns::Anything()),
"A comma separated list of names denoting those boundaries "
"on which the heat flux is fixed and described by the "
"boundary heat flux object selected in the 'Model name' parameter. "
"All boundary indicators used by the geometry but not explicitly "
"listed here or in the list of 'Fixed temperature boundary indicators' "
"in the 'Boundary temperature model' will end up with no-flux "
"(insulating) boundary conditions."
"\n\n"
"The names of the boundaries listed here can either be "
"numbers (in which case they correspond to the numerical "
"boundary indicators assigned by the geometry object), or they "
"can correspond to any of the symbolic names the geometry object "
"may have provided for each part of the boundary. You may want "
"to compare this with the documentation of the geometry model you "
"use in your model."
"\n\n"
"This parameter only describes which boundaries have a fixed "
"heat flux, but not what heat flux should hold on these "
"boundaries. The latter piece of information needs to be "
"implemented in a plugin in the BoundaryHeatFlux "
"group, unless an existing implementation in this group "
"already provides what you want.");
}
prm.leave_subsection();
prm.enter_subsection ("Nullspace removal");
{
prm.declare_entry ("Remove nullspace", "",
Patterns::MultipleSelection("net rotation|angular momentum|"
"net surface rotation|"
"net translation|linear momentum|"
"net x translation|net y translation|net z translation|"
"linear x momentum|linear y momentum|linear z momentum"),
"Choose none, one or several from "
"\n\n"
"* net rotation"
"\n"
"* angular momentum"
"\n"
"* net translation"
"\n"
"* net surface rotation"
"\n"
"* linear momentum"
"\n"
"* net x translation"
"\n"
"* net y translation"
"\n"
"* net z translation"
"\n"
"* linear x momentum"
"\n"
"* linear y momentum"
"\n"
"* linear z momentum"
"\n\n"
"These are a selection of operations to remove certain parts of the nullspace from "
"the velocity after solving. For some geometries and certain boundary conditions "
"the velocity field is not uniquely determined but contains free translations "
"and/or rotations. Depending on what you specify here, these non-determined "
"modes will be removed from the velocity field at the end of the Stokes solve step.\n"
"\n\n"
"The ``angular momentum'' option removes a rotation such that the net angular momentum "
"is zero. The ``linear * momentum'' options remove translations such that the net "
"momentum in the relevant direction is zero. The ``net rotation'' option removes the "
"net rotation of the whole domain, the ``net surface rotation'' option removes the net "
"rotation of the top surface, and the ``net * translation'' options remove the "
"net translations in the relevant directions. For most problems there should not be a "
"significant difference between the momentum and rotation/translation versions of "
"nullspace removal, although the momentum versions are more physically motivated. "
"They are equivalent for constant density simulations, and approximately equivalent "
"when the density variations are small."
"\n\n"
"Note that while more than one operation can be selected it only makes sense to "
"pick one rotational and one translational operation.");
}
prm.leave_subsection();
prm.enter_subsection ("Mesh refinement");
{
prm.declare_entry ("Initial global refinement", "2",
Patterns::Integer (0),
"The number of global refinement steps performed on "
"the initial coarse mesh, before the problem is first "
"solved there."
"\n\n"
"Note that it is possible to supply conflicting refinement "
"and coarsening settings, such as an 'Initial global refinement' "
"of 4 and a 'Maximum refinement function' strategy that limits "
"the refinement locally to 2. In this case, the tagging strategies "
"such as the 'Maximum refinement function' will remove refinement "
"flags in each initial global refinement step, such that the "
"resulting mesh is not necessarily uniform or of the level "
"given by the 'Initial global refinement' parameter.");
prm.declare_entry ("Initial adaptive refinement", "0",
Patterns::Integer (0),
"The number of adaptive refinement steps performed after "
"initial global refinement but while still within the first "
"time step. These refinement steps (n) are added to the value "
"for initial global refinement (m) so that the final mesh has "
"cells that are at most on refinement level $n+m$.");
prm.declare_entry ("Time steps between mesh refinement", "10",
Patterns::Integer (0),
"The number of time steps after which the mesh is to be "
"adapted again based on computed error indicators. If 0 "
"then the mesh will never be changed.");
prm.declare_entry ("Refinement fraction", "0.3",
Patterns::Double(0., 1.),
"Cells are sorted from largest to smallest by their total error "
"(determined by the Strategy). Then the cells with the largest "
"error (top of this sorted list) that account for given fraction "
"of the error are refined.");
prm.declare_entry ("Coarsening fraction", "0.05",
Patterns::Double(0., 1.),
"Cells are sorted from largest to smallest by their total error "
"(determined by the Strategy). Then the cells with the smallest "
"error (bottom of this sorted list) that account for the given fraction "
"of the error are coarsened.");
prm.declare_entry ("Adapt by fraction of cells", "false",
Patterns::Bool(),
"Use fraction of the total number of cells instead of "
"fraction of the total error as the limit for refinement "
"and coarsening.");
prm.declare_entry ("Minimum refinement level", "0",
Patterns::Integer (0),
"The minimum refinement level each cell should have, "
"and that can not be exceeded by coarsening. "
"Should not be higher than the 'Initial global refinement' "
"parameter.");
prm.declare_entry ("Additional refinement times", "",
Patterns::List (Patterns::Double (0.)),
"A list of times so that if the end time of a time step "
"is beyond this time, an additional round of mesh refinement "
"is triggered. This is mostly useful to make sure we "
"can get through the initial transient phase of a simulation "
"on a relatively coarse mesh, and then refine again when we "
"are in a time range that we are interested in and where "
"we would like to use a finer mesh. Units: Each element of the "
"list has units years if the "
"'Use years instead of seconds' parameter is set; "
"seconds otherwise.");
prm.declare_entry ("Run postprocessors on initial refinement", "false",
Patterns::Bool (),
"Whether or not the postprocessors should be executed after "
"each of the initial adaptive refinement cycles that are run at "
"the start of the simulation. This is useful for "
"plotting/analyzing how the mesh refinement parameters are "
"working for a particular model.");
prm.declare_entry ("Skip solvers on initial refinement", "false",
Patterns::Bool (),
"Whether or not solvers should be executed during the initial "
"adaptive refinement cycles that are run at the start of the "
"simulation.");
prm.declare_entry ("Skip setup initial conditions on initial refinement", "false",
Patterns::Bool (),
"Whether or not the initial conditions should be set up during the "
"adaptive refinement cycles that are run at the start of the "
"simulation.");
}
prm.leave_subsection();
prm.enter_subsection ("Postprocess");
{
prm.declare_entry ("Run postprocessors on nonlinear iterations", "false",
Patterns::Bool (),
"Whether or not the postprocessors should be executed after "
"each of the nonlinear iterations done within one time step. "
"As this is mainly an option for the purposes of debugging, "
"it is not supported when the 'Time between graphical output' "
"is larger than zero, or when the postprocessor is not intended "
"to be run more than once per timestep.");
}
prm.leave_subsection();
prm.enter_subsection ("Checkpointing");
{
prm.declare_entry ("Time between checkpoint", "0",
Patterns::Integer (0),
"The wall time between performing checkpoints. "
"If 0, will use the checkpoint step frequency instead. "
"Units: Seconds.");
prm.declare_entry ("Steps between checkpoint", "0",
Patterns::Integer (0),
"The number of timesteps between performing checkpoints. "
"If 0 and time between checkpoint is not specified, "
"checkpointing will not be performed. "
"Units: None.");
}
prm.leave_subsection ();
prm.enter_subsection ("Discretization");
{
prm.declare_entry ("Stokes velocity polynomial degree", "2",
Patterns::Integer (1),
"The polynomial degree to use for the velocity variables "
"in the Stokes system. The polynomial degree for the pressure "
"variable will then be one less in order to make the velocity/pressure "