Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added template specializations for acoustic and elastic kernels class #291

Merged
merged 5 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 172 additions & 4 deletions include/domain/impl/kernels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,174 @@ namespace kernels {
template <specfem::wavefield::simulation_field WavefieldType,
specfem::dimension::type DimensionType,
specfem::element::medium_tag medium, typename qp_type>
class kernels {
class kernels;

template <specfem::wavefield::simulation_field WavefieldType,
specfem::dimension::type DimensionType, typename qp_type>
class kernels<WavefieldType, DimensionType,
specfem::element::medium_tag::elastic, qp_type> {
public:
using quadrature_point_type = qp_type;
using dimension = specfem::dimension::dimension<DimensionType>;
kernels() = default;

kernels(const type_real dt, const specfem::compute::assembly &assembly,
const quadrature_point_type &quadrature_points);

/**
* @brief Compute the interaction of stiffness matrix with wavefield at a time
* step
*
* @param istep Time step
*/
inline void compute_stiffness_interaction(const int istep) const {
isotropic_elements.compute_stiffness_interaction(istep);
anisotropic_elements.compute_stiffness_interaction(istep);
isotropic_elements_dirichlet.compute_stiffness_interaction(istep);
anisotropic_elements_dirichlet.compute_stiffness_interaction(istep);
isotropic_elements_stacey.compute_stiffness_interaction(istep);
anisotropic_elements_stacey.compute_stiffness_interaction(istep);
isotropic_elements_stacey_dirichlet.compute_stiffness_interaction(istep);
anisotropic_elements_stacey_dirichlet.compute_stiffness_interaction(istep);
return;
}

/**
* @brief Compute the mass matrix
*
* @param dt Time step
*/
inline void compute_mass_matrix(const type_real dt) const {
isotropic_elements.compute_mass_matrix(dt);
anisotropic_elements.compute_mass_matrix(dt);
isotropic_elements_dirichlet.compute_mass_matrix(dt);
anisotropic_elements_dirichlet.compute_mass_matrix(dt);
isotropic_elements_stacey.compute_mass_matrix(dt);
anisotropic_elements_stacey.compute_mass_matrix(dt);
isotropic_elements_stacey_dirichlet.compute_mass_matrix(dt);
anisotropic_elements_stacey_dirichlet.compute_mass_matrix(dt);
return;
}

/**
* @brief Compute the interaction of source with wavefield at a time step
*
* @param timestep Time step
*/
inline void compute_source_interaction(const int timestep) const {
isotropic_sources.compute_source_interaction(timestep);
anisotropic_sources.compute_source_interaction(timestep);
return;
}

/**
* @brief Compute seismograms at a time step
*
* @param isig_step Seismogram time step. Same if seismogram is computed at
* every time step.
*/
inline void compute_seismograms(const int &isig_step) const {
isotropic_receivers.compute_seismograms(isig_step);
anisotropic_receivers.compute_seismograms(isig_step);
return;
}

private:
constexpr static specfem::element::boundary_tag dirichlet =
specfem::element::boundary_tag::acoustic_free_surface;
constexpr static specfem::element::boundary_tag stacey =
specfem::element::boundary_tag::stacey;
constexpr static specfem::element::boundary_tag none =
specfem::element::boundary_tag::none;
constexpr static specfem::element::boundary_tag composite_stacey_dirichlet =
specfem::element::boundary_tag::composite_stacey_dirichlet;
constexpr static specfem::element::property_tag isotropic =
specfem::element::property_tag::isotropic;
constexpr static specfem::element::property_tag anisotropic =
specfem::element::property_tag::anisotropic;
constexpr static specfem::element::medium_tag elastic =
specfem::element::medium_tag::elastic;

constexpr static int NGLL = quadrature_point_type::NGLL;

template <specfem::dimension::type dimension,
specfem::element::property_tag property,
specfem::element::boundary_tag boundary>
using element_kernel = specfem::domain::impl::kernels::element_kernel<
WavefieldType, DimensionType, elastic, property, boundary,
NGLL>; ///< Underlying element kernel data structure

template <specfem::dimension::type dimension,
specfem::element::property_tag property>
using source_kernel = specfem::domain::impl::kernels::source_kernel<
WavefieldType, DimensionType, elastic, property,
quadrature_point_type>; ///< Underlying source kernel data structure

template <specfem::dimension::type dimension,
specfem::element::property_tag property>
using receiver_kernel = specfem::domain::impl::kernels::receiver_kernel<
WavefieldType, DimensionType, elastic, property,
quadrature_point_type>; ///< Underlying receiver kernel data structure

element_kernel<DimensionType, isotropic, none>
isotropic_elements; ///< Stiffness kernels for isotropic elements

element_kernel<DimensionType, isotropic, dirichlet>
isotropic_elements_dirichlet; ///< Stiffness kernels for isotropic
///< elements with Dirichlet boundary
///< conditions

element_kernel<DimensionType, isotropic, stacey>
isotropic_elements_stacey; ///< Stiffness kernels for isotropic elements
///< with Stacey boundary conditions

element_kernel<DimensionType, isotropic, composite_stacey_dirichlet>
isotropic_elements_stacey_dirichlet; ///< Stiffness kernels for isotropic
///< elements with Stacey and
///< Dirichlet boundary conditions on
///< the same element

element_kernel<DimensionType, anisotropic, none>
anisotropic_elements; ///< Stiffness kernels for anisotropic elements

element_kernel<DimensionType, anisotropic, dirichlet>
anisotropic_elements_dirichlet; ///< Stiffness kernels for anisotropic
///< elements with Dirichlet boundary
///< conditions

element_kernel<DimensionType, anisotropic, stacey>
anisotropic_elements_stacey; ///< Stiffness kernels for anisotropic
///< elements with Stacey boundary conditions

element_kernel<DimensionType, anisotropic, composite_stacey_dirichlet>
anisotropic_elements_stacey_dirichlet; ///< Stiffness kernels for
///< anisotropic elements with
///< Stacey and Dirichlet boundary
///< conditions on the same element

source_kernel<DimensionType, isotropic> isotropic_sources; ///< Source kernels
///< for isotropic
///< elements

source_kernel<DimensionType, anisotropic>
anisotropic_sources; ///< Source
///< kernels for
///< anisotropic
///< elements

receiver_kernel<DimensionType, isotropic>
isotropic_receivers; ///< Kernels for computing seismograms within
///< isotropic elements

receiver_kernel<DimensionType, anisotropic>
anisotropic_receivers; ///< Kernels for computing seismograms within
///< anisotropic elements
};

template <specfem::wavefield::simulation_field WavefieldType,
specfem::dimension::type DimensionType, typename qp_type>
class kernels<WavefieldType, DimensionType,
specfem::element::medium_tag::acoustic, qp_type> {
public:
using quadrature_point_type = qp_type;
using dimension = specfem::dimension::dimension<DimensionType>;
Expand Down Expand Up @@ -83,26 +249,28 @@ class kernels {
specfem::element::boundary_tag::composite_stacey_dirichlet;
constexpr static specfem::element::property_tag isotropic =
specfem::element::property_tag::isotropic;
constexpr static specfem::element::medium_tag acoustic =
specfem::element::medium_tag::acoustic;

constexpr static int NGLL = quadrature_point_type::NGLL;

template <specfem::dimension::type dimension,
specfem::element::property_tag property,
specfem::element::boundary_tag boundary>
using element_kernel = specfem::domain::impl::kernels::element_kernel<
WavefieldType, DimensionType, medium, property, boundary,
WavefieldType, DimensionType, acoustic, property, boundary,
NGLL>; ///< Underlying element kernel data structure

template <specfem::dimension::type dimension,
specfem::element::property_tag property>
using source_kernel = specfem::domain::impl::kernels::source_kernel<
WavefieldType, DimensionType, medium, property,
WavefieldType, DimensionType, acoustic, property,
quadrature_point_type>; ///< Underlying source kernel data structure

template <specfem::dimension::type dimension,
specfem::element::property_tag property>
using receiver_kernel = specfem::domain::impl::kernels::receiver_kernel<
WavefieldType, DimensionType, medium, property,
WavefieldType, DimensionType, acoustic, property,
quadrature_point_type>; ///< Underlying receiver kernel data structure

element_kernel<DimensionType, isotropic, none>
Expand Down
105 changes: 90 additions & 15 deletions include/domain/impl/kernels.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,16 @@ void allocate_elements(
}
}

if constexpr (wavefield_type == specfem::wavefield::simulation_field::forward ||
wavefield_type == specfem::wavefield::simulation_field::adjoint) {
if constexpr (wavefield_type ==
specfem::wavefield::simulation_field::forward ||
wavefield_type ==
specfem::wavefield::simulation_field::adjoint) {

std::cout << " - Element type: \n"
<< " - dimension : " << dimension::to_string()
<< "\n"
<< " - Element type : " << specfem::element::to_string(
medium_tag, property_tag)
<< "\n"
<< " - Element type : "
<< specfem::element::to_string(medium_tag, property_tag) << "\n"
<< " - Boundary Conditions : "
<< specfem::domain::impl::boundary_conditions::print_boundary_tag<
boundary_tag>()
Expand Down Expand Up @@ -190,12 +191,85 @@ void allocate_isotropic_receivers(
} // namespace

template <specfem::wavefield::simulation_field WavefieldType,
specfem::dimension::type DimensionType,
specfem::element::medium_tag medium, typename qp_type>
specfem::domain::impl::kernels::
kernels<WavefieldType, DimensionType, medium, qp_type>::kernels(
const type_real dt, const specfem::compute::assembly &assembly,
const qp_type &quadrature_points) {
specfem::dimension::type DimensionType, typename qp_type>
specfem::domain::impl::kernels::kernels<
WavefieldType, DimensionType, specfem::element::medium_tag::elastic,
qp_type>::kernels(const type_real dt,
const specfem::compute::assembly &assembly,
const qp_type &quadrature_points) {

const int nspec = assembly.mesh.nspec;
specfem::kokkos::HostView1d<element_tag> element_tags(
"specfem::domain::domain::element_tag", nspec);

// -----------------------------------------------------------
for (int ispec = 0; ispec < nspec; ispec++) {
element_tags(ispec) =
element_tag(assembly.properties.h_element_types(ispec),
assembly.properties.h_element_property(ispec),
assembly.boundaries.boundary_tags(ispec));
}

if constexpr (WavefieldType ==
specfem::wavefield::simulation_field::forward ||
WavefieldType ==
specfem::wavefield::simulation_field::adjoint) {
std::cout << " Element Statistics \n"
<< "------------------------------\n"
<< "- Types of elements in elastic medium :\n\n";
}

// -----------------------------------------------------------

// Allocate isotropic elements with dirichlet boundary conditions
allocate_elements(assembly, element_tags, isotropic_elements_dirichlet);

// Allocate aniostropic elements with dirichlet boundary conditions
allocate_elements(assembly, element_tags, anisotropic_elements_dirichlet);

// Allocate isotropic elements with stacey boundary conditions
allocate_elements(assembly, element_tags, isotropic_elements_stacey);

// Allocate anisotropic elements with stacey boundary conditions
allocate_elements(assembly, element_tags, anisotropic_elements_stacey);

// Allocate isotropic elements with stacey dirichlet boundary conditions
allocate_elements(assembly, element_tags,
isotropic_elements_stacey_dirichlet);

// Allocate anisotropic elements with stacey dirichlet boundary conditions
allocate_elements(assembly, element_tags,
anisotropic_elements_stacey_dirichlet);

// Allocate isotropic elements
allocate_elements(assembly, element_tags, isotropic_elements);

// Allocate anisotropic elements
allocate_elements(assembly, element_tags, anisotropic_elements);

// Allocate isotropic sources

allocate_isotropic_sources(assembly, quadrature_points, isotropic_sources);

// Allocate isotropic receivers

allocate_isotropic_receivers(assembly, quadrature_points,
isotropic_receivers);

// Compute mass matrices

this->compute_mass_matrix(dt);

return;
}

template <specfem::wavefield::simulation_field WavefieldType,
specfem::dimension::type DimensionType, typename qp_type>
specfem::domain::impl::kernels::kernels<
WavefieldType, DimensionType, specfem::element::medium_tag::acoustic,
qp_type>::kernels(const type_real dt,
const specfem::compute::assembly &assembly,
const qp_type &quadrature_points) {

const int nspec = assembly.mesh.nspec;
specfem::kokkos::HostView1d<element_tag> element_tags(
Expand All @@ -209,12 +283,13 @@ specfem::domain::impl::kernels::
assembly.boundaries.boundary_tags(ispec));
}

if constexpr (WavefieldType == specfem::wavefield::simulation_field::forward ||
WavefieldType == specfem::wavefield::simulation_field::adjoint) {
if constexpr (WavefieldType ==
specfem::wavefield::simulation_field::forward ||
WavefieldType ==
specfem::wavefield::simulation_field::adjoint) {
std::cout << " Element Statistics \n"
<< "------------------------------\n"
<< "- Types of elements in " << specfem::element::to_string(medium)
<< " medium :\n\n";
<< "- Types of elements in acoustic medium :\n\n";
}

// -----------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions include/medium/compute_wavefield.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "acoustic_isotropic2d/acoustic_isotropic2d.hpp"
#include "elastic_anisotropic2d/elastic_anisotropic2d.hpp"
#include "elastic_isotropic2d/elastic_isotropic2d.hpp"
#include <Kokkos_Core.hpp>

Expand Down
Loading
Loading