jacobian_block_mod Module

Provides a derived type which is useful for representing blocks in a Jacobian matrix. This follows the abstract calculus pattern, providing operators for matrix multiplication and for solving the linear(ised) system. See the documentation for the jacobian_block type for more details.


Uses

  • module~~jacobian_block_mod~~UsesGraph module~jacobian_block_mod jacobian_block_mod logger_mod logger_mod module~jacobian_block_mod->logger_mod factual_mod factual_mod module~jacobian_block_mod->factual_mod f95_lapack f95_lapack module~jacobian_block_mod->f95_lapack iso_fortran_env iso_fortran_env module~jacobian_block_mod->iso_fortran_env penf penf module~jacobian_block_mod->penf module~boundary_types_mod boundary_types_mod module~jacobian_block_mod->module~boundary_types_mod

Used by

  • module~~jacobian_block_mod~~UsedByGraph module~jacobian_block_mod jacobian_block_mod module~ice_shelf_mod ice_shelf_mod module~ice_shelf_mod->module~jacobian_block_mod module~preconditioner_mod preconditioner_mod module~preconditioner_mod->module~jacobian_block_mod module~ice_sheet_mod ice_sheet_mod module~ice_sheet_mod->module~jacobian_block_mod

Contents


Variables

TypeVisibility AttributesNameInitial
integer, private, parameter:: no_extra_derivative =-1

Interfaces

public interface jacobian_block

  • private function constructor(source_field, direction, extra_derivative, boundary_locs, boundary_types, boundary_operations, coef) result(this)

    Author
    Chris MacMackin
    Date
    December 2016

    Build a block in a Jacobian matrix, with the form where is a scalar field and is the differentiation operator in the -direction. Additionally, a further differentiation operator may be added to the right hand side of this matrix block. Optional arguments allow for handling of boundary conditions. See the end of the documentation of the jacobian_block type for a description of how boundary conditions are treated.

    Arguments

    Type IntentOptional AttributesName
    class(scalar_field), intent(in) :: source_field

    A scalar field () making up this block of the Jacobian

    integer, intent(in) :: direction

    The direction in which field derivatives are taken.

    integer, intent(in), optional :: extra_derivative

    If present, specifies the direction of a differentiation operator to be added to the right hand side of this matrix block.

    integer, intent(in), optional dimension(:):: boundary_locs

    The locations in the raw representation of rhs for which boundary conditions are specified. Defaults to there being none.

    integer, intent(in), optional dimension(:):: boundary_types

    Integers specifying the type of boundary condition. The type of boundary condition corresponding to a given integer is specified in boundary_types_mod. Only Dirichlet and Neumann conditions are supported. Defaults to Dirichlet. The order in which they are stored must match that of boundary_locs.

    procedure(jacobian_block_bounds), optional :: boundary_operations

    A function specifying the values to place at the boundaries of the result when using the Jacobian block for multiplication. By default, all boundaries are set to 0. The order in which the resulting values are stored should match that of boundary_locs.

    real(kind=r8), intent(in), optional :: coef

    An optional coefficient by which the the term in the operator will be multipled. Default value is 1.

    Return Value type(jacobian_block)

    A new Jacobian block


Derived Types

type, public :: jacobian_block

A data type representing a submatrix of a Jacobian. Specifically, it represents the commonly occurring operation where is the differentiation operator in the -direction. Optionally, there can be an additional differentiation operator on the right-hand-side of this.

Read more…

Components

TypeVisibility AttributesNameInitial
integer, private :: direction

The direction in which any derivatives are taken.

integer, private :: extra_derivative =no_extra_derivative

The direction in which to apply a differentiation on the right-hand-side of the Jacobian block operator. Defaults none.

class(scalar_field), private, allocatable:: contents

The value, , to which the Jacobian block operation is beiing applied.

real(kind=r8), private :: coef =1._r8

Optional coefficient by which the the term in the operator will be multiplied.

procedure(jacobian_block_bounds), private, pointer, nopass:: get_boundaries

A subroutine which determines the expected boundary conditions (and their location in the raw array) for the solution of the Jacobian block.

class(scalar_field), private, allocatable:: derivative

The cached derivative of contents

real(kind=r8), private, dimension(:), allocatable:: diagonal

The diagonal of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: super_diagonal

The super-diagonal of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: sub_diagonal

The sub-diagonal of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: l_multipliers

Multipliers defining the L matrix in the LU factorisation of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: u_diagonal

The diagonal of the U matrix in the LU factorisation of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: u_superdiagonal1

The first superdiagonal of the U matrix in the LU factorisation of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: u_superdiagonal2

The second superdiagonal of the U matrix in the LU factorisation of the tridiagonal matrix representation of this block.

integer, private, dimension(:), allocatable:: pivots

Pivot indicies from the LU factorisation of the tridiagonal matrix representation of this block.

real(kind=r8), private, dimension(:), allocatable:: boundary_vals

Expected boundary values for the solution to the Jacobian block.

integer, private, dimension(:), allocatable:: boundary_locs

Locations in the raw arrays which are used to specify boundary conditions.

integer, private, dimension(:), allocatable:: boundary_types

The types of boundary conditions, specified using the parameters found in boundary_types_mod.

real(kind=r8), private :: real_increment

A scalar value which is to be added to this Jacobian block (i.e. to the diagonal).

class(scalar_field), private, allocatable:: field_increment

A scalar field which is to be added to this Jacobian block (i.e. to the diagonal).

type(jacobian_block), private, pointer:: block_increment=> null()

Another Jacobian block which is to be added to this one

integer, private :: has_increment =0

Indicates whether or not there has been an increment added to this block. If not, then 0. If a scalar real value has been added, then 1. If a scalar value has been added, then 2.

Constructor

private function constructor(source_field, direction, extra_derivative, boundary_locs, boundary_types, boundary_operations, coef)

Build a block in a Jacobian matrix, with the form where is a scalar field and is the differentiation operator in the -direction. Additionally, a further differentiation operator may be added to the right hand side of this matrix block. Optional arguments allow for handling of boundary conditions. See the end of the documentation of the jacobian_block type for a description of how boundary conditions are treated.

Type-Bound Procedures

procedure, private :: jacobian_block_multiply
procedure, private :: jacobian_block_add_real
procedure, private :: jacobian_block_add_field
procedure, private :: jacobian_block_add_block
procedure, private :: jacobian_block_assign
procedure, private :: get_tridiag => jacobian_block_get_tridiag
generic, public :: operator(*) => jacobian_block_multiply
generic, public :: operator(+) => jacobian_block_add_real, jacobian_block_add_field, jacobian_block_add_block
generic, public :: assignment(=) => jacobian_block_assign
procedure, public :: solve_for => jacobian_block_solve

Functions

private function constructor(source_field, direction, extra_derivative, boundary_locs, boundary_types, boundary_operations, coef) result(this)

Author
Chris MacMackin
Date
December 2016

Build a block in a Jacobian matrix, with the form where is a scalar field and is the differentiation operator in the -direction. Additionally, a further differentiation operator may be added to the right hand side of this matrix block. Optional arguments allow for handling of boundary conditions. See the end of the documentation of the jacobian_block type for a description of how boundary conditions are treated.

Arguments

Type IntentOptional AttributesName
class(scalar_field), intent(in) :: source_field

A scalar field () making up this block of the Jacobian

integer, intent(in) :: direction

The direction in which field derivatives are taken.

integer, intent(in), optional :: extra_derivative

If present, specifies the direction of a differentiation operator to be added to the right hand side of this matrix block.

integer, intent(in), optional dimension(:):: boundary_locs

The locations in the raw representation of rhs for which boundary conditions are specified. Defaults to there being none.

integer, intent(in), optional dimension(:):: boundary_types

Integers specifying the type of boundary condition. The type of boundary condition corresponding to a given integer is specified in boundary_types_mod. Only Dirichlet and Neumann conditions are supported. Defaults to Dirichlet. The order in which they are stored must match that of boundary_locs.

procedure(jacobian_block_bounds), optional :: boundary_operations

A function specifying the values to place at the boundaries of the result when using the Jacobian block for multiplication. By default, all boundaries are set to 0. The order in which the resulting values are stored should match that of boundary_locs.

real(kind=r8), intent(in), optional :: coef

An optional coefficient by which the the term in the operator will be multipled. Default value is 1.

Return Value type(jacobian_block)

A new Jacobian block

private recursive function jacobian_block_multiply(this, rhs) result(product)

Author
Chris MacMackin
Date
December 2016

Provides a matrix multiplication operator between a Jacobian block and a scalar field (which corresponds to a state vector).

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(in) :: this
class(scalar_field), intent(in) :: rhs

A field corresponding to a state vector being multiplied by the Jacobian block.

Return Value class(scalar_field), pointer

private function jacobian_block_add_real(this, rhs) result(sum)

Author
Chris MacMackin
Date
December 2016

Produces a Jacobian block which has been offset by some constant increment.

Read more…

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(in) :: this
real(kind=r8), intent(in) :: rhs

A scalar which should be added to this block

Return Value type(jacobian_block)

private function jacobian_block_add_field(this, rhs) result(sum)

Author
Chris MacMackin
Date
May 2017

Produces a Jacobian block which has been offset by a scalar field.

Read more…

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(in) :: this
class(scalar_field), intent(in) :: rhs

A scalar which should be added to this block

Return Value type(jacobian_block)

private function jacobian_block_add_block(this, rhs) result(sum)

Author
Chris MacMackin
Date
May 2017

Produces a Jacobian block which is the sum of two existing blocks. Boundary conditions are set by the first operand (this).

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(in) :: this
class(jacobian_block), intent(in), target:: rhs

A second block which should be added to this block

Return Value type(jacobian_block)

private function jacobian_block_solve(this, rhs) result(solution)

Author
Chris MacMackin
Date
December 2016

Solves the linear(ised) system represented by this Jacobian block, for a given right hand side state vector (represented by a scalar field).

Read more…

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(inout) :: this
class(scalar_field), intent(in) :: rhs

The right hand side of the linear(ised) system.

Return Value class(scalar_field), pointer


Subroutines

private subroutine jacobian_block_assign(this, rhs)

Author
Chris MacMackin
Date
December 2016

Copies the contents of the rhs Jacobian block into this one. It will safely deallocate any data necessary.

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(out) :: this
type(jacobian_block), intent(in) :: rhs

private recursive subroutine jacobian_block_get_tridiag(this, diagonal, subdiagonal, superdiagonal)

Author
Chris MacMackin
Date
May 2017

Computes the tridiagonal matrix used to solve for this Jacobian block.

Arguments

Type IntentOptional AttributesName
class(jacobian_block), intent(in) :: this
real(kind=r8), intent(out), dimension(:), allocatable:: diagonal
real(kind=r8), intent(out), dimension(:), allocatable:: subdiagonal
real(kind=r8), intent(out), dimension(:), allocatable:: superdiagonal

private subroutine jacobian_block_bounds(contents, derivative, rhs, boundary_locs, boundary_types, boundary_values)

Author
Chris MacMackin
Date
January 2016

A default implementation of the get_boundaries procedure pointer for the jacobian_block type. It corresponds to setting all boundaries to 0 when multiplying a field by the Jacobian block.

Arguments

Type IntentOptional AttributesName
class(scalar_field), intent(in) :: contents

The field used to construct the Jacobian block

class(scalar_field), intent(in) :: derivative

The first spatial derivative of the field used to construct the Jacobian block, in the direction specified

class(scalar_field), intent(in) :: rhs

The scalar field representing the vector being multiplied by Jacobian

integer, intent(in), dimension(:), allocatable:: boundary_locs

The locations in the raw representation of rhs containing the boundaries.

integer, intent(in), dimension(:), allocatable:: boundary_types

Integers specifying the type of boundary condition. The type of boundary condition corresponding to a given integer is specified in boundary_types_mod. Only Dirichlet and Neumann conditions are supported. The storage order must correspond to that of boundary_locs.

real(kind=r8), intent(out), dimension(:), allocatable:: boundary_values

The values to go at the boundaries when multiplying a field by the Jacobian block. The storage order must be the same as for boundary_locs.