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:
AffineMapFieldHomothecyPointapply_kernel_to_fieldapply_lincombapply_to_field_arrayattachmapcomposecompose_field_arrayscompose_fieldscurldivergenceevaluateevaluate!evaluate_fieldevaluate_field!evaluate_field_arrayevaluate_fieldsevaluate_fields!field_array_cachefield_array_gradientfield_array_operationfield_cachefield_cachesfield_gradientfield_gradientsfield_operationfield_return_typefield_return_typesgrad2curlgradientgradient_typeintegratelaplacianlincombsymmetric_gradienttest_array_of_fieldstest_fieldΔε∇
Interface
Gridap.Fields.Field — Typeabstract type Field <: KernelAbstract 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
nffields at a vector ofnppoints (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 ∇ = gradientAlias for the gradient function.
Gridap.Fields.gradient_type — Functiongradient_type(::Type{T},x::Point) where TWorking with several fields at once
Gridap.Fields.field_return_types — Methodfield_return_types(f::Tuple,x) -> TupleComputes 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) -> TupleEquivalent to
tuple((field_cache(fi,x) for fi in f)...)Gridap.Fields.evaluate_fields — Methodevaluate_fields(f::Tuple,x) -> TupleEquivalent to
tuple((evaluate_fields(fi,x) for fi in f)...)Gridap.Fields.evaluate_fields! — Methodevaluate_fields!(cf::Tuple,f::Tuple,x) -> TupleEquivalent to
tuple((evaluate_fields!(ci,fi,x) for (ci,fi) in zip(c,f))...)Gridap.Fields.field_gradients — Methodfield_gradients(b...) -> TupleEquivalent to
map(field_gradient,b)Gridap.Fields.gradient_all — Methodgradient_all(b...) -> TupleEquivalent to
map(gradient,b)Gridap.Fields.evaluate_all — Methodevaluate_all(f::Tuple,x) -> TupleEquivalent 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...) -> FieldReturns 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) -> AbstractArrayEvaluates 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) -> TupleReturns 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)
endGridap.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) -> TupleEquivalent 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 TReturns 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 TGridap.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*bOn the other hand, the gradient of the resulting field is defined as
∇ax = evaluate(gradient(a),x)
∇ax*bGridap.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_gradientAlias for the symmetric gradient
Gridap.Fields.curl — Methodcurl(f)Gridap.Fields.grad2curl — Methodgrad2curl(∇f)Gridap.Fields.laplacian — Methodlaplacian(f)Gridap.Fields.Δ — Functionconst Δ = laplacianAlias for the laplacian function
A fancy way of typing the differential operators is via the nabla object defined in the library.
Base.:* — Method∇*fEquivalent 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}
endThis 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