Fields

Overview

The Field classes are the central elements for implementing a platform portable CFD framework. Fields should allow to perform basic algebraic operations such as binary operations like the addition or subtraction of two fields, or scalar operations like the multiplication of a field with a scalar.

In the following, we will explain the implementation details of the field operations using the additions operator as an example. The block of code below shows an example implementation of the addition operator.

[[nodiscard]] Field<T> operator+(const Field<T>& rhs)
{
    Field<T> result(exec_, size_);
    result = *this;
    add(result, rhs);
    return result;
}

Besides creating a temporary for the result it mainly calls the free standing add function which is implemented in FieldOperations.hpp. This, in turn, dispatches to the addOp functor, that holds the actual addition kernels. In the case of addition this is implemented as a Kokkos::parallel_for function, see Kokkos documentation for more details.

using executor = typename Executor::exec;
auto a_f = a.field();
auto b_f = b.field();
Kokkos::parallel_for(
   Kokkos::RangePolicy<executor>(0, a_f.size()),
   KOKKOS_CLASS_LAMBDA(const int i) { a_f[i] = a_f[i] + b_f[i]; }
);

The code snippet also highlights another important aspect, the executor. The executor, here defines the Kokkos::RangePolicy, see Kokkos Programming Model. Besides defining the RangePolicy, the executor also holds functions for allocating and deallocationg memory. A full example of using NeoFOAMs fields with a GPU executor could be implemented as

NeoFOAM::GPUExecutor GPUExec {};
NeoFOAM::Field<NeoFOAM::scalar> GPUa(GPUExec, N);
NeoFOAM::fill(GPUa, 1.0);
NeoFOAM::Field<NeoFOAM::scalar> GPUb(GPUExec, N);
NeoFOAM::fill(GPUb, 2.0);
auto GPUc = GPUa + GPUb;

Interface

template<typename ValueType>
class Field

A class to contain the data and executors for a field and define some basic operations.

Public Functions

inline Field(const Executor &exec, size_t size)

Create a Field with a given size on an executor.

Parameters:
  • exec – Executor associated to the matrix

  • size – size of the matrix

inline Field(const Executor &exec, std::vector<ValueType> in)

Create a Field with a given size on an executor.

Parameters:
  • exec – Executor associated to the matrix

  • in – a vector of elements to copy over

inline Field(const Field<ValueType> &rhs)
inline ~Field()

Destroy the Field object.

template<typename func>
inline void apply(func f)

applies a functor, transformation, to the field

Note

Ideally the f should be a KOKKOS_LAMBA

Parameters:

f – The functor to map over the field.

inline Field<ValueType> copyToExecutor(Executor dstExec) const

Copies the data to a new field on a specific executor.

Parameters:

dstExec – The executor on which the data should be copied.

Returns:

A copy of the field on the host.

inline Field<ValueType> copyToHost() const

Returns a copy of the field back to the host.

Returns:

A copy of the field on the host.

inline void copyToHost(Field<ValueType> &result)

Copies the data (from anywhere) to a parsed host field.

Warning

exits if the size of the result field is not the same as the source field.

Parameters:

result – The field into which the data must be copied. Must be sized.

inline KOKKOS_FUNCTION ValueType & operator() (const int i)

Function call operator.

Warning

This function is not implemented

Parameters:

i – The index of cell in the field

Returns:

The value at the index i

inline KOKKOS_FUNCTION const ValueType & operator() (const int i) const

Function call operator.

Warning

This function is not implemented

Parameters:

i – The index of cell in the field

Returns:

The value at the index i

inline void operator=(const Field<ValueType> &rhs)

Assignment operator, Sets the field values to that of the parsed field.

Warning

This field will be sized to the size of the parsed field.

Parameters:

rhs – The field to copy from.

inline void operator=(const ValueType &rhs)

Assignment operator, Sets the field values to that of the value.

Parameters:

rhs – The value to set the field to.

inline Field<ValueType> operator+(const Field<ValueType> &rhs)

Arithmetic add operator, addition of a second field.

Parameters:

rhs – The field to add with this field.

Returns:

The result of the addition.

inline Field<ValueType> operator-(const Field<ValueType> &rhs)

Arithmetic subtraction operator, subtraction by a second field.

Parameters:

rhs – The field to subtract from this field.

Returns:

The result of the subtraction.

inline Field<ValueType> operator*(const Field<scalar> &rhs)

Arithmetic subtraction operator, subtraction by a second field.

Parameters:

rhs – The field to subtract from this field.

Returns:

The result of the subtraction.

inline Field<ValueType> operator*(const scalar rhs)

Arithmetic multiply operator, multiplies every cell in the field by a scalar.

Parameters:

rhs – The scalar to multiply with the field.

Returns:

The result of the multiplication.

inline void setSize(const size_t size)

Set the Size of the field.

Parameters:

size – The new size to set the field to.

inline ValueType *data()

Direct access to the underlying field data.

Returns:

Pointer to the first cell data in the field.

inline const ValueType *data() const

Direct access to the underlying field data.

Returns:

Pointer to the first cell data in the field.

inline const Executor &exec() const

Gets the executor associated with the field.

Returns:

Reference to the executor.

inline size_t size() const

Gets the size of the field.

Returns:

The size of the field.

inline std::span<ValueType> span()

Gets the field as a span.

Returns:

Span of the field.

inline const std::span<ValueType> span() const

Gets the field as a span.

Returns:

Span of the field.

inline std::span<ValueType> span(std::pair<size_t, size_t> range)

Gets a sub view of the field as a span.

Returns:

Span of the field.

inline const std::span<ValueType> span(std::pair<size_t, size_t> range) const

Gets a sub view of the field as a span.

Returns:

Span of the field.