goalie package

Submodules

goalie.adjoint module

Drivers for solving adjoint problems on sequences of meshes.

annotate_qoi(get_qoi)[source]

Decorator that ensures QoIs are annotated properly.

To be applied to the get_qoi() method.

Parameters:

get_qoi – a function mapping a dictionary of solution data and an integer index to a QoI function

class AdjointMeshSeq(time_partition, initial_meshes, **kwargs)[source]

Bases: MeshSeq

An extension of MeshSeq to account for solving adjoint problems on a sequence of meshes.

For time-dependent quantities of interest, the solver should access and modify J, which holds the QoI value.

property initial_condition

Get the initial conditions associated with the first subinterval.

Returns:

a dictionary whose keys are field names and whose values are the corresponding initial conditions applied on the first subinterval

Return type:

AttrDict with str keys and firedrake.function.Function values

get_qoi(subinterval)[source]

Get the function for evaluating the QoI, which has either zero or one arguments, corresponding to either an end time or time integrated quantity of interest, respectively. If the QoI has an argument then it is for the current time.

Signature for the function to be returned: ` :arg t: the current time (for time-integrated QoIs) :type t: :class:`float` :return: the QoI as a 0-form :rtype: :class:`ufl.form.Form` `

Parameters:
  • solution_map (dict with str keys and values and firedrake.function.Function values) – a dictionary whose keys are the solution field names and whose values are the corresponding solutions

  • subinterval (int) – the subinterval index

Returns:

the function for obtaining the QoI

Return type:

see docstring above

get_checkpoints(solver_kwargs=None, run_final_subinterval=False)[source]

Solve forward on the sequence of meshes, extracting checkpoints corresponding to the starting fields on each subinterval.

The QoI is also evaluated.

Parameters:
  • solver_kwargs (dict with str keys and values which may take various types) – additional keyword arguments to be passed to the solver

  • run_final_subinterval (bool) – if True, the solver is run on the final subinterval

Returns:

checkpoints for each subinterval

Return type:

list of firedrake.function.Functions

get_solve_blocks(field, subinterval, has_adj_sol=True)[source]

Get all blocks of the tape corresponding to solve steps for prognostic solution field on a given subinterval.

Parameters:
  • field (str) – name of the prognostic solution field

  • subinterval (int) – subinterval index

  • has_adj_sol (bool) – if True, only blocks with adj_sol attributes will be considered

Returns:

list of solve blocks

Return type:

list of pyadjoint.block.Blocks

solve_adjoint(solver_kwargs=None, adj_solver_kwargs=None, get_adj_values=False, test_checkpoint_qoi=False)[source]

Solve an adjoint problem on a sequence of subintervals.

As well as the quantity of interest value, solution fields are computed - see AdjointSolutionData for more information.

Parameters:
  • solver_kwargs (dict with str keys and values which may take various types) – parameters for the forward solver, as well as any parameters for the QoI, which should be included as a sub-dictionary with key ‘qoi_kwargs’

  • adj_solver_kwargs (dict with str keys and values which may take various types) – parameters for the adjoint solver

  • get_adj_values (bool) – if True, adjoint actions are also returned at exported timesteps

  • test_checkpoint_qoi – solve over the final subinterval when checkpointing so that the QoI value can be checked across runs

Returns:

the solution data of the forward and adjoint solves

Return type:

AdjointSolutionData

static th(num)[source]

Convert from cardinal to ordinal.

Parameters:

num (int) – the cardinal number to convert

Returns:

the corresponding ordinal number

Return type:

str

check_qoi_convergence()[source]

Check for convergence of the fixed point iteration due to the relative difference in QoI value being smaller than the specified tolerance.

Returns:

True if QoI convergence is detected, else False

Return type:

bool

goalie.error_estimation module

Tools to automate goal-oriented error estimation.

form2indicator(F)[source]

Given a 0-form, multiply the integrand of each of its integrals by a \(\mathbb P0\) test function and reassemble to give an element-wise error indicator.

Note that a 0-form does not contain any firedrake.ufl_expr.TestFunctions or firedrake.ufl_expr.TrialFunctions.

Parameters:

F (ufl.form.Form) – the 0-form

Returns:

the corresponding error indicator field

Return type:

firedrake.function.Function

get_dwr_indicator(F, adjoint_error, test_space=None)[source]

Given a 1-form and an approximation of the error in the adjoint solution, compute a dual weighted residual (DWR) error indicator.

Note that each term of a 1-form contains only one firedrake.ufl_expr.TestFunction. The 1-form most commonly corresponds to the variational form of a PDE. If the PDE is linear, it should be written as in the nonlinear case (i.e., with the solution field in place of any firedrake.ufl_expr.TrialFunctions.

Parameters:
  • F (ufl.form.Form) – the form

  • adjoint_error (firedrake.function.Function or dict with str keys and firedrake.function.Function values) – a dictionary whose keys are field names and whose values are the approximations to the corresponding components of the adjoint error, or a single such component

  • test_space (firedrake.functionspaceimpl.WithGeometry) – a dictionary whose keys are field names and whose values are the test spaces for the corresponding fields, or a single such test space (or None to determine the test space(s) automatically)

Returns:

the DWR indicator

Return type:

firedrake.function.Function

goalie.function_data module

Nested dictionaries of solution data Functions.

class FunctionData(time_partition, function_spaces)[source]

Bases: ABC

Abstract base class for classes holding field data.

items()[source]
extract(layout='field')[source]

Extract field data array in a specified layout.

The default layout is a doubly-nested dictionary whose first key is the field name and second key is the field label. Entries of the doubly-nested dictionary are doubly-nested lists, indexed first by subinterval and then by export. That is: data[field][label][subinterval][export].

Choosing a different layout simply promotes the specified variable to first access: * layout == "label" implies data[label][field][subinterval][export] * layout == "subinterval" implies

data[subinterval][field][label][export]

The export index is not promoted because the number of exports may differ across subintervals.

Parameters:

layout (str) – the layout to promote, as described above

export(output_fpath, export_field_types=None, initial_condition=None)[source]

Export field data to a file. The file format is determined by the extension of the output file path. Supported formats are ‘.pvd’ and ‘.h5’.

If the output file format is ‘.pvd’, the data is exported as a series of VTK files using Firedrake’s VTKFile. Since mixed function spaces are not supported by VTK, each subfunction of a mixed function is exported separately. If initial conditions are provided and fields other than ‘forward’ are to be exported, the initial values of these other fields are set to ‘nan’ since they are not defined at the initial time (e.g., ‘adjoint’ fields).

If the output file format is ‘.h5’, the data is exported as a single HDF5 file using Firedrake’s CheckpointFile. If names of meshes in the mesh sequence are not unique, they are renamed to "mesh_i", where i is the subinterval index. Functions are saved with names of the form "field_label". Initial conditions are named in the form "field_initial". The exported data may then be loaded using, for example,

with CheckpointFile(output_fpath, "r") as afile:
    first_mesh = afile.load_mesh("mesh_0")
    initial_condition = afile.load_function(first_mesh, "u_initial")
    first_export = afile.load_function(first_mesh, "u_forward", idx=0)
Parameters:
  • output_fpath (str) – the path to the output file

  • export_field_types (str or list of str) – the field types to export; defaults to all available field types

  • initial_condition (dict of Function) – if provided, exports the provided initial condition for ‘forward’ fields.

transfer(target, method='interpolate')[source]

Transfer all functions from this FunctionData object to the target FunctionData object by interpolation, projection or prolongation.

Parameters:
  • target (FunctionData) – the target FunctionData object to which to transfer the data

  • method (str) – the transfer method to use. Either ‘interpolate’, ‘project’ or ‘prolong’

class ForwardSolutionData(*args, **kwargs)[source]

Bases: FunctionData

Class representing solution data for general forward problems.

For a given exported timestep, the field types are:

  • 'forward': the forward solution after taking the timestep;

  • 'forward_old': the forward solution before taking the timestep (provided the problem is not steady-state).

class AdjointSolutionData(*args, **kwargs)[source]

Bases: FunctionData

Class representing solution data for general adjoint problems.

For a given exported timestep, the field types are:

  • 'forward': the forward solution after taking the timestep;

  • 'forward_old': the forward solution before taking the timestep (provided the problem is not steady-state)

  • 'adjoint': the adjoint solution after taking the timestep;

  • 'adjoint_next': the adjoint solution before taking the timestep backwards (provided the problem is not steady-state).

class IndicatorData(time_partition, meshes)[source]

Bases: FunctionData

Class representing error indicator data.

Note that this class has a single dictionary with the field name as the key, rather than a doubly-nested dictionary.

goalie.go_mesh_seq module

Drivers for goal-oriented error estimation on sequences of meshes.

class GoalOrientedMeshSeq(*args, **kwargs)[source]

Bases: AdjointMeshSeq

An extension of AdjointMeshSeq to account for goal-oriented problems.

read_forms(forms_dictionary)[source]

Read in the variational form corresponding to each prognostic field.

Parameters:

forms_dictionary (dict) – dictionary where the keys are the field names and the values are the UFL forms

property forms

Get the variational form associated with each prognostic field.

Returns:

dictionary where the keys are the field names and the values are the UFL forms

Return type:

dict

get_enriched_mesh_seq(enrichment_method='p', num_enrichments=1)[source]

Construct a sequence of globally enriched spaces.

The following global enrichment methods are supported: * h-refinement (enrichment_method='h') - refine each mesh element uniformly in each direction; * p-refinement (enrichment_method='p') - increase the function space polynomial order by one globally.

Parameters:
  • enrichment_method (str) – the method for enriching the mesh sequence

  • num_enrichments (int) – the number of enrichments to apply

Returns:

the enriched mesh sequence

Type:

the type is inherited from the parent mesh sequence

property indicators
Returns:

the error indicator data object

Return type:

IndicatorData

indicate_errors(enrichment_kwargs=None, solver_kwargs=None, indicator_fn=<cyfunction get_dwr_indicator>)[source]

Compute goal-oriented error indicators for each subinterval based on solving the adjoint problem in a globally enriched space.

Parameters:
  • enrichment_kwargs (dict with str keys and values which may take various types) – keyword arguments to pass to the global enrichment method - see get_enriched_mesh_seq() for the supported enrichment methods and options

  • solver_kwargs (dict with str keys and values which may take various types) – parameters for the forward solver, as well as any parameters for the QoI, which should be included as a sub-dictionary with key ‘qoi_kwargs’

  • indicator_fn – function which maps the form, adjoint error and enriched space(s) as arguments to the error indicator firedrake.function.Function

Returns:

solution and indicator data objects

Rtype1:

AdjointSolutionData

Rtype2:

IndicatorData

error_estimate(absolute_value=False)[source]

Deduce the error estimator value associated with error indicator fields defined over the mesh sequence.

Parameters:

absolute_value (bool) – if True, the modulus is taken on each element

Returns:

the error estimator value

Return type:

float

check_estimator_convergence()[source]

Check for convergence of the fixed point iteration due to the relative difference in error estimator value being smaller than the specified tolerance.

Returns:

True if estimator convergence is detected, else False

Return type:

bool

fixed_point_iteration(adaptor, parameters=None, update_params=None, enrichment_kwargs=None, adaptor_kwargs=None, solver_kwargs=None, indicator_fn=<cyfunction get_dwr_indicator>)[source]

Apply goal-oriented mesh adaptation using a fixed point iteration loop approach.

Parameters:
  • adaptor – function for adapting the mesh sequence. Its arguments are the mesh sequence and the solution and indicator data objects. It should return True if the convergence criteria checks are to be skipped for this iteration. Otherwise, it should return False.

  • parameters (GoalOrientedAdaptParameters) – parameters to apply to the mesh adaptation process

  • update_params – function for updating params at each iteration. Its arguments are the parameter class and the fixed point iteration

  • enrichment_kwargs (dict with str keys and values which may take various types) – keyword arguments to pass to the global enrichment method

  • solver_kwargs (dict with str keys and values which may take various types) – parameters to pass to the solver

  • adaptor_kwargs (dict with str keys and values which may take various types) – parameters to pass to the adaptor

  • indicator_fn – function which maps the form, adjoint error and enriched space(s) as arguments to the error indicator firedrake.function.Function

Returns:

solution and indicator data objects

Rtype1:

AdjointSolutionData

Rtype2:

IndicatorData

goalie.log module

Loggers for Goalie.

Code mostly copied from the Thetis project.

get_new_logger(name, fmt='%(levelname)s %(message)s')[source]
Parameters:
  • name (str) – the name for the logger

  • fmt (str) – format string to use

Returns:

logger instance

Return type:

logging.StreamHandler

set_log_level(level)[source]

goalie.math module

bessi0(x)[source]

Modified Bessel function of the first kind.

Code taken from [Vetterling et al., 1992].

bessk0(x)[source]

Modified Bessel function of the second kind.

Code taken from [Vetterling et al., 1992].

goalie.mesh_seq module

Sequences of meshes corresponding to a TimePartition.

class MeshSeq(time_partition, initial_meshes, **kwargs)[source]

Bases: object

A sequence of meshes for solving a PDE associated with a particular TimePartition of the temporal domain.

debug(msg)[source]

Print a debug message.

Parameters:

msg (str) – the message to print

warning(msg)[source]

Print a warning message.

Parameters:

msg (str) – the message to print

info(msg)[source]

Print an info level message.

Parameters:

msg (str) – the message to print

count_elements()[source]

Count the number of elements in each mesh in the sequence.

Returns:

list of element counts

Return type:

list of ints

count_vertices()[source]

Count the number of vertices in each mesh in the sequence.

Returns:

list of vertex counts

Return type:

list of ints

set_meshes(meshes)[source]

Set all meshes in the sequence and deduce various properties.

Parameters:

meshes (list of firedrake.MeshGeometrys or firedrake.MeshGeometry) – list of meshes to use in the sequence, or a single mesh to use for all subintervals

plot(fig=None, axes=None, **kwargs)[source]

Plot the meshes comprising a 2D MeshSeq.

Parameters:
  • fig (matplotlib.figure.Figure) – matplotlib figure to use

  • axes (matplotlib.axes._axes.Axes) – matplotlib axes to use

Returns:

matplotlib figure and axes for the plots

Rtype1:

matplotlib.figure.Figure

Rtype2:

matplotlib.axes._axes.Axes

All keyword arguments are passed to firedrake.pyplot.triplot().

get_function_spaces(mesh)[source]

Construct the function spaces corresponding to each field, for a given mesh.

Parameters:

mesh (firedrake.mesh.MeshGeometry) – the mesh to base the function spaces on

Returns:

a dictionary whose keys are field names and whose values are the corresponding function spaces

Return type:

dict with str keys and firedrake.functionspaceimpl.FunctionSpace values

get_initial_condition()[source]

Get the initial conditions applied on the first mesh in the sequence.

Returns:

the dictionary, whose keys are field names and whose values are the corresponding initial conditions applied

Return type:

dict with str keys and firedrake.function.Function values

get_solver()[source]

Get the function mapping a subinterval index and an initial condition dictionary to a dictionary of solutions for the corresponding solver step.

Signature for the function to be returned: ```

arg index:

the subinterval index

type index:

int

arg ic:

map from fields to the corresponding initial condition components

type ic:

dict with str keys and firedrake.function.Function values

return:

map from fields to the corresponding solutions

rtype:

dict with str keys and firedrake.function.Function values

```

Returns:

the function for obtaining the solver

Return type:

see docstring above

property function_spaces

Get the function spaces associated with the mesh sequence.

Returns:

a dictionary whose keys are field names and whose values are the corresponding function spaces

Return type:

AttrDict with str keys and firedrake.functionspaceimpl.FunctionSpace values

property initial_condition

Get the initial conditions associated with the first subinterval.

Returns:

a dictionary whose keys are field names and whose values are the corresponding initial conditions applied on the first subinterval

Return type:

AttrDict with str keys and firedrake.function.Function values

property solver

See get_solver().

property solutions
Returns:

the solution data object

Return type:

FunctionData

get_checkpoints(run_final_subinterval=False, solver_kwargs=None)[source]

Get checkpoints corresponding to the starting fields on each subinterval.

Parameters:
  • run_final_subinterval (bool) – if True, the solver is run on the final subinterval

  • solver_kwargs (dict with str keys and values which may take various types) – parameters for the forward solver

Returns:

checkpoints for each subinterval

Return type:

list of firedrake.function.Functions

solve_forward(solver_kwargs=None)[source]

Solve a forward problem on a sequence of subintervals.

A dictionary of solution fields is computed - see ForwardSolutionData for more details.

Parameters:

solver_kwargs (dict whose keys are strs and whose values may take various types) – parameters for the forward solver

Returns:

the solution data of the forward solves

Return type:

ForwardSolutionData

check_element_count_convergence()[source]

Check for convergence of the fixed point iteration due to the relative difference in element count being smaller than the specified tolerance.

Returns:

an array, whose entries are True if convergence is detected on the corresponding subinterval

Return type:

list of bools

fixed_point_iteration(adaptor, parameters=None, update_params=None, solver_kwargs=None, adaptor_kwargs=None)[source]

Apply mesh adaptation using a fixed point iteration loop approach.

Parameters:
  • adaptor – function for adapting the mesh sequence. Its arguments are the mesh sequence and the solution data object. It should return True if the convergence criteria checks are to be skipped for this iteration. Otherwise, it should return False.

  • parameters (AdaptParameters) – parameters to apply to the mesh adaptation process

  • update_params – function for updating params at each iteration. Its arguments are the parameter class and the fixed point iteration

  • solver_kwargs (dict with str keys and values which may take various types) – parameters to pass to the solver

  • adaptor_kwargs (dict with str keys and values which may take various types) – parameters to pass to the adaptor

Returns:

solution data object

Return type:

ForwardSolutionData

goalie.metric module

Driver functions for metric-based mesh adaptation.

enforce_variable_constraints(metrics, h_min=1e-30, h_max=1e+30, a_max=100000.0, boundary_tag=None)[source]

Post-process a list of metrics to enforce minimum and maximum element sizes, as well as maximum anisotropy.

Parameters:
space_time_normalise(metrics, time_partition, metric_parameters, global_factor=None, boundary=False, restrict_sizes=True, restrict_anisotropy=True)[source]

Apply \(L^p\) normalisation in both space and time.

Based on Equation (1) in [Barral et al., 2016].

Parameters:
  • metrics (list of RiemannianMetrics) – the metrics associated with each subinterval

  • time_partition (TimePartition) – temporal discretisation for the problem at hand

  • metric_parameters (list of dicts or a single dict to use for all subintervals) – dictionary containing the target space-time metric complexity under dm_plex_metric_target_complexity and the normalisation order under dm_plex_metric_p, or a list thereof

  • global_factor (float) – pre-computed global normalisation factor

  • boundary (bool) – if True, the normalisation to be performed over the boundary

  • restrict_sizes (bool) – if True, minimum and maximum metric magnitudes are enforced

  • restrict_anisotropy (bool) – if True, maximum anisotropy is enforced

Returns:

the space-time normalised metrics

Return type:

list of RiemannianMetrics

ramp_complexity(base, target, iteration, num_iterations=3)[source]

Ramp up the target complexity over the first few iterations.

Parameters:
  • base (float) – the base complexity to start from

  • target (float) – the desired complexity

  • iteration (int) – the current iteration

  • num_iterations (int) – how many iterations to ramp over?

Returns:

the ramped target complexity

Return type:

float

goalie.options module

class AdaptParameters(parameters=None)[source]

Bases: AttrDict

A class for holding parameters associated with adaptive mesh fixed point iteration loops.

class GoalOrientedAdaptParameters(parameters=None)[source]

Bases: AdaptParameters

A class for holding parameters associated with goal-oriented adaptive mesh fixed point iteration loops.

goalie.plot module

Driver functions for plotting solution data.

plot_snapshots(solutions, time_partition, field, label, **kwargs)[source]

Plot a sequence of snapshots associated with solutions.field.label and a given TimePartition.

Any keyword arguments are passed to firedrake.plot.tricontourf().

Parameters:
  • solutionsAttrDict of solutions computed by solving a forward or adjoint problem

  • time_partition – the TimePartition object used to solve the problem

  • field – solution field of choice

  • label – choose from 'forward', 'forward_old' 'adjoint' and 'adjoint_next'

plot_indicator_snapshots(indicators, time_partition, field, **kwargs)[source]

Plot a sequence of snapshots associated with indicators and a given TimePartition

Any keyword arguments are passed to firedrake.plot.tricontourf().

Parameters:
  • indicators – list of list of indicators, indexed by mesh sequence index, then timestep

  • time_partition – the TimePartition object used to solve the problem

goalie.point_seq module

class PointSeq(time_partition, **kwargs)[source]

Bases: MeshSeq

A simplified subset of MeshSeq for ODE problems.

In this version, a single mesh comprised of a single vertex is shared across all subintervals.

set_meshes(mesh)[source]

Update the mesh associated with the PointSeq, as well as the associated attributes.

Parameters:

mesh – the vertex-only mesh

goalie.time_partition module

Partitioning for the temporal domain.

class TimePartition(end_time, num_subintervals, timesteps, field_names, num_timesteps_per_export=1, start_time=0.0, subintervals=None, field_types=None)[source]

Bases: object

A partition of the time interval of interest into subintervals.

The subintervals are assumed to be uniform in length. However, different timestep values may be used on each subinterval.

debug(attr)[source]

Print attribute ‘msg’ for debugging purposes.

Parameters:

attr – the attribute to display debugging information for

property num_timesteps

:returns the total number of timesteps :rtype: int

class TimeInterval(*args, **kwargs)[source]

Bases: TimePartition

A trivial TimePartition with a single subinterval.

property timestep
Returns:

the timestep used on the single interval

Return type:

float

class TimeInstant(field_names, **kwargs)[source]

Bases: TimeInterval

A TimePartition for steady-state problems.

Under the hood this means dividing \([0,1)\) into a single timestep.

goalie.utility module

Utility functions and classes for mesh adaptation.

class AttrDict(*args, **kwargs)[source]

Bases: dict

Dictionary that provides both self[key] and self.key access to members.

Disclaimer: Copied from stackoverflow.

effectivity_index(error_indicator, Je)[source]

Compute the overestimation factor of some error estimator for the QoI error.

Note that this is only typically used for simple steady-state problems with analytical solutions.

Parameters:
  • error_indicator (firedrake.function.Function) – a \(\mathbb P0\) error indicator which localises contributions to an error estimator to individual elements

  • Je (float) – the error in the quantity of interest

Returns:

the effectivity index

Return type:

float

create_directory(path, comm=<mpi4py.MPI.Intracomm object>)[source]

Create a directory on disk.

Disclaimer: Code copied from Thetis.

Parameters:
  • path (str) – path to the directory

  • comm (mpi4py.MPI.Intracomm) – MPI communicator

Returns:

the path in absolute form

Rtype path:

str

Module contents