specfem::assembly::fields

template<specfem::element::dimension_tag DimensionTag>
struct fields

Spectral element simulation fields management container.

This class provides storage and management for all simulation fields (wavefields) used in spectral element computations. It manages forward, adjoint, backward, and buffer fields for wave propagation simulations, seismic imaging, and full waveform inversion applications.

The class handles different simulation field types:

  • Forward fields: Primary wave propagation simulation

  • Adjoint fields: Reverse-time adjoint wave propagation

  • Backward fields: Backward propagation for gradient computation

  • Buffer fields: Temporary storage for checkpointing and I/O

Each field type contains the appropriate wavefield components based on the medium type (displacement for elastic, potential for acoustic, etc.) and spatial dimension. The class provides unified access to fields with efficient device/host memory management.

// Construct fields for forward simulation
specfem::assembly::fields<specfem::element::dimension_tag::dim2> sim_fields(
    mesh, element_types, specfem::simulation::type::forward);

// Access forward wavefield
auto forward_field = sim_fields.get_simulation_field<
    specfem::simulation::field_type::forward>();

// Copy fields to device for computation
sim_fields.copy_to_device();

Template Parameters:

DimensionTag – Spatial dimension (2D or 3D)

Public Functions

fields() = default

Default constructor.

Initializes an empty fields container with no allocated storage.

fields(const specfem::assembly::mesh<dimension_tag> &mesh, const specfem::assembly::element_types<dimension_tag> &element_types, const specfem::simulation::type simulation)

Construct simulation fields from mesh and simulation configuration.

Initializes all simulation fields (forward, adjoint, backward, buffer) based on the mesh geometry, element types, and simulation requirements. Allocates appropriate field storage for the specified spatial dimension and medium types present in the mesh.

specfem::assembly::fields<specfem::element::dimension_tag::dim2> fields(
    mesh, element_types, specfem::simulation::type::forward_adjoint);

Parameters:
  • mesh – Assembly mesh containing global numbering and connectivity

  • element_types – Element classification for field allocation

  • simulation – Simulation type determining which fields to initialize

template<specfem::simulation::field_type ReturnFieldType>
inline constexpr const specfem::assembly::simulation_field<dimension_tag, ReturnFieldType> &get_simulation_field() const

Get simulation field of specified type.

Template method that provides compile-time access to different simulation field types. The return type is determined at compile time based on the template parameter, enabling efficient field access in device kernels.

// Get forward field for wave propagation
auto forward = fields.get_simulation_field<
    specfem::simulation::field_type::forward>();

// Get adjoint field for reverse propagation
auto adjoint = fields.get_simulation_field<
    specfem::simulation::field_type::adjoint>();

Template Parameters:

ReturnFieldType – Type of simulation field to retrieve

Returns:

Reference to the requested simulation field

void copy_to_device()

Copy all simulation fields from host to device memory.

Transfers all active simulation fields (forward, adjoint, backward, buffer) from host-accessible memory to device memory for GPU computations. This is typically called before starting device-based wave propagation kernels.

void copy_to_host()

Copy all simulation fields from device to host memory.

Transfers all active simulation fields from device memory back to host-accessible memory for post-processing, I/O operations, or debugging. This is typically called after completing device-based computations.

Public Members

int nglob

Total number of global points in the mesh.

specfem::assembly::simulation_field<dimension_tag, specfem::simulation::field_type::buffer> buffer

Buffer simulation field for temporary storage and checkpointing.

Used for intermediate storage during time stepping, I/O operations, and checkpointing in long simulations.

specfem::assembly::simulation_field<dimension_tag, specfem::simulation::field_type::forward> forward

Forward simulation field for primary wave propagation.

Contains displacement (elastic), potential (acoustic), or appropriate field variables for forward-time wave propagation simulations.

specfem::assembly::simulation_field<dimension_tag, specfem::simulation::field_type::adjoint> adjoint

Adjoint simulation field for reverse-time wave propagation.

Used in adjoint methods for seismic imaging, full waveform inversion, and gradient computation. Propagates backward in time from receivers.

specfem::assembly::simulation_field<dimension_tag, specfem::simulation::field_type::backward> backward

Backward simulation field for gradient computation.

Used in conjunction with adjoint fields for computing gradients in full waveform inversion and optimization algorithms.

specfem::assembly::simulation_field

template<specfem::element::dimension_tag DimensionTag, specfem::simulation::field_type SimulationWavefieldType>
struct simulation_field

Individual simulation field storage container.

This class provides storage and access for a specific type of simulation field (forward, adjoint, backward, or buffer) in spectral element computations.

Dimension-Specific Implementation

template<specfem::simulation::field_type SimulationWavefieldType>
struct simulation_field<specfem::element::dimension_tag::dim2, SimulationWavefieldType>

2D simulation field container for spectral element wave computations

This template specialization provides storage and management for simulation fields in 2D spectral element meshes. It handles different wavefield types (forward, adjoint, backward, buffer) and supports multiple physical media (elastic P-SV, elastic SH, acoustic, poroelastic).

The class manages field components appropriate for each medium:

  • Elastic P-SV: displacement (ux, uz), velocity, acceleration

  • Elastic SH: displacement (uy), velocity, acceleration

  • Acoustic: potential, velocity potential, acceleration potential

  • Poroelastic: solid and fluid phase displacements and pressures

Template Parameters:

SimulationWavefieldType – Type of simulation field (forward, adjoint, backward, buffer)

Public Functions

simulation_field() = default

Default constructor.

Initializes an empty 2D simulation field with no allocated storage.

simulation_field(const specfem::assembly::mesh<dimension_tag> &mesh, const specfem::assembly::element_types<dimension_tag> &element_types)

Construct 2D simulation field from mesh and element information.

Initializes the simulation field by allocating storage for all medium types present in the mesh. Creates global indexing mappings and allocates appropriate field components based on the 2D mesh structure and element classifications.

Parameters:
  • mesh – 2D assembly mesh containing global numbering and connectivity

  • element_types – Element classification determining field allocation

void copy_to_host()

Copy 2D simulation field data from device to host memory.

Synchronizes all field components and index mappings from device-accessible memory to host memory for post-processing, I/O, or debugging operations.

void copy_to_device()

Copy 2D simulation field data from host to device memory.

Synchronizes all field components and index mappings from host memory to device-accessible memory for GPU-accelerated computations.

template<specfem::simulation::field_type DestinationWavefieldType>
inline void operator=(const simulation_field<dimension_tag, DestinationWavefieldType> &rhs)

Assignment operator for copying from different wavefield types.

Enables copying field data between different simulation field types (e.g., from forward to buffer, adjoint to backward) while preserving the field structure and indexing information.

Template Parameters:

DestinationWavefieldType – Source wavefield type to copy from

Parameters:

rhs – Source simulation field to copy data from

template<specfem::element::medium_tag MediumTag>
inline int get_nglob() const

Get number of global points for a specific medium type.

Returns the total number of global degrees of freedom for the specified medium type in the 2D simulation field.

Template Parameters:

MediumTag – Medium type to query (elastic_psv, elastic_sh, acoustic, etc.)

Returns:

Number of global points for the specified medium

template<specfem::element::medium_tag MediumTag>
inline constexpr specfem::assembly::fields_impl::field_impl<dimension_tag, MediumTag> const &get_field() const

Get field implementation for a specific medium type.

Provides access to the underlying field storage for the specified medium type, containing the appropriate field components (displacement, velocity, acceleration for elastic; potential derivatives for acoustic, etc.).

auto elastic_field =
field.get_field<specfem::element::medium_tag::elastic_psv>(); auto
displacement = elastic_field.displacement;
// Now you can use displacement for further computations

Template Parameters:

MediumTag – Medium type to access (elastic_psv, elastic_sh, acoustic, etc.)

Returns:

Const reference to the field implementation for the specified medium

int get_total_degrees_of_freedom()

Get total degrees of freedom across all medium types.

Computes the total number of degrees of freedom in the 2D simulation field, summing over all active medium types and their respective field components.

Returns:

Total number of degrees of freedom in the assembled system

Public Members

int nglob = 0

Total number of global points across all media.

int nspec

Number of spectral elements in the 2D mesh.

int ngllz

Number of quadrature points in z-direction.

int ngllx

Number of quadrature points in x-direction.

IndexViewType index_mapping

Device index mapping from (ispec,iz,ix) to linear index

IndexViewType::host_mirror_type h_index_mapping

Host mirror of index mapping for CPU operations

specfem::tag_dispatch::Storage<specfem::datatype::ElementIndexRange, decltype(combinations)> dof_ranges

Per-medium DOF range; begin_index() is the compact DOF base offset

Public Static Attributes

static constexpr auto dimension_tag = specfem::element::dimension_tag::dim2

Dimension tag.

static constexpr auto simulation_wavefield = SimulationWavefieldType

Simulation wavefield type.

template<specfem::simulation::field_type SimulationWavefieldType>
struct simulation_field<specfem::element::dimension_tag::dim3, SimulationWavefieldType>

3D simulation field container for spectral element wave computations

This template specialization provides storage and management for simulation fields in 3D spectral element meshes. It handles different wavefield types (forward, adjoint, backward, buffer) with support for elastic media.

The 3D implementation currently focuses on elastic media with displacement, velocity, and acceleration field components (ux, uy, uz and derivatives).

Template Parameters:

SimulationWavefieldType – Type of simulation field (forward, adjoint, backward, buffer)

Public Functions

simulation_field() = default

Default constructor.

Initializes an empty 3D simulation field with no allocated storage.

simulation_field(const specfem::assembly::mesh<dimension_tag> &mesh, const specfem::assembly::element_types<dimension_tag> &element_types)

Construct 3D simulation field from mesh and element information.

Initializes the 3D simulation field by allocating storage for elastic medium present in the 3D mesh. Creates global indexing mappings for the full 3D tensor grid and allocates appropriate field components based on the 3D mesh structure and element classifications.

specfem::assembly::simulation_field<specfem::element::dimension_tag::dim3,
    specfem::simulation::field_type::forward> field(mesh,
element_types);

Parameters:
  • mesh – 3D assembly mesh containing global numbering and connectivity

  • element_types – 3D element classification determining field allocation

void copy_to_host()

Copy 3D simulation field data from device to host memory.

Synchronizes all 3D field components and index mappings from device-accessible memory to host memory for post-processing, I/O, or debugging operations. Handles the full 3D tensor structure efficiently.

void copy_to_device()

Copy 3D simulation field data from host to device memory.

Synchronizes all 3D field components and index mappings from host memory to device-accessible memory for GPU-accelerated 3D computations.

template<specfem::simulation::field_type DestinationWavefieldType>
inline void operator=(const simulation_field<dimension_tag, DestinationWavefieldType> &rhs)

Assignment operator for copying between 3D wavefield types.

Enables copying 3D field data between different simulation field types (e.g., from forward to buffer, adjoint to backward) while preserving the 3D field structure and indexing information.

Template Parameters:

DestinationWavefieldType – Source wavefield type to copy from

Parameters:

rhs – Source 3D simulation field to copy data from

template<specfem::element::medium_tag MediumTag>
inline int get_nglob() const

Get number of global points for 3D elastic medium.

Returns the total number of global degrees of freedom for the elastic medium type in the 3D simulation field.

int nglob_elastic =
field.get_nglob<specfem::element::medium_tag::elastic>();

Template Parameters:

MediumTag – Medium type to query (currently elastic for 3D)

Returns:

Number of global points for the specified 3D medium

template<specfem::element::medium_tag MediumTag>
inline constexpr specfem::assembly::fields_impl::field_impl<dimension_tag, MediumTag> const &get_field() const

Get 3D field implementation for elastic medium.

Provides access to the underlying 3D field storage for the elastic medium, containing displacement, velocity, and acceleration components (ux, uy, uz and their time derivatives) appropriate for 3D wave propagation.

const auto& elastic_field =
field.get_field<specfem::element::medium_tag::elastic>();
const auto& displacement = elastic_field.displacement;

Template Parameters:

MediumTag – Medium type to access (elastic for 3D applications)

Returns:

Const reference to the 3D field implementation for elastic medium

int get_total_degrees_of_freedom()

Get total degrees of freedom in the 3D elastic system.

Computes the total number of degrees of freedom in the 3D simulation field, accounting for the elastic medium and its field components (3 displacement components × number of global points).

Returns:

Total number of degrees of freedom in the assembled 3D system

Public Members

int nglob = 0

Number of global degrees of freedom.

int nspec

Number of spectral elements.

int ngllz

Number of quadrature points in z direction.

int nglly

Number of quadrature points in y direction.

int ngllx

Number of quadrature points in x direction.

IndexViewType index_mapping

Device 3D index mapping from (ispec,iz,iy,ix) to linear index

IndexViewType::host_mirror_type h_index_mapping

Host mirror of 3D index mapping for CPU operations

specfem::tag_dispatch::Storage<specfem::datatype::ElementIndexRange, decltype(combinations)> dof_ranges

Per-medium DOF range; begin_index() is the compact DOF base offset

Public Static Attributes

static constexpr auto dimension_tag = specfem::element::dimension_tag::dim3

Dimension tag.

static constexpr auto simulation_wavefield = SimulationWavefieldType

Simulation wavefield type.

Data Access Functions

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void add_on_device(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

High-performance device-side field accumulation for spectral elements.

Public interface for accumulating values into simulation fields on the default compute device (GPU if GPU support is enabled) devices. This function provides a unified interface for adding values to multiple field components simultaneously.

Usage Examples:

// Elastic medium: Add to displacement and velocity fields
auto disp = specfem::point::displacement<...>(...);
auto vel = specfem::point::velocity<...>(...);

// Update fields at a specific quadrature point
disp(0) += delta_disp_x;
disp(1) += delta_disp_z;

// Single kernel call updates multiple components
add_on_device(assembly_index, elastic_field, disp, vel);

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function should be called from device kernels

Template Parameters:
Parameters:
  • index – Spatial index (element + quadrature point information)

  • field – Simulation field container holding medium-specific field data

  • accessors – Variable number of field accessors for simultaneous updates

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void atomic_add_on_device(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

Atomic field accumulation for spectral elements on device.

Public interface for atomically accumulating values into simulation fields on GPU devices. This function provides a unified interface for adding values to multiple field components simultaneously with guaranteed thread-safety through atomic operations.

Usage Examples:

// Elastic medium: Atomically add to displacement and velocity fields
auto disp = specfem::point::displacement<...>(...);
auto vel = specfem::point::velocity<...>(...);

// Update field values in accessor
disp(0) += delta_disp_x;
disp(1) += delta_disp_z;

// Single atomic kernel call updates multiple components thread-safely
atomic_add_on_device(simd_index, elastic_field, disp, vel);

// Use in parallel assembly where race conditions may occur
Kokkos::parallel_for("assembly_kernel", range, KOKKOS_LAMBDA(int i) {
  // Multiple threads may write to same global indices
  atomic_add_on_device(global_index[i], field, accessor1, accessor2);
});

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function should be called from device kernels where thread-safety is required

Note

Atomic operations ensure correctness but may reduce performance compared to add_on_device

Warning

Use atomic operations only when multiple threads may write to the same memory location. Use regular add_on_device when thread-safety is not required.

Template Parameters:
Parameters:
  • index – Spatial index (element + quadrature point information with SIMD support)

  • field – Simulation field container holding medium-specific field data

  • accessors – Variable number of field accessors for simultaneous atomic updates

Pre:

All accessors must have the same medium tag (e.g., all elastic or all acoustic)

Pre:

All accessors must be field accessor types

Pre:

IndexType must support SIMD operations

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void load_on_device(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

Device-side field data loading for spectral elements.

Public interface for loading field data from simulation fields into accessors on GPU devices. This function provides a unified interface for retrieving values from multiple field components simultaneously with optimized device memory access patterns.

Usage Examples:

// Elastic medium: Load displacement and velocity fields
auto disp = specfem::point::displacement<...>(...);
auto vel = specfem::point::velocity<...>(...);

// Single kernel call loads multiple components from field
load_on_device(simd_index, elastic_field, disp, vel);

// Access loaded values
auto disp_x = disp(0);
auto disp_z = disp(1);

// Use in device kernels for field retrieval
Kokkos::parallel_for("load_kernel", range, KOKKOS_LAMBDA(int i) {
  load_on_device(index[i], field, accessor1, accessor2);
  // Process loaded field data
});

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function is device-only (KOKKOS_FORCEINLINE_FUNCTION) and should be called from device kernels

Note

Supports both SIMD and non-SIMD index types for optimal performance

Template Parameters:
  • IndexType – Index type (specfem::point::index, specfem::chunk::element_index, specfem::chunk::edge_index with SIMD support)

  • ContainerType – Simulation field container (2D/3D specializations)

  • AccessorTypes – Variadic field accessor types

Parameters:
  • index – Spatial index (element + quadrature point information with optional SIMD support)

  • field – Simulation field container holding medium-specific field data

  • accessors – Variable number of field accessors to populate with loaded data

Pre:

All accessors must have the same medium tag (e.g., all elastic or all acoustic)

Pre:

All accessors must be field accessor types

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void load_on_host(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

Host-side field data loading for spectral elements and debugging.

Public interface for loading field data from simulation fields into accessors on the host (CPU). This function provides a unified interface for retrieving values from multiple field components simultaneously for host-based computations and debugging.

Usage Examples:

// Host-side debugging: Load displacement field values
auto disp = specfem::point::displacement<...>(...);

// Load field data on host for analysis
load_on_host(assembly_index, elastic_field, disp);

// Access loaded values for debugging
std::cout << "Displacement X: " << disp(0) << std::endl;
std::cout << "Displacement Z: " << disp(1) << std::endl;

// Host-based field processing
for (int i = 0; i < num_points; ++i) {
  load_on_host(host_index[i], field, accessor);
  // Process field data on host
}

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function is host-only and should be called from host code

Note

For device operations, use load_on_device instead

Note

Supports both SIMD and non-SIMD index types

Template Parameters:
  • IndexType – Index type (specfem::point::index, specfem::chunk::element_index, specfem::chunk::edge_index with SIMD support)

  • ContainerType – Simulation field container (2D/3D specializations)

  • AccessorTypes – Variadic field accessor types

Parameters:
  • index – Spatial index (element + quadrature point information with optional SIMD support)

  • field – Simulation field container holding medium-specific field data

  • accessors – Variable number of field accessors to populate with loaded data

Pre:

All accessors must have the same medium tag (e.g., all elastic or all acoustic)

Pre:

All accessors must be field accessor types

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void store_on_device(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

High-performance device-side field data storage for spectral elements.

Public interface for storing field data from accessors into simulation fields on GPU devices. This function provides a unified interface for writing values from multiple field components simultaneously with optimized device memory access patterns.

Usage Examples:

// Elastic medium: Store computed displacement and velocity
auto disp = specfem::point::displacement<...>(...);
auto vel = specfem::point::velocity<...>(...);

// Update accessor values
disp(0) = computed_disp_x;
disp(1) = computed_disp_z;
vel(0) = computed_vel_x;

// Single kernel call stores multiple components to field
store_on_device(assembly_index, elastic_field, disp, vel);

// Use in device kernels for field updates
Kokkos::parallel_for("store_kernel", range, KOKKOS_LAMBDA(int i) {
  // Compute new field values
  store_on_device(index[i], field, accessor1, accessor2);
});

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function is device-only (KOKKOS_FORCEINLINE_FUNCTION) and should be called from device kernels

Note

For thread-safe operations where race conditions may occur, use atomic_add_on_device instead

Template Parameters:
  • IndexType – Index type (specfem::point::assembly_index)

  • ContainerType – Simulation field container (2D/3D specializations)

  • AccessorTypes – Variadic field accessor types

Parameters:
  • index – Spatial index (element + quadrature point information)

  • field – Simulation field container holding medium-specific field data to be modified

  • accessors – Variable number of field accessors containing data to store

Pre:

All accessors must have the same medium tag (e.g., all elastic or all acoustic)

Pre:

All accessors must be field accessor types

template<typename IndexType, typename ContainerType, typename ...AccessorTypes, typename std::enable_if_t<(specfem::data_access::is_field<AccessorTypes>::value && ...), int> = 0>
void store_on_host(const IndexType &index, const ContainerType &field, AccessorTypes&... accessors)

Host-side field data storage for spectral elements and debugging.

Public interface for storing field data from accessors into simulation fields on the host (CPU). This function provides a unified interface for writing values from multiple field components simultaneously for host-based computations and debugging.

Usage Examples:

// Host-side field initialization or debugging
auto disp = specfem::point::displacement<...>(...);
auto vel = specfem::point::velocity<...>(...);

// Set initial or computed values
disp(0) = initial_disp_x;
disp(1) = initial_disp_z;
velocity(0) = initial_vel_x;

// Store values to field on host
store_on_host(assembly_index, elastic_field, disp, vel);

// Host-based field processing and storage
for (int i = 0; i < num_points; ++i) {
  // Compute field values on host
  store_on_host(host_index[i], field, accessor1, accessor2);
}

Note

All accessors must target the same medium type (enforced at compile-time)

Note

This function is host-only and should be called from host code

Note

For device operations, use store_on_device instead

Note

No atomic operations needed on host as there’s typically no thread contention

Template Parameters:
Parameters:
  • index – Spatial index (element + quadrature point information)

  • field – Simulation field container holding medium-specific field data to be modified

  • accessors – Variable number of field accessors containing data to store

Pre:

All accessors must have the same medium tag (e.g., all elastic or all acoustic)

Pre:

All accessors must be field accessor types

Implementation Details