Diagnostics
diagnostics
This module provides a class to simplify computing of diagnostics typically encountered in geodynamical simulations. Users instantiate the class by providing relevant parameters and call individual class methods to compute associated diagnostics.
FunctionContext(quad_degree, func)
Hold objects that can be derived from a Firedrake Function.
This class gathers references to objects that can be pulled from a Firedrake
Function object and calculates quantities based on those objects that will remain
constant for the duration of a simulation. The set of objects/quantities stored
are: mesh, function_space, dx and ds measures, the FacetNormal of the mesh
(as the .normal attribute) and the volume of the domain.
Typical usage example:
function_contexts[F] = FunctionContext(quad_degree, F)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quad_degree
|
int
|
Quadrature degree to use when approximating integrands involving |
required |
func
|
Function
|
Function |
required |
Source code in g-adopt/gadopt/diagnostics.py
208 209 210 | |
function
cached
property
The function associated with the instance
mesh
cached
property
The mesh on which the function has been defined
function_space
cached
property
The function space on which the function has been defined
dx
cached
property
The volume integration measure defined by the mesh and
quad_degree passed when creating this instance
ds
cached
property
The surface integration measure defined by the mesh and
quad_degree passed when creating this instance
normal
cached
property
The facet normal of the mesh belonging to this instance
volume
cached
property
The volume of the mesh belonging to this instance
boundary_ids
cached
property
The boundary IDs of the mesh associated with this instance
check_boundary_id(boundary_id)
cached
Check if a boundary id or tuple of boundary ids is valid
Source code in g-adopt/gadopt/diagnostics.py
260 261 262 263 264 265 266 267 268 269 270 271 272 273 | |
surface_area(boundary_id)
cached
The surface area of the mesh on the boundary belonging to boundary_id
Source code in g-adopt/gadopt/diagnostics.py
275 276 277 278 279 | |
get_boundary_nodes(boundary_id)
cached
Return the list of nodes on the boundary owned by this process
Creates a DirichletBC object, then uses the .nodes attribute for that
object to provide a list of indices that reside on the boundary of the domain
of the function associated with this FunctionContext instance. The
dof_dset.size parameter of the FunctionSpace is used to exclude nodes in
the halo region of the domain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
boundary_id
|
Sequence[int | str] | int | str
|
Integer ID of the domain boundary |
required |
Returns:
| Type | Description |
|---|---|
list[int]
|
List of integers corresponding to nodes on the boundary identified by |
list[int]
|
|
Source code in g-adopt/gadopt/diagnostics.py
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | |
BaseDiagnostics(quad_degree, **funcs)
A base class containing useful operations for diagnostics
For each Firedrake function passed as a keyword argument in the funcs parameter,
store that function as an attribute of the class accessible by its keyword, e.g.:
diag = BaseDiagnostics(quad_degree, z=z)
sets the Firedrake function z to the diag.z parameter.
If the function is a MixedFunction, the subfunctions will be accessible by an
index, e.g.:
diag = BaseDiagnostics(quad_degree, z=z)
sets the subfunctions of z to diag.z_0, diag.z_1, etc. A FunctionContext
is created for each function. These attributes are accessed by the
diag._function_contexts dict.
This class is intended to be subclassed by domain-specific diagnostic classes
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quad_degree
|
int
|
Quadrature degree to use when approximating integrands managed by |
required |
**funcs
|
Function | None
|
Firedrake functions to associate with this instance |
{}
|
Initialise a BaseDiagnostics object.
Sets the quad_degree for measures used by this object and passes the
remaining keyword arguments through to register_functions.
Source code in g-adopt/gadopt/diagnostics.py
331 332 333 334 335 336 337 338 339 340 | |
register_functions(*, quad_degree=None, **funcs)
Register a function with this BaseDiagnostics object.
Creates a FunctionContext object for each function passed in as a keyword
argument. Also creates an attribute on the instance to access the input function
named for the key of the keyword argument. i.e:
> diag.register_functions(self, F=F)
> type(diag.F)
<class 'firedrake.function.Function'>
None, the attribute will still be created
but set to 0.0. If a mixed function is entered, each subfunction will have
a FunctionContext object associated with it, and the attribute will be named
with an additional number to denote the index of the subfunction i.e.:
```
diag.register_functions(self, F) type(diag.F) AttributeError: 'Requested 'F', which lives on a mixed space. Instead, access subfunctions via F_0, F_1, ..." type(diag.F_0)
type(diag.F_1)
Args:
quad_degree (optional): The quadrature degree for the measures to be used
by this function. If None, the quad_degree passed at object
instantiation time is used. Defaults to None.
**funcs: key-value pairs of Firedrake functions to associate with this
instance
Source code in g-adopt/gadopt/diagnostics.py
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 | |
get_upward_component(f)
cached
Get the upward (against gravity) component of a function.
Returns a UFL expression for the upward component of a function. Uses the
G-ADOPT vertical_component function and caches the result such that the
UFL expression only needs to be constructed once per run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Function
|
Function |
required |
Returns:
| Type | Description |
|---|---|
Operator
|
UFL expression for the vertical component of |
Source code in g-adopt/gadopt/diagnostics.py
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | |
min(func_or_op, boundary_id=None, dim=None)
Calculate the minimum value of a function. See _minmax
docstring for more information.
Source code in g-adopt/gadopt/diagnostics.py
632 633 634 635 636 637 638 639 640 641 642 | |
max(func_or_op, boundary_id=None, dim=None)
Calculate the maximum value of a function See _minmax
docstring for more information.
Source code in g-adopt/gadopt/diagnostics.py
644 645 646 647 648 649 650 651 652 653 654 | |
integral(f, boundary_id=None)
Calculate the integral of a function over the domain associated with it
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Function
|
Function. |
required |
boundary_id
|
optional
|
Boundary ID. If not provided or set to |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Result of integration |
Source code in g-adopt/gadopt/diagnostics.py
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | |
l1norm(f, boundary_id=None)
Calculate the L1norm of a function over the domain associated with it
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Function
|
Function. |
required |
boundary_id
|
optional
|
Boundary ID .If not provided or set to |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
L1 norm |
Source code in g-adopt/gadopt/diagnostics.py
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | |
l2norm(f, boundary_id=None)
Calculate the L2norm of a function over the domain associated with it
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Function
|
Function. |
required |
boundary_id
|
optional
|
Boundary ID. If not provided or set to |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
L2 norm |
Source code in g-adopt/gadopt/diagnostics.py
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | |
rms(f)
Calculate the RMS of a function over the domain associated with it
For the purposes of this function, RMS is defined as L2norm/volume
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Function
|
Function. |
required |
boundary_id
|
optional
|
Boundary ID. If not provided or set to |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
RMS |
Source code in g-adopt/gadopt/diagnostics.py
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 | |
GeodynamicalDiagnostics(z, T=None, /, bottom_id=None, top_id=None, *, quad_degree=4)
Bases: BaseDiagnostics
Typical simulation diagnostics used in geodynamical simulations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
z
|
Function
|
Firedrake function for mixed Stokes function space (velocity, pressure) |
required |
T
|
Function | None
|
Firedrake function for temperature |
None
|
bottom_id
|
Sequence[int | str] | int | str | None
|
Bottom boundary identifier |
None
|
top_id
|
Sequence[int | str] | int | str | None
|
Top boundary identifier |
None
|
quad_degree
|
int
|
Degree of polynomial quadrature approximation |
4
|
Note
All diagnostics are returned as floats.
Methods:
| Name | Description |
|---|---|
u_rms |
Root-mean-square velocity |
u_rms_top |
Root-mean-square velocity along the top boundary |
Nu_top |
Nusselt number at the top boundary |
Nu_bottom |
Nusselt number at the bottom boundary |
T_avg |
Average temperature in the domain |
T_min |
Minimum temperature in domain |
T_max |
Maximum temperature in domain |
ux_max |
Maximum velocity (first component, optionally over a given boundary) |
Source code in g-adopt/gadopt/diagnostics.py
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | |
GIADiagnostics(u, /, bottom_id=None, top_id=None, *, quad_degree=4)
Bases: BaseDiagnostics
Typical simulation diagnostics used in glacial isostatic adjustment simulations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Firedrake function for displacement |
required | |
bottom_id
|
Sequence[int | str] | int | str | None
|
Bottom boundary identifier |
None
|
top_id
|
Sequence[int | str] | int | str | None
|
Top boundary identifier |
None
|
quad_degree
|
int
|
Degree of polynomial quadrature approximation |
4
|
Note
All diagnostics are returned as floats.
Methods:
| Name | Description |
|---|---|
u_rms |
Root-mean-square displacement |
u_rms_top |
Root-mean-square displacement along the top boundary |
ux_max |
Maximum displacement (first component, optionally over a given boundary) |
uv_min |
Minimum vertical displacement, optionally over a given boundary |
uv_max |
Maximum vertical displacement, optionally over a given boundary |
l2_norm_top |
L2 norm of displacement on top surface |
l1_norm_top |
L1 norm of displacement on top surface |
integrated_displacement |
integral of displacement on top surface |
Source code in g-adopt/gadopt/diagnostics.py
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | |
uv_min(boundary_id=None)
Minimum value of vertical component of velocity/displacement
Source code in g-adopt/gadopt/diagnostics.py
870 871 872 | |
uv_max(boundary_id=None)
Maximum value of vertical component of velocity/displacement
Source code in g-adopt/gadopt/diagnostics.py
874 875 876 | |
extract_functions(func_or_op)
cached
Extract all Firedrake functions associated with a UFL expression.
This function recursively searches through any UFL expression for Firedrake
Function objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func_or_op
|
Expr
|
The UFL expression to search through |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
An object that was neither a UFL Operator or UFL Terminal |
Returns:
| Type | Description |
|---|---|
set[Function]
|
The set of found Firedrake Functions |
Source code in g-adopt/gadopt/diagnostics.py
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 | |
ts_cache(_func=None, *, input_funcs=None, make_key=partial(_make_key, typed=False))
Cache the results of a diagnostic function on a per-timestep basis
This function creates a decorator that caches the results of any diagnostic
function found in a BaseDiagnostic object (or any subclass thereof) for as long
as the underlying Firedrake functions remain unmodified. The modification of
Firedrake functions is tracked by the dat_version attribute of the dat object
which is based on the 'state' of the underlying PETSc object (see e.g.
https://petsc.org/release/manualpages/Sys/PetscObjectStateGet/). Pyop2 also
maintains a similar counter for non-PETSc objects.
The purpose of this decorator is to allow multiple calls to the same diagnostic function within a timestep to reuse already computed quantities (e.g. Nusselt numbers on top/bottom boundaries in energy conservation calculations) or for underlying diagnostic algorithms to calculate multiple diagnostics at once when it is efficient to do so (e.g. min/max field values - in large parallel applications small reductions are dominated by network communication time, so it costs almost no extra calculate both the minimum and maximum value of the same field simultaneously).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
_func
|
optional
|
Used to determine if the decorator is being called with or without parentheses. |
None
|
input_funcs
|
optional
|
A string or Sequence of strings of Firedrake functions that the cached results depend on. The decorator will automatically detect Firedrake functions in its arguments, this allows custom diagnostics that do not take functions as arguments to correctly track dependent functions. Default behaviour is to track automatically detected functions only. |
None
|
make_key
|
optional
|
A function to turn args and *kwargs into a valid dictionary key. Defaults to the same method used by functools.cache with typed=False. |
partial(_make_key, typed=False)
|
Raises:
| Type | Description |
|---|---|
TypeError
|
The decorator has been used on an object that is not a G-ADOPT
BaseDiagnostic object
An attribute specified in |
AttributeError
|
The BaseDiagnostic object does not have an attribute named in the
|
Source code in g-adopt/gadopt/diagnostics.py
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 | |