Gridap.Fields
Gridap.Fields
— ModuleThis module provides:
- An interface for physical fields, basis of physical fields and related objects.
- Helpers functions to work with fields and arrays of fields.
- Helpers functions to create lazy operation trees from fields and arrays of fields
The exported names are:
AffineMap
Field
Homothecy
Point
apply_kernel_to_field
apply_lincomb
apply_to_field_array
attachmap
compose
compose_field_arrays
compose_fields
curl
divergence
evaluate
evaluate!
evaluate_field
evaluate_field!
evaluate_field_array
evaluate_fields
evaluate_fields!
field_array_cache
field_array_gradient
field_array_operation
field_cache
field_caches
field_gradient
field_gradients
field_operation
field_return_type
field_return_types
grad2curl
gradient
gradient_type
integrate
laplacian
lincomb
symmetric_gradient
test_array_of_fields
test_field
Δ
ε
∇
Interface
Gridap.Fields.Field
— Typeabstract type Field <: Kernel
Abstract type representing physical fields, bases of fields, and other related objects. These different cases are distinguished by the return value obtained when evaluating them. E.g., a physical field returns a vector of values when evaluated at a vector of points, and a basis of nf
fields returns a 2d matrix (np
x nf
) when evaluated at a vector of np
points.
The following functions need to be overloaded:
The following functions can be also provided optionally
Moreover, if the field_gradient(f)
is not provided, a default implementation that uses the following functions will be used.
In order to be able to call field_gradient
again on the resulting object the following methods have to be provided
These four methods are only designed to be called by the default implementation of field_gradient(f)
and thus cannot be assumed that they are available for an arbitrary field. For this reason, these functions are not exported. The general way of evaluating a gradient of a field is to build the gradient with field_gradient(f)
and evaluating the resulting object. For evaluating the hessian, use two times field_gradient
.
The interface can be tested with
Most of the functionality implemented in terms of this interface relies in duck typing (this is why all functions in the interface have the word "field"). Thus, it is not strictly needed to work with types that inherit from Field
. This is specially useful in order to accommodate existing types into this framework without the need to implement a wrapper type that inherits from Field
. For instance, a default implementation is available for numbers, which behave like "constant" fields, or arrays of numbers, which behave like "constant" bases of fields. However, we recommend that new types inherit from Field
.
Gridap.Fields.Point
— Typeconst Point{D,T} = VectorValue{D,T}
Type representing a point of D dimensions with coordinates of type T. Fields are evaluated at vectors of Point
objects.
Gridap.Fields.evaluate_field!
— Methodevaluate_field!(cache, f, x)
Returns an array containing the values of evaluating the field f
at the vector of points x
by (possibly) using the scratch data in the cache
object. The returned value is an array, for which the length of the first axis is length(x)
, i.e., the number of points where the field has been evaluated.E.g., a physical field returns a vector of np
values when evaluated at a vector of np
points, and a basis of nf
fields returns a 2d matrix (np
x nf
) when evaluated at a vector of np
points.
This choice is made
- for performance reasons when integrating fields (i.e., adding contributions at different points) since the added values are closer in memory with this layout.
- In order to simplify operations between field objects. E.g., the result of evaluating a physical field and a basis of
nf
fields at a vector ofnp
points (which leads to a vector and a matrix of size(np,)
and(np,nf)
respectively) can be conveniently added with the broadcasted sum.+
operator.
The cache
object is computed with the field_cache
function.
Gridap.Fields.field_cache
— Methodfield_cache(f, x)
Returns the cache object needed to evaluate field f
at the vector of points x
.
Gridap.Fields.field_gradient
— Methodfield_gradient(f)
Returns another field that represents the gradient of the given one
Gridap.Fields.field_return_type
— Methodfield_return_type(f, x)
Computes the type obtained when evaluating field f
at point x
. It returns typeof(evaluate_field(f,x))
by default.
Gridap.Fields.evaluate_gradient!
— Methodevaluate_gradient!(cache, f, x)
Gridap.Fields.gradient_cache
— Methodgradient_cache(f, x)
Gridap.Fields.evaluate_hessian!
— Methodevaluate_hessian!(cache, f, x)
Gridap.Fields.hessian_cache
— Methodhessian_cache(cache, x)
Gridap.Fields.test_field
— Functiontest_field(
f,
x::AbstractVector{<:Point},
v::AbstractArray,cmp=(==);
grad=nothing,
hessian=nothing)
Function used to test the field interface. v
is an array containing the expected result of evaluating the field f
at the vector of points x
. The comparison is performed using the cmp
function. For fields objects that support the field_gradient
function, the key-word argument grad
can be used. It should contain the result of evaluating field_gradient(f)
at x. Idem for hessian
. The checks are performed with the @test
macro.
Helper functions using fields
Gridap.Fields.evaluate_field
— Methodevaluate_field(f, x)
Evaluates the field f
at the vector of points x
by creating a temporary cache internally. Equivalent to
c = field_cache(f,x)
evaluate_field!(c,f,x)
Gridap.Fields.evaluate
— Methodevaluate(f::Field,x)
Equivalent to
evaluate_field(f,x)
But only for types that inherit from Field
. Types that implement the field interface but not inherit from Field
(e.g., numbers and arrays of numbers) cannot use this function. Use evaluate_field
instead.
Gridap.Fields.evaluate!
— Methodevaluate!(cache,f::Field,x)
Equivalent to
evaluate_field!(cache,f,x)
But only for types that inherit from Field
. Types that implement the field interface but not inherit from Field
(e.g., numbers and arrays of numbers) cannot use this function. Use evaluate_field!
instead.
Gridap.Fields.gradient
— Methodgradient(f::Field)
Equivalent to
field_gradient(f)
But only for types that inherit from Field
. Types that implement the field interface but not inherit from Field
(e.g., numbers and arrays of numbers) cannot use this function. Use field_gradient
instead.
Gridap.Fields.∇
— Functionconst ∇ = gradient
Alias for the gradient
function.
Gridap.Fields.gradient_type
— Functiongradient_type(::Type{T},x::Point) where T
Working with several fields at once
Gridap.Fields.field_return_types
— Methodfield_return_types(f::Tuple,x) -> Tuple
Computes a tuple with the return types of the fields in the tuple f
when evaluated at the vector of points x
Equivalent to
tuple(( field_return_type(fi,x) for fi in f)...)
Gridap.Fields.field_caches
— Methodfield_caches(f::Tuple,x) -> Tuple
Equivalent to
tuple((field_cache(fi,x) for fi in f)...)
Gridap.Fields.evaluate_fields
— Methodevaluate_fields(f::Tuple,x) -> Tuple
Equivalent to
tuple((evaluate_fields(fi,x) for fi in f)...)
Gridap.Fields.evaluate_fields!
— Methodevaluate_fields!(cf::Tuple,f::Tuple,x) -> Tuple
Equivalent to
tuple((evaluate_fields!(ci,fi,x) for (ci,fi) in zip(c,f))...)
Gridap.Fields.field_gradients
— Methodfield_gradients(b...) -> Tuple
Equivalent to
map(field_gradient,b)
Gridap.Fields.gradient_all
— Methodgradient_all(b...) -> Tuple
Equivalent to
map(gradient,b)
Gridap.Fields.evaluate_all
— Methodevaluate_all(f::Tuple,x) -> Tuple
Equivalent to
tuple((evaluate(fi,x) for fi in f)...)
Applying kernels to fields
Gridap.Fields.apply_kernel_to_field
— Methodapply_kernel_to_field(k,f...) -> Field
Returns a field obtained by applying the kernel k
to the values of the fields in f
. That is, the returned field evaluated at a vector of points x
provides the value obtained by applying kernel k
to the values of the fields f
at the vector of points x
. Formally, the resulting field at a vector of points x
is defined as
fx = evaluate_fields(f,x)
apply_kernel(k,fx...)
In order to be able to call the field_gradient
function of the resulting field, one needs to define the gradient operator associated with the underlying kernel. This is done by adding a new method to apply_kernel_gradient(k,f...)
for each kernel type.
Gridap.Fields.apply_kernel_gradient
— Methodapply_kernel_gradient(k,f...)
Returns a field representing the gradient of the field obtained with
apply_kernel_to_field(k,f...)
Working with arrays of fields
Gridap.Fields.evaluate_field_array
— Methodevaluate_field_array(f::AbstractArray,x::AbstractArray) -> AbstractArray
Evaluates the fields in the array f
at all the vector of points in the array of vector of points x
and returns the result as a lazy array.
The result is numerically equivalent to
map(evaluate_field,a,x)
Gridap.Fields.evaluate
— Methodevaluate(a::AbstractArray{<:Field},x::AbstractArray)
Equivalent to
evaluate_field_array(a,x)
But only for arrays a
whose element type inherits from Field
. If this is not the case, use evaluate_field_array(a,x)
instead.
Gridap.Fields.field_array_gradient
— Methodfield_array_gradient(a::AbstractArray)
Returns an array containing the gradients of the fields in the array a
. Numerically equivalent to
map(field_gradient,a)
Gridap.Fields.gradient
— Methodgradient(f::AbstractArray{<:Field})
Equivalent to
field_array_gradient(f)
but only for arrays whose element type is <:Field
. Use function field_array_gradient
otherwise.
Gridap.Fields.field_array_cache
— Methodfield_array_cache(a::AbstractArray,x::AbstractArray) -> Tuple
Returns the caches needed to perform the following iteration
ca, cfi, cx = field_array_cache(a,x)
for i in length(a)
fi = getindex!(ca,a,i)
xi = getindex!(cx,x,i)
fxi = evaluate!(cfi,fi,xi)
end
Gridap.Fields.test_array_of_fields
— Functionfunction test_array_of_fields(
a::AbstractArray,
x::AbstractArray,
v::AbstractArray,
cmp::Function=(==);
grad = nothing)
Function to test an array of fields a
. The array v
is the expected result when calling evaluate_field_array(a,x)
. The entries in the computed array and the expected one are compared with the cmp
function. The key-word argument grad
is optional. If present, it should contain the expected result of
∇a = field_array_gradient(a)
evaluate_field_array(∇a,x)
Working with several arrays of fields at once
Gridap.Fields.evaluate_field_arrays
— Methodevaluate_field_arrays(f::Tuple,x::AbstractArray) -> Tuple
Equivalent to
tuple((evaluate_field_array(fi,x) for fi in f)...)
Gridap.Fields.field_array_gradients
— Methodfield_array_gradients(f...)
Equivalent to
map(field_array_gradient,f)
Applying kernels to arrays of fields
Gridap.Fields.apply_to_field_array
— Methodapply_to_field_array(k,f::AbstractArray...)
apply_to_field_array(::Type{T},k,f::AbstractArray...) where T
Returns an array of fields numerically equivalent to
map( (x...) -> apply_kernel_to_field(k,x...), f )
Gridap.Fields.kernel_evaluate
— Methodkernel_evaluate(k,x,f...)
Function to control the evaluation of the field resulting from the operation apply(k,f...)
, where k
is a kernel and f...
contains several arrays of fields.
By default, this function is implemented as
g = apply(k,f...)
evaluate_field_array(g,x)
However, it can be rewritten for specific kernels in order to improve performance and simplify the underlying operation tree.
Gridap.Fields.apply_gradient
— Methodapply_gradient(k,f...)
Function to control the generation of the gradient the field resulting from the operation apply(k,f...)
, where k
is a kernel and f...
contains several arrays of fields.
By default, it returns the array obtained as
a = apply(k,f...)
field_array_gradient(a)
However, it can be rewritten for specific kernels in order to improve performance and simplify the underlying operation tree.
Operations on fields and arrays of fields
Gridap.Fields.field_operation
— Methodfield_operation(op::Function,a)
field_operation(op::Function,a,b)
Gridap.Fields.field_array_operation
— Methodfield_array_operation(op::Function,a)
field_array_operation(op::Function,a,b)
field_array_operation(::Type{T},op::Function,a) where T
field_array_operation(::Type{T},op::Function,a,b) where T
Gridap.Fields.compose_fields
— Methodcompose_fields(g,f)
Gridap.Fields.compose_field_arrays
— Methodcompose_field_arrays(g,f)
Gridap.Fields.compose
— Methodcompose(g::Field,f::Field)
Gridap.Fields.compose
— Methodcompose(g::AbstractArray{<:Field},f::AbstractArray{<:Field})
Gridap.Fields.compose
— Methodcompose(g::Function,f...)
Returns a new field obtained by composition of function g
and the fields f
. The value of the resulting field at a vector of points x
is numerically equivalent to
fx = evaluate_fields(f,x)
apply_kernel(bcast(g), fx...)
The gradient of the resulting field evaluated at a vector of points x
is equivalent to
fx = evaluate_fields(f,x)
apply_kernel(bcast(gradient(g)), fx...)
Note that it is needed to overload gradient(::typeof(g))
for the given function g
in order to be able to compute the gradient.
As in function apply_kernel_to_field
if any of the inputs in f
is a number or an array instead of a field it will be treated as a "constant field".
Gridap.Fields.compose
— Methodcompose(g::Function,f::AbstractArray...)
Returns an array of fields numerically equivalent to
map( (x...)->compose(g,x...), f...)
Gridap.Fields.lincomb
— Methodlincomb(a::Field,b::AbstractVector)
Returns a field obtained by the "linear combination" of the value of the field basis a
and the coefficient vector b
. The value of the resulting field evaluated at a vector of points x
is defined as
ax = evaluate(a,x)
ax*b
On the other hand, the gradient of the resulting field is defined as
∇ax = evaluate(gradient(a),x)
∇ax*b
Gridap.Fields.lincomb
— Methodlincomb(a::AbstractArray{<:Field},b::AbstractArray)
Returns an array of fields numerically equivalent to
map(lincomb,a,b)
Gridap.Fields.apply_lincomb
— Methodapply_lincomb(ax,b)
Gridap.Fields.attachmap
— Methodattachmap(f,phi)
Gridap.Fields.attachmap
— Methodattachmap(f::AbstractArray,phi::AbstractArray)
Gridap.Fields.integrate
— Methodintegrate(f,x,w,j)
Gridap.Fields.integrate
— Methodintegrate(f::AbstractArray,x,w,j)
Differential operators
In addition to the gradient
function already discussed, the following differential operators are defined.
Gridap.Fields.divergence
— Methoddivergence(f)
Gridap.Fields.symmetric_gradient
— Methodsymmetric_gradient(f)
Gridap.Fields.ε
— Functionconst ε = symmetric_gradient
Alias for the symmetric gradient
Gridap.Fields.curl
— Methodcurl(f)
Gridap.Fields.grad2curl
— Methodgrad2curl(∇f)
Gridap.Fields.laplacian
— Methodlaplacian(f)
Gridap.Fields.Δ
— Functionconst Δ = laplacian
Alias for the laplacian
function
A fancy way of typing the differential operators is via the nabla object defined in the library.
Base.:*
— Method∇*f
Equivalent to
divergence(f)
Gridap.TensorValues.outer
— Methodouter(∇,f)
Equivalent to
gradient(f)
Gridap.TensorValues.outer
— Methodouter(f,∇)
Equivalent to
transpose(gradient(f))
LinearAlgebra.cross
— Methodcross(∇,f)
Equivalent to
curl(f)
Concrete Field implementations
Gridap.Fields.Homothecy
— Typestruct Homothecy{D,T} <:Field
origin::Point{D,T}
scaling::Point{D,T}
end
This type is slightly more general than a homothecy since we allow anisotropic scalings.
Implements the Field
interface up to first order derivatives
Gridap.Fields.AffineMap
— Type