forked from geodynamics/aspect
/
simulator_access.h
726 lines (619 loc) · 23.7 KB
/
simulator_access.h
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
/*
Copyright (C) 2011 - 2016 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/>.
*/
#ifndef _aspect_simulator_access_h
#define _aspect_simulator_access_h
#include <aspect/global.h>
#include <aspect/parameters.h>
#include <aspect/introspection.h>
#include <deal.II/base/table_handler.h>
#include <deal.II/base/timer.h>
#include <deal.II/base/conditional_ostream.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/fe/fe.h>
#include <deal.II/fe/mapping_q.h>
namespace aspect
{
using namespace dealii;
// forward declarations:
template <int dim> class Simulator;
template <int dim> struct SimulatorSignals;
template <int dim> class LateralAveraging;
namespace GravityModel
{
template <int dim> class Interface;
}
namespace HeatingModel
{
template <int dim> class Manager;
}
namespace InitialTemperature
{
template <int dim> class Manager;
template <int dim> class Interface;
}
namespace BoundaryTemperature
{
template <int dim> class Manager;
template <int dim> class Interface;
}
namespace BoundaryComposition
{
template <int dim> class Interface;
}
namespace BoundaryTraction
{
template <int dim> class Interface;
}
namespace BoundaryVelocity
{
template <int dim> class Interface;
}
namespace InitialComposition
{
template <int dim> class Manager;
template <int dim> class Interface;
}
namespace InitialTopographyModel
{
template <int dim> class Interface;
}
namespace AdiabaticConditions
{
template <int dim> class Interface;
}
template <int dim> class MeltHandler;
/**
* SimulatorAccess is a base class for different plugins like postprocessors.
* It provides access to the various variables of the main class that
* plugins may want to use in their evaluations, such as solution vectors,
* the current time, time step sizes, material models, or the triangulations
* and DoFHandlers that correspond to solutions.
*
* This class is the interface between plugins and the main simulator class.
* Using this insulation layer, the plugins need not know anything about the
* internal details of the simulation class.
*
* Every Postprocessor is required to derive from SimulatorAccess. It is
* optional for other plugins like MaterialModel, GravityModel, etc..
*
* Since the functions providing access to details of the simulator class
* are meant to be used only by derived classes of this class (rather than
* becoming part of the public interface of these classes), the functions of
* this class are made @p protected.
*
* @ingroup Simulator
*/
template <int dim>
class SimulatorAccess
{
public:
/**
* Default constructor. Initialize the SimulatorAccess object without
* a reference to a particular Simulator object. You will later have
* to call initialize() to provide this reference to the Simulator
* object.
*/
SimulatorAccess ();
/**
* Create a SimulatorAccess object that is already initialized for
* a particular Simulator.
*/
SimulatorAccess (const Simulator<dim> &simulator_object);
/**
* Destructor. Does nothing but is virtual so that derived classes
* destructors are also virtual.
*/
virtual
~SimulatorAccess ();
/**
* Initialize this class for a given simulator. This function is marked
* as virtual so that derived classes can do something upon
* initialization as well, for example look up and cache data; derived
* classes should call this function from the base class as well,
* however.
*
* @param simulator_object A reference to the main simulator object.
*/
virtual void initialize_simulator (const Simulator<dim> &simulator_object);
/** @name Accessing variables that identify overall properties of the simulator */
/** @{ */
/**
* Return a reference to an introspection object that describes overall
* properties of the simulator. In particular, it provides symbolic
* names for extractors and component masks for each variable, etc, and
* thereby reduces the need for implicit knowledge throughout the code
* base.
*/
const Introspection<dim> &
introspection () const;
/**
* Return a reference to the Simulator itself. Note that you can not
* access any members or functions of the Simulator. This function
* exists so that any class with SimulatorAccess can create other
* objects with SimulatorAccess (because initializing them requires a
* reference to the Simulator).
*/
const Simulator<dim> &
get_simulator () const;
/**
* Return a reference to the parameters object that describes all run-time
* parameters used in the current simulation.
*/
const Parameters<dim> &
get_parameters () const;
/**
* Get Access to the structure containing the signals of the simulator.
*/
SimulatorSignals<dim> &
get_signals() const;
/**
* Return the MPI communicator for this simulation.
*/
MPI_Comm
get_mpi_communicator () const;
/**
* Return the timer object for this simulation. Since the timer is
* mutable in the Simulator class, this allows plugins to define their
* own sections in the timer to measure the time spent in sections of
* their code.
*/
TimerOutput &
get_computing_timer () const;
/**
* Return a reference to the stream object that only outputs something
* on one processor in a parallel program and simply ignores output put
* into it on all other processors.
*/
const ConditionalOStream &
get_pcout () const;
/**
* Return the current simulation time in seconds.
*/
double get_time () const;
/**
* Return the size of the current time step.
*/
double
get_timestep () const;
/**
* Return the size of the last time step.
*/
double
get_old_timestep () const;
/**
* Return the current number of a time step.
*/
unsigned int
get_timestep_number () const;
/**
* Return the current nonlinear iteration number of a time step.
*/
unsigned int
get_nonlinear_iteration () const;
/**
* Return a reference to the triangulation in use by the simulator
* object.
*/
const parallel::distributed::Triangulation<dim> &
get_triangulation () const;
/**
* Return the global volume of the computational domain.
*/
double
get_volume () const;
/**
* Return a reference to the mapping used to describe the boundary of
* the domain.
*/
const Mapping<dim> &
get_mapping () const;
/**
* Return the directory specified in the input parameter file to be the
* place where output files are to be placed. The string is terminated
* by a directory separator (i.e., '/').
*/
std::string
get_output_directory () const;
/**
* Return whether we use the adiabatic heating term.
*/
bool
include_adiabatic_heating () const;
/**
* Return whether we use the latent heat term.
*/
bool
include_latent_heat () const;
/**
* Return whether we solve the equations for melt transport.
*/
bool
include_melt_transport () const;
/**
* Return the stokes velocity degree.
*/
int
get_stokes_velocity_degree () const;
/**
* Return the adiabatic surface temperature.
*/
double
get_adiabatic_surface_temperature () const;
/**
* Return the adiabatic surface pressure.
*/
double
get_surface_pressure () const;
/**
* Return whether things like velocities should be converted from the
* seconds in the MKS system to years. The value of this flag is set by
* the corresponding entry in the input parameter file.
*/
bool
convert_output_to_years () const;
/**
* Return the number of the current pre refinement step.
* This can be useful for plugins that want to function differently in
* the initial adaptive refinements and later on.
* This will be not initialized before Simulator<dim>::run() is called.
* It iterates upward from 0 to parameters.initial_adaptive_refinement
* during the initial adaptive refinement steps, and equals
* std::numeric_limits<unsigned int>::max() afterwards.
*/
unsigned int
get_pre_refinement_step () const;
/**
* Return the number of compositional fields specified in the input
* parameter file that will be advected along with the flow field.
*/
unsigned int
n_compositional_fields () const;
/**
* Compute the error indicators in the same way they are normally used
* for mesh refinement. The mesh is not refined when doing so, but the
* indicators can be used when generating graphical output to check why
* mesh refinement is proceeding as it is.
*/
void
get_refinement_criteria(Vector<float> &estimated_error_per_cell) const;
/**
* Returns the entropy viscosity on each locally owned cell as it is
* used to stabilize the temperature equation.
*/
void
get_artificial_viscosity(Vector<float> &viscosity_per_cell) const;
/**
* Returns the entropy viscosity on each locally owned cell as it is
* used to stabilize the composition equation.
*/
void
get_artificial_viscosity_composition(Vector<float> &viscosity_per_cell,
const unsigned int compositional_variable) const;
/** @} */
/** @name Accessing variables that identify the solution of the problem */
/** @{ */
/**
* Return a reference to the vector that has the current linearization
* point of the entire system, i.e. the velocity and pressure variables
* as well as the temperature and compositional fields. This vector is
* associated with the DoFHandler object returned by get_dof_handler().
* This vector is only different from the one returned by get_solution()
* during the solver phase.
*
* @note In general the vector is a distributed vector; however, it
* contains ghost elements for all locally relevant degrees of freedom.
*/
const LinearAlgebra::BlockVector &
get_current_linearization_point () const;
/**
* Return a reference to the vector that has the current solution of the
* entire system, i.e. the velocity and pressure variables as well as
* the temperature. This vector is associated with the DoFHandler
* object returned by get_dof_handler().
*
* @note In general the vector is a distributed vector; however, it
* contains ghost elements for all locally relevant degrees of freedom.
*/
const LinearAlgebra::BlockVector &
get_solution () const;
/**
* Return a reference to the vector that has the solution of the entire
* system at the previous time step. This vector is associated with the
* DoFHandler object returned by get_stokes_dof_handler().
*
* @note In general the vector is a distributed vector; however, it
* contains ghost elements for all locally relevant degrees of freedom.
*/
const LinearAlgebra::BlockVector &
get_old_solution () const;
/**
* Return a reference to the vector that has the solution of the entire
* system at the second-to-last time step. This vector is associated with the
* DoFHandler object returned by get_stokes_dof_handler().
*
* @note In general the vector is a distributed vector; however, it
* contains ghost elements for all locally relevant degrees of freedom.
*/
const LinearAlgebra::BlockVector &
get_old_old_solution () const;
/**
* Return a reference to the vector that has the mesh velocity for
* simulations with a free surface.
*
* @note In general the vector is a distributed vector; however, it
* contains ghost elements for all locally relevant degrees of freedom.
*/
const LinearAlgebra::BlockVector &
get_mesh_velocity () const;
/**
* Return a reference to the DoFHandler that is used to discretize the
* variables at the current time step.
*/
const DoFHandler<dim> &
get_dof_handler () const;
/**
* Return a reference to the finite element that the DoFHandler that is
* used to discretize the variables at the current time step is built
* on. This is the finite element for the entire, couple problem, i.e.,
* it contains sub-elements for velocity, pressure, temperature and all
* other variables in this problem (e.g., compositional variables, if
* used in this simulation).
*/
const FiniteElement<dim> &
get_fe () const;
/**
* Return a reference to the system matrix at the current time step.
*/
const LinearAlgebra::BlockSparseMatrix &
get_system_matrix () const;
/**
* Return a reference to the system preconditioner matrix at the current time step.
*/
const LinearAlgebra::BlockSparseMatrix &
get_system_preconditioner_matrix () const;
/** @} */
/** @name Accessing variables that identify aspects of the simulation */
/** @{ */
/**
* Return a pointer to the material model to access functions like
* density().
*/
const MaterialModel::Interface<dim> &
get_material_model () const;
/**
* This function simply calls Simulator<dim>::compute_material_model_input_values()
* with the given arguments.
*/
void
compute_material_model_input_values (const LinearAlgebra::BlockVector &input_solution,
const FEValuesBase<dim,dim> &input_finite_element_values,
const typename DoFHandler<dim>::active_cell_iterator &cell,
const bool compute_strainrate,
MaterialModel::MaterialModelInputs<dim> &material_model_inputs) const;
/**
* This function simply calls Simulator<dim>::create_additional_material_model_outputs()
* with the given arguments.
*/
void
create_additional_material_model_outputs (MaterialModel::MaterialModelOutputs<dim> &) const;
/**
* Return a pointer to the gravity model description.
*/
const GravityModel::Interface<dim> &
get_gravity_model () const;
/**
* Return a pointer to the initial topography model.
*/
const InitialTopographyModel::Interface<dim> &
get_initial_topography_model () const;
/**
* Return a pointer to the geometry model.
*/
const GeometryModel::Interface<dim> &
get_geometry_model () const;
/**
* Return a pointer to the object that describes the adiabatic
* conditions.
*/
const AdiabaticConditions::Interface<dim> &
get_adiabatic_conditions () const;
/**
* Return whether the current model has a boundary temperature object
* set. This is useful because a simulation does not actually have to
* declare any boundary temperature model, for example if all
* boundaries are insulating. In such cases, there is no
* boundary temperature model that can provide, for example,
* a minimal and maximal temperature on the boundary.
*/
bool has_boundary_temperature () const;
/**
* Return a reference to the object that describes the temperature
* boundary values.
*
* @deprecated: Use get_boundary_temperature_manager() instead.
*/
const BoundaryTemperature::Interface<dim> &
get_boundary_temperature () const DEAL_II_DEPRECATED;
/**
* Return an reference to the manager of the initial temperature models.
* This can then i.e. be used to get the names of the initial temperature
* models used in a computation, or to compute the initial temperature
* for a given position.
*/
const BoundaryTemperature::Manager<dim> &
get_boundary_temperature_manager () const;
/**
* Return whether the current model has a boundary composition object
* set. This is useful because a simulation does not actually have to
* declare any boundary composition model, for example if all
* boundaries are reflecting. In such cases, there is no
* boundary composition model that can provide, for example,
* a minimal and maximal temperature on the boundary.
*/
bool has_boundary_composition () const;
/**
* Return a reference to the object that describes the composition
* boundary values.
*/
const BoundaryComposition::Interface<dim> &
get_boundary_composition () const;
/**
* Return a reference to the object that describes traction
* boundary conditions.
*/
const std::map<types::boundary_id,std_cxx11::shared_ptr<BoundaryTraction::Interface<dim> > > &
get_boundary_traction () const;
/**
* Return a pointer to the object that describes the temperature initial
* values.
*
* @deprecated Use <code> get_initial_temperature_manager </code> instead.
*/
const InitialTemperature::Interface<dim> &
get_initial_temperature () const DEAL_II_DEPRECATED;
/**
* Return a reference to the manager of the initial temperature models.
* This can then i.e. be used to get the names of the initial temperature
* models used in a computation, or to compute the initial temperature
* for a given position.
*/
const InitialTemperature::Manager<dim> &
get_initial_temperature_manager () const;
/**
* Return a pointer to the object that describes the composition initial
* values.
*/
const InitialComposition::Interface<dim> &
get_initial_composition () const DEAL_II_DEPRECATED;
/**
* Return a pointer to the manager of the initial composition model.
* This can then i.e. be used to get the names of the initial composition
* models used in a computation.
*/
const InitialComposition::Manager<dim> &
get_initial_composition_manager () const;
/**
* Return a set of boundary indicators that describes which of the
* boundaries have a fixed temperature.
*/
const std::set<types::boundary_id> &
get_fixed_temperature_boundary_indicators () const;
/**
* Return a set of boundary indicators that describes which of the
* boundaries have a fixed composition.
*/
const std::set<types::boundary_id> &
get_fixed_composition_boundary_indicators () const;
/**
* Return a set of boundary indicators that describes which of the
* boundaries have a free surface boundary condition
*/
const std::set<types::boundary_id> &
get_free_surface_boundary_indicators () const;
/**
* Return the map of prescribed_boundary_velocity
*/
const std::map<types::boundary_id,std_cxx11::shared_ptr<BoundaryVelocity::Interface<dim> > >
get_prescribed_boundary_velocity () const;
/**
* Return a pointer to the manager of the heating model.
* This can then i.e. be used to get the names of the heating models
* used in a computation.
*/
const HeatingModel::Manager<dim> &
get_heating_model_manager () const;
/**
* Return a pointer to the melt handler.
*/
const MeltHandler<dim> &
get_melt_handler () const;
/**
* Return a reference to the lateral averaging object owned
* by the simulator, which can be used to query lateral averages
* of various quantities at depth slices.
*/
const LateralAveraging<dim> &
get_lateral_averaging () const;
/**
* Return a pointer to the object that describes the DoF
* constraints for the time step we are currently solving.
*/
const ConstraintMatrix &
get_current_constraints() const;
/**
* Return whether or not the current object has been initialized by providing it with
* a pointer to a Simulator class object.
*/
bool simulator_is_initialized () const;
/**
* Return the value used for rescaling the pressure in the linear
* solver.
*/
double
get_pressure_scaling () const;
/**
* A convenience function that copies the values of the compositional
* fields at the quadrature point q given as input parameter to the
* output vector composition_values_at_q_point.
*/
static
void
get_composition_values_at_q_point (const std::vector<std::vector<double> > &composition_values,
const unsigned int q,
std::vector<double> &composition_values_at_q_point);
/**
* Return a writable reference to the statistics object into which
* you can store additional data that then shows up in the
* <code>output_dir/statistics</code> file.
*
* Postprocessor objects get a reference to this object automatically
* when called, but other plugins may not. They do not usually
* produce output anyway, but through this function they can still
* record information as necessary.
* @return
*/
TableHandler &get_statistics_object() const;
/**
* This function can be used to find out whether the list of
* postprocessors that are run at the end of each time step
* contains an object of the given template type. If so, the function
* returns a pointer to the postprocessor object of this type. If
* no postprocessor of this type has been selected in the input
* file (or, has been required by another postprocessor using the
* Postprocess::Interface::required_other_postprocessors()
* mechanism), then the function returns a NULL pointer.
*/
template <typename PostprocessorType>
PostprocessorType *
find_postprocessor () const;
/** @} */
private:
/**
* A pointer to the simulator object to which we want to get access.
*/
const Simulator<dim> *simulator;
};
template <int dim>
template <typename PostprocessorType>
inline
PostprocessorType *
SimulatorAccess<dim>::find_postprocessor () const
{
return simulator->postprocess_manager.template find_postprocessor<PostprocessorType>();
}
}
#endif