Gridap.Fields

Gridap.FieldsModule
source

Interface

Gridap.Fields.FieldType
abstract 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.

source
Gridap.Fields.PointType
const 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.

source
Gridap.Fields.evaluate_field!Method
evaluate_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 of np 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.

source
Gridap.Fields.field_return_typeMethod
field_return_type(f, x)

Computes the type obtained when evaluating field f at point x. It returns typeof(evaluate_field(f,x)) by default.

source
Gridap.Fields.test_fieldFunction
test_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.

source

Helper functions using fields

Gridap.Fields.evaluate_fieldMethod
evaluate_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)
source
Gridap.Fields.evaluateMethod
evaluate(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.

source
Gridap.Fields.evaluate!Method
evaluate!(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.

source
Gridap.Fields.gradientMethod
gradient(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.

source

Working with several fields at once

Gridap.Fields.field_return_typesMethod
field_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)...)
source

Applying kernels to fields

Gridap.Fields.apply_kernel_to_fieldMethod
apply_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.

source

Working with arrays of fields

Gridap.Fields.evaluate_field_arrayMethod
evaluate_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)
source
Gridap.Fields.evaluateMethod
evaluate(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.

source
Gridap.Fields.field_array_gradientMethod
field_array_gradient(a::AbstractArray)

Returns an array containing the gradients of the fields in the array a. Numerically equivalent to

map(field_gradient,a)
source
Gridap.Fields.gradientMethod
gradient(f::AbstractArray{<:Field})

Equivalent to

field_array_gradient(f)

but only for arrays whose element type is <:Field. Use function field_array_gradient otherwise.

source
Gridap.Fields.field_array_cacheMethod
field_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
source
Gridap.Fields.test_array_of_fieldsFunction
function 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)
source

Working with several arrays of fields at once

Applying kernels to arrays of fields

Gridap.Fields.apply_to_field_arrayMethod
apply_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 )
source
Gridap.Fields.kernel_evaluateMethod
kernel_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.

source
Gridap.Fields.apply_gradientMethod
apply_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.

source

Operations on fields and arrays of fields

Gridap.Fields.field_array_operationMethod
field_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
source
Gridap.Fields.composeMethod
compose(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".

source
Gridap.Fields.composeMethod
compose(g::Function,f::AbstractArray...)

Returns an array of fields numerically equivalent to

map( (x...)->compose(g,x...), f...)
source
Gridap.Fields.lincombMethod
lincomb(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
source
Gridap.Fields.lincombMethod
lincomb(a::AbstractArray{<:Field},b::AbstractArray)

Returns an array of fields numerically equivalent to

map(lincomb,a,b)
source

Differential operators

In addition to the gradient function already discussed, the following differential operators are defined.

A fancy way of typing the differential operators is via the nabla object defined in the library.

Concrete Field implementations

Gridap.Fields.HomothecyType
struct 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

source