diff --git a/CMakeLists.txt b/CMakeLists.txt index 528c63e89..6ed0a2fc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,18 +327,6 @@ target_link_libraries( point ) -# add_library( -# utilities -# src/utilities/utilities.cpp -# ) - -# target_link_libraries( -# utilities -# jacobian -# Kokkos::kokkos -# specfem_mpi -# ) - add_library( read_seismogram src/IO/seismogram/reader.cpp @@ -429,8 +417,7 @@ target_link_libraries( add_library( compute src/compute/compute_mesh.cpp - src/compute/impl/element_types.cpp - src/compute/impl/value_containers.cpp + src/compute/element_types/element_types.cpp src/compute/compute_partial_derivatives.cpp src/compute/compute_properties.cpp src/compute/compute_kernels.cpp @@ -460,17 +447,14 @@ target_link_libraries( ) add_library( - domain - src/domain/impl/boundary_conditions/boundary_conditions.cpp - src/domain/impl/elements/kernel.cpp - src/domain/impl/kernels.cpp - src/domain/domain.cpp + boundary_conditions + src/boundary_conditions/boundary_conditions.cpp ) target_link_libraries( - domain + boundary_conditions Kokkos::kokkos - enumerations + ${BOOST_LIBS} ) add_library( @@ -483,7 +467,7 @@ target_link_libraries( medium Kokkos::kokkos compute - domain + boundary_conditions enumerations ) @@ -498,14 +482,22 @@ target_link_libraries( ) add_library( - kernels - src/kernels/frechet_kernels.cpp + kokkos_kernels + src/kokkos_kernels/impl/compute_mass_matrix.cpp + src/kokkos_kernels/impl/invert_mass_matrix.cpp + src/kokkos_kernels/impl/divide_mass_matrix.cpp + src/kokkos_kernels/impl/compute_seismogram.cpp + src/kokkos_kernels/impl/compute_source_interaction.cpp + src/kokkos_kernels/impl/compute_stiffness_interaction.cpp + src/kokkos_kernels/impl/compute_material_derivatives.cpp + src/kokkos_kernels/frechet_kernels.cpp ) target_link_libraries( - kernels + kokkos_kernels Kokkos::kokkos compute + boundary_conditions ) add_library( @@ -530,8 +522,7 @@ target_link_libraries( solver Kokkos::kokkos timescheme - domain - kernels + kokkos_kernels medium ) @@ -603,8 +594,7 @@ target_link_libraries( yaml-cpp writer reader - kernels - domain + kokkos_kernels medium solver ${BOOST_LIBS} @@ -630,10 +620,9 @@ target_link_libraries( writer plotter reader - domain medium coupled_interface - kernels + kokkos_kernels solver ${BOOST_LIBS} ) @@ -695,10 +684,9 @@ if (SPECFEMPP_BINDING_PYTHON) writer plotter reader - domain medium coupled_interface - kernels + kokkos_kernels solver ${BOOST_LIBS} pybind11::headers diff --git a/include/IO/kernel/writer.hpp b/include/IO/kernel/writer.hpp index 96f3641d1..fa60e23da 100644 --- a/include/IO/kernel/writer.hpp +++ b/include/IO/kernel/writer.hpp @@ -1,8 +1,8 @@ #pragma once +#include "IO/writer.hpp" #include "compute/interface.hpp" #include "enumerations/interface.hpp" -#include "IO/writer.hpp" namespace specfem { namespace IO { diff --git a/include/IO/kernel/writer.tpp b/include/IO/kernel/writer.tpp index 72a5ecd55..ec458b179 100644 --- a/include/IO/kernel/writer.tpp +++ b/include/IO/kernel/writer.tpp @@ -15,6 +15,7 @@ specfem::IO::kernel_writer::kernel_writer(const std::string outpu template void specfem::IO::kernel_writer::write(specfem::compute::assembly &assembly) { const auto &mesh = assembly.mesh; + auto &element_types = assembly.element_types; auto &kernels = assembly.kernels; using DomainView = @@ -35,7 +36,7 @@ void specfem::IO::kernel_writer::write(specfem::compute::assembly { typename OutputLibrary::Group elastic = file.createGroup("/ElasticIsotropic"); - const auto element_indices = kernels.get_elements_on_host( + const auto element_indices = element_types.get_elements_on_host( specfem::element::medium_tag::elastic, specfem::element::property_tag::isotropic); n_elastic_isotropic = element_indices.size(); @@ -89,7 +90,7 @@ void specfem::IO::kernel_writer::write(specfem::compute::assembly { typename OutputLibrary::Group elastic = file.createGroup("/ElasticAnisotropic"); - const auto element_indices = kernels.get_elements_on_host( + const auto element_indices = element_types.get_elements_on_host( specfem::element::medium_tag::elastic, specfem::element::property_tag::anisotropic); n_elastic_anisotropic = element_indices.size(); @@ -146,7 +147,7 @@ void specfem::IO::kernel_writer::write(specfem::compute::assembly { typename OutputLibrary::Group acoustic = file.createGroup("/Acoustic"); - const auto element_indices = kernels.get_elements_on_host(specfem::element::medium_tag::acoustic); + const auto element_indices = element_types.get_elements_on_host(specfem::element::medium_tag::acoustic); n_acoustic = element_indices.size(); DomainView x("xcoordinates_acoustic", n_acoustic, ngllz, ngllx); diff --git a/include/IO/property/writer.tpp b/include/IO/property/writer.tpp index fcfd04199..563a22428 100644 --- a/include/IO/property/writer.tpp +++ b/include/IO/property/writer.tpp @@ -15,6 +15,7 @@ specfem::IO::property_writer::property_writer(const std::string o template void specfem::IO::property_writer::write(specfem::compute::assembly &assembly) { const auto &mesh = assembly.mesh; + auto &element_types = assembly.element_types; auto &properties = assembly.properties; using DomainView = @@ -35,7 +36,7 @@ void specfem::IO::property_writer::write(specfem::compute::assemb { typename OutputLibrary::Group elastic = file.createGroup("/ElasticIsotropic"); - const auto element_indices = properties.get_elements_on_host( + const auto element_indices = element_types.get_elements_on_host( specfem::element::medium_tag::elastic, specfem::element::property_tag::isotropic); n_elastic_isotropic = element_indices.size(); @@ -64,7 +65,7 @@ void specfem::IO::property_writer::write(specfem::compute::assemb { typename OutputLibrary::Group elastic = file.createGroup("/ElasticAnisotropic"); - const auto element_indices = properties.get_elements_on_host( + const auto element_indices = element_types.get_elements_on_host( specfem::element::medium_tag::elastic, specfem::element::property_tag::anisotropic); n_elastic_anisotropic = element_indices.size(); @@ -100,7 +101,7 @@ void specfem::IO::property_writer::write(specfem::compute::assemb { typename OutputLibrary::Group acoustic = file.createGroup("/Acoustic"); - const auto element_indices = properties.get_elements_on_host(specfem::element::medium_tag::acoustic); + const auto element_indices = element_types.get_elements_on_host(specfem::element::medium_tag::acoustic); n_acoustic = element_indices.size(); DomainView x("xcoordinates_acoustic", n_acoustic, ngllz, ngllx); diff --git a/include/domain/impl/boundary_conditions/boundary_conditions.hpp b/include/boundary_conditions/boundary_conditions.hpp similarity index 97% rename from include/domain/impl/boundary_conditions/boundary_conditions.hpp rename to include/boundary_conditions/boundary_conditions.hpp index be2e742f9..246e9f550 100644 --- a/include/domain/impl/boundary_conditions/boundary_conditions.hpp +++ b/include/boundary_conditions/boundary_conditions.hpp @@ -9,8 +9,7 @@ #include namespace specfem { -namespace domain { -namespace impl { + namespace boundary_conditions { template @@ -78,6 +77,4 @@ compute_mass_matrix_terms(const type_real dt, const PointBoundaryType &boundary, } } // namespace boundary_conditions -} // namespace impl -} // namespace domain } // namespace specfem diff --git a/include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp b/include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp similarity index 93% rename from include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp rename to include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp index 33cbc1eae..83f0cbcfa 100644 --- a/include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp +++ b/include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp @@ -5,8 +5,6 @@ #include namespace specfem { -namespace domain { -namespace impl { namespace boundary_conditions { using composite_stacey_dirichlet_type = std::integral_constant< @@ -28,6 +26,4 @@ KOKKOS_FUNCTION void impl_compute_mass_matrix_terms( PointMassMatrixType &mass_matrix); } // namespace boundary_conditions -} // namespace impl -} // namespace domain } // namespace specfem diff --git a/include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp b/include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp similarity index 90% rename from include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp rename to include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp index 3ae307f3e..d3a477124 100644 --- a/include/domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp +++ b/include/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp @@ -1,9 +1,9 @@ #pragma once #include "composite_stacey_dirichlet.hpp" -#include "domain/impl/boundary_conditions/boundary_conditions.hpp" -#include "domain/impl/boundary_conditions/dirichlet/dirichlet.hpp" -#include "domain/impl/boundary_conditions/stacey/stacey.hpp" +#include "boundary_conditions/boundary_conditions.hpp" +#include "boundary_conditions/dirichlet/dirichlet.hpp" +#include "boundary_conditions/stacey/stacey.hpp" #include "enumerations/boundary.hpp" #include "point/boundary.hpp" #include @@ -11,7 +11,7 @@ template KOKKOS_FUNCTION void -specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions( +specfem::boundary_conditions::impl_apply_boundary_conditions( const composite_stacey_dirichlet_type &, const PointBoundaryType &boundary, const PointPropertyType &property, const PointFieldType &field, PointAccelerationType &acceleration) { @@ -47,7 +47,7 @@ specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions( template KOKKOS_FUNCTION void -specfem::domain::impl::boundary_conditions::impl_compute_mass_matrix_terms( +specfem::boundary_conditions::impl_compute_mass_matrix_terms( const composite_stacey_dirichlet_type &, const type_real dt, const PointBoundaryType &boundary, const PointPropertyType &property, PointMassMatrixType &mass_matrix) { diff --git a/include/domain/impl/boundary_conditions/dirichlet/dirichlet.hpp b/include/boundary_conditions/dirichlet/dirichlet.hpp similarity index 97% rename from include/domain/impl/boundary_conditions/dirichlet/dirichlet.hpp rename to include/boundary_conditions/dirichlet/dirichlet.hpp index 15f99dbf2..4026564b9 100644 --- a/include/domain/impl/boundary_conditions/dirichlet/dirichlet.hpp +++ b/include/boundary_conditions/dirichlet/dirichlet.hpp @@ -6,8 +6,6 @@ #include namespace specfem { -namespace domain { -namespace impl { namespace boundary_conditions { using acoustic_free_surface_type = std::integral_constant< @@ -85,6 +83,4 @@ KOKKOS_FORCEINLINE_FUNCTION void impl_compute_mass_matrix_terms( }; } // namespace boundary_conditions -} // namespace impl -} // namespace domain } // namespace specfem diff --git a/include/domain/impl/boundary_conditions/none/none.hpp b/include/boundary_conditions/none/none.hpp similarity index 94% rename from include/domain/impl/boundary_conditions/none/none.hpp rename to include/boundary_conditions/none/none.hpp index 06f53062b..93c403d7e 100644 --- a/include/domain/impl/boundary_conditions/none/none.hpp +++ b/include/boundary_conditions/none/none.hpp @@ -5,8 +5,6 @@ #include namespace specfem { -namespace domain { -namespace impl { namespace boundary_conditions { using none_type = std::integral_constant namespace specfem { -namespace domain { -namespace impl { namespace boundary_conditions { using stacey_type = @@ -27,6 +25,4 @@ KOKKOS_FUNCTION void impl_compute_mass_matrix_terms( const PointPropertyType &property, PointMassMatrixType &mass_matrix); } // namespace boundary_conditions -} // namespace impl -} // namespace domain } // namespace specfem diff --git a/include/domain/impl/boundary_conditions/stacey/stacey.tpp b/include/boundary_conditions/stacey/stacey.tpp similarity index 98% rename from include/domain/impl/boundary_conditions/stacey/stacey.tpp rename to include/boundary_conditions/stacey/stacey.tpp index 3ca6472a0..7f3010b0a 100644 --- a/include/domain/impl/boundary_conditions/stacey/stacey.tpp +++ b/include/boundary_conditions/stacey/stacey.tpp @@ -1,7 +1,7 @@ #pragma once #include "algorithms/dot.hpp" -#include "domain/impl/boundary_conditions/boundary_conditions.hpp" +#include "boundary_conditions/boundary_conditions.hpp" #include "enumerations/medium.hpp" #include "point/field.hpp" #include "stacey.hpp" @@ -335,7 +335,7 @@ impl_enforce_traction(const elastic_type &, const anisotropic_type &, template KOKKOS_FUNCTION void -specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions( +specfem::boundary_conditions::impl_apply_boundary_conditions( const stacey_type &, const PointBoundaryType &boundary, const PointPropertyType &property, const PointFieldType &field, PointAccelerationType &acceleration) { @@ -354,7 +354,7 @@ specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions( template KOKKOS_FORCEINLINE_FUNCTION void -specfem::domain::impl::boundary_conditions::impl_compute_mass_matrix_terms( +specfem::boundary_conditions::impl_compute_mass_matrix_terms( const stacey_type &, const type_real dt, const PointBoundaryType &boundary, const PointPropertyType &property, PointMassMatrixType &mass_matrix) { diff --git a/include/compute/assembly/assembly.hpp b/include/compute/assembly/assembly.hpp index ee13c6153..e4591f4ff 100644 --- a/include/compute/assembly/assembly.hpp +++ b/include/compute/assembly/assembly.hpp @@ -34,6 +34,8 @@ namespace compute { */ struct assembly { specfem::compute::mesh mesh; ///< Properties of the assembled mesh + specfem::compute::element_types element_types; ///< Element tags for every + ///< spectral element specfem::compute::partial_derivatives partial_derivatives; ///< Partial ///< derivatives of ///< the basis diff --git a/include/compute/boundary_values/boundary_values.hpp b/include/compute/boundary_values/boundary_values.hpp index 8cd6bcdc5..100ad6ee3 100644 --- a/include/compute/boundary_values/boundary_values.hpp +++ b/include/compute/boundary_values/boundary_values.hpp @@ -25,7 +25,7 @@ class boundary_values { composite_stacey_dirichlet; boundary_values(const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries); template diff --git a/include/compute/boundary_values/boundary_values_container.hpp b/include/compute/boundary_values/boundary_values_container.hpp index deeba8b48..f1c113754 100644 --- a/include/compute/boundary_values/boundary_values_container.hpp +++ b/include/compute/boundary_values/boundary_values_container.hpp @@ -33,7 +33,7 @@ class boundary_value_container { boundary_value_container() = default; boundary_value_container(const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries); void sync_to_host() { diff --git a/include/compute/boundary_values/boundary_values_container.tpp b/include/compute/boundary_values/boundary_values_container.tpp index 464c2e338..fb765568a 100644 --- a/include/compute/boundary_values/boundary_values_container.tpp +++ b/include/compute/boundary_values/boundary_values_container.tpp @@ -8,7 +8,7 @@ template specfem::compute::boundary_value_container:: boundary_value_container(const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries) : property_index_mapping( "specfem::compute::boundary_value_container::property_index_mapping", @@ -24,11 +24,11 @@ specfem::compute::boundary_value_container:: acoustic = specfem::compute::impl::boundary_medium_container< DimensionType, specfem::element::medium_tag::acoustic, BoundaryTag>( - nstep, mesh, properties, boundaries, h_property_index_mapping); + nstep, mesh, element_types, boundaries, h_property_index_mapping); elastic = specfem::compute::impl::boundary_medium_container< DimensionType, specfem::element::medium_tag::elastic, BoundaryTag>( - nstep, mesh, properties, boundaries, h_property_index_mapping); + nstep, mesh, element_types, boundaries, h_property_index_mapping); Kokkos::deep_copy(property_index_mapping, h_property_index_mapping); } diff --git a/include/compute/boundary_values/impl/boundary_medium_container.hpp b/include/compute/boundary_values/impl/boundary_medium_container.hpp index b80f726c9..d7eac3345 100644 --- a/include/compute/boundary_values/impl/boundary_medium_container.hpp +++ b/include/compute/boundary_values/impl/boundary_medium_container.hpp @@ -39,7 +39,7 @@ class boundary_medium_container { boundary_medium_container( const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries, specfem::kokkos::HostView1d property_index_mapping); diff --git a/include/compute/boundary_values/impl/boundary_medium_container.tpp b/include/compute/boundary_values/impl/boundary_medium_container.tpp index 4c023237f..c84825d19 100644 --- a/include/compute/boundary_values/impl/boundary_medium_container.tpp +++ b/include/compute/boundary_values/impl/boundary_medium_container.tpp @@ -10,7 +10,7 @@ specfem::compute::impl::boundary_medium_container:: boundary_medium_container( const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries, specfem::kokkos::HostView1d property_index_mapping) { @@ -20,8 +20,8 @@ specfem::compute::impl::boundary_medium_container:: const specfem::mesh::mesh &mesh, const specfem::compute::points &points, const specfem::compute::quadrature &quadratures, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, const specfem::compute::mesh_to_compute_mapping &mapping) { const auto interface_container = @@ -526,7 +526,7 @@ specfem::compute::interface_container:: mesh.coupled_interfaces.get()); int num_interfaces = interface_container.num_interfaces; - const int ngll = properties.ngllx; + const int ngll = points.ngllx; if (num_interfaces == 0) { this->num_interfaces = 0; @@ -545,10 +545,10 @@ specfem::compute::interface_container:: const int ispec1_compute = mapping.mesh_to_compute(ispec1_mesh); const int ispec2_compute = mapping.mesh_to_compute(ispec2_mesh); - if (!(((properties.h_medium_tags(ispec1_compute) == MediumTag1) && - (properties.h_medium_tags(ispec2_compute) == MediumTag2)) || - ((properties.h_medium_tags(ispec1_compute) == MediumTag2 && - properties.h_medium_tags(ispec2_compute) == MediumTag1)))) { + if (!(((element_types.get_medium_tag(ispec1_compute) == MediumTag1) && + (element_types.get_medium_tag(ispec2_compute) == MediumTag2)) || + ((element_types.get_medium_tag(ispec1_compute) == MediumTag2 && + element_types.get_medium_tag(ispec2_compute) == MediumTag1)))) { throw std::runtime_error( "Coupled Interfaces: Interface is not between the correct mediums"); diff --git a/include/compute/element_types/element_types.hpp b/include/compute/element_types/element_types.hpp new file mode 100644 index 000000000..20cb8229f --- /dev/null +++ b/include/compute/element_types/element_types.hpp @@ -0,0 +1,156 @@ +#pragma once + +#include "compute/compute_mesh.hpp" +#include "enumerations/material_definitions.hpp" +#include "enumerations/medium.hpp" +#include "mesh/materials/materials.hpp" +#include "point/coordinates.hpp" +#include + +namespace specfem { +namespace compute { +/** + * @brief Element types for every quadrature point in the + * finite element mesh + * + */ +struct element_types { +protected: + using MediumTagViewType = + Kokkos::View; ///< Underlying view type + ///< to store medium tags + using PropertyTagViewType = + Kokkos::View; ///< Underlying view type + ///< to store property + ///< tags + using BoundaryViewType = + Kokkos::View; ///< Underlying view type + ///< to store + ///< boundary tags + + using IndexViewType = + Kokkos::View; ///< Underlying view + ///< type to store + ///< indices of + ///< elements + +public: + int nspec; ///< total number of spectral elements + int ngllz; ///< number of quadrature points in z dimension + int ngllx; ///< number of quadrature points in x dimension + + MediumTagViewType medium_tags; ///< View to store medium tags + PropertyTagViewType property_tags; ///< View to store property tags + BoundaryViewType boundary_tags; ///< View to store boundary tags + + /** + * @brief Default constructor + * + */ + element_types() = default; + + /** + * @brief Construct a new properties object from mesh information + * + * @param nspec Number of spectral elements + * @param ngllz Number of quadrature points in z direction + * @param ngllx Number of quadrature points in x direction + * @param mapping Mapping of spectral element index from mesh to assembly + * @param tags Element Tags for every spectral element + */ + element_types( + const int nspec, const int ngllz, const int ngllx, + const specfem::compute::mesh_to_compute_mapping &mapping, + const specfem::mesh::tags &tags); + + Kokkos::View + get_elements_on_host(const specfem::element::medium_tag tag) const; + + Kokkos::View + get_elements_on_device(const specfem::element::medium_tag tag) const; + + Kokkos::View + get_elements_on_host(const specfem::element::medium_tag tag, + const specfem::element::property_tag property) const; + + Kokkos::View + get_elements_on_device(const specfem::element::medium_tag tag, + const specfem::element::property_tag property) const; + + Kokkos::View + get_elements_on_host(const specfem::element::medium_tag tag, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary) const; + + Kokkos::View + get_elements_on_device(const specfem::element::medium_tag tag, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary) const; + + specfem::element::medium_tag get_medium_tag(const int ispec) const { + return medium_tags(ispec); + } + + specfem::element::property_tag get_property_tag(const int ispec) const { + return property_tags(ispec); + } + + specfem::element::boundary_tag get_boundary_tag(const int ispec) const { + return boundary_tags(ispec); + } + +private: +#define MEDIUM_TAG_VARIABLES(DIMENSION_TAG, MEDIUM_TAG) \ + IndexViewType CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)); \ + IndexViewType::HostMirror CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG)); + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS(MEDIUM_TAG_VARIABLES, + WHERE(DIMENSION_TAG_DIM2) + WHERE(MEDIUM_TAG_ELASTIC, + MEDIUM_TAG_ACOUSTIC)) + +#undef MEDIUM_TAG_VARIABLES + +#define MATERIAL_SYSTEMS_VARIABLE_NAMES(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + IndexViewType CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); \ + IndexViewType::HostMirror CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + MATERIAL_SYSTEMS_VARIABLE_NAMES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef MATERIAL_SYSTEMS_VARIABLE_NAMES + +#define ELEMENT_TYPES_VARIABLE_NAMES(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + IndexViewType CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG)); \ + IndexViewType::HostMirror CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG)); + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + ELEMENT_TYPES_VARIABLE_NAMES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef ELEMENT_TYPES_VARIABLE_NAMES +}; + +} // namespace compute +} // namespace specfem diff --git a/include/compute/fields/fields.hpp b/include/compute/fields/fields.hpp index 467f1f7ac..5d4db8a78 100644 --- a/include/compute/fields/fields.hpp +++ b/include/compute/fields/fields.hpp @@ -34,7 +34,7 @@ struct fields { * @param simulation Current simulation type */ fields(const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, const specfem::simulation::type simulation); ///@} diff --git a/include/compute/fields/impl/field_impl.hpp b/include/compute/fields/impl/field_impl.hpp index 2ba1527d6..1da50d731 100644 --- a/include/compute/fields/impl/field_impl.hpp +++ b/include/compute/fields/impl/field_impl.hpp @@ -2,7 +2,7 @@ #define _COMPUTE_FIELDS_IMPL_FIELD_IMPL_HPP_ #include "compute/compute_mesh.hpp" -#include "compute/properties/interface.hpp" +#include "compute/element_types/element_types.hpp" #include "kokkos_abstractions.h" #include @@ -20,7 +20,7 @@ class field_impl { field_impl( const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_type, Kokkos::View assembly_index_mapping); diff --git a/include/compute/fields/impl/field_impl.tpp b/include/compute/fields/impl/field_impl.tpp index 065d14135..ebb9db43a 100644 --- a/include/compute/fields/impl/field_impl.tpp +++ b/include/compute/fields/impl/field_impl.tpp @@ -2,6 +2,7 @@ #define _COMPUTE_FIELDS_IMPL_FIELD_IMPL_TPP_ #include "compute/fields/impl/field_impl.hpp" +#include "compute/element_types/element_types.hpp" #include "kokkos_abstractions.h" #include @@ -23,12 +24,11 @@ template specfem::compute::impl::field_impl::field_impl( const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, Kokkos::View assembly_index_mapping) { const auto index_mapping = mesh.points.h_index_mapping; - const auto element_type = properties.h_medium_tags; const int nspec = mesh.points.nspec; const int ngllz = mesh.points.ngllz; const int ngllx = mesh.points.ngllx; @@ -39,7 +39,8 @@ specfem::compute::impl::field_impl::field_impl( for (int ix = 0; ix < ngllx; ++ix) { for (int iz = 0; iz < ngllz; ++iz) { for (int ispec = 0; ispec < nspec; ++ispec) { - if (element_type(ispec) == MediumTag) { + const auto medium = element_types.get_medium_tag(ispec); + if (medium == MediumTag) { const int index = index_mapping(ispec, iz, ix); // get global index // increase the count only if the global index is not already counted /// static_cast(medium::value) is the index of the medium in the diff --git a/include/compute/fields/simulation_field.hpp b/include/compute/fields/simulation_field.hpp index 21269721b..70335c809 100644 --- a/include/compute/fields/simulation_field.hpp +++ b/include/compute/fields/simulation_field.hpp @@ -47,7 +47,7 @@ struct simulation_field { * @param properties Material properties */ simulation_field(const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties); + const specfem::compute::element_types &element_types); ///@} /** diff --git a/include/compute/fields/simulation_field.tpp b/include/compute/fields/simulation_field.tpp index 09f1504bb..d63854b86 100644 --- a/include/compute/fields/simulation_field.tpp +++ b/include/compute/fields/simulation_field.tpp @@ -31,7 +31,7 @@ template int compute_nglob(const ViewType index_mapping) { template specfem::compute::simulation_field::simulation_field( const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties) { + const specfem::compute::element_types &element_types) { nglob = compute_nglob(mesh.points.h_index_mapping); @@ -68,11 +68,11 @@ specfem::compute::simulation_field::simulation_field( elastic = specfem::compute::impl::field_impl( - mesh, properties, elastic_index); + mesh, element_types, elastic_index); acoustic = specfem::compute::impl::field_impl< specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic>( - mesh, properties, acoustic_index); + mesh, element_types, acoustic_index); Kokkos::deep_copy(assembly_index_mapping, h_assembly_index_mapping); diff --git a/include/compute/impl/element_types.hpp b/include/compute/impl/element_types.hpp deleted file mode 100644 index 32967e2e1..000000000 --- a/include/compute/impl/element_types.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#pragma once - -#include "compute/compute_mesh.hpp" -#include "enumerations/medium.hpp" -#include "mesh/materials/materials.hpp" -#include "point/coordinates.hpp" -#include - -namespace specfem { -namespace compute { - -namespace impl { -/** - * @brief Element types for every quadrature point in the - * finite element mesh - * - */ -struct element_types { -protected: - using IndexViewType = Kokkos::View; - using MediumTagViewType = - Kokkos::View; ///< Underlying view type to - ///< store medium tags - using PropertyTagViewType = - Kokkos::View; ///< Underlying view type to - ///< store property tags - using BoundaryViewType = - Kokkos::View; //< Underlying view type to store - // boundary tags - -public: - int nspec; ///< total number of spectral elements - int ngllz; ///< number of quadrature points in z dimension - int ngllx; ///< number of quadrature points in x dimension - MediumTagViewType medium_tags; ///< Medium tag for every spectral element - PropertyTagViewType property_tags; ///< Property tag for every spectral - ///< element - BoundaryViewType boundary_tags; ///< Boundary tags for every element in the - ///< mesh - MediumTagViewType::HostMirror h_medium_tags; ///< Host mirror of @ref - ///< medium_tags - PropertyTagViewType::HostMirror h_property_tags; ///< Host mirror of @ref - ///< property_tags - - IndexViewType property_index_mapping; - IndexViewType::HostMirror h_property_index_mapping; - - /** - * @brief Default constructor - * - */ - element_types() = default; - - /** - * @brief Construct a new properties object from mesh information - * - * @param nspec Number of spectral elements - * @param ngllz Number of quadrature points in z direction - * @param ngllx Number of quadrature points in x direction - * @param mapping Mapping of spectral element index from mesh to assembly - * @param tags Element Tags for every spectral element - */ - element_types( - const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags); - - element_types(const element_types &) = default; - - /** - * @brief Copy misfit kernel data to host - * - */ - void copy_to_host() { - Kokkos::deep_copy(h_medium_tags, medium_tags); - Kokkos::deep_copy(h_property_tags, property_tags); - Kokkos::deep_copy(h_property_index_mapping, property_index_mapping); - } - - void copy_to_device() { - Kokkos::deep_copy(medium_tags, h_medium_tags); - Kokkos::deep_copy(property_tags, h_property_tags); - Kokkos::deep_copy(property_index_mapping, h_property_index_mapping); - } - - /** - * @brief Get the indices of elements of a given type as a view on the device - * - * @param medium Medium tag of the elements - * @return Kokkos::View View of the indices of elements of the given - * type - */ - Kokkos::View - get_elements_on_device(const specfem::element::medium_tag medium) const; - - /** - * @brief Get the indices of elements of a given type as a view on the device - * - * @param medium Medium tag of the elements - * @param property Property tag of the elements - * @return Kokkos::View View of the indices of elements of the given - * type - */ - Kokkos::View - get_elements_on_device(const specfem::element::medium_tag medium, - const specfem::element::property_tag property) const; - - /** - * @brief Get the indices of elements of a given type as a view on the host - * - * @param medium Medium tag of the elements - * @return Kokkos::View View of - * the indices of elements of the given type - */ - Kokkos::View - get_elements_on_host(const specfem::element::medium_tag medium) const; - - /** - * @brief Get the indices of elements of a given type as a view on the host - * - * @param medium Medium tag of the elements - * @param property Property tag of the elements - * @return Kokkos::View View of - * the indices of elements of the given type - */ - Kokkos::View - get_elements_on_host(const specfem::element::medium_tag medium, - const specfem::element::property_tag property) const; - - /** - * @brief Get the indices of elements of a given type as a view on the host - * - * @param medium Medium tag of the elements - * @param boundary Boundary tag of the elements - * @return Kokkos::View View of - * the indices of elements of the given type - */ - Kokkos::View - get_elements_on_host(const specfem::element::medium_tag medium, - const specfem::element::boundary_tag boundary) const; -}; - -} // namespace impl -} // namespace compute -} // namespace specfem diff --git a/include/compute/impl/value_containers.hpp b/include/compute/impl/value_containers.hpp index 45b0e5dff..e8b247f7f 100644 --- a/include/compute/impl/value_containers.hpp +++ b/include/compute/impl/value_containers.hpp @@ -1,20 +1,33 @@ #pragma once -#include "compute/impl/element_types.hpp" +#include "enumerations/medium.hpp" +#include namespace specfem { namespace compute { namespace impl { /** - * @brief Values for every quadrature point in the - * finite element mesh + * @brief Values for every quadrature point in the finite element mesh * */ template < template class containers_type> struct value_containers { + + using IndexViewType = Kokkos::View; + + int nspec; ///< Total number of spectral elements + int ngllz; ///< Number of quadrature points in z dimension + int ngllx; ///< Number of quadrature points in x dimension + + IndexViewType property_index_mapping; ///< View to store property index + ///< mapping + IndexViewType::HostMirror h_property_index_mapping; ///< Host mirror of + ///< property index + ///< mapping + containers_type elastic_isotropic; ///< Elastic isotropic material values @@ -81,15 +94,6 @@ struct value_containers { } }; -void compute_number_of_elements_per_medium( - const int nspec, const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, - const specfem::kokkos::HostView1d - &h_medium_tags, - const specfem::kokkos::HostView1d - &h_property_tags, - int &n_elastic_isotropic, int &n_elastic_anisotropic, int &n_acoustic); - } // namespace impl } // namespace compute } // namespace specfem diff --git a/include/compute/kernels/kernels.hpp b/include/compute/kernels/kernels.hpp index 7dee50b79..bd97d6760 100644 --- a/include/compute/kernels/kernels.hpp +++ b/include/compute/kernels/kernels.hpp @@ -1,6 +1,6 @@ #pragma once -#include "compute/impl/element_types.hpp" +#include "compute/element_types/element_types.hpp" #include "compute/impl/value_containers.hpp" #include "enumerations/medium.hpp" #include "medium/material_kernels.hpp" @@ -17,8 +17,7 @@ namespace compute { * */ struct kernels - : public impl::element_types, - public impl::value_containers { + : public impl::value_containers { public: /** * @name Constructors @@ -42,8 +41,7 @@ struct kernels * @param tags Tags for every element in spectral element mesh */ kernels(const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags); + const specfem::compute::element_types &element_types); ///@} /** @@ -51,12 +49,10 @@ struct kernels * */ void copy_to_host() { - impl::element_types::copy_to_host(); impl::value_containers::copy_to_host(); } void copy_to_device() { - impl::element_types::copy_to_device(); impl::value_containers::copy_to_device(); } }; diff --git a/include/compute/properties/properties.hpp b/include/compute/properties/properties.hpp index c8391310d..2addf56aa 100644 --- a/include/compute/properties/properties.hpp +++ b/include/compute/properties/properties.hpp @@ -1,6 +1,6 @@ #pragma once -#include "compute/impl/element_types.hpp" +#include "compute/element_types/element_types.hpp" #include "compute/impl/value_containers.hpp" #include "enumerations/specfem_enums.hpp" #include "kokkos_abstractions.h" @@ -23,8 +23,7 @@ namespace compute { * */ struct properties - : public impl::element_types, - public impl::value_containers { + : public impl::value_containers { /** * @name Constructors */ @@ -49,10 +48,8 @@ struct properties * assignment if true) */ properties(const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, - const specfem::mesh::materials &materials, - const bool &has_gll_model); + const specfem::compute::element_types &element_types, + const specfem::mesh::materials &materials, bool has_gll_model); ///@} @@ -61,13 +58,11 @@ struct properties * */ void copy_to_host() { - impl::element_types::copy_to_host(); impl::value_containers< specfem::medium::material_properties>::copy_to_host(); } void copy_to_device() { - impl::element_types::copy_to_device(); impl::value_containers< specfem::medium::material_properties>::copy_to_device(); } diff --git a/include/compute/properties/properties.tpp b/include/compute/properties/properties.tpp deleted file mode 100644 index 2570a1d7f..000000000 --- a/include/compute/properties/properties.tpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "properties.hpp" -#include - -template -specfem::medium::material_properties< - type, property>::medium_property(const int nspec, const int n_element, - const int ngllz, const int ngllx, - const specfem::mesh::materials &materials, - const specfem::kokkos::HostView1d - property_material_mapping) - : specfem::medium::properties_container( - n_element, ngllz, ngllx) { - - int count = 0; - for (int ispec = 0; ispec < nspec; ++ispec) { - const auto material_specification = materials.material_index_mapping(ispec); - const int index = material_specification.index; - if ((material_specification.type == type) && - (material_specification.property == property)) { - h_property_index_mapping(ispec) = count; - for (int iz = 0; iz < ngllz; ++iz) { - for (int ix = 0; ix < ngllx; ++ix) { - // Get the material at index from mesh::materials - auto material = - std::get >( - materials[index]); - // Assign the material property to the property container - auto point_property = material.get_property(); - this->assign(count, iz, ix, property); - } - } - count++; - } - } - - assert(count == n_element); - - this->copy_to_device(); - - return; -} diff --git a/include/compute/receivers/receivers.hpp b/include/compute/receivers/receivers.hpp index 1a6b35443..ca981288c 100644 --- a/include/compute/receivers/receivers.hpp +++ b/include/compute/receivers/receivers.hpp @@ -1,5 +1,6 @@ #pragma once +#include "compute/element_types/element_types.hpp" #include "enumerations/specfem_enums.hpp" #include #include @@ -269,8 +270,7 @@ class SeismogramIterator { * @brief Struct to store information related to the receivers * */ -struct receivers : private impl::element_types, - public impl::StationIterator, +struct receivers : public impl::StationIterator, public impl::SeismogramIterator { private: using IndexViewType = @@ -316,7 +316,7 @@ struct receivers : private impl::element_types, const std::vector &stypes, const specfem::compute::mesh &mesh, const specfem::mesh::tags &tags, - const specfem::compute::properties &properties); + const specfem::compute::element_types &element_types); /** * @brief Get the spectral element indices in which the receivers are located @@ -358,6 +358,7 @@ struct receivers : private impl::element_types, } private: + int nspec; ///< Total number of spectral elements IndexViewType elements; ///< View to store the elements associated with the ///< receivers IndexViewType::HostMirror h_elements; ///< Host view to store the @@ -370,6 +371,23 @@ struct receivers : private impl::element_types, LagrangeInterpolantType::HostMirror h_lagrange_interpolant; ///< Lagrange interpolant for every receiver ///< stored on the host + specfem::compute::element_types element_types; ///< Element types + +#define RECEIVER_INDICES_VARIABLE_NAME(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + IndexViewType CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); \ + IndexViewType::HostMirror CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + RECEIVER_INDICES_VARIABLE_NAME, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef RECEIVER_INDICES_VARIABLE_NAME template friend KOKKOS_FUNCTION void @@ -416,14 +434,14 @@ load_on_device(const MemberType &team_member, const IteratorType &iterator, if (index.ispec >= receivers.nspec) { std::string message = "Invalid element detected in kernel at " + - std::string(__FILE__) + + std::string(__FILE__) + ":" + std::to_string(__LINE__); Kokkos::abort(message.c_str()); } if (receivers.receiver_domain_index_mapping(index.ispec) == -1) { std::string message = "Invalid element detected in kernel at " + - std::string(__FILE__) + + std::string(__FILE__) + ":" + std::to_string(__LINE__); Kokkos::abort(message.c_str()); } diff --git a/include/compute/sources/source_medium.hpp b/include/compute/sources/source_medium.hpp index e6feabec0..7319055ce 100644 --- a/include/compute/sources/source_medium.hpp +++ b/include/compute/sources/source_medium.hpp @@ -1,6 +1,7 @@ #pragma once #include "compute/compute_mesh.hpp" +#include "compute/element_types/element_types.hpp" #include "source/source.hpp" #include "specfem_setup.hpp" #include @@ -71,7 +72,7 @@ struct source_medium { * @param sources Vector of sources located within the medium * @param mesh Finite element mesh information * @param partial_derivatives Partial derivatives for every quadrature point - * @param properties Material properties for every quadrature point + * @param element_types Element types for every spectral element * @param t0 Initial time * @param dt Time step * @param nsteps Number of time steps @@ -80,7 +81,7 @@ struct source_medium { const std::vector > &sources, const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, const type_real t0, + const specfem::compute::element_types &element_types, const type_real t0, const type_real dt, const int nsteps); ///@} diff --git a/include/compute/sources/source_medium.tpp b/include/compute/sources/source_medium.tpp index 1adf3a3a2..65713f86e 100644 --- a/include/compute/sources/source_medium.tpp +++ b/include/compute/sources/source_medium.tpp @@ -7,29 +7,27 @@ template -specfem::compute::impl::source_medium:: - source_medium( - const std::vector > &sources, - const specfem::compute::mesh &mesh, - const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, const type_real t0, - const type_real dt, const int nsteps) +specfem::compute::impl::source_medium::source_medium( + const std::vector > &sources, + const specfem::compute::mesh &mesh, + const specfem::compute::partial_derivatives &partial_derivatives, + const specfem::compute::element_types &element_types, const type_real t0, + const type_real dt, const int nsteps) : source_index_mapping("specfem::sources::source_index_mapping", sources.size()), h_source_index_mapping(Kokkos::create_mirror_view(source_index_mapping)), source_time_function("specfem::sources::source_time_function", nsteps, sources.size(), components), h_source_time_function(Kokkos::create_mirror_view(source_time_function)), - source_array("specfem::sources::source_array", sources.size(), - components, mesh.quadratures.gll.N, - mesh.quadratures.gll.N), + source_array("specfem::sources::source_array", sources.size(), components, + mesh.quadratures.gll.N, mesh.quadratures.gll.N), h_source_array(Kokkos::create_mirror_view(source_array)) { for (int isource = 0; isource < sources.size(); isource++) { auto sv_source_array = Kokkos::subview( this->h_source_array, isource, Kokkos::ALL, Kokkos::ALL, Kokkos::ALL); sources[isource]->compute_source_array(mesh, partial_derivatives, - properties, sv_source_array); + element_types, sv_source_array); auto sv_stf_array = Kokkos::subview(this->h_source_time_function, Kokkos::ALL, isource, Kokkos::ALL); sources[isource]->compute_source_time_function(t0, dt, nsteps, diff --git a/include/compute/sources/sources.hpp b/include/compute/sources/sources.hpp index 813e20996..19c74aa76 100644 --- a/include/compute/sources/sources.hpp +++ b/include/compute/sources/sources.hpp @@ -26,8 +26,21 @@ struct sources { using WavefieldTagViewType = Kokkos::View; ///< Underlying view type to - ///< store wavefield tags + Kokkos::DefaultExecutionSpace>; ///< Underlying view type + ///< to store wavefield + ///< tags + + using BoundaryTagViewType = + Kokkos::View; ///< Underlying view type + ///< to store boundary + ///< tags + + using PropertyTagViewType = + Kokkos::View; ///< Underlying view type + ///< to store property + ///< tags public: /** @@ -56,7 +69,7 @@ struct sources { const std::vector > &sources, const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, const type_real t0, + const specfem::compute::element_types &element_types, const type_real t0, const type_real dt, const int nsteps); ///@} @@ -71,6 +84,8 @@ struct sources { */ Kokkos::View get_elements_on_host( const specfem::element::medium_tag medium, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary, const specfem::wavefield::simulation_field wavefield) const; /** @@ -84,6 +99,8 @@ struct sources { */ Kokkos::View get_elements_on_device( const specfem::element::medium_tag medium, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary, const specfem::wavefield::simulation_field wavefield) const; /** @@ -111,7 +128,15 @@ struct sources { WavefieldTagViewType wavefield_types; ///< Wavefield on which source is ///< applied WavefieldTagViewType::HostMirror h_wavefield_types; ///< Host mirror of - ///< wavefield_type + ///< wavefield_types + BoundaryTagViewType boundary_types; ///< Boundary type for every spectral + ///< element + BoundaryTagViewType::HostMirror h_boundary_types; ///< Host mirror of + ///< boundary_types + PropertyTagViewType property_types; ///< Property type for every spectral + ///< element + PropertyTagViewType::HostMirror h_property_types; ///< Host mirror of + ///< property_types #define SOURCE_MEDIUM_DECLARATION(DIMENSION_TAG, MEDIUM_TAG) \ specfem::compute::impl::source_medium friend KOKKOS_INLINE_FUNCTION void load_on_device(const IndexType index, @@ -250,7 +306,7 @@ void load_on_host(const IndexType index, const specfem::compute::sources &sources, PointSourceType &point_source) { - static_assert(IndexType::simd::using_simd == false, + static_assert(IndexType::using_simd == false, "IndexType must not use SIMD when loading sources"); static_assert( diff --git a/include/domain/domain.hpp b/include/domain/domain.hpp deleted file mode 100644 index 70eadcc6f..000000000 --- a/include/domain/domain.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include "compute/assembly/assembly.hpp" -#include "impl/kernels.hpp" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" -#include - -namespace specfem { -namespace domain { - -/** - * @brief Compute kernels for compute evolution of wavefield under the influence - * of a source within a domain of elements specified by MediumTag. - * - * @tparam WavefieldType Type of wavefield. Forward or adjoint - * @tparam DimensionType Dimension of the domain. 2D or 3D - * @tparam MediumTag Tag specifying the medium - * @tparam qp_type Type of quadrature points i.e. static or dynamic (will be - * deprecated soon) - */ -template -class domain : public specfem::domain::impl::kernels::kernels< - WavefieldType, DimensionType, MediumTag, qp_type> { -public: - constexpr static auto dimension = DimensionType; ///< Dimension of the domain - constexpr static auto medium_tag = MediumTag; ///< Medium tag - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - constexpr static int components = - specfem::element::attributes::components(); - using quadrature_points_type = qp_type; - - /** - * @brief Generate a new domain from an assembled mesh - * - * @param dt Time step - * @param assembly Assembled mesh - * @param quadrature_points Quadrature points object - */ - domain(const type_real dt, const specfem::compute::assembly &assembly, - const quadrature_points_type &quadrature_points) - : field(assembly.fields.get_simulation_field()), - specfem::domain::impl::kernels::kernels< - WavefieldType, DimensionType, MediumTag, quadrature_points_type>( - dt, assembly, quadrature_points) {} - - ~domain() = default; - - /** - * @brief Invert the mass matrix - */ - void invert_mass_matrix(); - - /** - * @brief Divide acceleration by mass matrix - */ - void divide_mass_matrix(); - -private: - specfem::compute::simulation_field field; ///< Wavefield -}; -} // namespace domain - -} // namespace specfem diff --git a/include/domain/domain.tpp b/include/domain/domain.tpp deleted file mode 100644 index da7c45b6a..000000000 --- a/include/domain/domain.tpp +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "domain.hpp" -#include "parallel_configuration/range_config.hpp" -#include "policies/range.hpp" -#include - -template -void specfem::domain::domain::divide_mass_matrix() { - const int nglob = field.template get_nglob(); - constexpr bool using_simd = true; - using LoadFieldType = specfem::point::field; - using StoreFieldType = specfem::point::field; - - using ParallelConfig = specfem::parallel_config::default_range_config< - specfem::datatype::simd, - Kokkos::DefaultExecutionSpace>; - - using RangePolicy = specfem::policy::range; - - RangePolicy range(nglob); - - Kokkos::parallel_for( - "specfem::domain::domain::divide_mass_matrix", - static_cast(range), - KOKKOS_CLASS_LAMBDA(const int iglob) { - const auto iterator = range.range_iterator(iglob); - const auto index = iterator(0); - - LoadFieldType load_field; - specfem::compute::load_on_device(index.index, field, load_field); - StoreFieldType store_field(load_field.divide_mass_matrix()); - specfem::compute::store_on_device(index.index, store_field, field); - }); - - Kokkos::fence(); - - return; -} - -template -void specfem::domain::domain::invert_mass_matrix() { - const int nglob = field.template get_nglob(); - constexpr bool using_simd = true; - using PointFieldType = specfem::point::field; - - using ParallelConfig = specfem::parallel_config::default_range_config< - specfem::datatype::simd, - Kokkos::DefaultExecutionSpace>; - - using RangePolicy = specfem::policy::range; - - RangePolicy range(nglob); - - Kokkos::parallel_for( - "specfem::domain::domain::divide_mass_matrix", - static_cast(range), - KOKKOS_CLASS_LAMBDA(const int iglob) { - const auto iterator = range.range_iterator(iglob); - const auto index = iterator(0); - - PointFieldType load_field; - specfem::compute::load_on_device(index.index, field, load_field); - PointFieldType store_field(load_field.invert_mass_matrix()); - specfem::compute::store_on_device(index.index, store_field, field); - }); - - Kokkos::fence(); -} diff --git a/include/domain/impl/elements/kernel.hpp b/include/domain/impl/elements/kernel.hpp deleted file mode 100644 index 5725ac3cd..000000000 --- a/include/domain/impl/elements/kernel.hpp +++ /dev/null @@ -1,334 +0,0 @@ -#pragma once - -#include "chunk_element/field.hpp" -#include "chunk_element/stress_integrand.hpp" -#include "compute/interface.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "parallel_configuration/chunk_config.hpp" -#include "point/boundary.hpp" -#include "point/field.hpp" -#include "point/field_derivatives.hpp" -#include "point/properties.hpp" -#include "point/stress_integrand.hpp" -#include "policies/chunk.hpp" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace kernels { -/** - * @brief Datatypes used in the kernels - */ -template -class KernelDatatypes { -public: - constexpr static auto wavefield_type = WavefieldType; - constexpr static auto dimension = DimensionType; - constexpr static auto medium_tag = MediumTag; - constexpr static auto property_tag = PropertyTag; - constexpr static auto boundary_tag = BoundaryTag; - constexpr static int ngll = NGLL; - constexpr static bool using_simd = true; - - using simd = specfem::datatype::simd; - using ParallelConfig = specfem::parallel_config::default_chunk_config< - DimensionType, simd, Kokkos::DefaultExecutionSpace>; - - using ChunkPolicyType = specfem::policy::element_chunk; - - using PointBoundaryType = - specfem::point::boundary; - - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - constexpr static int components = - specfem::element::attributes::components(); - - using ChunkElementFieldType = specfem::chunk_element::field< - ParallelConfig::chunk_size, ngll, DimensionType, MediumTag, - specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, - true, false, false, false, using_simd>; - - using ChunkStressIntegrandType = specfem::chunk_element::stress_integrand< - ParallelConfig::chunk_size, ngll, DimensionType, MediumTag, - specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, - using_simd>; - - using ElementQuadratureType = specfem::element::quadrature< - ngll, specfem::dimension::type::dim2, specfem::kokkos::DevScratchSpace, - Kokkos::MemoryTraits, true, true>; - - using PointAccelerationType = - specfem::point::field; - using PointVelocityType = - specfem::point::field; - - using PointFieldDerivativesType = - specfem::point::field_derivatives; - - using PointMassType = specfem::point::field; - - using PointPropertyType = - specfem::point::properties; - - using PointPartialDerivativesType = - specfem::point::partial_derivatives; -}; - -template -class element_kernel_base { -private: - /// Datatypes used in the kernels - using datatypes = KernelDatatypes; - using simd = typename datatypes::simd; - using ChunkPolicyType = typename datatypes::ChunkPolicyType; - using PointBoundaryType = typename datatypes::PointBoundaryType; - using ChunkElementFieldType = typename datatypes::ChunkElementFieldType; - using ChunkStressIntegrandType = typename datatypes::ChunkStressIntegrandType; - using ElementQuadratureType = typename datatypes::ElementQuadratureType; - using PointAccelerationType = typename datatypes::PointAccelerationType; - using PointVelocityType = typename datatypes::PointVelocityType; - using PointFieldDerivativesType = - typename datatypes::PointFieldDerivativesType; - using PointMassType = typename datatypes::PointMassType; - using PointPropertyType = typename datatypes::PointPropertyType; - using PointPartialDerivativesType = - typename datatypes::PointPartialDerivativesType; - - constexpr static int components = datatypes::components; - constexpr static int num_dimensions = datatypes::num_dimensions; - -public: - /** - * @name Compile-time constants - * - */ - ///@{ - constexpr static auto wavefield_type = WavefieldType; ///< Type of wavefield - constexpr static auto dimension = - DimensionType; ///< Dimension of the elements - constexpr static auto medium_tag = MediumTag; ///< Medium tag of the elements - constexpr static auto property_tag = - PropertyTag; ///< Property tag of the elements - constexpr static auto boundary_tag = - BoundaryTag; ///< Boundary tag of the elements - constexpr static int ngll = NGLL; - ///@} - -public: - /** - * @brief Get the total number of elements in this kernel - * - * @return int Number of elements - */ - inline int total_elements() const { return nelements; } - - element_kernel_base() = default; - element_kernel_base( - const specfem::compute::assembly &assembly, - const specfem::kokkos::HostView1d h_element_kernel_index_mapping); - - void compute_mass_matrix( - const type_real dt, - const specfem::compute::simulation_field &field) const; - - void compute_stiffness_interaction( - const int istep, - const specfem::compute::simulation_field &field) const; - -protected: - int nelements; ///< Number of elements in this kernel - specfem::compute::points points; ///< Assembly information - specfem::compute::quadrature quadrature; ///< Information on integration - ///< quadrature - specfem::kokkos::DeviceView1d - element_kernel_index_mapping; ///< Spectral element index for every - ///< element in this kernel - specfem::kokkos::HostMirror1d - h_element_kernel_index_mapping; ///< Host mirror of - ///< element_kernel_index_mapping - specfem::compute::properties properties; ///< Material properties - specfem::compute::partial_derivatives partial_derivatives; ///< Spatial - ///< derivatives of - ///< basis - ///< functions - specfem::compute::boundaries boundaries; ///< Boundary information - specfem::compute::boundary_value_container - boundary_values; ///< Boundary values to store information on field values - ///< at boundaries for reconstruction during adjoint - ///< simulations -}; - -/** - * @brief Compute Kernels for computing evolution of wavefield within elements - * defined by element tags - * - * @tparam WavefieldType Type of the wavefield on which this kernel operates - * @tparam DimensionType Dimension for the elements within this kernel - * @tparam MediumTag Medium tag for the elements within this kernel - * @tparam PropertyTag Property tag for the elements within this kernel - * @tparam BoundaryTag Boundary tag for the elements within this kernel - * @tparam NGLL Number of GLL points in each dimension for the elements within - * this kernel - */ -template -class element_kernel - : public element_kernel_base { - -public: - /** - * @name Constructors - * - */ - ///@{ - - /** - * @brief Default Constructor - */ - element_kernel() = default; - - /** - * @brief Construct a element kernels based on assembly information - * - * @param assembly Assembly information - * @param h_element_kernel_index_mapping Spectral element index for every - * element in this kernel - */ - element_kernel( - const specfem::compute::assembly &assembly, - const specfem::kokkos::HostView1d h_element_kernel_index_mapping) - : field(assembly.fields.get_simulation_field()), - element_kernel_base( - assembly, h_element_kernel_index_mapping) {} - ///@} - - /** - * @brief Compute the mass matrix for the elements in this kernel - * - * @param dt Time step - */ - void compute_mass_matrix(const type_real dt) const { - element_kernel_base::compute_mass_matrix(dt, field); - } - - /** - * @brief Compute the interaction of wavefield with stiffness matrix - * - * @param istep Time step - */ - void compute_stiffness_interaction(const int istep) const { - element_kernel_base::compute_stiffness_interaction(istep, field); - } - -private: - specfem::compute::simulation_field field; ///< Wavefield -}; - -template -class element_kernel - : public element_kernel_base { - -private: - /// Datatypes used in the kernels - using datatypes = - KernelDatatypes; - using simd = typename datatypes::simd; - using ChunkPolicyType = typename datatypes::ChunkPolicyType; - using PointBoundaryType = typename datatypes::PointBoundaryType; - using ChunkElementFieldType = typename datatypes::ChunkElementFieldType; - using ChunkStressIntegrandType = typename datatypes::ChunkStressIntegrandType; - using ElementQuadratureType = typename datatypes::ElementQuadratureType; - using PointAccelerationType = typename datatypes::PointAccelerationType; - using PointVelocityType = typename datatypes::PointVelocityType; - using PointFieldDerivativesType = - typename datatypes::PointFieldDerivativesType; - using PointMassType = typename datatypes::PointMassType; - using PointPropertyType = typename datatypes::PointPropertyType; - using PointPartialDerivativesType = - typename datatypes::PointPartialDerivativesType; - - constexpr static int components = datatypes::components; - constexpr static int num_dimensions = datatypes::num_dimensions; - -public: - /** - * @name Compile-time constants - * - */ - ///@{ - constexpr static auto wavefield_type = - specfem::wavefield::simulation_field::backward; ///< Type of wavefield - constexpr static auto dimension = - DimensionType; ///< Dimension of the elements - constexpr static auto medium_tag = MediumTag; ///< Medium tag of the elements - constexpr static auto property_tag = - PropertyTag; ///< Property tag of the elements - constexpr static auto boundary_tag = - specfem::element::boundary_tag::stacey; ///< Boundary tag of the elements - constexpr static int ngll = NGLL; - ///@} - -public: - element_kernel() = default; - element_kernel( - const specfem::compute::assembly &assembly, - const specfem::kokkos::HostView1d h_element_kernel_index_mapping) - : field(assembly.fields.get_simulation_field< - specfem::wavefield::simulation_field::backward>()), - element_kernel_base( - assembly, h_element_kernel_index_mapping) {} - - void compute_mass_matrix(const type_real dt) const { - element_kernel_base::compute_mass_matrix(dt, field); - } - - void compute_stiffness_interaction(const int istep) const; - -private: - specfem::compute::simulation_field< - specfem::wavefield::simulation_field::backward> - field; -}; - -} // namespace kernels -} // namespace impl -} // namespace domain -} // namespace specfem diff --git a/include/domain/impl/elements/kernel.tpp b/include/domain/impl/elements/kernel.tpp deleted file mode 100644 index 695df2b76..000000000 --- a/include/domain/impl/elements/kernel.tpp +++ /dev/null @@ -1,338 +0,0 @@ -#pragma once - -#include "algorithms/divergence.hpp" -#include "algorithms/gradient.hpp" -#include "compute/assembly/assembly.hpp" -#include "domain/impl/boundary_conditions/boundary_conditions.hpp" -#include "medium/compute_stress_integrand.hpp" -#include "medium/compute_mass_matrix.hpp" -#include "enumerations/dimension.hpp" -#include "enumerations/medium.hpp" -#include "enumerations/specfem_enums.hpp" -#include "kernel.hpp" -#include "medium/medium.hpp" -#include "specfem_setup.hpp" -#include - -template -specfem::domain::impl::kernels::element_kernel_base< - WavefieldType, DimensionType, MediumTag, PropertyTag, BoundaryTag, - NGLL>::element_kernel_base(const specfem::compute::assembly &assembly, - const specfem::kokkos::HostView1d - h_element_kernel_index_mapping) - : nelements(h_element_kernel_index_mapping.extent(0)), - element_kernel_index_mapping("specfem::domain::impl::kernels::element_" - "kernel_base::element_kernel_index_mapping", - nelements), - h_element_kernel_index_mapping(h_element_kernel_index_mapping), - points(assembly.mesh.points), quadrature(assembly.mesh.quadratures), - partial_derivatives(assembly.partial_derivatives), - properties(assembly.properties), boundaries(assembly.boundaries), - boundary_values(assembly.boundary_values.get_container()) { - - // Check if the elements being allocated to this kernel are of the correct - // type - for (int ispec = 0; ispec < nelements; ispec++) { - const int ielement = h_element_kernel_index_mapping(ispec); - if ((assembly.properties.h_medium_tags(ielement) != MediumTag) && - (assembly.properties.h_property_tags(ielement) != PropertyTag)) { - throw std::runtime_error("Invalid element detected in kernel"); - } - } - - // Assert that ispec of the elements is contiguous - for (int ispec = 0; ispec < nelements; ispec++) { - if (ispec != 0) { - if (h_element_kernel_index_mapping(ispec) != - h_element_kernel_index_mapping(ispec - 1) + 1) { - throw std::runtime_error("Element index mapping is not contiguous"); - } - } - } - - Kokkos::deep_copy(element_kernel_index_mapping, - h_element_kernel_index_mapping); - return; -} - - -template -void specfem::domain::impl::kernels::element_kernel_base< - WavefieldType, DimensionType, MediumTag, PropertyTag, BoundaryTag, - NGLL>::compute_mass_matrix(const type_real dt, - const specfem::compute::simulation_field< - WavefieldType> &field) const { - if (nelements == 0) - return; - - const auto wgll = quadrature.gll.weights; - - constexpr int simd_size = simd::size(); - - ChunkPolicyType chunk_policy(element_kernel_index_mapping, NGLL, NGLL); - - Kokkos::parallel_for( - "specfem::domain::impl::kernels::elements::compute_mass_matrix", - static_cast(chunk_policy), - KOKKOS_CLASS_LAMBDA(const typename ChunkPolicyType::member_type &team) { - for (int tile = 0; tile < ChunkPolicyType::tile_size * simd_size; - tile += ChunkPolicyType::chunk_size * simd_size) { - const int starting_element_index = - team.league_rank() * ChunkPolicyType::tile_size * simd_size + - tile; - - if (starting_element_index >= nelements) { - break; - } - - const auto iterator = - chunk_policy.league_iterator(starting_element_index); - - Kokkos::parallel_for( - Kokkos::TeamThreadRange(team, iterator.chunk_size()), - [&](const int i) { - const auto iterator_index = iterator(i); - const auto index = iterator_index.index; - const int ix = iterator_index.index.ix; - const int iz = iterator_index.index.iz; - - const auto point_property = [&]() -> PointPropertyType { - PointPropertyType point_property; - - specfem::compute::load_on_device(index, properties, - point_property); - return point_property; - }(); - - const auto point_partial_derivatives = - [&]() -> PointPartialDerivativesType { - PointPartialDerivativesType point_partial_derivatives; - specfem::compute::load_on_device(index, partial_derivatives, - point_partial_derivatives); - return point_partial_derivatives; - }(); - - PointMassType mass_matrix = - specfem::medium::mass_matrix_component( - point_property, point_partial_derivatives); - - for (int icomp = 0; icomp < components; icomp++) { - mass_matrix.mass_matrix(icomp) *= wgll(ix) * wgll(iz); - } - - PointBoundaryType point_boundary; - specfem::compute::load_on_device(index, boundaries, - point_boundary); - - specfem::domain::impl::boundary_conditions:: - compute_mass_matrix_terms(dt, point_boundary, - point_property, mass_matrix); - - specfem::compute::atomic_add_on_device(index, mass_matrix, - field); - }); - } - }); - - Kokkos::fence(); - - return; -} - -template -void specfem::domain::impl::kernels::element_kernel_base< - WavefieldType, DimensionType, MediumTag, PropertyTag, BoundaryTag, NGLL>:: - compute_stiffness_interaction( - const int istep, - const specfem::compute::simulation_field &field) const { - - if (nelements == 0) - return; - - const auto hprime = quadrature.gll.hprime; - const auto wgll = quadrature.gll.weights; - const auto index_mapping = points.index_mapping; - - int scratch_size = ChunkElementFieldType::shmem_size() + - ChunkStressIntegrandType::shmem_size() + - ElementQuadratureType::shmem_size(); - - ChunkPolicyType chunk_policy(element_kernel_index_mapping, NGLL, NGLL); - - constexpr int simd_size = simd::size(); - - Kokkos::parallel_for( - "specfem::domain::impl::kernels::elements::compute_stiffness_interaction", - chunk_policy.set_scratch_size(0, Kokkos::PerTeam(scratch_size)), - KOKKOS_CLASS_LAMBDA(const typename ChunkPolicyType::member_type &team) { - ChunkElementFieldType element_field(team); - ElementQuadratureType element_quadrature(team); - ChunkStressIntegrandType stress_integrand(team); - - specfem::compute::load_on_device(team, quadrature, element_quadrature); - for (int tile = 0; tile < ChunkPolicyType::tile_size * simd_size; - tile += ChunkPolicyType::chunk_size * simd_size) { - const int starting_element_index = - team.league_rank() * ChunkPolicyType::tile_size * simd_size + - tile; - - if (starting_element_index >= nelements) { - break; - } - - const auto iterator = - chunk_policy.league_iterator(starting_element_index); - specfem::compute::load_on_device(team, iterator, field, - element_field); - - team.team_barrier(); - - specfem::algorithms::gradient( - team, iterator, partial_derivatives, - element_quadrature.hprime_gll, element_field.displacement, - // Compute stresses using the gradients - [&](const typename ChunkPolicyType::iterator_type::index_type - &iterator_index, - const typename PointFieldDerivativesType::ViewType &du) { - const auto &index = iterator_index.index; - - PointPartialDerivativesType point_partial_derivatives; - specfem::compute::load_on_device(index, partial_derivatives, - point_partial_derivatives); - - PointPropertyType point_property; - specfem::compute::load_on_device(index, properties, - point_property); - - PointFieldDerivativesType field_derivatives(du); - - const auto point_stress = specfem::medium::compute_stress( - point_property, field_derivatives); - - const auto F = point_stress * point_partial_derivatives; - - const int &ielement = iterator_index.ielement; - - for (int icomponent = 0; icomponent < components; - ++icomponent) { - for (int idim = 0; idim < num_dimensions; ++idim) { - stress_integrand.F(ielement, index.iz, index.ix, idim, - icomponent) = F(idim, icomponent); - } - } - }); - - team.team_barrier(); - - specfem::algorithms::divergence( - team, iterator, partial_derivatives, wgll, - element_quadrature.hprime_wgll, stress_integrand.F, - [&, istep = istep]( - const typename ChunkPolicyType::iterator_type::index_type - &iterator_index, - const typename PointAccelerationType::ViewType &result) { - const auto &index = iterator_index.index; - PointAccelerationType acceleration(result); - - for (int icomponent = 0; icomponent < components; - ++icomponent) { - acceleration.acceleration(icomponent) *= - static_cast(-1.0); - } - - PointPropertyType point_property; - specfem::compute::load_on_device(index, properties, - point_property); - - PointVelocityType velocity; - specfem::compute::load_on_device(index, field, velocity); - - PointBoundaryType point_boundary; - specfem::compute::load_on_device(index, boundaries, - point_boundary); - - specfem::domain::impl::boundary_conditions:: - apply_boundary_conditions(point_boundary, point_property, - velocity, acceleration); - - // Store forward boundary values for reconstruction during - // adjoint simulations. The function does nothing if the - // boundary tag is not stacey - if constexpr (WavefieldType == - specfem::wavefield::simulation_field::forward) { - specfem::compute::store_on_device(istep, index, acceleration, - boundary_values); - } - - specfem::compute::atomic_add_on_device(index, acceleration, - field); - }); - } - }); - - Kokkos::fence(); - - return; -} - -template -void specfem::domain::impl::kernels::element_kernel< - specfem::wavefield::simulation_field::backward, DimensionType, MediumType, PropertyTag, - specfem::element::boundary_tag::stacey, - NGLL>::compute_stiffness_interaction(const int istep) const { - - if (this->nelements == 0) - return; - - ChunkPolicyType chunk_policy(this->element_kernel_index_mapping, NGLL, NGLL); - - constexpr int simd_size = simd::size(); - - Kokkos::parallel_for( - "specfem::domain::impl::kernels::elements::compute_stiffness_" - "interaction", - static_cast(chunk_policy), - KOKKOS_CLASS_LAMBDA(const typename ChunkPolicyType::member_type &team) { - for (int tile = 0; tile < ChunkPolicyType::tile_size * simd_size; - tile += ChunkPolicyType::chunk_size * simd_size) { - const int starting_element_index = - team.league_rank() * ChunkPolicyType::tile_size * simd_size + - tile; - - if (starting_element_index >= this->nelements) { - break; - } - - const auto iterator = - chunk_policy.league_iterator(starting_element_index); - - Kokkos::parallel_for( - Kokkos::TeamThreadRange(team, iterator.chunk_size()), - [&](const int i) { - const auto iterator_index = iterator(i); - const auto index = iterator_index.index; - - PointAccelerationType acceleration; - specfem::compute::load_on_device( - istep, index, this->boundary_values, acceleration); - - specfem::compute::atomic_add_on_device(index, acceleration, - this->field); - }); - } - }); -} diff --git a/include/domain/impl/kernels.hpp b/include/domain/impl/kernels.hpp deleted file mode 100644 index 795695d6b..000000000 --- a/include/domain/impl/kernels.hpp +++ /dev/null @@ -1,303 +0,0 @@ -#pragma once - -#include "compute/interface.hpp" -#include "domain/impl/elements/kernel.hpp" -#include "domain/impl/receivers/interface.hpp" -#include "domain/impl/sources/interface.hpp" -#include "enumerations/interface.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace kernels { - -template -class kernels; - -template -class kernels { -public: - using quadrature_point_type = qp_type; - using dimension = specfem::dimension::dimension; - 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) { - isotropic_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 - using element_kernel = specfem::domain::impl::kernels::element_kernel< - WavefieldType, DimensionType, elastic, property, boundary, - NGLL>; ///< Underlying element kernel data structure - - template - using source_kernel = specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, elastic, property, - NGLL>; ///< Underlying source kernel data structure - - template - using receiver_kernel = specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, elastic, property, - NGLL>; ///< Underlying receiver kernel data structure - - element_kernel - isotropic_elements; ///< Stiffness kernels for isotropic elements - - // element_kernel - // isotropic_elements_dirichlet; ///< Stiffness kernels for isotropic - // ///< elements with Dirichlet boundary - // ///< conditions - - element_kernel - isotropic_elements_stacey; ///< Stiffness kernels for isotropic elements - ///< with Stacey boundary conditions - - // element_kernel - // isotropic_elements_stacey_dirichlet; ///< Stiffness kernels for - // isotropic - // ///< elements with Stacey and - // ///< Dirichlet boundary - // conditions on - // ///< the same element - - element_kernel - anisotropic_elements; ///< Stiffness kernels for anisotropic elements - - // element_kernel - // anisotropic_elements_dirichlet; ///< Stiffness kernels for - // anisotropic - // ///< elements with Dirichlet boundary - // ///< conditions - - element_kernel - anisotropic_elements_stacey; ///< Stiffness kernels for anisotropic - ///< elements with Stacey boundary conditions - - // element_kernel - // anisotropic_elements_stacey_dirichlet; ///< Stiffness kernels for - // ///< anisotropic elements with - // ///< Stacey and Dirichlet - // boundary - // ///< conditions on the same - // element - - source_kernel isotropic_sources; ///< Source kernels - ///< for isotropic - ///< elements - - receiver_kernel - isotropic_receivers; ///< Kernels for computing seismograms within - ///< isotropic elements - - receiver_kernel - anisotropic_receivers; ///< Kernels for computing seismograms within - ///< anisotropic elements -}; - -template -class kernels { -public: - using quadrature_point_type = qp_type; - using dimension = specfem::dimension::dimension; - 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); - isotropic_elements_dirichlet.compute_stiffness_interaction(istep); - isotropic_elements_stacey.compute_stiffness_interaction(istep); - isotropic_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); - isotropic_elements_dirichlet.compute_mass_matrix(dt); - isotropic_elements_stacey.compute_mass_matrix(dt); - isotropic_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) { - isotropic_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); - 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::medium_tag acoustic = - specfem::element::medium_tag::acoustic; - - constexpr static int NGLL = quadrature_point_type::NGLL; - - template - using element_kernel = specfem::domain::impl::kernels::element_kernel< - WavefieldType, DimensionType, acoustic, property, boundary, - NGLL>; ///< Underlying element kernel data structure - - template - using source_kernel = specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, acoustic, property, - NGLL>; ///< Underlying source kernel data structure - - template - using receiver_kernel = specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, acoustic, property, - NGLL>; ///< Underlying receiver kernel data structure - - element_kernel - isotropic_elements; ///< Stiffness kernels for isotropic elements - - element_kernel - isotropic_elements_dirichlet; ///< Stiffness kernels for isotropic - ///< elements with Dirichlet boundary - ///< conditions - - element_kernel - isotropic_elements_stacey; ///< Stiffness kernels for isotropic elements - ///< with Stacey boundary conditions - - element_kernel - isotropic_elements_stacey_dirichlet; ///< Stiffness kernels for isotropic - ///< elements with Stacey and - ///< Dirichlet boundary conditions on - ///< the same element - - source_kernel isotropic_sources; ///< Source kernels - ///< for isotropic - ///< elements - - receiver_kernel - isotropic_receivers; ///< Kernels for computing seismograms within - ///< isotropic elements -}; -} // namespace kernels -} // namespace impl -} // namespace domain -} // namespace specfem diff --git a/include/domain/impl/kernels.tpp b/include/domain/impl/kernels.tpp deleted file mode 100644 index 6f527da0f..000000000 --- a/include/domain/impl/kernels.tpp +++ /dev/null @@ -1,287 +0,0 @@ -#pragma once - -#include "boundary_conditions/boundary_conditions.hpp" -#include "kernels.hpp" - -namespace { -/// Struct to tag each element -struct element_tag { - - element_tag(const specfem::element::medium_tag &medium_tag, - const specfem::element::property_tag &property_tag, - const specfem::element::boundary_tag &boundary_tag) - : medium_tag(medium_tag), property_tag(property_tag), - boundary_tag(boundary_tag) {} - - element_tag() = default; - - specfem::element::property_tag property_tag; - specfem::element::boundary_tag boundary_tag; - specfem::element::medium_tag medium_tag; -}; - -template -void allocate_elements( - const specfem::compute::assembly &assembly, - const specfem::kokkos::HostView1d element_tags, - ElementType &elements) { - - constexpr auto wavefield_type = ElementType::wavefield_type; - constexpr auto medium_tag = ElementType::medium_tag; - constexpr auto property_tag = ElementType::property_tag; - constexpr auto boundary_tag = ElementType::boundary_tag; - - using dimension = specfem::dimension::dimension; - using medium_type = - specfem::element::attributes; - - const int nspec = assembly.mesh.nspec; - - // count number of elements in this domain - int nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (element_tags(ispec).medium_tag == medium_tag && - element_tags(ispec).property_tag == property_tag && - element_tags(ispec).boundary_tag == boundary_tag) { - - // make sure acoustic free surface elements are acoustic - if (element_tags(ispec).boundary_tag == - specfem::element::boundary_tag::acoustic_free_surface) { - if (element_tags(ispec).medium_tag != - specfem::element::medium_tag::acoustic) { - throw std::runtime_error("Error: acoustic free surface boundary " - "condition found non acoustic element"); - } - } - nelements++; - } - } - - specfem::kokkos::DeviceView1d ispec_domain( - "specfem::domain::domain::h_ispec_domain", nelements); - specfem::kokkos::HostMirror1d h_ispec_domain = - Kokkos::create_mirror_view(ispec_domain); - - // Get ispec for each element in this domain - int index = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (element_tags(ispec).medium_tag == medium_tag && - element_tags(ispec).property_tag == property_tag && - element_tags(ispec).boundary_tag == boundary_tag) { - h_ispec_domain(index) = ispec; - index++; - } - } - - 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, - boundary_tag) - << "\n" - // << " - Boundary Conditions : " - // << - // specfem::domain::impl::boundary_conditions::print_boundary_tag< - // boundary_tag>() - << "\n" - << " - Number of elements : " << nelements << "\n\n"; - } - - // Create isotropic acoustic surface elements - elements = { assembly, h_ispec_domain }; -} - -template -void allocate_isotropic_sources(const specfem::compute::assembly &assembly, - specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, medium_tag, - property_tag, NGLL> &isotropic_sources) { - - // Allocate isotropic sources - isotropic_sources = specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, medium_tag, property_tag, NGLL>(assembly); - - return; -} - -template -void allocate_receivers(const specfem::compute::assembly &assembly, - specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, medium_tag, - property_tag, NGLL> &receivers) { - - // const auto medium = medium_tag; - // const auto property = property_tag; - - // // Create isotropic sources - // const auto ispec_array = assembly.receivers.h_ispec_array; - - // // Count the number of sources within this medium - // int nreceivers = 0; - // for (int ireceiver = 0; ireceiver < ispec_array.extent(0); ireceiver++) { - // const int ispec = ispec_array(ireceiver); - // if (assembly.properties.h_medium_tags(ispec) == medium && - // assembly.properties.h_property_tags(ispec) == property) { - // nreceivers++; - // } - // } - - // // Save the index for sources in this domain - // specfem::kokkos::HostView1d h_receiver_kernel_index_mapping( - // "specfem::domain::domain::receiver_kernel_index_mapping", nreceivers); - - // specfem::kokkos::HostMirror1d h_receiver_mapping( - // "specfem::domain::domain::receiver_mapping", nreceivers); - - // int index = 0; - // for (int ireceiver = 0; ireceiver < ispec_array.extent(0); ireceiver++) { - // const int ispec = ispec_array(ireceiver); - // if (assembly.properties.h_medium_tags(ispec) == medium && - // assembly.properties.h_property_tags(ispec) == property) { - // h_receiver_kernel_index_mapping(index) = ispec_array(ireceiver); - // h_receiver_mapping(index) = ireceiver; - // index++; - // } - // } - - // Allocate isotropic sources - receivers = specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, medium_tag, property_tag, NGLL>(assembly); - - return; -} -} // namespace - -template -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) : isotropic_receivers(assembly), anisotropic_receivers(assembly) { - - const int nspec = assembly.mesh.nspec; - specfem::kokkos::HostView1d element_tags( - "specfem::domain::domain::element_tag", nspec); - - // ----------------------------------------------------------- - for (int ispec = 0; ispec < nspec; ispec++) { - element_tags(ispec) = - element_tag(assembly.properties.h_medium_tags(ispec), - assembly.properties.h_property_tags(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, isotropic_sources); - // Compute mass matrices - - this->compute_mass_matrix(dt); - - return; -} - -template -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) : isotropic_receivers(assembly) { - - const int nspec = assembly.mesh.nspec; - specfem::kokkos::HostView1d element_tags( - "specfem::domain::domain::element_tag", nspec); - - // ----------------------------------------------------------- - for (int ispec = 0; ispec < nspec; ispec++) { - element_tags(ispec) = - element_tag(assembly.properties.h_medium_tags(ispec), - assembly.properties.h_property_tags(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 acoustic medium :\n\n"; - } - - // ----------------------------------------------------------- - - // Allocate isotropic elements with dirichlet boundary conditions - allocate_elements(assembly, element_tags, isotropic_elements_dirichlet); - - // Allocate isotropic elements with stacey boundary conditions - allocate_elements(assembly, element_tags, isotropic_elements_stacey); - - // Allocate isotropic elements with stacey dirichlet boundary conditions - allocate_elements(assembly, element_tags, - isotropic_elements_stacey_dirichlet); - - // Allocate isotropic elements - allocate_elements(assembly, element_tags, isotropic_elements); - - // Allocate isotropic sources - - allocate_isotropic_sources(assembly, isotropic_sources); - - // Compute mass matrices - - this->compute_mass_matrix(dt); - - return; -} diff --git a/include/domain/impl/receivers/acoustic/acoustic2d.hpp b/include/domain/impl/receivers/acoustic/acoustic2d.hpp deleted file mode 100644 index 25101b008..000000000 --- a/include/domain/impl/receivers/acoustic/acoustic2d.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _DOMIAN_IMPL_RECEIVERS_ACOUSTIC2D_HPP_ -#define _DOMIAN_IMPL_RECEIVERS_ACOUSTIC2D_HPP_ - -#include "constants.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { - -template -class receiver { -public: - using dimension = specfem::enums::element::dimension::dim2; - using medium_type = specfem::enums::element::medium::acoustic; - using quadrature_points_type = qp_type; - - template - using ScratchViewType = - typename quadrature_points_type::template ScratchViewType; - - KOKKOS_INLINE_FUNCTION virtual void get_field( - const int xz, const int isig_step, - const ScratchViewType field, - const ScratchViewType field_dot, - const ScratchViewType field_dot_dot, - const ScratchViewType hprime_xx, - const ScratchViewType hprime_zz) const {}; - KOKKOS_INLINE_FUNCTION virtual void - compute_seismogram_components(const int xz, const int isig_step, - specfem::kokkos::array_type - &l_seismogram_components) const {}; - KOKKOS_INLINE_FUNCTION virtual void compute_seismogram( - const int isig_step, - const specfem::kokkos::array_type &seismogram_components){}; - KOKKOS_INLINE_FUNCTION virtual specfem::enums::seismogram::type - get_seismogram_type() const = 0; - KOKKOS_INLINE_FUNCTION virtual int get_ispec() const = 0; -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif /* _DOMIAN_IMPL_RECEIVERS_ACOUSTIC2D_HPP_ */ diff --git a/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.hpp b/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.hpp deleted file mode 100644 index 2a9558b2b..000000000 --- a/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.hpp +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTRPOIC_HPP_ -#define DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTRPOIC_HPP_ - -#include "constants.hpp" -// #include "domain/impl/receivers/acoustic/acoustic2d.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { -/** - * @brief Template specialization for receiver located inside 2D isotropic - * acoustic element with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { - -private: - constexpr static auto dimension = specfem::dimension::type::dim2; - constexpr static auto medium_tag = specfem::element::medium_tag::acoustic; - constexpr static auto property_tag = - specfem::element::property_tag::isotropic; - - using ElementQuadratureViewType = typename specfem::element::quadrature< - NGLL, dimension, specfem::kokkos::DevScratchSpace, - Kokkos::MemoryTraits, true, true>::ViewType; - - using ElementFieldType = - typename specfem::element::field, - true, true, true, false, using_simd>; - -public: - /** - * @name Typedefs - */ - ///@{ - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - - constexpr static int components = - specfem::element::attributes::components(); - ///@} - - /** - * @brief Number of Gauss-Lobatto-Legendre quadrature points - */ - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - - KOKKOS_FUNCTION - receiver() = default; - - // /** - // * @brief Construct a new elemental receiver object - // * - // * @param sin_rec sin of the receiver angle - // * @param cos_rec cosine of the receiver angle - // * @param receiver_array receiver array containing pre-computed lagrange - // * interpolants - // * @param partial_derivatives struct used to store partial derivatives at - // * quadrature points - // * @param properties struct used to store material properties at - // quadrature - // * points - // * @param receiver_field view to store compute receiver field at all GLL - // * points where the receiver is located - // */ - // KOKKOS_FUNCTION - // receiver(const specfem::kokkos::DeviceView1d sin_rec, - // const specfem::kokkos::DeviceView1d cos_rec, - // const specfem::kokkos::DeviceView4d receiver_array, - // const specfem::compute::partial_derivatives - // &partial_derivatives, const specfem::compute::properties - // &properties, specfem::kokkos::DeviceView6d - // receiver_field); - - /** - * @brief Compute and populate the receiver field at all GLL points where the - * receiver is located for a given time step - * - * @param ireceiver Index of the receiver - * @param iseis Index of the seismogram - * @param ispec Index of the element - * @param siesmogram_type Type of the seismogram - * @param xz Index of the quadrature point - * @param isig_step Seismogram step. Seismograms step = current time step / - * seismogram sampling rate - * @param field Global wavefield - * @param field_dot Global wavefield time derivative - * @param field_dot_dot Global wavefield second time derivative - * @param hprime_xx Derivates of Lagrange interpolants in the x direction - * @param hprime_zz Derivates of Lagrange interpolants in the z direction - */ - KOKKOS_FUNCTION - void get_field( - const int iz, const int ix, - const specfem::point::partial_derivatives - partial_derivatives, - const specfem::point::properties - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType active_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const; - - // /** - // * @brief Compute the seismogram components for a given receiver and - // * seismogram - // * - // * @param ireceiver Index of the receiver - // * @param iseis Index of the seismogram - // * @param seismogram_type Type of the seismogram - // * @param xz Index of the quadrature point - // * @param isig_step Seismogram step. Seismograms step = current time step - // / - // * seismogram sampling rate - // * @param l_seismogram_components Local seismogram components - // */ - // KOKKOS_FUNCTION - // void compute_seismogram_components( - // const int &ireceiver, const int &iseis, - // const specfem::enums::seismogram::type &seismogram_type, const int - // &xz, const int &isig_step, specfem::kokkos::array_type - // &l_seismogram_components) const; - - // /** - // * @brief Store the computed seismogram components in the global - // seismogram - // * view - // * - // * @param ireceiver Index of the receiver - // * @param seismogram_components Local seismogram components - // * @param receiver_seismogram Gloabl seismogram view - // */ - // KOKKOS_FUNCTION - // void compute_seismogram( - // const int &ireceiver, - // const specfem::kokkos::array_type - // &seismogram_components, specfem::kokkos::DeviceView1d - // receiver_seismogram) const; - -private: - specfem::kokkos::DeviceView1d sin_rec; ///< sin of the receiver - ///< angle - specfem::kokkos::DeviceView1d cos_rec; ///< cosine of the receiver - ///< angle - specfem::kokkos::DeviceView4d receiver_array; ///< receiver array - ///< containing - ///< pre-computed - ///< lagrange - ///< interpolants - specfem::kokkos::DeviceView3d xix; ///< xix - specfem::kokkos::DeviceView3d gammax; ///< gammax - specfem::kokkos::DeviceView3d xiz; ///< xiz - specfem::kokkos::DeviceView3d gammaz; ///< gammaz - specfem::kokkos::DeviceView3d rho_inverse; ///< rho inverse - specfem::kokkos::DeviceView6d - receiver_field; ///< view to store compute receiver field at all GLL - ///< points where the receiver is located -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif /* DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTRPOIC_HPP_ */ diff --git a/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.tpp b/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.tpp deleted file mode 100644 index 5238a59e0..000000000 --- a/include/domain/impl/receivers/acoustic/acoustic2d_isotropic.tpp +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTROPIC_TPP_ -#define DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTROPIC_TPP_ - -#include "constants.hpp" -// #include "domain/impl/receivers/acoustic/acoustic2d.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include - -// template -// KOKKOS_FUNCTION specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::acoustic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// receiver(const specfem::kokkos::DeviceView1d sin_rec, -// const specfem::kokkos::DeviceView1d cos_rec, -// const specfem::kokkos::DeviceView4d receiver_array, -// const specfem::compute::partial_derivatives -// &partial_derivatives, const specfem::compute::properties -// &properties, specfem::kokkos::DeviceView6d -// receiver_field) -// : sin_rec(sin_rec), cos_rec(cos_rec), receiver_array(receiver_array), -// receiver_field(receiver_field) { - -// #ifndef NDEBUG -// assert(partial_derivatives.xix.extent(1) == NGLL); -// assert(partial_derivatives.xix.extent(2) == NGLL); -// assert(partial_derivatives.gammax.extent(1) == NGLL); -// assert(partial_derivatives.gammax.extent(2) == NGLL); -// assert(partial_derivatives.xiz.extent(1) == NGLL); -// assert(partial_derivatives.xiz.extent(2) == NGLL); -// assert(partial_derivatives.gammaz.extent(1) == NGLL); -// assert(partial_derivatives.gammaz.extent(2) == NGLL); - -// // Properties -// assert(properties.rho_inverse.extent(1) == NGLL); -// assert(properties.rho_inverse.extent(2) == NGLL); -// #endif - -// this->xix = partial_derivatives.xix; -// this->gammax = partial_derivatives.gammax; -// this->xiz = partial_derivatives.xiz; -// this->gammaz = partial_derivatives.gammaz; -// this->rho_inverse = properties.rho_inverse; -// return; -// } - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::receivers::receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, using_simd>:: - get_field( - const int iz, const int ix, - const specfem::point::partial_derivatives - partial_derivatives, - const specfem::point::properties - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType element_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const { - - if(seismo_type == specfem::enums::seismogram::type::displacement - || seismo_type == specfem::enums::seismogram::type::velocity - || seismo_type == specfem::enums::seismogram::type::acceleration){ - - const auto active_field = [&]() -> - typename ElementFieldType::ViewType { - switch (seismo_type) { - case specfem::enums::seismogram::type::displacement: - return element_field.displacement; - break; - case specfem::enums::seismogram::type::velocity: - return element_field.velocity; - break; - case specfem::enums::seismogram::type::acceleration: - return element_field.acceleration; - break; - default: - DEVICE_ASSERT(false, "seismogram not supported"); - return {}; - break; - } - }(); - type_real dchi_dxi = 0.0; - type_real dchi_dgamma = 0.0; - -#ifndef KOKKOS_ENABLE_CUDA -#pragma unroll -#endif - for (int l = 0; l < NGLL; l++) { - dchi_dxi += hprime(ix, l) * active_field(iz, l, 0); - dchi_dgamma += hprime(iz, l) * active_field(l, ix, 0); - } - - // dchidx - type_real fieldx = (dchi_dxi * partial_derivatives.xix + - dchi_dgamma * partial_derivatives.gammax); - - // dchidz - type_real fieldz = (dchi_dxi * partial_derivatives.xiz + - dchi_dgamma * partial_derivatives.gammaz); - - // Receiver field is probably not the best way of storing this, since this - // would require global memory accesses. A better way for doing this would be - // create register array and the store the values there. However, post - // simulation people might require the field stored inside an element where a - // receiver is located. If the number of receivers << nspec - hopefully this - // shouldn't be a bottleneck. - if (specfem::globals::simulation_wave == specfem::wave::p_sv) { - receiver_field(0) = fieldx * properties.rho_inverse; - receiver_field(1) = fieldz * properties.rho_inverse; - } else if (specfem::globals::simulation_wave == specfem::wave::sh) { - receiver_field(0) = fieldx * properties.rho_inverse; - receiver_field(1) = 0; - } - }else if(seismo_type == specfem::enums::seismogram::type::pressure){ - receiver_field(0) = - element_field.acceleration(iz,ix,0); - receiver_field(1) = 0; - }else{ - DEVICE_ASSERT(false, "seismogram not supported"); - } - - return; -} - -// template -// KOKKOS_INLINE_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::acoustic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram_components( -// const int &ireceiver, const int &iseis, -// const specfem::enums::seismogram::type &seismogram_type, const int -// &xz, const int &isig_step, specfem::kokkos::array_type -// &l_seismogram_components) const { -// int ix, iz; -// sub2ind(xz, NGLL, iz, ix); - -// switch (seismogram_type) { -// case specfem::enums::seismogram::type::displacement: -// case specfem::enums::seismogram::type::velocity: -// case specfem::enums::seismogram::type::acceleration: -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += -// this->receiver_array(ireceiver, iz, ix, 1) * -// this->receiver_field(isig_step, ireceiver, iseis, 1, iz, ix); -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += 0; -// } -// break; - -// default: -// // seismogram not supported -// assert(false); -// break; -// } -// } - -// template -// KOKKOS_INLINE_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::acoustic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram( -// const int &ireceiver, -// const specfem::kokkos::array_type -// &seismogram_components, specfem::kokkos::DeviceView1d -// receiver_seismogram) const { - -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// receiver_seismogram(0) = -// this->cos_rec(ireceiver) * seismogram_components[0] + -// this->sin_rec(ireceiver) * seismogram_components[1]; -// receiver_seismogram(1) = -// this->sin_rec(ireceiver) * seismogram_components[0] + -// this->cos_rec(ireceiver) * seismogram_components[1]; -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// receiver_seismogram(0) = seismogram_components[0]; -// receiver_seismogram(1) = 0; -// } - -// return; -// } - -#endif /* DOMAIN_IMPL_RECEIVERS_ACOUSTIC2D_ISOTROPIC_TPP_ */ diff --git a/include/domain/impl/receivers/acoustic/interface.hpp b/include/domain/impl/receivers/acoustic/interface.hpp deleted file mode 100644 index 4b81c76fb..000000000 --- a/include/domain/impl/receivers/acoustic/interface.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _DOMAIN_RECEIVERS_ACOUSTIC_INTERFACE_HPP_ -#define _DOMAIN_RECEIVERS_ACOUSTIC_INTERFACE_HPP_ - -// #include "acoustic2d.hpp" -#include "acoustic2d_isotropic.hpp" -#include "acoustic2d_isotropic.tpp" - -#endif /* _DOMAIN_RECEIVERS_ACOUSTIC_INTERFACE_HPP_ */ diff --git a/include/domain/impl/receivers/container.hpp b/include/domain/impl/receivers/container.hpp deleted file mode 100644 index 0a34b068f..000000000 --- a/include/domain/impl/receivers/container.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _RECEIVER_CONTAINER_HPP -#define _RECEIVER_CONTAINER_HPP - -#include "enumerations/interface.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { - -template struct container { -public: - base_elemental_receiver *receiver; - - KOKKOS_FUNCTION - container() = default; - - KOKKOS_FUNCTION - container(base_elemental_receiver *receiver) { - this->receiver = receiver; - return; - } - - template - KOKKOS_INLINE_FUNCTION void get_field(Args... values) const { - this->receiver->get_field(values...); - return; - } - - KOKKOS_INLINE_FUNCTION specfem::enums::seismogram::type - get_seismogram_type() const { - return this->receiver->get_seismogram_type(); - } - - template - KOKKOS_INLINE_FUNCTION void compute_seismogram(Args... values) const { - this->receiver->compute_seismogram(values...); - return; - } - - template - KOKKOS_INLINE_FUNCTION void - compute_seismogram_components(Args &&...values) const { - this->receiver->compute_seismogram_components( - std::forward(values)...); - return; - } - - KOKKOS_INLINE_FUNCTION int get_ispec() const { - return this->receiver->get_ispec(); - } - - KOKKOS_FUNCTION - ~container() = default; -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/receivers/elastic/elastic2d.hpp b/include/domain/impl/receivers/elastic/elastic2d.hpp deleted file mode 100644 index c637c51e4..000000000 --- a/include/domain/impl/receivers/elastic/elastic2d.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_HPP_ -#define _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_HPP_ - -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { - -template -class receiver { -public: - using dimension = specfem::enums::element::dimension::dim2; - using medium_type = specfem::enums::element::medium::elastic; - using quadrature_points_type = qp_type; - - template - using ScratchViewType = - typename quadrature_points_type::template ScratchViewType; - - KOKKOS_INLINE_FUNCTION virtual void get_field( - const int xz, const int isig_step, - const ScratchViewType fieldx, - const ScratchViewType field_dot, - const ScratchViewType fieldx_dot_dot, - const ScratchViewType s_hprime_xx, - const ScratchViewType s_hprime_zz) const {}; - KOKKOS_INLINE_FUNCTION virtual void - compute_seismogram_components(const int xz, const int isig_step, - specfem::kokkos::array_type - &l_seismogram_components) const {}; - KOKKOS_INLINE_FUNCTION virtual void compute_seismogram( - const int isig_step, - const specfem::kokkos::array_type &seismogram_components){}; - KOKKOS_INLINE_FUNCTION virtual specfem::enums::seismogram::type - get_seismogram_type() const = 0; - KOKKOS_INLINE_FUNCTION virtual int get_ispec() const = 0; -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif /* _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_HPP_ */ diff --git a/include/domain/impl/receivers/elastic/elastic2d_anisotropic.hpp b/include/domain/impl/receivers/elastic/elastic2d_anisotropic.hpp deleted file mode 100644 index 659ae2079..000000000 --- a/include/domain/impl/receivers/elastic/elastic2d_anisotropic.hpp +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once - -#include "constants.hpp" -// #include "domain/impl/receivers/elastic/elastic2d.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "quadrature/interface.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { -/** - * @brief Elemental receiver specialization for 2D elastic isotropic spectral - * elements with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::anisotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { -private: - constexpr static auto dimension = specfem::dimension::type::dim2; - constexpr static auto property_tag = - specfem::element::property_tag::anisotropic; - constexpr static auto medium_tag = specfem::element::medium_tag::elastic; - - using ElementQuadratureViewType = typename specfem::element::quadrature< - NGLL, dimension, specfem::kokkos::DevScratchSpace, - Kokkos::MemoryTraits, true, false>::ViewType; - - using ElementFieldType = - typename specfem::element::field, - true, true, true, false, using_simd>; - -public: - /** - * @name Typedefs - */ - ///@{ - /** - * @brief Dimension of the element - * - */ - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - - constexpr static int components = - specfem::element::attributes::components(); - ///@} - - /** - * @brief Number of Gauss-Lobatto-Legendre quadrature points - */ - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - - KOKKOS_FUNCTION receiver() = default; - - // /** - // * @brief Construct a new elemental receiver object - // * - // * @param sin_rec sin of the receiver angle - // * @param cos_rec cosine of the receiver angle - // * @param receiver_array receiver array containing pre-computed lagrange - // * interpolants - // * @param partial_derivatives struct used to store partial derivatives at - // * quadrature points - // * @param properties struct used to store material properties at - // quadrature - // * points - // * @param receiver_field view to store compute receiver field at all GLL - // * points where the receiver is located - // */ - // KOKKOS_FUNCTION - // receiver(const specfem::kokkos::DeviceView1d sin_rec, - // const specfem::kokkos::DeviceView1d cos_rec, - // const specfem::kokkos::DeviceView4d receiver_array, - // const specfem::compute::partial_derivatives - // &partial_derivatives, const specfem::compute::properties - // &properties, specfem::kokkos::DeviceView6d - // receiver_field); - - /** - * @brief Compute and populate the receiver field at all GLL points where the - * receiver is located for a given time step - * - * @param ireceiver Index of the receiver - * @param iseis Index of the seismogram - * @param ispec Index of the element - * @param siesmogram_type Type of the seismogram - * @param xz Index of the quadrature point - * @param isig_step Seismogram step. Seismograms step = current time step / - * seismogram sampling rate - * @param field Global wavefield - * @param field_dot Global wavefield time derivative - * @param field_dot_dot Global wavefield second time derivative - * @param hprime_xx Derivates of Lagrange interpolants in the x direction - * @param hprime_zz Derivates of Lagrange interpolants in the z direction - */ - KOKKOS_FUNCTION - void get_field( - const int iz, const int ix, - const specfem::point::partial_derivatives - partial_derivatives, - const specfem::point::properties - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType active_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const; - - // /** - // * @brief Compute the seismogram components for a given receiver and - // * seismogram - // * - // * @param ireceiver Index of the receiver - // * @param iseis Index of the seismogram - // * @param seismogram_type Type of the seismogram - // * @param xz Index of the quadrature point - // * @param isig_step Seismogram step. Seismograms step = current time step - // / - // * seismogram sampling rate - // * @param l_seismogram_components Local seismogram components - // */ - // KOKKOS_FUNCTION void compute_seismogram_components( - // const int &ireceiver, const int &iseis, - // const specfem::enums::seismogram::type &seismogram_type, const int - // &xz, const int &isig_step, specfem::kokkos::array_type - // &l_seismogram_components) const; - - // /** - // * @brief Store the computed seismogram components in the global - // seismogram - // * view - // * - // * @param ireceiver Index of the receiver - // * @param seismogram_components Local seismogram components - // * @param receiver_seismogram Gloabl seismogram view - // */ - // KOKKOS_FUNCTION void compute_seismogram( - // const int &ireceiver, - // const specfem::kokkos::array_type - // &seismogram_components, specfem::kokkos::DeviceView1d - // receiver_seismogram) const; -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem diff --git a/include/domain/impl/receivers/elastic/elastic2d_anisotropic.tpp b/include/domain/impl/receivers/elastic/elastic2d_anisotropic.tpp deleted file mode 100644 index 88ed464af..000000000 --- a/include/domain/impl/receivers/elastic/elastic2d_anisotropic.tpp +++ /dev/null @@ -1,215 +0,0 @@ -#pragma once - -#include "compute/interface.hpp" -// #include "domain/impl/receivers/elastic/elastic2d.hpp" -#include "domain/impl/receivers/elastic/elastic2d_isotropic.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" -#include - -// template -// KOKKOS_FUNCTION specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// receiver(const specfem::kokkos::DeviceView1d sin_rec, -// const specfem::kokkos::DeviceView1d cos_rec, -// const specfem::kokkos::DeviceView4d receiver_array, -// const specfem::compute::partial_derivatives -// &partial_derivatives, const specfem::compute::properties -// &properties, specfem::kokkos::DeviceView6d -// receiver_field) -// : sin_rec(sin_rec), cos_rec(cos_rec), receiver_array(receiver_array), -// receiver_field(receiver_field) {} - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::receivers::receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::anisotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd>::get_field(const int iz, const int ix, - const specfem::point::partial_derivatives< - dimension, false, using_simd> - partial_derivatives, - const specfem::point::properties< - dimension, medium_tag, property_tag, using_simd> - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType element_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const { - - if (seismo_type == specfem::enums::seismogram::type::displacement || - seismo_type == specfem::enums::seismogram::type::velocity || - seismo_type == specfem::enums::seismogram::type::acceleration) { - - const auto active_field = [&]() -> typename ElementFieldType::ViewType { - switch (seismo_type) { - case specfem::enums::seismogram::type::displacement: - return element_field.displacement; - break; - case specfem::enums::seismogram::type::velocity: - return element_field.velocity; - break; - case specfem::enums::seismogram::type::acceleration: - return element_field.acceleration; - break; - default: - DEVICE_ASSERT(false, "seismogram not supported"); - return {}; - break; - } - }(); - // Receiver field is probably not the best way of storing this, since this - // would require global memory accesses. A better way for doing this would - // be create register array and the store the values there. However, post - // simulation people might require the field stored inside an element where - // a receiver is located. If the number of receivers << nspec - hopefully - // this shouldn't be a bottleneck. - if (specfem::globals::simulation_wave == specfem::wave::p_sv) { - receiver_field(0) = active_field(iz, ix, 0); - receiver_field(1) = active_field(iz, ix, 1); - } else if (specfem::globals::simulation_wave == specfem::wave::sh) { - receiver_field(0) = active_field(iz, ix, 0); - receiver_field(1) = 0; - } - } else if (seismo_type == specfem::enums::seismogram::type::pressure) { - - if (properties.c12 < 1.e-7 || properties.c23 < 1.e-7) { - Kokkos::abort( - "C_12 or C_23 are zero, cannot compute pressure. Check your material " - "properties. Or, deactivate the pressure computation."); - } - - type_real dsx_dxi = 0.0; - type_real dsx_dgamma = 0.0; - type_real dsz_dxi = 0.0; - type_real dsz_dgamma = 0.0; - -#ifndef KOKKOS_ENABLE_CUDA -#pragma unroll -#endif - for (int l = 0; l < NGLL; l++) { - dsx_dxi += hprime(ix, l) * element_field.displacement(iz, l, 0); - dsx_dgamma += hprime(iz, l) * element_field.displacement(l, ix, 0); - dsz_dxi += hprime(ix, l) * element_field.displacement(iz, l, 1); - dsz_dgamma += hprime(iz, l) * element_field.displacement(l, ix, 1); - } - type_real dsx_dx, dsx_dz, dsz_dx, dsz_dz; - dsx_dx = dsx_dxi * partial_derivatives.xix + - dsx_dgamma * partial_derivatives.gammax; - dsx_dz = dsx_dxi * partial_derivatives.xiz + - dsx_dgamma * partial_derivatives.gammaz; - dsz_dx = dsz_dxi * partial_derivatives.xix + - dsz_dgamma * partial_derivatives.gammax; - dsz_dz = dsz_dxi * partial_derivatives.xiz + - dsz_dgamma * partial_derivatives.gammaz; - - // https://specfem2d-kokkos.readthedocs.io/en/devel/api/datatypes/field_derivatives/point.html#_CPPv4N7specfem5point17field_derivatives2duE - // tells us that fhe first index is the derivative index -#define du(i, j) \ - (i == 0 ? (j == 0 ? dsx_dx : dsz_dx) : (j == 0 ? dsx_dz : dsz_dz)) - // the unneeded strain components should be omitted at compile time? - - // P_SV case - // sigma_xx - const auto sigma_xx = properties.c11 * du(0, 0) + - properties.c13 * du(1, 1) + - properties.c15 * (du(1, 0) + du(0, 1)); - - // sigma_zz - const auto sigma_zz = properties.c13 * du(0, 0) + - properties.c33 * du(1, 1) + - properties.c35 * (du(1, 0) + du(0, 1)); - - // sigma_yy - const auto sigma_yy = properties.c12 * du(0, 0) + - properties.c23 * du(1, 1) + - properties.c25 * (du(1, 0) + du(0, 1)); - - receiver_field(0) = - -1.0 * (sigma_xx + sigma_zz + sigma_yy) / 3.0; - -#undef du - } else { - DEVICE_ASSERT(false, "seismogram not supported"); - } - - return; -} - -// template -// KOKKOS_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram_components( -// const int &ireceiver, const int &iseis, -// const specfem::enums::seismogram::type &seismogram_type, const int -// &xz, const int &isig_step, specfem::kokkos::array_type -// &l_seismogram_components) const { -// int ix, iz; -// sub2ind(xz, NGLL, iz, ix); - -// switch (seismogram_type) { -// case specfem::enums::seismogram::type::displacement: -// case specfem::enums::seismogram::type::velocity: -// case specfem::enums::seismogram::type::acceleration: -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += -// this->receiver_array(ireceiver, iz, ix, 1) * -// this->receiver_field(isig_step, ireceiver, iseis, 1, iz, ix); -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += 0; -// } -// break; - -// default: -// // seismogram not supported -// assert(false && "seismogram not supported"); -// break; -// } -// } - -// template -// KOKKOS_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram( -// const int &ireceiver, -// const specfem::kokkos::array_type -// &seismogram_components, specfem::kokkos::DeviceView1d -// receiver_seismogram) const { - -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// receiver_seismogram(0) = -// this->cos_rec(ireceiver) * seismogram_components[0] + -// this->sin_rec(ireceiver) * seismogram_components[1]; -// receiver_seismogram(1) = -// this->sin_rec(ireceiver) * seismogram_components[0] + -// this->cos_rec(ireceiver) * seismogram_components[1]; -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// receiver_seismogram(0) = -// this->cos_rec(ireceiver) * seismogram_components[0] + -// this->sin_rec(ireceiver) * seismogram_components[1]; -// receiver_seismogram(1) = 0; -// } - -// return; -// } diff --git a/include/domain/impl/receivers/elastic/elastic2d_isotropic.hpp b/include/domain/impl/receivers/elastic/elastic2d_isotropic.hpp deleted file mode 100644 index d50085bcf..000000000 --- a/include/domain/impl/receivers/elastic/elastic2d_isotropic.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_HPP_ -#define _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_HPP_ - -#include "constants.hpp" -// #include "domain/impl/receivers/elastic/elastic2d.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "quadrature/interface.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { -/** - * @brief Elemental receiver specialization for 2D elastic isotropic spectral - * elements with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { -private: - constexpr static auto dimension = specfem::dimension::type::dim2; - constexpr static auto property_tag = - specfem::element::property_tag::isotropic; - constexpr static auto medium_tag = specfem::element::medium_tag::elastic; - - using ElementQuadratureViewType = typename specfem::element::quadrature< - NGLL, dimension, specfem::kokkos::DevScratchSpace, - Kokkos::MemoryTraits, true, false>::ViewType; - - using ElementFieldType = - typename specfem::element::field, - true, true, true, false, using_simd>; - -public: - /** - * @name Typedefs - */ - ///@{ - /** - * @brief Dimension of the element - * - */ - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - - constexpr static int components = - specfem::element::attributes::components(); - ///@} - - /** - * @brief Number of Gauss-Lobatto-Legendre quadrature points - */ - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - - KOKKOS_FUNCTION receiver() = default; - - // /** - // * @brief Construct a new elemental receiver object - // * - // * @param sin_rec sin of the receiver angle - // * @param cos_rec cosine of the receiver angle - // * @param receiver_array receiver array containing pre-computed lagrange - // * interpolants - // * @param partial_derivatives struct used to store partial derivatives at - // * quadrature points - // * @param properties struct used to store material properties at - // quadrature - // * points - // * @param receiver_field view to store compute receiver field at all GLL - // * points where the receiver is located - // */ - // KOKKOS_FUNCTION - // receiver(const specfem::kokkos::DeviceView1d sin_rec, - // const specfem::kokkos::DeviceView1d cos_rec, - // const specfem::kokkos::DeviceView4d receiver_array, - // const specfem::compute::partial_derivatives - // &partial_derivatives, const specfem::compute::properties - // &properties, specfem::kokkos::DeviceView6d - // receiver_field); - - /** - * @brief Compute and populate the receiver field at all GLL points where the - * receiver is located for a given time step - * - * @param ireceiver Index of the receiver - * @param iseis Index of the seismogram - * @param ispec Index of the element - * @param siesmogram_type Type of the seismogram - * @param xz Index of the quadrature point - * @param isig_step Seismogram step. Seismograms step = current time step / - * seismogram sampling rate - * @param field Global wavefield - * @param field_dot Global wavefield time derivative - * @param field_dot_dot Global wavefield second time derivative - * @param hprime_xx Derivates of Lagrange interpolants in the x direction - * @param hprime_zz Derivates of Lagrange interpolants in the z direction - */ - KOKKOS_FUNCTION - void get_field( - const int iz, const int ix, - const specfem::point::partial_derivatives - partial_derivatives, - const specfem::point::properties - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType active_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const; - - // /** - // * @brief Compute the seismogram components for a given receiver and - // * seismogram - // * - // * @param ireceiver Index of the receiver - // * @param iseis Index of the seismogram - // * @param seismogram_type Type of the seismogram - // * @param xz Index of the quadrature point - // * @param isig_step Seismogram step. Seismograms step = current time step - // / - // * seismogram sampling rate - // * @param l_seismogram_components Local seismogram components - // */ - // KOKKOS_FUNCTION void compute_seismogram_components( - // const int &ireceiver, const int &iseis, - // const specfem::enums::seismogram::type &seismogram_type, const int - // &xz, const int &isig_step, specfem::kokkos::array_type - // &l_seismogram_components) const; - - // /** - // * @brief Store the computed seismogram components in the global - // seismogram - // * view - // * - // * @param ireceiver Index of the receiver - // * @param seismogram_components Local seismogram components - // * @param receiver_seismogram Gloabl seismogram view - // */ - // KOKKOS_FUNCTION void compute_seismogram( - // const int &ireceiver, - // const specfem::kokkos::array_type - // &seismogram_components, specfem::kokkos::DeviceView1d - // receiver_seismogram) const; -}; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif /* _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_HPP_ */ diff --git a/include/domain/impl/receivers/elastic/elastic2d_isotropic.tpp b/include/domain/impl/receivers/elastic/elastic2d_isotropic.tpp deleted file mode 100644 index 8e0e231d7..000000000 --- a/include/domain/impl/receivers/elastic/elastic2d_isotropic.tpp +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_TPP_ -#define _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_TPP_ - -#include "compute/interface.hpp" -// #include "domain/impl/receivers/elastic/elastic2d.hpp" -#include "domain/impl/receivers/elastic/elastic2d_isotropic.hpp" -#include "domain/impl/receivers/receiver.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" -#include - -// template -// KOKKOS_FUNCTION specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// receiver(const specfem::kokkos::DeviceView1d sin_rec, -// const specfem::kokkos::DeviceView1d cos_rec, -// const specfem::kokkos::DeviceView4d receiver_array, -// const specfem::compute::partial_derivatives -// &partial_derivatives, const specfem::compute::properties -// &properties, specfem::kokkos::DeviceView6d -// receiver_field) -// : sin_rec(sin_rec), cos_rec(cos_rec), receiver_array(receiver_array), -// receiver_field(receiver_field) {} - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::receivers::receiver< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd>::get_field(const int iz, const int ix, - const specfem::point::partial_derivatives< - dimension, false, using_simd> - partial_derivatives, - const specfem::point::properties< - dimension, medium_tag, property_tag, using_simd> - properties, - const ElementQuadratureViewType hprime, - const ElementFieldType element_field, - const specfem::enums::seismogram::type seismo_type, - Kokkos::View - receiver_field) const { - - if(seismo_type == specfem::enums::seismogram::type::displacement - || seismo_type == specfem::enums::seismogram::type::velocity - || seismo_type == specfem::enums::seismogram::type::acceleration){ - - const auto active_field = [&]() -> - typename ElementFieldType::ViewType { - switch (seismo_type) { - case specfem::enums::seismogram::type::displacement: - return element_field.displacement; - break; - case specfem::enums::seismogram::type::velocity: - return element_field.velocity; - break; - case specfem::enums::seismogram::type::acceleration: - return element_field.acceleration; - break; - default: - DEVICE_ASSERT(false, "seismogram not supported"); - return {}; - break; - } - }(); - // Receiver field is probably not the best way of storing this, since this - // would require global memory accesses. A better way for doing this would be - // create register array and the store the values there. However, post - // simulation people might require the field stored inside an element where a - // receiver is located. If the number of receivers << nspec - hopefully this - // shouldn't be a bottleneck. - if (specfem::globals::simulation_wave == specfem::wave::p_sv) { - receiver_field(0) = active_field(iz, ix, 0); - receiver_field(1) = active_field(iz, ix, 1); - } else if (specfem::globals::simulation_wave == specfem::wave::sh) { - receiver_field(0) = active_field(iz, ix, 0); - receiver_field(1) = 0; - } - }else if(seismo_type == specfem::enums::seismogram::type::pressure){ - - type_real dsx_dxi = 0.0; - type_real dsx_dgamma = 0.0; - type_real dsz_dxi = 0.0; - type_real dsz_dgamma = 0.0; - -#ifndef KOKKOS_ENABLE_CUDA -#pragma unroll -#endif - for (int l = 0; l < NGLL; l++) { - dsx_dxi += hprime(ix, l) * element_field.displacement(iz, l, 0); - dsx_dgamma += hprime(iz, l) * element_field.displacement(l, ix, 0); - dsz_dxi += hprime(ix, l) * element_field.displacement(iz, l, 1); - dsz_dgamma += hprime(iz, l) * element_field.displacement(l, ix, 1); - } - type_real dsx_dx, dsx_dz, dsz_dx, dsz_dz; - dsx_dx = dsx_dxi * partial_derivatives.xix + - dsx_dgamma * partial_derivatives.gammax; - dsx_dz = dsx_dxi * partial_derivatives.xiz + - dsx_dgamma * partial_derivatives.gammaz; - dsz_dx = dsz_dxi * partial_derivatives.xix + - dsz_dgamma * partial_derivatives.gammax; - dsz_dz = dsz_dxi * partial_derivatives.xiz + - dsz_dgamma * partial_derivatives.gammaz; - - //https://specfem2d-kokkos.readthedocs.io/en/devel/api/datatypes/field_derivatives/point.html#_CPPv4N7specfem5point17field_derivatives2duE - // tells us that fhe first index is the derivative index -#define du(i,j) (i==0? (j==0? dsx_dx:dsz_dx):(j==0? dsx_dz:dsz_dz)) - // the unneeded strain components should be omitted at compile time? - - // https://github.com/SPECFEM/specfem2d/blob/98741db1a0c8082ca57364f5b17ea95df6cbf1c2/src/specfem2D/compute_pressure.f90#L398 - // pressure = - trace(sigma) / 3 = -kappa * trace(epsilon) - - //precomputing kappa may be helpful. - receiver_field(0) = - (properties.lambda + (2.0/3.0)*properties.mu)*(dsx_dx + dsz_dz); - receiver_field(1) = 0; - -#undef du - }else{ - DEVICE_ASSERT(false, "seismogram not supported"); - } - - return; -} - -// template -// KOKKOS_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram_components( -// const int &ireceiver, const int &iseis, -// const specfem::enums::seismogram::type &seismogram_type, const int -// &xz, const int &isig_step, specfem::kokkos::array_type -// &l_seismogram_components) const { -// int ix, iz; -// sub2ind(xz, NGLL, iz, ix); - -// switch (seismogram_type) { -// case specfem::enums::seismogram::type::displacement: -// case specfem::enums::seismogram::type::velocity: -// case specfem::enums::seismogram::type::acceleration: -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += -// this->receiver_array(ireceiver, iz, ix, 1) * -// this->receiver_field(isig_step, ireceiver, iseis, 1, iz, ix); -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// l_seismogram_components[0] += -// this->receiver_array(ireceiver, iz, ix, 0) * -// this->receiver_field(isig_step, ireceiver, iseis, 0, iz, ix); -// l_seismogram_components[1] += 0; -// } -// break; - -// default: -// // seismogram not supported -// assert(false && "seismogram not supported"); -// break; -// } -// } - -// template -// KOKKOS_FUNCTION void specfem::domain::impl::receivers::receiver< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// compute_seismogram( -// const int &ireceiver, -// const specfem::kokkos::array_type -// &seismogram_components, specfem::kokkos::DeviceView1d -// receiver_seismogram) const { - -// if (specfem::globals::simulation_wave == specfem::wave::p_sv) { -// receiver_seismogram(0) = -// this->cos_rec(ireceiver) * seismogram_components[0] + -// this->sin_rec(ireceiver) * seismogram_components[1]; -// receiver_seismogram(1) = -// this->sin_rec(ireceiver) * seismogram_components[0] + -// this->cos_rec(ireceiver) * seismogram_components[1]; -// } else if (specfem::globals::simulation_wave == specfem::wave::sh) { -// receiver_seismogram(0) = -// this->cos_rec(ireceiver) * seismogram_components[0] + -// this->sin_rec(ireceiver) * seismogram_components[1]; -// receiver_seismogram(1) = 0; -// } - -// return; -// } - -#endif /* _DOMAIN_IMPL_RECEIVERS_ELASTIC2D_ISOTROPIC_TPP_ */ diff --git a/include/domain/impl/receivers/elastic/interface.hpp b/include/domain/impl/receivers/elastic/interface.hpp deleted file mode 100644 index c30734e6c..000000000 --- a/include/domain/impl/receivers/elastic/interface.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _DOMAIN_RECEIVERS_ELASTIC_INTERFACE_HPP_ -#define _DOMAIN_RECEIVERS_ELASTIC_INTERFACE_HPP_ - -// #include "elastic2d.hpp" -#include "elastic2d_anisotropic.hpp" -#include "elastic2d_anisotropic.tpp" -#include "elastic2d_isotropic.hpp" -#include "elastic2d_isotropic.tpp" - -#endif /* _DOMAIN_RECEIVERS_ELASTIC_INTERFACE_HPP_ */ diff --git a/include/domain/impl/receivers/interface.hpp b/include/domain/impl/receivers/interface.hpp deleted file mode 100644 index 2ad0a68fa..000000000 --- a/include/domain/impl/receivers/interface.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _DOMAIN_RECEIVERS_INTERFACE_HPP -#define _DOMAIN_RECEIVERS_INTERFACE_HPP - -// #include "acoustic/acoustic2d.hpp" -#include "acoustic/acoustic2d_isotropic.hpp" -#include "acoustic/acoustic2d_isotropic.tpp" -#include "container.hpp" -// #include "elastic/elastic2d.hpp" -#include "elastic/elastic2d_isotropic.hpp" -#include "elastic/elastic2d_isotropic.tpp" -#include "kernel.hpp" -#include "kernel.tpp" -#include "receiver.hpp" - -#endif /* _DOMAIN_RECEIVERS_INTERFACE_HPP */ diff --git a/include/domain/impl/receivers/kernel.hpp b/include/domain/impl/receivers/kernel.hpp deleted file mode 100644 index 6cfaaf220..000000000 --- a/include/domain/impl/receivers/kernel.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _DOMAIN_IMPL_RECEIVERS_KERNEL_HPP -#define _DOMAIN_IMPL_RECEIVERS_KERNEL_HPP - -#include "domain/impl/receivers/acoustic/interface.hpp" -#include "domain/impl/receivers/elastic/interface.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace kernels { - -template -class receiver_kernel { - -public: - receiver_kernel() = default; - - receiver_kernel(const specfem::compute::assembly &assembly); - - void compute_seismograms(const int &isig_step) const; - -private: - using IndexViewType = Kokkos::View; - IndexViewType elements; - specfem::compute::assembly assembly; - Kokkos::View - receiver_kernel_index_mapping; -}; -} // namespace kernels -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif // _DOMAIN_IMPL_RECEIVERS_KERNEL_HPP diff --git a/include/domain/impl/receivers/receiver.hpp b/include/domain/impl/receivers/receiver.hpp deleted file mode 100644 index f28339726..000000000 --- a/include/domain/impl/receivers/receiver.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef DOMAIN_RECEIVER_ELEMENTS_HPP -#define DOMAIN_RECEIVER_ELEMENTS_HPP - -#include "enumerations/interface.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace receivers { -/** - * @brief Elemental receiver class - * - * Elemental receiver class to compute the seismogram at the receiver location. - * - * @tparam properties Properties of the receiver - */ -template -class receiver; - -} // namespace receivers -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/acoustic/acoustic2d.hpp b/include/domain/impl/sources/acoustic/acoustic2d.hpp deleted file mode 100644 index 10cfe4d15..000000000 --- a/include/domain/impl/sources/acoustic/acoustic2d.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ACOUSTIC2D_HPP -#define _DOMAIN_SOURCE_ACOUSTIC2D_HPP - -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "specfem_setup.hpp" -#include - -/** - * @brief Decltype for the field subviewed at particular global index - * - */ -using field_type = Kokkos::Subview< - specfem::kokkos::DeviceView2d, int, - std::remove_const_t >; - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source class for 2D acoustic media. - * - * Base class for all 2D acoustic elemental sources. This class contains pure - * virtual methods that must be implemented by the template specializations. - * - * @tparam quadrature_points Number of Gauss-Lobatto-Legendre quadrature points - * defined at compile time or at runtime - */ -template -class source { -public: - using dimension = specfem::enums::element::dimension::dim2; - using medium_type = specfem::enums::element::medium::acoustic; - using quadrature_points_type = quadrature_points; - /** - * @brief Compute the source time function value at a given time - * - * @param t Time - * @return type_real Source time function value - */ - KOKKOS_INLINE_FUNCTION virtual type_real - eval_stf(const type_real &t) const = 0; - - /** - * @brief Compute elemental source contribution to the global force vector - * - * @param xz Index of the quadrature point - * @param stf_value Source time function value - * @param accel Acceleration contribution to the global force vector by the - * source - */ - KOKKOS_INLINE_FUNCTION virtual void - compute_interaction(const int &xz, const type_real &stf_value, - type_real *accel) const = 0; - - /** - * @brief Update the acceleration field - * - * @param accel Acceleration contribution to the global force vector by the - * source - * @param field_dot_dot Acceleration field subviewed at global index - * ibool(ispec, iz, ix) - */ - KOKKOS_INLINE_FUNCTION virtual void - update_acceleration(const type_real *accel, - field_type field_dot_dot) const = 0; - - /** - * @brief Get the ispec index of the source - * - * @return int ispec index of the source - */ - KOKKOS_INLINE_FUNCTION virtual int get_ispec() const = 0; -}; - -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/acoustic/acoustic2d_isotropic.hpp b/include/domain/impl/sources/acoustic/acoustic2d_isotropic.hpp deleted file mode 100644 index b913da286..000000000 --- a/include/domain/impl/sources/acoustic/acoustic2d_isotropic.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ACOUSTIC_ISOTROPIC2D_HPP -#define _DOMAIN_SOURCE_ACOUSTIC_ISOTROPIC2D_HPP - -#include "compute/interface.hpp" -// #include "domain/impl/sources/acoustic/acoustic2d.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source specialization for 2D elastic isotropic spectral - * elements with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class source< - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { - -public: - /** - * @name Typedefs - */ - ///@{ - constexpr static int num_dimensions = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::acoustic>::dimension(); - constexpr static int components = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::acoustic>::components(); - constexpr static auto medium_tag = specfem::element::medium_tag::acoustic; - constexpr static auto property_tag = - specfem::element::property_tag::isotropic; - constexpr static auto dimension = specfem::dimension::type::dim2; - - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - ///@} - - /** - * @brief Default elemental source constructor - * - */ - KOKKOS_FUNCTION source() = default; - - /** - * @brief Default elemental source copy constructor - * - */ - KOKKOS_FUNCTION source(const source &) = default; - - // /** - // * @brief Construct a new elemental source object - // * - // * @param properties struct used to store material properties - // * @param source_array Source array containing pre-computed lagrange - // * interpolants - // */ - // KOKKOS_FUNCTION - // source(const specfem::compute::properties &properties, - // const specfem::kokkos::DeviceView4d source_array); - - /** - * @brief Compute the interaction of the source with the medium computed at - * the quadrature point xz - * - * @param isource Index of the source - * @param ispec Index of the element - * @param xz Quadrature point index in the element - * @param stf_value Value of the source time function at the current time step - * @param acceleration Acceleration contribution to the global force vector by - * the source - */ - KOKKOS_INLINE_FUNCTION void compute_interaction( - const specfem::datatype::ScalarPointViewType &source_array, - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &lagrange_interpolants, - specfem::datatype::ScalarPointViewType - &acceleration) const; -}; -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/acoustic/acoustic2d_isotropic.tpp b/include/domain/impl/sources/acoustic/acoustic2d_isotropic.tpp deleted file mode 100644 index 5d4697151..000000000 --- a/include/domain/impl/sources/acoustic/acoustic2d_isotropic.tpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ACOUSTIC_ISOTROPIC2D_TPP -#define _DOMAIN_SOURCE_ACOUSTIC_ISOTROPIC2D_TPP - -#include "compute/interface.hpp" -#include "domain/impl/sources/acoustic/acoustic2d_isotropic.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include "specfem_setup.hpp" -#include - -using field_type = Kokkos::Subview< - specfem::kokkos::DeviceView2d, int, - std::remove_const_t >; - -// ----------------------------------------------------------------------------- -// SPECIALIZED ELEMENT -// ----------------------------------------------------------------------------- - -// template -// KOKKOS_FUNCTION specfem::domain::impl::sources::source< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::acoustic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// source(const specfem::compute::properties &properties, -// const specfem::kokkos::DeviceView4d source_array) -// : source_array(source_array), kappa(properties.kappa) { - -// // #ifndef NDEBUG -// // assert(source_array.extent(1) == NGLL); -// // assert(source_array.extent(2) == NGLL); -// // assert(properties.kappa.extent(1) == NGLL); -// // assert(properties.kappa.extent(2) == NGLL); -// // #endif - -// return; -// } - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::sources::source< - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, using_simd>:: - compute_interaction( - const specfem::datatype::ScalarPointViewType &stf, - const specfem::datatype::ScalarPointViewType &lagrange_interpolant, - specfem::datatype::ScalarPointViewType &acceleration) const { - - acceleration(0) = lagrange_interpolant(0) * stf(0); - - return; -} - -#endif diff --git a/include/domain/impl/sources/acoustic/interface.hpp b/include/domain/impl/sources/acoustic/interface.hpp deleted file mode 100644 index 1bfad796c..000000000 --- a/include/domain/impl/sources/acoustic/interface.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _DOMAIN_IMPL_SOURCES_ACOUSTIC_INTERFACE_HPP -#define _DOMAIN_IMPL_SOURCES_ACOUSTIC_INTERFACE_HPP - -// #include "acoustic2d.hpp" -#include "acoustic2d_isotropic.hpp" -#include "acoustic2d_isotropic.tpp" - -#endif // _DOMAIN_IMPL_SOURCES_ACOUSTIC_INTERFACE_HPP diff --git a/include/domain/impl/sources/container.hpp b/include/domain/impl/sources/container.hpp deleted file mode 100644 index 1fd451e5b..000000000 --- a/include/domain/impl/sources/container.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _SOURCE_CONTAINER_HPP -#define _SOURCE_CONTAINER_HPP - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -template struct container { -public: - base_elemental_source *source; - - KOKKOS_FUNCTION - container() = default; - - KOKKOS_FUNCTION - container(base_elemental_source *source) { - this->source = source; - return; - } - - template - KOKKOS_INLINE_FUNCTION void compute_interaction(Args... values) const { - this->source->compute_interaction(values...); - return; - } - - template - KOKKOS_INLINE_FUNCTION void update_acceleration(Args... values) const { - this->source->update_acceleration(values...); - return; - } - - KOKKOS_INLINE_FUNCTION - type_real eval_stf(const type_real &t) const { - return this->source->eval_stf(t); - } - - KOKKOS_INLINE_FUNCTION - int get_ispec() const { return this->source->get_ispec(); } - - KOKKOS_FUNCTION - ~container() = default; -}; -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/elastic/elastic2d.hpp b/include/domain/impl/sources/elastic/elastic2d.hpp deleted file mode 100644 index a2ad5ca61..000000000 --- a/include/domain/impl/sources/elastic/elastic2d.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ELASTIC2D_HPP -#define _DOMAIN_SOURCE_ELASTIC2D_HPP - -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "specfem_setup.hpp" -#include - -/** - * @brief Decltype for the field subviewed at particular global index - * - */ -using field_type = Kokkos::Subview< - specfem::kokkos::DeviceView2d, int, - std::remove_const_t >; - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source class for 2D elastic media. - * - * Base class for all 2D elastic elemental sources. This class contains pure - * virtual methods that must be implemented by the template specializations. - * - * @tparam quadrature_points Number of Gauss-Lobatto-Legendre quadrature points - * defined at compile time or at runtime - */ -template -class source { -public: - using dimension = specfem::enums::element::dimension::dim2; - using medium_type = specfem::enums::element::medium::elastic; - using quadrature_points_type = quadrature_points; - /** - * @brief Compute the source time function value at a given time - * - * @param t Time - * @return type_real Source time function value - */ - KOKKOS_INLINE_FUNCTION virtual type_real - eval_stf(const type_real &t) const = 0; - - /** - * @brief Compute elemental source contribution to the global force vector - * - * @param xz Index of the quadrature point - * @param stf_value Source time function value - * @param accel Acceleration contribution to the global force vector by the - * source - */ - KOKKOS_INLINE_FUNCTION virtual void - compute_interaction(const int &xz, const type_real &stf_value, - type_real *accel) const = 0; - - /** - * @brief Update the acceleration field - * - * @param accel Acceleration contribution to the global force vector by the - * source - * @param field_dot_dot Acceleration field subviewed at global index - * ibool(ispec, iz, ix) - */ - KOKKOS_INLINE_FUNCTION virtual void - update_acceleration(const type_real *accel, - field_type field_dot_dot) const = 0; - - /** - * @brief Get the ispec index of the source - * - * @return int ispec index of the source - */ - KOKKOS_INLINE_FUNCTION virtual int get_ispec() const = 0; -}; - -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/elastic/elastic2d_anisotropic.hpp b/include/domain/impl/sources/elastic/elastic2d_anisotropic.hpp deleted file mode 100644 index 8e93896e5..000000000 --- a/include/domain/impl/sources/elastic/elastic2d_anisotropic.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "compute/interface.hpp" -// #include "domain/impl/sources/elastic/elastic2d.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source specialization for 2D elastic isotropic spectral - * elements with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class source< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::anisotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { - -public: - /** - * @name Typedefs - */ - ///@{ - constexpr static int num_dimensions = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::elastic>::dimension(); - constexpr static int components = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::elastic>::components(); - constexpr static auto medium_tag = specfem::element::medium_tag::elastic; - constexpr static auto property_tag = - specfem::element::property_tag::anisotropic; - constexpr static auto dimension = specfem::dimension::type::dim2; - - /** - * @brief Number of Gauss-Lobatto-Legendre quadrature points - */ - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - ///@} - - /** - * @brief Default elemental source constructor - * - */ - KOKKOS_FUNCTION source() = default; - - /** - * @brief Default elemental source copy constructor - * - */ - KOKKOS_FUNCTION source(const source &) = default; - - // /** - // * @brief Construct a new elemental source object - // * - // * @param source_array Source array containing pre-computed lagrange - // * interpolants - // */ - // KOKKOS_FUNCTION source(const specfem::compute::properties &properties, - // specfem::kokkos::DeviceView4d - // source_array); - - /** - * @brief Compute the interaction of the source with the medium computed at - * the quadrature point xz - * - * @param isource Index of the source - * @param ispec Index of the element - * @param xz Quadrature point index in the element - * @param stf_value Value of the source time function at the current time step - * @param acceleration Acceleration contribution to the global force vector by - * the source - */ - KOKKOS_INLINE_FUNCTION void compute_interaction( - const specfem::datatype::ScalarPointViewType &stf, - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &lagrange_interpolant, - specfem::datatype::ScalarPointViewType - &acceleration) const; -}; -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem diff --git a/include/domain/impl/sources/elastic/elastic2d_anisotropic.tpp b/include/domain/impl/sources/elastic/elastic2d_anisotropic.tpp deleted file mode 100644 index af11bf30e..000000000 --- a/include/domain/impl/sources/elastic/elastic2d_anisotropic.tpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "compute/interface.hpp" -#include "domain/impl/sources/elastic/elastic2d_anisotropic.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include "specfem_setup.hpp" -#include - -// ----------------------------------------------------------------------------- -// SPECIALIZED ELEMENT -// ----------------------------------------------------------------------------- - -// template -// KOKKOS_FUNCTION specfem::domain::impl::sources::source< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// source(const specfem::compute::properties &properties, -// specfem::kokkos::DeviceView4d source_array) { - -// // #ifndef NDEBUG -// // assert(source_array.extent(1) == NGLL); -// // assert(source_array.extent(2) == NGLL); -// // #endif - -// return; -// } - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::sources::source< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::anisotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd>:: - compute_interaction( - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &stf, - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> - &lagrange_interpolant, - specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &acceleration) - const { - - if constexpr (specfem::globals::simulation_wave == specfem::wave::p_sv) { - acceleration(0) = lagrange_interpolant(0) * stf(0); - acceleration(1) = lagrange_interpolant(1) * stf(1); - } else if constexpr (specfem::globals::simulation_wave == specfem::wave::sh) { - acceleration(0) = lagrange_interpolant(0) * stf(0); - acceleration(1) = 0; - } - - return; -} diff --git a/include/domain/impl/sources/elastic/elastic2d_isotropic.hpp b/include/domain/impl/sources/elastic/elastic2d_isotropic.hpp deleted file mode 100644 index 38d825b10..000000000 --- a/include/domain/impl/sources/elastic/elastic2d_isotropic.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ELASTIC_ISOTROPIC2D_HPP -#define _DOMAIN_SOURCE_ELASTIC_ISOTROPIC2D_HPP - -#include "compute/interface.hpp" -// #include "domain/impl/sources/elastic/elastic2d.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source specialization for 2D elastic isotropic spectral - * elements with static quadrature points - * - * @tparam NGLL Number of Gauss-Lobatto-Legendre quadrature points defined at - * compile time - */ -template -class source< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd> { - -public: - /** - * @name Typedefs - */ - ///@{ - constexpr static int num_dimensions = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::elastic>::dimension(); - constexpr static int components = specfem::element::attributes< - specfem::dimension::type::dim2, - specfem::element::medium_tag::elastic>::components(); - constexpr static auto medium_tag = specfem::element::medium_tag::elastic; - constexpr static auto property_tag = - specfem::element::property_tag::isotropic; - constexpr static auto dimension = specfem::dimension::type::dim2; - - /** - * @brief Number of Gauss-Lobatto-Legendre quadrature points - */ - using quadrature_points_type = - specfem::enums::element::quadrature::static_quadrature_points; - ///@} - - /** - * @brief Default elemental source constructor - * - */ - KOKKOS_FUNCTION source() = default; - - /** - * @brief Default elemental source copy constructor - * - */ - KOKKOS_FUNCTION source(const source &) = default; - - // /** - // * @brief Construct a new elemental source object - // * - // * @param source_array Source array containing pre-computed lagrange - // * interpolants - // */ - // KOKKOS_FUNCTION source(const specfem::compute::properties &properties, - // specfem::kokkos::DeviceView4d - // source_array); - - /** - * @brief Compute the interaction of the source with the medium computed at - * the quadrature point xz - * - * @param isource Index of the source - * @param ispec Index of the element - * @param xz Quadrature point index in the element - * @param stf_value Value of the source time function at the current time step - * @param acceleration Acceleration contribution to the global force vector by - * the source - */ - KOKKOS_INLINE_FUNCTION void compute_interaction( - const specfem::datatype::ScalarPointViewType &stf, - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &lagrange_interpolant, - specfem::datatype::ScalarPointViewType - &acceleration) const; -}; -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/domain/impl/sources/elastic/elastic2d_isotropic.tpp b/include/domain/impl/sources/elastic/elastic2d_isotropic.tpp deleted file mode 100644 index 9c4d3a624..000000000 --- a/include/domain/impl/sources/elastic/elastic2d_isotropic.tpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _DOMAIN_SOURCE_ELASTIC_ISOTROPIC2D_TPP -#define _DOMAIN_SOURCE_ELASTIC_ISOTROPIC2D_TPP - -#include "compute/interface.hpp" -#include "domain/impl/sources/elastic/elastic2d_isotropic.hpp" -#include "domain/impl/sources/source.hpp" -#include "enumerations/interface.hpp" -#include "globals.h" -#include "kokkos_abstractions.h" -#include "source_time_function/source_time_function.hpp" -#include "specfem_setup.hpp" -#include - -// ----------------------------------------------------------------------------- -// SPECIALIZED ELEMENT -// ----------------------------------------------------------------------------- - -// template -// KOKKOS_FUNCTION specfem::domain::impl::sources::source< -// specfem::enums::element::dimension::dim2, -// specfem::enums::element::medium::elastic, -// specfem::enums::element::quadrature::static_quadrature_points, -// specfem::enums::element::property::isotropic>:: -// source(const specfem::compute::properties &properties, -// specfem::kokkos::DeviceView4d source_array) { - -// // #ifndef NDEBUG -// // assert(source_array.extent(1) == NGLL); -// // assert(source_array.extent(2) == NGLL); -// // #endif - -// return; -// } - -template -KOKKOS_INLINE_FUNCTION void specfem::domain::impl::sources::source< - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::element::property_tag::isotropic, - specfem::enums::element::quadrature::static_quadrature_points, - using_simd>:: - compute_interaction( - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &stf, - const specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> - &lagrange_interpolant, - specfem::datatype::ScalarPointViewType< - type_real, components, using_simd> &acceleration) - const { - - if constexpr (specfem::globals::simulation_wave == specfem::wave::p_sv) { - acceleration(0) = lagrange_interpolant(0) * stf(0); - acceleration(1) = lagrange_interpolant(1) * stf(1); - } else if constexpr (specfem::globals::simulation_wave == specfem::wave::sh) { - acceleration(0) = lagrange_interpolant(0) * stf(0); - acceleration(1) = 0; - } - - return; -} - -#endif diff --git a/include/domain/impl/sources/elastic/interface.hpp b/include/domain/impl/sources/elastic/interface.hpp deleted file mode 100644 index 68a4210f3..000000000 --- a/include/domain/impl/sources/elastic/interface.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _DOMAIN_IMPL_SOURCES_ELASTIC_INTERFACE_HPP -#define _DOMAIN_IMPL_SOURCES_ELASTIC_INTERFACE_HPP - -// #include "elastic2d.hpp" -#include "elastic2d_anisotropic.hpp" -#include "elastic2d_anisotropic.tpp" -#include "elastic2d_isotropic.hpp" -#include "elastic2d_isotropic.tpp" - -#endif // _DOMAIN_IMPL_SOURCES_ELASTIC_INTERFACE_HPP diff --git a/include/domain/impl/sources/interface.hpp b/include/domain/impl/sources/interface.hpp deleted file mode 100644 index 543aac67c..000000000 --- a/include/domain/impl/sources/interface.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _DOMAIN_SOURCES_INTERFACE_HPP -#define _DOMAIN_SOURCES_INTERFACE_HPP - -// #include "acoustic/acoustic2d.hpp" -#include "acoustic/acoustic2d_isotropic.hpp" -#include "acoustic/acoustic2d_isotropic.tpp" -// #include "container.hpp" -// #include "elastic/elastic2d.hpp" -#include "elastic/elastic2d_isotropic.hpp" -#include "elastic/elastic2d_isotropic.tpp" -#include "kernel.hpp" -#include "kernel.tpp" -#include "source.hpp" - -#endif diff --git a/include/domain/impl/sources/kernel.hpp b/include/domain/impl/sources/kernel.hpp deleted file mode 100644 index a9d571fa5..000000000 --- a/include/domain/impl/sources/kernel.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "compute/interface.hpp" -#include "domain/impl/sources/acoustic/interface.hpp" -#include "domain/impl/sources/elastic/interface.hpp" -#include "enumerations/interface.hpp" -#include "kokkos_abstractions.h" -#include "specfem_setup.hpp" -#include - -namespace specfem { -namespace domain { -namespace impl { -namespace kernels { - -template -class source_kernel { -public: - constexpr static int num_dimensions = - specfem::element::attributes::dimension(); - constexpr static int components = - specfem::element::attributes::components(); - constexpr static auto medium_tag = MediumTag; - constexpr static auto property_tag = PropertyTag; - constexpr static auto dimension = DimensionType; - constexpr static auto wavefield_tag = WavefieldType; - - constexpr static bool using_simd = false; - - source_kernel() = default; - source_kernel(const specfem::compute::assembly &assembly); - - void compute_source_interaction(const int timestep); - -private: - using IndexViewType = Kokkos::View; - IndexViewType elements; - specfem::compute::sources sources; - specfem::compute::properties properties; - specfem::compute::simulation_field field; -}; -} // namespace kernels -} // namespace impl -} // namespace domain -} // namespace specfem diff --git a/include/domain/impl/sources/kernel.tpp b/include/domain/impl/sources/kernel.tpp deleted file mode 100644 index 509a3b44e..000000000 --- a/include/domain/impl/sources/kernel.tpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef _DOMAIN_IMPL_SOURCES_KERNEL_TPP -#define _DOMAIN_IMPL_SOURCES_KERNEL_TPP - -#include "compute/interface.hpp" -#include "domain/impl/sources/acoustic/interface.hpp" -#include "domain/impl/sources/elastic/interface.hpp" -#include "enumerations/interface.hpp" -#include "kernel.hpp" -#include "kokkos_abstractions.h" -#include "medium/compute_source.hpp" -#include "policies/chunk.hpp" -#include "specfem_setup.hpp" -#include - -template -specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, MediumTag, PropertyTag, - NGLL>::source_kernel(const specfem::compute::assembly &assembly) - : sources(assembly.sources), properties(assembly.properties), - field(assembly.fields.get_simulation_field()) { - - this->elements = sources.get_elements_on_device(medium_tag, wavefield_tag); - return; -} - -template -void specfem::domain::impl::kernels::source_kernel< - WavefieldType, DimensionType, MediumTag, PropertyTag, - NGLL>::compute_source_interaction(const int timestep) { - - sources.update_timestep(timestep); - - const int nelements = elements.size(); - - if (nelements == 0) - return; - - using PointSourcesType = - specfem::point::source; - - using PointPropertiesType = - specfem::point::properties; - - using simd = specfem::datatype::simd; - constexpr int simd_size = simd::size(); - -#ifdef KOKKOS_ENABLE_CUDA - constexpr int nthreads = 32; - constexpr int lane_size = 1; -#else - constexpr int nthreads = 1; - constexpr int lane_size = 1; -#endif - - using ParallelConfig = - specfem::parallel_config::chunk_config; - - using ChunkPolicy = specfem::policy::element_chunk; - - ChunkPolicy chunk_policy(elements, NGLL, NGLL); - - Kokkos::parallel_for( - "specfem::domain::impl::kernels::elements::compute_source_interaction", - static_cast(chunk_policy), - KOKKOS_CLASS_LAMBDA(const typename ChunkPolicy::member_type &team) { - for (int tile = 0; tile < ChunkPolicy::tile_size * simd_size; - tile += ChunkPolicy::chunk_size * simd_size) { - const int starting_element_index = - team.league_rank() * ChunkPolicy::tile_size * simd_size + tile; - - if (starting_element_index >= nelements) { - break; - } - - const auto iterator = - chunk_policy.league_iterator(starting_element_index); - - Kokkos::parallel_for( - Kokkos::TeamThreadRange(team, iterator.chunk_size()), - [&](const int i) { - const auto iterator_index = iterator(i); - const auto index = iterator_index.index; - - PointSourcesType point_source; - specfem::compute::load_on_device(index, sources, point_source); - - PointPropertiesType point_properties; - specfem::compute::load_on_device(index, properties, - point_properties); - - const auto acceleration = - specfem::medium::compute_source_contribution( - point_source, point_properties); - - specfem::compute::atomic_add_on_device(index, acceleration, - field); - }); - } - }); - - Kokkos::fence(); -} - -#endif // _DOMAIN_IMPL_SOURCES_KERNEL_TPP diff --git a/include/domain/impl/sources/source.hpp b/include/domain/impl/sources/source.hpp deleted file mode 100644 index eb6d2c6ec..000000000 --- a/include/domain/impl/sources/source.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DOMAIN_SOURCE_ELEMENTS_HPP -#define DOMAIN_SOURCE_ELEMENTS_HPP - -#include "enumerations/interface.hpp" - -namespace specfem { -namespace domain { -namespace impl { -namespace sources { -/** - * @brief Elemental source class - * - * Elemental source class to describe the source contribution to the global - * force vector. - * - * @tparam properties Properties of the source - */ -template -class source; - -} // namespace sources -} // namespace impl -} // namespace domain -} // namespace specfem - -#endif diff --git a/include/enumerations/interface.hpp b/include/enumerations/interface.hpp index f95b3ac14..32e63dca4 100644 --- a/include/enumerations/interface.hpp +++ b/include/enumerations/interface.hpp @@ -5,7 +5,6 @@ #include "dimension.hpp" #include "medium.hpp" // #include "properties.hpp" -#include "quadrature.hpp" #include "specfem_enums.hpp" #endif /* _ENUMERATIONS_INTERFACE_HPP_ */ diff --git a/include/enumerations/material_definitions.hpp b/include/enumerations/material_definitions.hpp index 558b46419..1b2bb86f6 100644 --- a/include/enumerations/material_definitions.hpp +++ b/include/enumerations/material_definitions.hpp @@ -6,7 +6,6 @@ namespace specfem { namespace element { -#define DIMENSION_TAG_DIM2 (0, specfem::dimension::type::dim2, dim2) /** * @name Element Tag macros * diff --git a/include/enumerations/quadrature.hpp b/include/enumerations/quadrature.hpp deleted file mode 100644 index 27a288233..000000000 --- a/include/enumerations/quadrature.hpp +++ /dev/null @@ -1,269 +0,0 @@ -#ifndef _ENUMERATIONS_QUADRATURE_HPP_ -#define _ENUMERATIONS_QUADRATURE_HPP_ - -#include "kokkos_abstractions.h" -#include "specfem_enums.hpp" -#include - -namespace specfem { -namespace enums { -namespace element { -/** - * @namespace number of quadrature points defined either at compile time or at - * runtime - * - */ -namespace quadrature { - -/** - * @brief define the number of quadrature points at runtime - * - */ -class dynamic_quadrature_points { -public: - int ngllx; ///< number of quadrature points in the x direction - int ngllz; ///< number of quadrature points in the z direction - - /** - * @brief Scratch memory space. Shared memory for GPUs and thread local memory - * for CPUs. - * - */ - using scratch_memory_space = - specfem::kokkos::DevExecSpace::scratch_memory_space; - - /** - * @brief Team member type. See Kokkos TeamHandle documentation for more - * details. - * - */ - using member_type = specfem::kokkos::DeviceTeam::member_type; - - /** - * @brief Scratch view type - * - * For dynamic quadrature points, the scratch view type is a 2D dynamic view - * stored on scratch space. - * - * @tparam T Type of the scratch view - * @tparam N Number of components - */ - template - using ScratchViewType = - Kokkos::View >; - - /** - * @brief Deleted default constructor - * - */ - dynamic_quadrature_points() = delete; - - /** - * @brief Construct a new dynamic quadrature points object - * - * @param ngllz Number of quadrature points in the z direction - * @param ngllx Number of quadrature points in the x direction - */ - dynamic_quadrature_points(const int &ngllz, const int &ngllx) - : ngllx(ngllx), ngllz(ngllz){}; - - /** - * @brief Destroy the dynamic quadrature points object - * - */ - ~dynamic_quadrature_points() = default; - - /** - * @brief Get the required size of the scratch memory space for a given type T - * and axes ax1 and ax2 - * - * @tparam T Tyoe of the scratch view - * @tparam ax1 Axis 1 - * @tparam ax2 Axis 2 - * @return std::size_t Size of the scratch memory space - */ - template - std::size_t shmem_size() const { - if constexpr (ax1 == specfem::enums::axes::x && - ax2 == specfem::enums::axes::x) { - return ScratchViewType::shmem_size(this->ngllx, this->ngllx); - } else if constexpr (ax1 == specfem::enums::axes::z && - ax2 == specfem::enums::axes::z) { - return ScratchViewType::shmem_size(this->ngllz, this->ngllz); - } else { - return ScratchViewType::shmem_size(this->ngllz, this->ngllx); - } - } - - /** - * @brief Get the scratch view for a given type T and axes ax1 and ax2 - * - * @tparam T Type of the scratch view - * @tparam ax1 Axis 1 - * @tparam ax2 Axis 2 - * @param ptr Address in the scratch memory space to allocate the scratch view - * @return ScratchViewType Scratch view allocated at the address ptr - */ - template - KOKKOS_INLINE_FUNCTION ScratchViewType - ScratchView(scratch_memory_space &ptr) const { - if constexpr (ax1 == specfem::enums::axes::x && - ax2 == specfem::enums::axes::x) { - return ScratchViewType(ptr, this->ngllx, this->ngllx); - } else if constexpr (ax1 == specfem::enums::axes::z && - ax2 == specfem::enums::axes::z) { - return ScratchViewType(ptr, this->ngllz, this->ngllz); - } else { - return ScratchViewType(ptr, this->ngllz, this->ngllx); - } - }; - - /** - * @brief Get the team thread range for a given axes ax1 and ax2 - * - * @tparam ax1 Axis 1 - * @tparam ax2 Axis 2 - * @param team_member Team member - * @return Kokkos::TeamThreadRange Team thread range - */ - template - KOKKOS_INLINE_FUNCTION auto - TeamThreadRange(const member_type &team_member) const { - if constexpr (ax1 == specfem::enums::axes::x && - ax2 == specfem::enums::axes::x) { - return Kokkos::TeamThreadRange(team_member, ngllx * ngllx); - } else if constexpr (ax1 == specfem::enums::axes::z && - ax2 == specfem::enums::axes::z) { - return Kokkos::TeamThreadRange(team_member, ngllz * ngllz); - } else { - return Kokkos::TeamThreadRange(team_member, ngllz * ngllx); - } - } - - /** - * @brief Get the number of quadrature points in the x and z directions - * - * @param ngllx Number of quadrature points in the x direction - * @param ngllz Number of quadrature points in the z direction - */ - KOKKOS_INLINE_FUNCTION void get_ngll(int *ngllx, int *ngllz) const { - *ngllx = this->ngllx; - *ngllz = this->ngllz; - } -}; - -/** - * @brief define the number of quadrature points at compile time - * - * @tparam NGLL Number of quadrature points - */ -template class static_quadrature_points { - -public: - constexpr static int NGLL = - NumberOfGLLPoints; ///< Number of quadrature points - /** - * @brief Scratch memory space type - * - */ - using scratch_memory_space = - specfem::kokkos::DevExecSpace::scratch_memory_space; - - /** - * @brief Team member type. See kokkos TeamHandle documentation for more - * details. - * - */ - using member_type = specfem::kokkos::DeviceTeam::member_type; - - /** - * @brief Scratch view type for a given type T. - * - * For static quadrature points, the scratch view is a 2D view of size NGLL x - * NGLL defined at compile time. - * - * @tparam T Type of the scratch view - * @tparam N Number of components - */ - template - using ScratchViewType = - specfem::kokkos::StaticDeviceScratchView3d; - - /** - * @brief Construct a new static quadrature points object - * - */ - constexpr static_quadrature_points() = default; - /** - * @brief Destroy the static quadrature points object - * - */ - ~static_quadrature_points() = default; - - /** - * @brief Get the required size of the scratch memory space for a given type T - * and axes ax1 and ax2 - * - * @tparam T Type of the scratch view - * @tparam ax_1 Axis 1 - * @tparam ax_2 Axis 2 - * @return std::size_t Size of the scratch memory space - */ - template - std::size_t shmem_size() const { - return ScratchViewType::shmem_size(); - } - - /** - * @brief Get the scratch view for a given type T and axes ax1 and ax2 - * - * @tparam T Type of the scratch view - * @tparam ax_1 Axis 1 - * @tparam ax_2 Axis 2 - * @param ptr Address in the scratch memory space to allocate the scratch view - * @return ScratchViewType Scratch view allocated at the address ptr - */ - template - KOKKOS_INLINE_FUNCTION ScratchViewType - ScratchView(const scratch_memory_space &ptr) const { - return ScratchViewType(ptr); - } - - /** - * @brief Get the team thread range for a given axes ax1 and ax2 - * - * @tparam ax_1 Axis 1 - * @tparam ax_2 Axis 2 - * @param team_member Team member - * @return Kokkos::TeamThreadRange Team thread range - */ - template - KOKKOS_INLINE_FUNCTION auto - TeamThreadRange(const member_type &team_member) const { - return Kokkos::TeamThreadRange(team_member, NGLL * NGLL); - } - - /** - * @brief Get the number of quadrature points in the x and z directions - * - * @param ngllx Number of quadrature points in the x direction - * @param ngllz Number of quadrature points in the z direction - */ - KOKKOS_INLINE_FUNCTION constexpr void get_ngll(int *ngllx, int *ngllz) const { - *ngllx = NGLL; - *ngllz = NGLL; - } -}; - -} // namespace quadrature -} // namespace element -} // namespace enums -} // namespace specfem - -#endif /* _ENUMERATIONS_QUADRATURE_HPP_ */ diff --git a/include/kernels/impl/domain_kernels.hpp b/include/kernels/impl/domain_kernels.hpp deleted file mode 100644 index 5a4cdb51f..000000000 --- a/include/kernels/impl/domain_kernels.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _SPECFEM_KERNELS_IMPL_DOMAIN_KERNELS_HPP -#define _SPECFEM_KERNELS_IMPL_DOMAIN_KERNELS_HPP - -#include "enumerations/dimension.hpp" -#include "enumerations/medium.hpp" -#include "enumerations/simulation.hpp" -#include "enumerations/specfem_enums.hpp" -#include "kernels.hpp" - -namespace specfem { -namespace kernels { -namespace impl { -template -class domain_kernels { -public: - domain_kernels(const type_real dt, const specfem::compute::assembly &assembly, - const qp_type &quadrature_points) - : elastic_kernels(dt, assembly, quadrature_points), - acoustic_kernels(dt, assembly, quadrature_points) {} - - void prepare_wavefields(); - - template - inline void update_wavefields(const int istep) { - if constexpr (medium == specfem::element::medium_tag::elastic) { - elastic_kernels.update_wavefields(istep); - } else if constexpr (medium == specfem::element::medium_tag::acoustic) { - acoustic_kernels.update_wavefields(istep); - } - } - - void initialize(const type_real &dt) { - - elastic_kernels.invert_mass_matrix(); - acoustic_kernels.invert_mass_matrix(); - return; - } - - inline void compute_seismograms(const int &isig_step) { - elastic_kernels.compute_seismograms(isig_step); - acoustic_kernels.compute_seismograms(isig_step); - } - -private: - specfem::kernels::impl::kernels - elastic_kernels; - specfem::kernels::impl::kernels - acoustic_kernels; -}; - -// template -// class domain_kernels { -// public: -// using elastic_type = specfem::enums::element::medium::elastic; -// using acoustic_type = specfem::enums::element::medium::acoustic; -// constexpr static auto forward_type = -// specfem::enums::simulation::type::forward; -// constexpr static auto adjoint_type = -// specfem::enums::simulation::type::adjoint; -// domain_kernels(const specfem::compute::assembly &assembly, -// const qp_type &quadrature_points); - -// void prepare_wavefields(); - -// template -// void update_wavefields(const int istep); - -// private: -// specfem::kernels::impl::domain_kernels_impl -// forward_kernels; -// specfem::kernels::impl::domain_kernels_impl -// adjoint_kernels; -// }; -} // namespace impl -} // namespace kernels -} // namespace specfem - -#endif /* _SPECFEM_KERNELS_IMPL_DOMAIN_KERNELS_HPP */ diff --git a/include/kernels/impl/kernels.hpp b/include/kernels/impl/kernels.hpp deleted file mode 100644 index a2ade16c4..000000000 --- a/include/kernels/impl/kernels.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _SPECFEM_KERNELS_IMPL_KERNELS_HPP -#define _SPECFEM_KERNELS_IMPL_KERNELS_HPP - -#include "compute/interface.hpp" -#include "domain/domain.hpp" -#include "enumerations/dimension.hpp" -#include "enumerations/medium.hpp" -#include "enumerations/simulation.hpp" -#include "enumerations/specfem_enums.hpp" -#include "interface_kernels.hpp" - -namespace specfem { -namespace kernels { -namespace impl { -template -class kernels - : public interface_kernels { - -public: - kernels(const type_real dt, const specfem::compute::assembly &assembly, - const qp_type &quadrature_points) - : domain(dt, assembly, quadrature_points), - interface_kernels(assembly) {} - - inline void update_wavefields(const int istep) { - interface_kernels::compute_coupling(); - domain.compute_source_interaction(istep); - domain.compute_stiffness_interaction(istep); - domain.divide_mass_matrix(); - } - - inline void invert_mass_matrix() { domain.invert_mass_matrix(); } - - inline void compute_seismograms(const int &isig_step) { - domain.compute_seismograms(isig_step); - } - -private: - specfem::domain::domain - domain; -}; -} // namespace impl -} // namespace kernels -} // namespace specfem - -#endif /* _SPECFEM_KERNELS_IMPL_KERNELS_HPP */ diff --git a/include/kernels/kernels.hpp b/include/kernels/kernels.hpp deleted file mode 100644 index b2cbaf35e..000000000 --- a/include/kernels/kernels.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _SPECFEM_KERNELS_HPP -#define _SPECFEM_KERNELS_HPP - -#include "compute/interface.hpp" -#include "enumerations/dimension.hpp" -#include "enumerations/simulation.hpp" -#include "impl/domain_kernels.hpp" - -namespace specfem { -namespace kernels { -template -class kernels - : public impl::domain_kernels { -public: - kernels(const type_real dt, const specfem::compute::assembly &assembly, - const qp_type &quadrature_points) - : impl::domain_kernels( - dt, assembly, quadrature_points) {} -}; - -} // namespace kernels -} // namespace specfem - -#endif /* _SPECFEM_KERNELS_HPP */ diff --git a/include/kokkos_kernels/domain_kernels.hpp b/include/kokkos_kernels/domain_kernels.hpp new file mode 100644 index 000000000..be3b1d57b --- /dev/null +++ b/include/kokkos_kernels/domain_kernels.hpp @@ -0,0 +1,169 @@ +#ifndef _SPECFEM_KERNELS_HPP +#define _SPECFEM_KERNELS_HPP + +#include "enumerations/dimension.hpp" +#include "enumerations/material_definitions.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/simulation.hpp" +#include "enumerations/specfem_enums.hpp" +#include "impl/compute_mass_matrix.hpp" +#include "impl/compute_seismogram.hpp" +#include "impl/compute_source_interaction.hpp" +#include "impl/compute_stiffness_interaction.hpp" +#include "impl/divide_mass_matrix.hpp" +#include "impl/interface_kernels.hpp" +#include "impl/invert_mass_matrix.hpp" + +namespace specfem { +namespace kokkos_kernels { +template +class domain_kernels { +public: + constexpr static auto dimension = DimensionType; + constexpr static auto wavefield = WavefieldType; + constexpr static auto ngll = NGLL; + + domain_kernels(const specfem::compute::assembly &assembly) + : assembly(assembly), coupling_interfaces_elastic(assembly), + coupling_interfaces_acoustic(assembly) {} + + template + inline void update_wavefields(const int istep) { + +#define CALL_COUPLING_INTERFACES_FUNCTION(DIMENSION_TAG, MEDIUM_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG) && \ + medium == GET_TAG(MEDIUM_TAG)) { \ + CREATE_VARIABLE_NAME(coupling_interfaces, GET_NAME(MEDIUM_TAG)) \ + .compute_coupling(); \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS(CALL_COUPLING_INTERFACES_FUNCTION, + WHERE(DIMENSION_TAG_DIM2) WHERE( + MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef CALL_COUPLING_INTERFACES_FUNCTION + +#define CALL_SOURCE_FORCE_UPDATE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG) && \ + medium == GET_TAG(MEDIUM_TAG)) { \ + impl::compute_source_interaction< \ + dimension, wavefield, ngll, GET_TAG(MEDIUM_TAG), \ + GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>(assembly, istep); \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + CALL_SOURCE_FORCE_UPDATE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef CALL_SOURCE_FORCE_UPDATE + +#define CALL_STIFFNESS_FORCE_UPDATE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG) && \ + medium == GET_TAG(MEDIUM_TAG)) { \ + impl::compute_stiffness_interaction< \ + dimension, wavefield, ngll, GET_TAG(MEDIUM_TAG), \ + GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>(assembly, istep); \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + CALL_STIFFNESS_FORCE_UPDATE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef CALL_STIFFNESS_FORCE_UPDATE + +#define CALL_DIVIDE_MASS_MATRIX_FUNCTION(DIMENSION_TAG, MEDIUM_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG) && \ + medium == GET_TAG(MEDIUM_TAG)) { \ + impl::divide_mass_matrix( \ + assembly); \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS(CALL_DIVIDE_MASS_MATRIX_FUNCTION, + WHERE(DIMENSION_TAG_DIM2) WHERE( + MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef CALL_DIVIDE_MASS_MATRIX_FUNCTION + } + + void initialize(const type_real &dt) { + +#define CALL_COMPUTE_MASS_MATRIX_FUNCTION(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG, BOUNDARY_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG)) { \ + impl::compute_mass_matrix( \ + dt, assembly); \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + CALL_COMPUTE_MASS_MATRIX_FUNCTION, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef CALL_COMPUTE_MASS_MATRIX_FUNCTION + +#define CALL_INITIALIZE_FUNCTION(DIMENSION_TAG, MEDIUM_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG)) { \ + impl::invert_mass_matrix( \ + assembly); \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS(CALL_INITIALIZE_FUNCTION, + WHERE(DIMENSION_TAG_DIM2) WHERE( + MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef CALL_INITIALIZE_FUNCTION + + return; + } + + inline void compute_seismograms(const int &isig_step) { + +#define CALL_COMPUTE_SEISMOGRAMS_FUNCTION(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + if constexpr (dimension == GET_TAG(DIMENSION_TAG)) { \ + impl::compute_seismograms(assembly, isig_step); \ + } + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + CALL_COMPUTE_SEISMOGRAMS_FUNCTION, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef CALL_COMPUTE_SEISMOGRAMS_FUNCTION + } + +private: + specfem::compute::assembly assembly; +#define COUPLING_INTERFACES_DECLARATION(DIMENSION_TAG, MEDIUM_TAG) \ + impl::interface_kernels \ + CREATE_VARIABLE_NAME(coupling_interfaces, GET_NAME(MEDIUM_TAG)); + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS(COUPLING_INTERFACES_DECLARATION, + WHERE(DIMENSION_TAG_DIM2) + WHERE(MEDIUM_TAG_ELASTIC, + MEDIUM_TAG_ACOUSTIC)) + +#undef COUPLING_INTERFACES_DECLARATION +}; + +} // namespace kokkos_kernels +} // namespace specfem + +#endif /* _SPECFEM_KERNELS_HPP */ diff --git a/include/kernels/frechet_kernels.hpp b/include/kokkos_kernels/frechet_kernels.hpp similarity index 73% rename from include/kernels/frechet_kernels.hpp rename to include/kokkos_kernels/frechet_kernels.hpp index 2356f1f03..bf92861c5 100644 --- a/include/kernels/frechet_kernels.hpp +++ b/include/kokkos_kernels/frechet_kernels.hpp @@ -5,26 +5,10 @@ #include "enumerations/dimension.hpp" #include "enumerations/material_definitions.hpp" #include "enumerations/medium.hpp" +#include "impl/compute_material_derivatives.hpp" namespace specfem { -namespace kernels { - -namespace impl { -/** - * @brief Compute the frechet derivatives for a particular material system. - * This function is not defined as a private method of frechet_kernels due to - * CUDA compatibility. - * - * @tparam MediumTag Medium tag. - * @tparam PropertyTag Property tag. - * @param dt Time interval. - */ -template -void compute_material_derivatives(const specfem::compute::assembly &assembly, - const type_real &dt); -} // namespace impl +namespace kokkos_kernels { /** * @brief Compute kernels used to compute Frechet derivatives. @@ -71,7 +55,7 @@ class frechet_kernels { private: specfem::compute::assembly assembly; ///< Assembly object. }; -} // namespace kernels +} // namespace kokkos_kernels } // namespace specfem #endif /* _SPECFEM_KERNELS_FRECHET_KERNELS_HPP */ diff --git a/include/kokkos_kernels/impl/compute_mass_matrix.hpp b/include/kokkos_kernels/impl/compute_mass_matrix.hpp new file mode 100644 index 000000000..553d7eae9 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_mass_matrix.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" + +namespace specfem { +namespace kokkos_kernels { +namespace impl { + +template +void compute_mass_matrix(const type_real &dt, + const specfem::compute::assembly &assembly); +} // namespace impl +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kokkos_kernels/impl/compute_mass_matrix.tpp b/include/kokkos_kernels/impl/compute_mass_matrix.tpp new file mode 100644 index 000000000..7d36184e6 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_mass_matrix.tpp @@ -0,0 +1,140 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "datatypes/simd.hpp" +#include "boundary_conditions/boundary_conditions.hpp" +#include "element/quadrature.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" +#include "parallel_configuration/chunk_config.hpp" +#include "point/boundary.hpp" +#include "point/field.hpp" +#include "point/partial_derivatives.hpp" +#include "point/properties.hpp" +#include "policies/chunk.hpp" +#include "medium/compute_mass_matrix.hpp" +#include + +template +void specfem::kokkos_kernels::impl::compute_mass_matrix( + const type_real &dt, const specfem::compute::assembly &assembly) { + + constexpr auto dimension = DimensionType; + constexpr auto wavefield = WavefieldType; + constexpr auto medium_tag = MediumTag; + constexpr auto property_tag = PropertyTag; + constexpr auto boundary_tag = BoundaryTag; + + const auto elements = assembly.element_types.get_elements_on_device( + MediumTag, PropertyTag, BoundaryTag); + + constexpr int components = + specfem::element::attributes::components(); + + const int nelements = elements.extent(0); + + if (nelements == 0) + return; + + constexpr bool using_simd = true; + using simd = specfem::datatype::simd; + using parallel_config = specfem::parallel_config::default_chunk_config< + dimension, simd, Kokkos::DefaultExecutionSpace>; + + using ChunkPolicyType = specfem::policy::element_chunk; + + using PointMassType = specfem::point::field; + + using PointPropertyType = + specfem::point::properties; + + using PointPartialDerivativesType = + specfem::point::partial_derivatives; + + using PointBoundaryType = + specfem::point::boundary; + + const auto &quadrature = assembly.mesh.quadratures; + const auto &partial_derivatives = assembly.partial_derivatives; + const auto &properties = assembly.properties; + const auto &boundaries = assembly.boundaries; + const auto field = assembly.fields.get_simulation_field(); + + const auto wgll = quadrature.gll.weights; + + constexpr int simd_size = simd::size(); + + ChunkPolicyType chunk_policy(elements, NGLL, NGLL); + + Kokkos::parallel_for( + "specfem::domain::impl::kernels::elements::compute_mass_matrix", + static_cast(chunk_policy), + KOKKOS_LAMBDA(const typename ChunkPolicyType::member_type &team) { + for (int tile = 0; tile < ChunkPolicyType::tile_size * simd_size; + tile += ChunkPolicyType::chunk_size * simd_size) { + const int starting_element_index = + team.league_rank() * ChunkPolicyType::tile_size * simd_size + + tile; + + if (starting_element_index >= nelements) { + break; + } + + const auto iterator = + chunk_policy.league_iterator(starting_element_index); + + Kokkos::parallel_for( + Kokkos::TeamThreadRange(team, iterator.chunk_size()), + [&](const int i) { + const auto iterator_index = iterator(i); + const auto index = iterator_index.index; + const int ix = iterator_index.index.ix; + const int iz = iterator_index.index.iz; + + const auto point_property = [&]() -> PointPropertyType { + PointPropertyType point_property; + + specfem::compute::load_on_device(index, properties, + point_property); + return point_property; + }(); + + const auto point_partial_derivatives = + [&]() -> PointPartialDerivativesType { + PointPartialDerivativesType point_partial_derivatives; + specfem::compute::load_on_device(index, partial_derivatives, + point_partial_derivatives); + return point_partial_derivatives; + }(); + + PointMassType mass_matrix = + specfem::medium::mass_matrix_component( + point_property, point_partial_derivatives); + + for (int icomp = 0; icomp < components; icomp++) { + mass_matrix.mass_matrix(icomp) *= wgll(ix) * wgll(iz); + } + + PointBoundaryType point_boundary; + specfem::compute::load_on_device(index, boundaries, + point_boundary); + + specfem::boundary_conditions:: + compute_mass_matrix_terms(dt, point_boundary, + point_property, mass_matrix); + + specfem::compute::atomic_add_on_device(index, mass_matrix, + field); + }); + } + }); + + Kokkos::fence(); +} diff --git a/include/kokkos_kernels/impl/compute_material_derivatives.hpp b/include/kokkos_kernels/impl/compute_material_derivatives.hpp new file mode 100644 index 000000000..97bee1e38 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_material_derivatives.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" + +namespace specfem { +namespace kokkos_kernels { + +namespace impl { +/** + * @brief Compute the frechet derivatives for a particular material system. + * This function is not defined as a private method of frechet_kernels due to + * CUDA compatibility. + * + * @tparam MediumTag Medium tag. + * @tparam PropertyTag Property tag. + * @param dt Time interval. + */ +template +void compute_material_derivatives(const specfem::compute::assembly &assembly, + const type_real &dt); +} // namespace impl + +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kernels/frechet_kernels.tpp b/include/kokkos_kernels/impl/compute_material_derivatives.tpp similarity index 96% rename from include/kernels/frechet_kernels.tpp rename to include/kokkos_kernels/impl/compute_material_derivatives.tpp index 327396f27..797faf73c 100644 --- a/include/kernels/frechet_kernels.tpp +++ b/include/kokkos_kernels/impl/compute_material_derivatives.tpp @@ -1,19 +1,20 @@ #pragma once +#include "algorithms/gradient.hpp" #include "chunk_element/field.hpp" #include "compute/assembly/assembly.hpp" +#include "compute_material_derivatives.hpp" +#include "medium/compute_frechet_derivatives.hpp" #include "parallel_configuration/chunk_config.hpp" #include "point/field.hpp" #include "point/field_derivatives.hpp" #include "policies/chunk.hpp" -#include "algorithms/gradient.hpp" -#include "medium/compute_frechet_derivatives.hpp" #include template -void specfem::kernels::impl::compute_material_derivatives( +void specfem::kokkos_kernels::impl::compute_material_derivatives( const specfem::compute::assembly &assembly, const type_real &dt) { auto &properties = assembly.properties; auto &kernels = assembly.kernels; @@ -23,7 +24,7 @@ void specfem::kernels::impl::compute_material_derivatives( auto &partial_derivatives = assembly.partial_derivatives; const auto element_index = - properties.get_elements_on_device(MediumTag, PropertyTag); + assembly.element_types.get_elements_on_device(MediumTag, PropertyTag); const int nelements = element_index.size(); @@ -63,7 +64,7 @@ void specfem::kernels::impl::compute_material_derivatives( using ChunkPolicy = specfem::policy::element_chunk; int scratch_size = 2 * ChunkElementFieldType::shmem_size() + - ElementQuadratureType::shmem_size(); + ElementQuadratureType::shmem_size(); ChunkPolicy chunk_policy(element_index, NGLL, NGLL); diff --git a/include/kokkos_kernels/impl/compute_seismogram.hpp b/include/kokkos_kernels/impl/compute_seismogram.hpp new file mode 100644 index 000000000..5a10234fc --- /dev/null +++ b/include/kokkos_kernels/impl/compute_seismogram.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" + +namespace specfem { +namespace kokkos_kernels { +namespace impl { + +template +void compute_seismograms(specfem::compute::assembly &assembly, + const int &isig_step); + +} // namespace impl +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/domain/impl/receivers/kernel.tpp b/include/kokkos_kernels/impl/compute_seismogram.tpp similarity index 76% rename from include/domain/impl/receivers/kernel.tpp rename to include/kokkos_kernels/impl/compute_seismogram.tpp index 20184becb..d0b2405c1 100644 --- a/include/domain/impl/receivers/kernel.tpp +++ b/include/kokkos_kernels/impl/compute_seismogram.tpp @@ -1,50 +1,46 @@ -#ifndef _DOMAIN_IMPL_RECEIVERS_KERNEL_TPP -#define _DOMAIN_IMPL_RECEIVERS_KERNEL_TPP +#pragma once #include "algorithms/interpolate.hpp" -#include "domain/impl/receivers/acoustic/interface.hpp" -#include "domain/impl/receivers/elastic/interface.hpp" -#include "enumerations/interface.hpp" -#include "kernel.hpp" -#include "kokkos_abstractions.h" +#include "chunk_element/field.hpp" +#include "compute/assembly/assembly.hpp" +#include "compute_seismogram.hpp" +#include "datatypes/simd.hpp" +#include "element/quadrature.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" #include "medium/compute_wavefield.hpp" #include "parallel_configuration/chunk_config.hpp" -#include "quadrature/interface.hpp" -#include "specfem_setup.hpp" +#include "policies/chunk.hpp" +#include -template -specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, MediumTag, PropertyTag, - NGLL>::receiver_kernel(const specfem::compute::assembly &assembly) - : assembly(assembly) { + specfem::element::property_tag PropertyTag> +void specfem::kokkos_kernels::impl::compute_seismograms( + specfem::compute::assembly &assembly, const int &isig_step) { - this->elements = + constexpr auto medium_tag = MediumTag; + constexpr auto property_tag = PropertyTag; + constexpr auto wavefield_type = WavefieldType; + constexpr int ngll = NGLL; + constexpr auto dimension = DimensionType; + + const auto elements = assembly.receivers.get_elements_on_device(MediumTag, PropertyTag); -} -template -void specfem::domain::impl::kernels::receiver_kernel< - WavefieldType, DimensionType, MediumTag, PropertyTag, - NGLL>::compute_seismograms(const int &isig_step) const { const int nelements = elements.extent(0); - constexpr int ngll = NGLL; if (nelements == 0) return; - auto receivers = assembly.receivers; + auto &receivers = assembly.receivers; const auto seismogram_types = receivers.get_seismogram_types(); - auto field = assembly.fields.get_simulation_field(); - auto quadrature = assembly.mesh.quadratures; - const int nseismograms = seismogram_types.size(); + const auto field = assembly.fields.get_simulation_field(); + const auto &quadrature = assembly.mesh.quadratures; constexpr bool using_simd = false; @@ -66,21 +62,17 @@ void specfem::domain::impl::kernels::receiver_kernel< Kokkos::DefaultExecutionSpace>; using ChunkPolicy = specfem::policy::element_chunk; - using ChunkElementFieldType = specfem::chunk_element::field< ParallelConfig::chunk_size, ngll, DimensionType, MediumTag, specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, true, true, true, false, using_simd>; - using ElementQuadratureType = specfem::element::quadrature< ngll, DimensionType, specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, true, false>; - using ViewType = specfem::datatype::ScalarChunkViewType< type_real, ParallelConfig::chunk_size, ngll, 2, specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, false>; - using ResultsViewType = Kokkos::View +void compute_source_interaction(specfem::compute::assembly &assembly, + const int ×tep); +} +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kokkos_kernels/impl/compute_source_interaction.tpp b/include/kokkos_kernels/impl/compute_source_interaction.tpp new file mode 100644 index 000000000..b4a640e94 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_source_interaction.tpp @@ -0,0 +1,129 @@ +#pragma once + +#include "chunk_element/field.hpp" +#include "compute/assembly/assembly.hpp" +#include "datatypes/simd.hpp" +#include "boundary_conditions/boundary_conditions.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" +#include "medium/compute_source.hpp" +#include "parallel_configuration/chunk_config.hpp" +#include "point/boundary.hpp" +#include "point/field.hpp" +#include "point/properties.hpp" +#include "point/sources.hpp" +#include "policies/chunk.hpp" +#include + +template +void specfem::kokkos_kernels::impl::compute_source_interaction( + specfem::compute::assembly &assembly, const int ×tep) { + +constexpr auto medium_tag = MediumTag; +constexpr auto property_tag = PropertyTag; +constexpr auto boundary_tag = BoundaryTag; +constexpr auto dimension = DimensionType; +constexpr int ngll = NGLL; +constexpr auto wavefield = WavefieldType; + +const auto elements = assembly.sources.get_elements_on_device( + MediumTag, PropertyTag, BoundaryTag, WavefieldType); + +const int nelements = elements.extent(0); + +if (nelements == 0) + return; + +auto &sources = assembly.sources; +const auto &properties = assembly.properties; +const auto &boundaries = assembly.boundaries; +const auto field = assembly.fields.get_simulation_field(); + +sources.update_timestep(timestep); + +using PointSourcesType = + specfem::point::source; +using PointPropertiesType = + specfem::point::properties; +using PointBoundaryType = + specfem::point::boundary; +using PointVelocityType = specfem::point::field; + +using simd = specfem::datatype::simd; +constexpr int simd_size = simd::size(); + +#ifdef KOKKOS_ENABLE_CUDA +constexpr int nthreads = 32; +constexpr int lane_size = 1; +#else +constexpr int nthreads = 1; +constexpr int lane_size = 1; +#endif + +using ParallelConfig = + specfem::parallel_config::chunk_config; + +using ChunkPolicy = specfem::policy::element_chunk; + +ChunkPolicy chunk_policy(elements, NGLL, NGLL); + +Kokkos::parallel_for( + "specfem::kernels::impl::domain_kernels::compute_source_interaction", + static_cast(chunk_policy), + KOKKOS_LAMBDA(const typename ChunkPolicy::member_type &team) { + for (int tile = 0; tile < ChunkPolicy::tile_size * simd_size; + tile += ChunkPolicy::chunk_size * simd_size) { + const int starting_element_index = + team.league_rank() * ChunkPolicy::tile_size * simd_size + tile; + + if (starting_element_index >= nelements) { + break; + } + + const auto iterator = + chunk_policy.league_iterator(starting_element_index); + + Kokkos::parallel_for( + Kokkos::TeamThreadRange(team, iterator.chunk_size()), + [&](const int i) { + const auto iterator_index = iterator(i); + const auto index = iterator_index.index; + + PointSourcesType point_source; + specfem::compute::load_on_device(index, sources, point_source); + + PointPropertiesType point_property; + specfem::compute::load_on_device(index, properties, + point_property); + + auto acceleration = + specfem::medium::compute_source_contribution(point_source, + point_property); + + PointBoundaryType point_boundary; + specfem::compute::load_on_device(index, boundaries, + point_boundary); + + PointVelocityType velocity; + specfem::compute::load_on_device(index, field, velocity); + + specfem::boundary_conditions:: + apply_boundary_conditions(point_boundary, point_property, + velocity, acceleration); + + specfem::compute::atomic_add_on_device(index, acceleration, + field); + }); + } + }); + +Kokkos::fence(); +} diff --git a/include/kokkos_kernels/impl/compute_stiffness_interaction.hpp b/include/kokkos_kernels/impl/compute_stiffness_interaction.hpp new file mode 100644 index 000000000..56e373703 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_stiffness_interaction.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" + +namespace specfem { +namespace kokkos_kernels { +namespace impl { + +template +void compute_stiffness_interaction(const specfem::compute::assembly &assembly, + const int &istep); +} +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kokkos_kernels/impl/compute_stiffness_interaction.tpp b/include/kokkos_kernels/impl/compute_stiffness_interaction.tpp new file mode 100644 index 000000000..2a404c7c8 --- /dev/null +++ b/include/kokkos_kernels/impl/compute_stiffness_interaction.tpp @@ -0,0 +1,218 @@ +#pragma once + +#include "algorithms/divergence.hpp" +#include "algorithms/gradient.hpp" +#include "boundary_conditions/boundary_conditions.hpp" +#include "chunk_element/field.hpp" +#include "chunk_element/stress_integrand.hpp" +#include "compute/assembly/assembly.hpp" +#include "datatypes/simd.hpp" +#include "element/quadrature.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" +#include "medium/compute_stress.hpp" +#include "parallel_configuration/chunk_config.hpp" +#include "point/boundary.hpp" +#include "point/field.hpp" +#include "point/field_derivatives.hpp" +#include "point/partial_derivatives.hpp" +#include "point/properties.hpp" +#include "point/sources.hpp" +#include "policies/chunk.hpp" +#include + +template +void specfem::kokkos_kernels::impl::compute_stiffness_interaction( + const specfem::compute::assembly &assembly, const int &istep) { + + constexpr auto medium_tag = MediumTag; + constexpr auto property_tag = PropertyTag; + constexpr auto boundary_tag = BoundaryTag; + constexpr int ngll = NGLL; + constexpr auto wavefield = WavefieldType; + constexpr auto dimension = DimensionType; + + const auto elements = assembly.element_types.get_elements_on_device( + MediumTag, PropertyTag, BoundaryTag); + + const int nelements = elements.extent(0); + + if (nelements == 0) + return; + + const auto &quadrature = assembly.mesh.quadratures; + const auto &partial_derivatives = assembly.partial_derivatives; + const auto &properties = assembly.properties; + const auto field = assembly.fields.get_simulation_field(); + const auto &boundaries = assembly.boundaries; + const auto boundary_values = + assembly.boundary_values.get_container(); + + constexpr bool using_simd = true; + using simd = specfem::datatype::simd; + using parallel_config = specfem::parallel_config::default_chunk_config< + dimension, simd, Kokkos::DefaultExecutionSpace>; + + constexpr int chunk_size = parallel_config::chunk_size; + + constexpr int components = + specfem::element::attributes::components(); + constexpr int num_dimensions = + specfem::element::attributes::dimension(); + + using ChunkPolicyType = specfem::policy::element_chunk; + using ChunkElementFieldType = specfem::chunk_element::field< + parallel_config::chunk_size, ngll, dimension, medium_tag, + specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, + true, false, false, false, using_simd>; + using ChunkStressIntegrandType = specfem::chunk_element::stress_integrand< + parallel_config::chunk_size, ngll, dimension, medium_tag, + specfem::kokkos::DevScratchSpace, Kokkos::MemoryTraits, + using_simd>; + using ElementQuadratureType = specfem::element::quadrature< + ngll, dimension, specfem::kokkos::DevScratchSpace, + Kokkos::MemoryTraits, true, true>; + + using PointBoundaryType = + specfem::point::boundary; + using PointVelocityType = + specfem::point::field; + using PointAccelerationType = + specfem::point::field; + using PointPartialDerivativesType = + specfem::point::partial_derivatives; + using PointPropertyType = + specfem::point::properties; + using PointFieldDerivativesType = + specfem::point::field_derivatives; + + const auto wgll = assembly.mesh.quadratures.gll.weights; + + int scratch_size = ChunkElementFieldType::shmem_size() + + ChunkStressIntegrandType::shmem_size() + + ElementQuadratureType::shmem_size(); + + ChunkPolicyType chunk_policy(elements, ngll, ngll); + + constexpr int simd_size = simd::size(); + + Kokkos::parallel_for( + "specfem::kernels::impl::domain_kernels::compute_stiffness_interaction", + chunk_policy.set_scratch_size(0, Kokkos::PerTeam(scratch_size)), + KOKKOS_LAMBDA(const typename ChunkPolicyType::member_type &team) { + ChunkElementFieldType element_field(team); + ElementQuadratureType element_quadrature(team); + ChunkStressIntegrandType stress_integrand(team); + + specfem::compute::load_on_device(team, quadrature, element_quadrature); + for (int tile = 0; tile < ChunkPolicyType::tile_size * simd_size; + tile += ChunkPolicyType::chunk_size * simd_size) { + const int starting_element_index = + team.league_rank() * ChunkPolicyType::tile_size * simd_size + + tile; + + if (starting_element_index >= nelements) { + break; + } + + const auto iterator = + chunk_policy.league_iterator(starting_element_index); + specfem::compute::load_on_device(team, iterator, field, + element_field); + + team.team_barrier(); + + specfem::algorithms::gradient( + team, iterator, partial_derivatives, + element_quadrature.hprime_gll, element_field.displacement, + // Compute stresses using the gradients + [&](const typename ChunkPolicyType::iterator_type::index_type + &iterator_index, + const typename PointFieldDerivativesType::ViewType &du) { + const auto &index = iterator_index.index; + + PointPartialDerivativesType point_partial_derivatives; + specfem::compute::load_on_device(index, partial_derivatives, + point_partial_derivatives); + + PointPropertyType point_property; + specfem::compute::load_on_device(index, properties, + point_property); + + PointFieldDerivativesType field_derivatives(du); + + const auto point_stress = specfem::medium::compute_stress( + point_property, field_derivatives); + + const auto F = point_stress * point_partial_derivatives; + + const int &ielement = iterator_index.ielement; + + for (int icomponent = 0; icomponent < components; + ++icomponent) { + for (int idim = 0; idim < num_dimensions; ++idim) { + stress_integrand.F(ielement, index.iz, index.ix, idim, + icomponent) = F(idim, icomponent); + } + } + }); + + team.team_barrier(); + + specfem::algorithms::divergence( + team, iterator, partial_derivatives, wgll, + element_quadrature.hprime_wgll, stress_integrand.F, + [&, istep = istep]( + const typename ChunkPolicyType::iterator_type::index_type + &iterator_index, + const typename PointAccelerationType::ViewType &result) { + const auto &index = iterator_index.index; + PointAccelerationType acceleration(result); + + for (int icomponent = 0; icomponent < components; + ++icomponent) { + acceleration.acceleration(icomponent) *= + static_cast(-1.0); + } + + PointPropertyType point_property; + specfem::compute::load_on_device(index, properties, + point_property); + + PointVelocityType velocity; + specfem::compute::load_on_device(index, field, velocity); + + PointBoundaryType point_boundary; + specfem::compute::load_on_device(index, boundaries, + point_boundary); + + specfem::boundary_conditions::apply_boundary_conditions( + point_boundary, point_property, velocity, acceleration); + + // Store forward boundary values for reconstruction during + // adjoint simulations. The function does nothing if the + // boundary tag is not stacey + if (wavefield == + specfem::wavefield::simulation_field::forward) { + specfem::compute::store_on_device(istep, index, acceleration, + boundary_values); + } + + specfem::compute::atomic_add_on_device(index, acceleration, + field); + }); + } + }); + + Kokkos::fence(); + + return; +} diff --git a/include/kokkos_kernels/impl/divide_mass_matrix.hpp b/include/kokkos_kernels/impl/divide_mass_matrix.hpp new file mode 100644 index 000000000..e09ab5be7 --- /dev/null +++ b/include/kokkos_kernels/impl/divide_mass_matrix.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "enumerations/dimension.hpp" +#include "enumerations/medium.hpp" +#include "enumerations/wavefield.hpp" + +namespace specfem { +namespace kokkos_kernels { +namespace impl { + +template +void divide_mass_matrix(const specfem::compute::assembly &assembly); +} + +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kokkos_kernels/impl/divide_mass_matrix.tpp b/include/kokkos_kernels/impl/divide_mass_matrix.tpp new file mode 100644 index 000000000..618891bff --- /dev/null +++ b/include/kokkos_kernels/impl/divide_mass_matrix.tpp @@ -0,0 +1,50 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "parallel_configuration/range_config.hpp" +#include "point/field.hpp" +#include "policies/range.hpp" +#include + +template +void specfem::kokkos_kernels::impl::divide_mass_matrix(const specfem::compute::assembly &assembly) { + + constexpr auto medium_tag = MediumTag; + constexpr auto wavefield = WavefieldType; + constexpr auto dimension = DimensionType; + const auto field = assembly.fields.get_simulation_field(); + + const int nglob = field.template get_nglob(); + constexpr bool using_simd = true; + using LoadFieldType = specfem::point::field; + using StoreFieldType = specfem::point::field; + + using ParallelConfig = specfem::parallel_config::default_range_config< + specfem::datatype::simd, + Kokkos::DefaultExecutionSpace>; + + using RangePolicy = specfem::policy::range; + + RangePolicy range(nglob); + + Kokkos::parallel_for( + "specfem::domain::domain::divide_mass_matrix", + static_cast(range), + KOKKOS_LAMBDA(const int iglob) { + const auto iterator = range.range_iterator(iglob); + const auto index = iterator(0); + + LoadFieldType load_field; + specfem::compute::load_on_device(index.index, field, load_field); + StoreFieldType store_field(load_field.divide_mass_matrix()); + specfem::compute::store_on_device(index.index, store_field, field); + }); + + Kokkos::fence(); + + return; +} diff --git a/include/kernels/impl/interface_kernels.hpp b/include/kokkos_kernels/impl/interface_kernels.hpp similarity index 97% rename from include/kernels/impl/interface_kernels.hpp rename to include/kokkos_kernels/impl/interface_kernels.hpp index 2d34c0762..9e52c7752 100644 --- a/include/kernels/impl/interface_kernels.hpp +++ b/include/kokkos_kernels/impl/interface_kernels.hpp @@ -8,7 +8,7 @@ #include "enumerations/simulation.hpp" namespace specfem { -namespace kernels { +namespace kokkos_kernels { namespace impl { template +void invert_mass_matrix(const specfem::compute::assembly &assembly); +} + +} // namespace kokkos_kernels +} // namespace specfem diff --git a/include/kokkos_kernels/impl/invert_mass_matrix.tpp b/include/kokkos_kernels/impl/invert_mass_matrix.tpp new file mode 100644 index 000000000..5a660aac2 --- /dev/null +++ b/include/kokkos_kernels/impl/invert_mass_matrix.tpp @@ -0,0 +1,47 @@ +#pragma once + +#include "compute/assembly/assembly.hpp" +#include "parallel_configuration/range_config.hpp" +#include "point/field.hpp" +#include "policies/range.hpp" +#include + +template +void specfem::kokkos_kernels::impl::invert_mass_matrix( + const specfem::compute::assembly &assembly) { + + constexpr auto medium_tag = MediumTag; + constexpr auto wavefield = WavefieldType; + constexpr auto dimension = DimensionType; + const auto field = assembly.fields.get_simulation_field(); + + const int nglob = field.template get_nglob(); + constexpr bool using_simd = true; + using PointFieldType = specfem::point::field; + + using ParallelConfig = specfem::parallel_config::default_range_config< + specfem::datatype::simd, + Kokkos::DefaultExecutionSpace>; + + using RangePolicy = specfem::policy::range; + + RangePolicy range(nglob); + + Kokkos::parallel_for( + "specfem::domain::domain::divide_mass_matrix", + static_cast(range), + KOKKOS_LAMBDA(const int iglob) { + const auto iterator = range.range_iterator(iglob); + const auto index = iterator(0); + + PointFieldType load_field; + specfem::compute::load_on_device(index.index, field, load_field); + PointFieldType store_field(load_field.invert_mass_matrix()); + specfem::compute::store_on_device(index.index, store_field, field); + }); + + Kokkos::fence(); +} diff --git a/include/medium/material_kernels.hpp b/include/medium/material_kernels.hpp index de9fb438e..3b3196c16 100644 --- a/include/medium/material_kernels.hpp +++ b/include/medium/material_kernels.hpp @@ -19,23 +19,19 @@ class material_kernels : public kernels_container { material_kernels() = default; material_kernels( - const int nspec, const int n_element, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, + const Kokkos::View elements, + const int ngllz, const int ngllx, const specfem::kokkos::HostView1d property_index_mapping) : specfem::medium::kernels_container( - n_element, ngllz, ngllx) { + elements.extent(0), ngllz, ngllx) { + + const int nelement = elements.extent(0); int count = 0; - for (int ispec = 0; ispec < nspec; ++ispec) { - const int ispec_mesh = mapping.compute_to_mesh(ispec); - const auto &tag = tags.tags_container(ispec_mesh); - if ((tag.medium_tag == type) && (tag.property_tag == property)) { - property_index_mapping(ispec) = count; - count++; - } + for (int i = 0; i < nelement; ++i) { + const int ispec = elements(i); + property_index_mapping(ispec) = count; + count++; } - - assert(count == n_element); } }; } // namespace medium diff --git a/include/medium/material_properties.hpp b/include/medium/material_properties.hpp index fbf5619e8..5c146cb1b 100644 --- a/include/medium/material_properties.hpp +++ b/include/medium/material_properties.hpp @@ -20,42 +20,36 @@ struct material_properties material_properties() = default; material_properties( - const int nspec, const int n_element, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, - const specfem::mesh::materials &materials, const bool &has_gll_model, + const Kokkos::View elements, + const int ngllz, const int ngllx, + const specfem::mesh::materials &materials, const bool has_gll_model, const specfem::kokkos::HostView1d property_index_mapping) - : specfem::medium::properties_container(n_element, ngllz, - ngllx) { + : specfem::medium::properties_container( + elements.extent(0), ngllz, ngllx) { + const int nelement = elements.extent(0); int count = 0; - for (int ispec = 0; ispec < nspec; ++ispec) { - const int ispec_mesh = mapping.compute_to_mesh(ispec); - const auto &tag = tags.tags_container(ispec_mesh); - - if ((tag.medium_tag == type) && (tag.property_tag == property)) { - property_index_mapping(ispec) = count; - if (!has_gll_model) { - for (int iz = 0; iz < ngllz; ++iz) { - for (int ix = 0; ix < ngllx; ++ix) { - // Get the material at index from mesh::materials - auto material = - std::get >( - materials[ispec_mesh]); - - // Assign the material property to the property container - auto point_property = material.get_properties(); - this->assign(specfem::point::index(count, iz, ix), - point_property); - } + for (int i = 0; i < nelement; ++i) { + const int ispec = elements(i); + property_index_mapping(ispec) = count; + if (!has_gll_model) { + for (int iz = 0; iz < ngllz; ++iz) { + for (int ix = 0; ix < ngllx; ++ix) { + // Get the material at index from mesh::materials + auto material = + std::get >( + materials[ispec]); + + // Assign the material property to the property container + auto point_property = material.get_properties(); + this->assign(specfem::point::index(count, iz, ix), + point_property); } } - count++; } + count++; } - assert(count == n_element); - if (!has_gll_model) { this->copy_to_device(); } diff --git a/include/parameter_parser/setup.hpp b/include/parameter_parser/setup.hpp index c3b9fb282..10ef9d89a 100644 --- a/include/parameter_parser/setup.hpp +++ b/include/parameter_parser/setup.hpp @@ -207,15 +207,13 @@ class setup { return this->solver->get_simulation_type(); } - template + template std::shared_ptr instantiate_solver( const type_real dt, const specfem::compute::assembly &assembly, std::shared_ptr time_scheme, - const qp_type &quadrature, const std::vector > &plotters) const { - return this->solver->instantiate(dt, assembly, time_scheme, quadrature, - plotters); + return this->solver->instantiate(dt, assembly, time_scheme, plotters); } int get_nsteps() const { return this->time_scheme->get_nsteps(); } diff --git a/include/parameter_parser/solver/solver.hpp b/include/parameter_parser/solver/solver.hpp index 8d5d47f2e..d2cff4e51 100644 --- a/include/parameter_parser/solver/solver.hpp +++ b/include/parameter_parser/solver/solver.hpp @@ -43,11 +43,10 @@ class solver { * @param quadrature Quadrature points object * @return std::shared_ptr Solver object */ - template + template std::shared_ptr instantiate(const type_real dt, const specfem::compute::assembly &assembly, std::shared_ptr time_scheme, - const qp_type &quadrature, const std::vector > &plotters) const; diff --git a/include/parameter_parser/solver/solver.tpp b/include/parameter_parser/solver/solver.tpp index ce04cd2c3..2cfe26859 100644 --- a/include/parameter_parser/solver/solver.tpp +++ b/include/parameter_parser/solver/solver.tpp @@ -1,42 +1,45 @@ #ifndef _SPECFEM_RUNTIME_CONFIGURATION_SOLVER_SOLVER_TPP_ #define _SPECFEM_RUNTIME_CONFIGURATION_SOLVER_SOLVER_TPP_ -#include "kernels/kernels.hpp" +#include "kokkos_kernels/domain_kernels.hpp" #include "solver.hpp" #include "solver/time_marching.hpp" #include "timescheme/newmark.hpp" #include #include -template +template std::shared_ptr -specfem::runtime_configuration::solver::solver::instantiate(const type_real dt, - const specfem::compute::assembly &assembly, +specfem::runtime_configuration::solver::solver::instantiate( + const type_real dt, const specfem::compute::assembly &assembly, std::shared_ptr time_scheme, - const qp_type &quadrature, const std::vector > &plotters) const { + const std::vector > &plotters) + const { if (this->simulation_type == "forward") { std::cout << "Instantiating Kernels \n"; std::cout << "-------------------------------\n"; - const auto kernels = specfem::kernels::kernels( - dt, assembly, quadrature); + const auto kernels = + specfem::kokkos_kernels::domain_kernels( + assembly); return std::make_shared< specfem::solver::time_marching>( + specfem::dimension::type::dim2, NGLL> >( kernels, time_scheme, plotters); } else if (this->simulation_type == "combined") { std::cout << "Instantiating Kernels \n"; std::cout << "-------------------------------\n"; - const auto adjoint_kernels = specfem::kernels::kernels(dt, - assembly, quadrature); - const auto backward_kernels = specfem::kernels::kernels(dt, - assembly, quadrature); + const auto adjoint_kernels = + specfem::kokkos_kernels::domain_kernels( + assembly); + const auto backward_kernels = specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::backward, + specfem::dimension::type::dim2, NGLL>(assembly); return std::make_shared< specfem::solver::time_marching>( + specfem::dimension::type::dim2, NGLL> >( assembly, adjoint_kernels, backward_kernels, time_scheme, plotters); } else { throw std::runtime_error("Simulation type not recognized"); diff --git a/include/point/boundary.hpp b/include/point/boundary.hpp index b31ddd802..c63d32633 100644 --- a/include/point/boundary.hpp +++ b/include/point/boundary.hpp @@ -212,10 +212,13 @@ struct boundary DimensionType, UseSIMD> &boundary); ///@} - datatype edge_weight = 0.0; ///< Integration weight associated with the edge - ///< at the quadrature point - NormalViewType edge_normal = { 0.0, 0.0 }; ///< Normal vector to the edge at - ///< the quadrature point + datatype edge_weight = + static_cast(0.0); ///< Integration weight associated with the + ///< edge at the quadrature point + NormalViewType edge_normal = { + static_cast(0.0), static_cast(0.0) + }; ///< Normal vector to the edge at + ///< the quadrature point }; /** diff --git a/include/policies/chunk.hpp b/include/policies/chunk.hpp index 84f5b7d5e..a4e53f938 100644 --- a/include/policies/chunk.hpp +++ b/include/policies/chunk.hpp @@ -220,7 +220,7 @@ class chunk { */ KOKKOS_INLINE_FUNCTION Kokkos::pair get_range() const { - return Kokkos::make_pair(indices(0), indices(num_elements - 1)); + return Kokkos::make_pair(indices(0), indices(num_elements - 1) + 1); } }; } // namespace iterator diff --git a/include/solver/time_marching.hpp b/include/solver/time_marching.hpp index 3bf681b71..1c76309fc 100644 --- a/include/solver/time_marching.hpp +++ b/include/solver/time_marching.hpp @@ -4,8 +4,8 @@ #include "enumerations/dimension.hpp" #include "enumerations/simulation.hpp" #include "enumerations/wavefield.hpp" -#include "kernels/frechet_kernels.hpp" -#include "kernels/kernels.hpp" +#include "kokkos_kernels/domain_kernels.hpp" +#include "kokkos_kernels/frechet_kernels.hpp" #include "plotter/plotter.hpp" #include "solver.hpp" #include "timescheme/newmark.hpp" @@ -22,14 +22,14 @@ namespace solver { * quadrature points */ template + specfem::dimension::type DimensionType, int NGLL> class time_marching; /** * @brief Time marching solver for forward simulation */ -template -class time_marching +template +class time_marching : public solver { public: /** @@ -45,8 +45,8 @@ class time_marching * @param time_scheme Time scheme */ time_marching( - const specfem::kernels::kernels< - specfem::wavefield::simulation_field::forward, DimensionType, qp_type> + const specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::forward, DimensionType, NGLL> &kernels, const std::shared_ptr time_scheme, const std::vector > &plotters) @@ -60,9 +60,9 @@ class time_marching void run() override; private: - specfem::kernels::kernels + specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::forward, DimensionType, + NGLL> kernels; ///< Computational kernels std::shared_ptr time_scheme; ///< Time ///< scheme @@ -74,8 +74,8 @@ class time_marching /** * @brief Time marching solver for combined adjoint and backward simulations */ -template -class time_marching +template +class time_marching : public solver { public: /** @@ -94,12 +94,12 @@ class time_marching */ time_marching( const specfem::compute::assembly &assembly, - const specfem::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, DimensionType, qp_type> + const specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::adjoint, DimensionType, NGLL> &adjoint_kernels, - const specfem::kernels::kernels< - specfem::wavefield::simulation_field::backward, DimensionType, - qp_type> &backward_kernels, + const specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::backward, DimensionType, NGLL> + &backward_kernels, const std::shared_ptr time_scheme, const std::vector > &plotters) : assembly(assembly), adjoint_kernels(adjoint_kernels), @@ -114,16 +114,15 @@ class time_marching void run() override; private: - constexpr static int NGLL = qp_type::NGLL; - specfem::kernels::kernels + specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::adjoint, DimensionType, + NGLL> adjoint_kernels; ///< Adjoint computational kernels - specfem::kernels::kernels + specfem::kokkos_kernels::domain_kernels< + specfem::wavefield::simulation_field::backward, DimensionType, + NGLL> backward_kernels; ///< Backward computational kernels - specfem::kernels::frechet_kernels + specfem::kokkos_kernels::frechet_kernels frechet_kernels; ///< Misfit kernels specfem::compute::assembly assembly; ///< Spectral element assembly object std::shared_ptr time_scheme; ///< Time diff --git a/include/solver/time_marching.tpp b/include/solver/time_marching.tpp index 4bd938c85..ef5296498 100644 --- a/include/solver/time_marching.tpp +++ b/include/solver/time_marching.tpp @@ -1,15 +1,14 @@ #ifndef _SPECFEM_SOLVER_TIME_MARCHING_TPP #define _SPECFEM_SOLVER_TIME_MARCHING_TPP -#include "domain/domain.hpp" #include "solver.hpp" #include "time_marching.hpp" #include "timescheme/newmark.hpp" #include -template +template void specfem::solver::time_marching::run() { + DimensionType, NGLL>::run() { constexpr auto acoustic = specfem::element::medium_tag::acoustic; constexpr auto elastic = specfem::element::medium_tag::elastic; @@ -50,9 +49,9 @@ void specfem::solver::time_marching +template void specfem::solver::time_marching::run() { + DimensionType, NGLL>::run() { constexpr auto acoustic = specfem::element::medium_tag::acoustic; constexpr auto elastic = specfem::element::medium_tag::elastic; diff --git a/include/source/adjoint_source.hpp b/include/source/adjoint_source.hpp index 627457f8f..5fea68a43 100644 --- a/include/source/adjoint_source.hpp +++ b/include/source/adjoint_source.hpp @@ -2,7 +2,7 @@ #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "source.hpp" #include "yaml-cpp/yaml.h" @@ -21,7 +21,7 @@ class adjoint_source : public source { void compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) override; specfem::wavefield::simulation_field get_wavefield_type() const override { diff --git a/include/source/external.hpp b/include/source/external.hpp index 7e63e03cb..119fc84eb 100644 --- a/include/source/external.hpp +++ b/include/source/external.hpp @@ -3,7 +3,7 @@ #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "source.hpp" #include "yaml-cpp/yaml.h" @@ -22,7 +22,7 @@ class external : public source { void compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) override; specfem::wavefield::simulation_field get_wavefield_type() const override { diff --git a/include/source/force_source.hpp b/include/source/force_source.hpp index 87491bc36..f49dbc217 100644 --- a/include/source/force_source.hpp +++ b/include/source/force_source.hpp @@ -3,7 +3,7 @@ #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "enumerations/specfem_enums.hpp" #include "kokkos_abstractions.h" #include "quadrature/interface.hpp" @@ -56,7 +56,7 @@ class force : public source { void compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) override; specfem::wavefield::simulation_field get_wavefield_type() const override { diff --git a/include/source/moment_tensor_source.hpp b/include/source/moment_tensor_source.hpp index e0945e6af..6b9641b8e 100644 --- a/include/source/moment_tensor_source.hpp +++ b/include/source/moment_tensor_source.hpp @@ -3,7 +3,7 @@ #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "constants.hpp" #include "enumerations/specfem_enums.hpp" #include "kokkos_abstractions.h" @@ -71,7 +71,7 @@ class moment_tensor : public source { void compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) override; specfem::wavefield::simulation_field get_wavefield_type() const override { diff --git a/include/source/source.hpp b/include/source/source.hpp index 412c596a9..ce93ed61c 100644 --- a/include/source/source.hpp +++ b/include/source/source.hpp @@ -3,7 +3,7 @@ #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "constants.hpp" #include "enumerations/wavefield.hpp" #include "kokkos_abstractions.h" @@ -71,7 +71,7 @@ class source { virtual void compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) = 0; void compute_source_time_function( diff --git a/src/algorithms/interpolate.cpp b/src/algorithms/interpolate.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/domain/impl/boundary_conditions/boundary_conditions.cpp b/src/boundary_conditions/boundary_conditions.cpp similarity index 92% rename from src/domain/impl/boundary_conditions/boundary_conditions.cpp rename to src/boundary_conditions/boundary_conditions.cpp index 87b3c242a..9b3023278 100644 --- a/src/domain/impl/boundary_conditions/boundary_conditions.cpp +++ b/src/boundary_conditions/boundary_conditions.cpp @@ -1,7 +1,7 @@ -#include "domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp" -#include "domain/impl/boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp" -#include "domain/impl/boundary_conditions/stacey/stacey.hpp" -#include "domain/impl/boundary_conditions/stacey/stacey.tpp" +#include "boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.hpp" +#include "boundary_conditions/composite_stacey_dirichlet/composite_stacey_dirichlet.tpp" +#include "boundary_conditions/stacey/stacey.hpp" +#include "boundary_conditions/stacey/stacey.tpp" #include "enumerations/dimension.hpp" #include "enumerations/material_definitions.hpp" #include "enumerations/medium.hpp" @@ -47,7 +47,7 @@ using boundary_type = BOUNDARY_TAG) \ /** Template instantiation for SIMD=false */ \ template KOKKOS_FUNCTION void \ - specfem::domain::impl::boundary_conditions::impl_compute_mass_matrix_terms< \ + specfem::boundary_conditions::impl_compute_mass_matrix_terms< \ PointBoundaryType, \ PointPropertyType, \ @@ -63,7 +63,7 @@ using boundary_type = \ /** Template instantiation for SIMD=true */ \ template KOKKOS_FUNCTION void \ - specfem::domain::impl::boundary_conditions::impl_compute_mass_matrix_terms< \ + specfem::boundary_conditions::impl_compute_mass_matrix_terms< \ PointBoundaryType, \ PointPropertyType, \ @@ -89,7 +89,7 @@ CALL_MACRO_FOR_ALL_ELEMENT_TYPES( BOUNDARY_TAG) \ /** Template instantiation for SIMD=false */ \ template KOKKOS_FUNCTION void \ - specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions< \ + specfem::boundary_conditions::impl_apply_boundary_conditions< \ PointBoundaryType, \ PointPropertyType, \ @@ -108,7 +108,7 @@ CALL_MACRO_FOR_ALL_ELEMENT_TYPES( \ /** Template instantiation for SIMD=true */ \ template KOKKOS_FUNCTION void \ - specfem::domain::impl::boundary_conditions::impl_apply_boundary_conditions< \ + specfem::boundary_conditions::impl_apply_boundary_conditions< \ PointBoundaryType, \ PointPropertyType, \ diff --git a/src/compute/assembly/assembly.cpp b/src/compute/assembly/assembly.cpp index aa6213101..02e8b5ed8 100644 --- a/src/compute/assembly/assembly.cpp +++ b/src/compute/assembly/assembly.cpp @@ -15,20 +15,18 @@ specfem::compute::assembly::assembly( const specfem::simulation::type simulation, const std::shared_ptr &property_reader) { this->mesh = { mesh.tags, mesh.control_nodes, quadratures }; + this->element_types = { this->mesh.nspec, this->mesh.ngllz, this->mesh.ngllx, + this->mesh.mapping, mesh.tags }; this->partial_derivatives = { this->mesh }; - this->properties = { - this->mesh.nspec, this->mesh.ngllz, this->mesh.ngllx, - this->mesh.mapping, mesh.tags, mesh.materials, - property_reader != nullptr - }; - if (property_reader) { - property_reader->read(*this); - } + this->properties = { this->mesh.nspec, this->mesh.ngllz, + this->mesh.ngllx, this->element_types, + mesh.materials, property_reader != nullptr }; this->kernels = { this->mesh.nspec, this->mesh.ngllz, this->mesh.ngllx, - this->mesh.mapping, mesh.tags }; - this->sources = { sources, this->mesh, this->partial_derivatives, - this->properties, t0, dt, - max_timesteps }; + this->element_types }; + this->sources = { + sources, this->mesh, this->partial_derivatives, this->element_types, t0, + dt, max_timesteps + }; this->receivers = { this->mesh.nspec, this->mesh.ngllz, this->mesh.ngllz, @@ -40,7 +38,7 @@ specfem::compute::assembly::assembly( stypes, this->mesh, mesh.tags, - this->properties }; + this->element_types }; this->boundaries = { this->mesh.nspec, this->mesh.ngllz, this->mesh.ngllx, mesh, this->mesh.mapping, this->mesh.quadratures, @@ -49,10 +47,10 @@ specfem::compute::assembly::assembly( this->mesh.points, this->mesh.quadratures, this->partial_derivatives, - this->properties, + this->element_types, this->mesh.mapping }; - this->fields = { this->mesh, this->properties, simulation }; - this->boundary_values = { max_timesteps, this->mesh, this->properties, + this->fields = { this->mesh, this->element_types, simulation }; + this->boundary_values = { max_timesteps, this->mesh, this->element_types, this->boundaries }; return; } diff --git a/src/compute/assembly/helper.hpp b/src/compute/assembly/helper.hpp index d81c4d81d..dfaeee25d 100644 --- a/src/compute/assembly/helper.hpp +++ b/src/compute/assembly/helper.hpp @@ -42,7 +42,7 @@ class helper { const int ngllx = assembly.mesh.ngllx; const auto elements = - assembly.properties.get_elements_on_device(medium_tag, property_tag); + assembly.element_types.get_elements_on_device(medium_tag, property_tag); const int nelements = elements.extent(0); diff --git a/src/compute/compute_boundary_values.cpp b/src/compute/compute_boundary_values.cpp index d964115a2..165992e16 100644 --- a/src/compute/compute_boundary_values.cpp +++ b/src/compute/compute_boundary_values.cpp @@ -20,7 +20,7 @@ template class specfem::compute::boundary_value_container< specfem::compute::boundary_values::boundary_values( const int nstep, const specfem::compute::mesh mesh, - const specfem::compute::properties properties, + const specfem::compute::element_types element_types, const specfem::compute::boundaries boundaries) - : stacey(nstep, mesh, properties, boundaries), - composite_stacey_dirichlet(nstep, mesh, properties, boundaries) {} + : stacey(nstep, mesh, element_types, boundaries), + composite_stacey_dirichlet(nstep, mesh, element_types, boundaries) {} diff --git a/src/compute/compute_kernels.cpp b/src/compute/compute_kernels.cpp index 20dcef89c..c0580fdc6 100644 --- a/src/compute/compute_kernels.cpp +++ b/src/compute/compute_kernels.cpp @@ -2,35 +2,51 @@ specfem::compute::kernels::kernels( const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags) - : specfem::compute::impl::element_types(nspec, ngllz, ngllx, mapping, - tags) { - // compute total number of elastic and acoustic spectral elements - int n_elastic_isotropic; - int n_elastic_anisotropic; - int n_acoustic; - - specfem::compute::impl::compute_number_of_elements_per_medium( - nspec, mapping, tags, h_medium_tags, h_property_tags, n_elastic_isotropic, - n_elastic_anisotropic, n_acoustic); + const specfem::compute::element_types &element_types) { + + this->nspec = nspec; + this->ngllz = ngllz; + this->ngllx = ngllx; + + this->property_index_mapping = + Kokkos::View( + "specfem::compute::kernels::property_index_mapping", nspec); + + this->h_property_index_mapping = + Kokkos::create_mirror_view(property_index_mapping); + + const auto elastic_isotropic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::elastic, + specfem::element::property_tag::isotropic); + + const auto elastic_anisotropic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::elastic, + specfem::element::property_tag::anisotropic); + + const auto acoustic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::acoustic, + specfem::element::property_tag::isotropic); + + for (int ispec = 0; ispec < nspec; ++ispec) { + h_property_index_mapping(ispec) = -1; + } acoustic_isotropic = specfem::medium::material_kernels< specfem::element::medium_tag::acoustic, specfem::element::property_tag::isotropic>( - nspec, n_acoustic, ngllz, ngllx, mapping, tags, h_property_index_mapping); + acoustic_elements, ngllz, ngllx, h_property_index_mapping); elastic_isotropic = specfem::medium::material_kernels< specfem::element::medium_tag::elastic, - specfem::element::property_tag::isotropic>(nspec, n_elastic_isotropic, - ngllz, ngllx, mapping, tags, - h_property_index_mapping); + specfem::element::property_tag::isotropic>( + elastic_isotropic_elements, ngllz, ngllx, h_property_index_mapping); elastic_anisotropic = specfem::medium::material_kernels< specfem::element::medium_tag::elastic, - specfem::element::property_tag::anisotropic>(nspec, n_elastic_anisotropic, - ngllz, ngllx, mapping, tags, - h_property_index_mapping); + specfem::element::property_tag::anisotropic>( + elastic_anisotropic_elements, ngllz, ngllx, h_property_index_mapping); + + Kokkos::deep_copy(property_index_mapping, h_property_index_mapping); return; } diff --git a/src/compute/compute_mesh.cpp b/src/compute/compute_mesh.cpp index 238ed6802..1885333b4 100644 --- a/src/compute/compute_mesh.cpp +++ b/src/compute/compute_mesh.cpp @@ -274,9 +274,9 @@ specfem::compute::mesh::mesh( specfem::compute::control_nodes(this->mapping, m_control_nodes); this->quadratures = specfem::compute::quadrature(m_quadratures, m_control_nodes); - nspec = this->control_nodes.nspec; - ngllx = this->quadratures.gll.N; - ngllz = this->quadratures.gll.N; + this->nspec = this->control_nodes.nspec; + this->ngllx = this->quadratures.gll.N; + this->ngllz = this->quadratures.gll.N; this->points = this->assemble(); } diff --git a/src/compute/compute_properties.cpp b/src/compute/compute_properties.cpp index 35010cec6..f21b2c0f1 100644 --- a/src/compute/compute_properties.cpp +++ b/src/compute/compute_properties.cpp @@ -2,42 +2,54 @@ specfem::compute::properties::properties( const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, - const specfem::mesh::materials &materials, const bool &has_gll_model) - : specfem::compute::impl::element_types(nspec, ngllz, ngllx, mapping, - tags) { + const specfem::compute::element_types &element_types, + const specfem::mesh::materials &materials, const bool has_gll_model) { - // compute total number of elastic and acoustic spectral elements - int n_elastic_isotropic; - int n_elastic_anisotropic; - int n_acoustic; + this->nspec = nspec; + this->ngllz = ngllz; + this->ngllx = ngllx; - specfem::compute::impl::compute_number_of_elements_per_medium( - nspec, mapping, tags, h_medium_tags, h_property_tags, n_elastic_isotropic, - n_elastic_anisotropic, n_acoustic); + this->property_index_mapping = + Kokkos::View( + "specfem::compute::properties::property_index_mapping", nspec); + this->h_property_index_mapping = + Kokkos::create_mirror_view(property_index_mapping); + + const auto elastic_isotropic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::elastic, + specfem::element::property_tag::isotropic); + + const auto elastic_anisotropic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::elastic, + specfem::element::property_tag::anisotropic); + + const auto acoustic_elements = element_types.get_elements_on_host( + specfem::element::medium_tag::acoustic, + specfem::element::property_tag::isotropic); + + for (int ispec = 0; ispec < nspec; ++ispec) { + h_property_index_mapping(ispec) = -1; + } acoustic_isotropic = specfem::medium::material_properties< specfem::element::medium_tag::acoustic, specfem::element::property_tag::isotropic>( - nspec, n_acoustic, ngllz, ngllx, mapping, tags, materials, has_gll_model, + acoustic_elements, ngllz, ngllx, materials, has_gll_model, h_property_index_mapping); elastic_isotropic = specfem::medium::material_properties< specfem::element::medium_tag::elastic, specfem::element::property_tag::isotropic>( - nspec, n_elastic_isotropic, ngllz, ngllx, mapping, tags, materials, - has_gll_model, h_property_index_mapping); + elastic_isotropic_elements, ngllz, ngllx, materials, has_gll_model, + h_property_index_mapping); elastic_anisotropic = specfem::medium::material_properties< specfem::element::medium_tag::elastic, specfem::element::property_tag::anisotropic>( - nspec, n_elastic_anisotropic, ngllz, ngllx, mapping, tags, materials, - has_gll_model, h_property_index_mapping); + elastic_anisotropic_elements, ngllz, ngllx, materials, has_gll_model, + h_property_index_mapping); Kokkos::deep_copy(property_index_mapping, h_property_index_mapping); - Kokkos::deep_copy(medium_tags, h_medium_tags); - Kokkos::deep_copy(property_tags, h_property_tags); return; } diff --git a/src/compute/compute_receivers.cpp b/src/compute/compute_receivers.cpp index 5d9f615a9..4e770a474 100644 --- a/src/compute/compute_receivers.cpp +++ b/src/compute/compute_receivers.cpp @@ -17,8 +17,9 @@ specfem::compute::receivers::receivers( const std::vector &stypes, const specfem::compute::mesh &mesh, const specfem::mesh::tags &tags, - const specfem::compute::properties &properties) - : lagrange_interpolant("specfem::compute::receivers::lagrange_interpolant", + const specfem::compute::element_types &element_types) + : nspec(nspec), + lagrange_interpolant("specfem::compute::receivers::lagrange_interpolant", receivers.size(), mesh.ngllz, mesh.ngllx), h_lagrange_interpolant(Kokkos::create_mirror_view(lagrange_interpolant)), elements("specfem::compute::receivers::elements", receivers.size()), @@ -27,8 +28,8 @@ specfem::compute::receivers::receivers( "specfem::compute::receivers::receiver_domain_index_mapping", nspec), h_receiver_domain_index_mapping( Kokkos::create_mirror_view(receiver_domain_index_mapping)), - impl::element_types(static_cast(properties)), - impl::StationIterator(receivers.size(), stypes.size()), + element_types(element_types), impl::StationIterator(receivers.size(), + stypes.size()), impl::SeismogramIterator(receivers.size(), stypes.size(), max_sig_step, dt, t0, nsteps_between_samples) { @@ -109,6 +110,79 @@ specfem::compute::receivers::receivers( } } +#define COUNT_RECEIVERS_PER_MATERIAL_SYSTEM(DIMENTION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + int CREATE_VARIABLE_NAME(count, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = 0; \ + for (int ireceiver = 0; ireceiver < h_elements.extent(0); ++ireceiver) { \ + int ispec = h_elements(ireceiver); \ + if (element_types.get_medium_tag(ispec) == GET_TAG(MEDIUM_TAG) && \ + element_types.get_property_tag(ispec) == GET_TAG(PROPERTY_TAG)) { \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) \ + ++; \ + } \ + } + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + COUNT_RECEIVERS_PER_MATERIAL_SYSTEM, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef COUNT_RECEIVERS_PER_MATERIAL_SYSTEM + +#define ALLOCATE_RECEIVERS_PER_MATERIAL_SYSTEM(DIMENTION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = \ + IndexViewType("specfem::compute::receivers::elements", \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG))); \ + CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = \ + Kokkos::create_mirror_view( \ + CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG))); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + ALLOCATE_RECEIVERS_PER_MATERIAL_SYSTEM, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef ALLOCATE_RECEIVERS_PER_MATERIAL_SYSTEM + +#define ASSIGN_RECEIVERS_PER_MATERIAL_SYSTEM(DIMENTION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + int CREATE_VARIABLE_NAME(index, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = 0; \ + for (int ireceiver = 0; ireceiver < h_elements.extent(0); ++ireceiver) { \ + int ispec = h_elements(ireceiver); \ + if (element_types.get_medium_tag(ispec) == GET_TAG(MEDIUM_TAG) && \ + element_types.get_property_tag(ispec) == GET_TAG(PROPERTY_TAG)) { \ + CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) \ + (CREATE_VARIABLE_NAME(index, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG))) = \ + ispec; \ + CREATE_VARIABLE_NAME(index, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) \ + ++; \ + } \ + } \ + Kokkos::deep_copy( \ + CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)), \ + CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG))); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + ASSIGN_RECEIVERS_PER_MATERIAL_SYSTEM, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef ASSIGN_RECEIVERS_PER_MATERIAL_SYSTEM + Kokkos::deep_copy(lagrange_interpolant, h_lagrange_interpolant); Kokkos::deep_copy(elements, h_elements); Kokkos::deep_copy(receiver_domain_index_mapping, @@ -121,35 +195,20 @@ Kokkos::View specfem::compute::receivers::get_elements_on_host( const specfem::element::medium_tag medium_tag, const specfem::element::property_tag property_tag) const { - int nreceivers = h_elements.extent(0); - - int ntags = h_medium_tags.extent(0); - int count = 0; - for (int ireceiver = 0; ireceiver < nreceivers; ++ireceiver) { - int ispec = h_elements(ireceiver); - - if (h_medium_tags(ispec) == medium_tag && - h_property_tags(ispec) == property_tag) { - count++; - } +#define RETURN_VALUE(DIMENTION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + if (medium_tag == GET_TAG(MEDIUM_TAG) && \ + property_tag == GET_TAG(PROPERTY_TAG)) { \ + return CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)); \ } - Kokkos::View elements( - "specfem::compute::receivers::elements", count); - - count = 0; - for (int ireceiver = 0; ireceiver < nreceivers; ++ireceiver) { - int ispec = h_elements(ireceiver); + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + RETURN_VALUE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) - if (h_medium_tags(ispec) == medium_tag && - h_property_tags(ispec) == property_tag) { - elements(count) = ispec; - count++; - } - } - - return elements; +#undef RETURN_VALUE } Kokkos::View @@ -157,12 +216,17 @@ specfem::compute::receivers::get_elements_on_device( const specfem::element::medium_tag medium_tag, const specfem::element::property_tag property_tag) const { - const auto h_elements = get_elements_on_host(medium_tag, property_tag); - - Kokkos::View elements( - "specfem::compute::receivers::elements", h_elements.extent(0)); +#define RETURN_VALUE(DIMENTION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + if (medium_tag == GET_TAG(MEDIUM_TAG) && \ + property_tag == GET_TAG(PROPERTY_TAG)) { \ + return CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENTION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)); \ + } - Kokkos::deep_copy(elements, h_elements); + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + RETURN_VALUE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) - return elements; +#undef RETURN_VALUE } diff --git a/src/compute/compute_sources.cpp b/src/compute/compute_sources.cpp index 7c5a664f2..7e5add8b6 100644 --- a/src/compute/compute_sources.cpp +++ b/src/compute/compute_sources.cpp @@ -17,7 +17,7 @@ template std::vector > sort_sources_per_medium( const std::vector > &sources, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, const specfem::compute::mesh &mesh) { std::vector > sorted_sources; @@ -28,7 +28,7 @@ std::vector > sort_sources_per_medium( const type_real z = source->get_z(); const specfem::point::global_coordinates coord(x, z); const auto lcoord = specfem::algorithms::locate_point(coord, mesh); - if (properties.h_medium_tags(lcoord.ispec) == MediumTag) { + if (element_types.get_medium_tag(lcoord.ispec) == MediumTag) { sorted_sources.push_back(source); } } @@ -47,7 +47,7 @@ specfem::compute::sources::sources( const std::vector > &sources, const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, const type_real t0, + const specfem::compute::element_types &element_types, const type_real t0, const type_real dt, const int nsteps) : timestep(0), nspec(mesh.nspec), source_domain_index_mapping( @@ -56,18 +56,22 @@ specfem::compute::sources::sources( Kokkos::create_mirror_view(source_domain_index_mapping)), medium_types("specfem::sources::medium_types", nspec), h_medium_types(Kokkos::create_mirror_view(medium_types)), + property_types("specfem::sources::property_types", nspec), + h_property_types(Kokkos::create_mirror_view(property_types)), + boundary_types("specfem::sources::boundary_types", nspec), + h_boundary_types(Kokkos::create_mirror_view(boundary_types)), wavefield_types("specfem::sources::wavefield_types", nspec), h_wavefield_types(Kokkos::create_mirror_view(wavefield_types)) { for (int ispec = 0; ispec < nspec; ispec++) { - source_domain_index_mapping(ispec) = -1; + h_source_domain_index_mapping(ispec) = -1; } #define SORT_SOURCES_PER_MEDIUM(DIMENSION_TAG, MEDIUM_TAG) \ auto CREATE_VARIABLE_NAME(source, GET_NAME(DIMENSION_TAG), \ GET_NAME(MEDIUM_TAG)) = \ sort_sources_per_medium( \ - sources, properties, mesh); + sources, element_types, mesh); CALL_MACRO_FOR_ALL_MEDIUM_TAGS( SORT_SOURCES_PER_MEDIUM, @@ -112,14 +116,20 @@ specfem::compute::sources::sources( "Multiple sources are detected in the same element"); \ } \ h_source_domain_index_mapping(lcoord.ispec) = isource; \ + assert(element_types.get_medium_tag(lcoord.ispec) == \ + GET_TAG(MEDIUM_TAG)); \ h_medium_types(lcoord.ispec) = GET_TAG(MEDIUM_TAG); \ + h_property_types(lcoord.ispec) = \ + element_types.get_property_tag(lcoord.ispec); \ + h_boundary_types(lcoord.ispec) = \ + element_types.get_boundary_tag(lcoord.ispec); \ h_wavefield_types(lcoord.ispec) = source->get_wavefield_type(); \ } \ this->CREATE_VARIABLE_NAME(source, GET_NAME(DIMENSION_TAG), \ GET_NAME(MEDIUM_TAG)) = \ specfem::compute::impl::source_medium( \ - current_sources, mesh, partial_derivatives, properties, t0, dt, \ + current_sources, mesh, partial_derivatives, element_types, t0, dt, \ nsteps); \ } @@ -128,51 +138,315 @@ specfem::compute::sources::sources( WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) #undef ASSIGN_MEMBERS + +#define COUNT_SOURCES_PER_ELEMENT_TYPE(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG, BOUNDARY_TAG) \ + int CREATE_VARIABLE_NAME(count_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::forward)) { \ + CREATE_VARIABLE_NAME(count_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } \ + int CREATE_VARIABLE_NAME(count_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::backward)) { \ + CREATE_VARIABLE_NAME(count_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } \ + int CREATE_VARIABLE_NAME(count_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::adjoint)) { \ + CREATE_VARIABLE_NAME(count_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + COUNT_SOURCES_PER_ELEMENT_TYPE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef COUNT_SOURCES_PER_ELEMENT_TYPE + +#define ALLOCATE_SOURCES_PER_ELEMENT_TYPE(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG, BOUNDARY_TAG) \ + this->CREATE_VARIABLE_NAME(elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + IndexViewType( \ + "specfem::compute::sources::elements_forward", \ + CREATE_VARIABLE_NAME(count_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + IndexViewType( \ + "specfem::compute::sources::elements_backward", \ + CREATE_VARIABLE_NAME(count_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + IndexViewType( \ + "specfem::compute::sources::elements_adjoint", \ + CREATE_VARIABLE_NAME(count_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements_forward, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements_backward, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements_adjoint, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))); + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + ALLOCATE_SOURCES_PER_ELEMENT_TYPE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef ALLOCATE_SOURCES_PER_ELEMENT_TYPE + +#define ASSIGN_SOURCES_PER_ELEMENT_TYPE(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG, BOUNDARY_TAG) \ + int CREATE_VARIABLE_NAME(index_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::forward)) { \ + this->CREATE_VARIABLE_NAME( \ + h_elements_forward, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))( \ + CREATE_VARIABLE_NAME(index_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } \ + int CREATE_VARIABLE_NAME(index_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::backward)) { \ + this->CREATE_VARIABLE_NAME( \ + h_elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))(CREATE_VARIABLE_NAME( \ + index_backward, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } \ + int CREATE_VARIABLE_NAME(index_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (h_source_domain_index_mapping(ispec) >= 0) { \ + if ((h_medium_types(ispec) == GET_TAG(MEDIUM_TAG)) && \ + (h_property_types(ispec) == GET_TAG(PROPERTY_TAG)) && \ + (h_boundary_types(ispec) == GET_TAG(BOUNDARY_TAG)) && \ + (h_wavefield_types(ispec) == \ + specfem::wavefield::simulation_field::adjoint)) { \ + this->CREATE_VARIABLE_NAME( \ + h_elements_adjoint, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))( \ + CREATE_VARIABLE_NAME(index_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + } \ + Kokkos::deep_copy( \ + this->CREATE_VARIABLE_NAME(elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)), \ + this->CREATE_VARIABLE_NAME(h_elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); \ + Kokkos::deep_copy( \ + this->CREATE_VARIABLE_NAME(elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)), \ + this->CREATE_VARIABLE_NAME(h_elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); \ + Kokkos::deep_copy( \ + this->CREATE_VARIABLE_NAME(elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)), \ + this->CREATE_VARIABLE_NAME(h_elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + ASSIGN_SOURCES_PER_ELEMENT_TYPE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef ASSIGN_SOURCES_PER_ELEMENT_TYPE + + Kokkos::deep_copy(source_domain_index_mapping, h_source_domain_index_mapping); + Kokkos::deep_copy(medium_types, h_medium_types); + Kokkos::deep_copy(wavefield_types, h_wavefield_types); + Kokkos::deep_copy(property_types, h_property_types); + Kokkos::deep_copy(boundary_types, h_boundary_types); } Kokkos::View specfem::compute::sources::get_elements_on_host( const specfem::element::medium_tag medium, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary, const specfem::wavefield::simulation_field wavefield) const { - int nsources = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_source_domain_index_mapping(ispec) >= 0) { - if ((h_medium_types(ispec) == medium) && - (h_wavefield_types(ispec) == wavefield)) { - nsources++; - } - } +#define RETURN_VALUE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, BOUNDARY_TAG) \ + if ((wavefield == specfem::wavefield::simulation_field::forward) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(h_elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ + } \ + if ((wavefield == specfem::wavefield::simulation_field::backward) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(h_elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ + } \ + if ((wavefield == specfem::wavefield::simulation_field::adjoint) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(h_elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ } - Kokkos::View indices( - "specfem::compute::sources::get_sources_on_host", nsources); - - int isource = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_source_domain_index_mapping(ispec) >= 0) { - if ((h_medium_types(ispec) == medium) && - (h_wavefield_types(ispec) == wavefield)) { - indices(isource) = ispec; - isource++; - } - } - } + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + RETURN_VALUE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) - return indices; +#undef RETURN_VALUE } Kokkos::View specfem::compute::sources::get_elements_on_device( const specfem::element::medium_tag medium, + const specfem::element::property_tag property, + const specfem::element::boundary_tag boundary, const specfem::wavefield::simulation_field wavefield) const { - auto h_indices = get_elements_on_host(medium, wavefield); - - Kokkos::View indices( - "specfem::compute::sources::get_sources_on_device", h_indices.extent(0)); +#define RETURN_VALUE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, BOUNDARY_TAG) \ + if ((wavefield == specfem::wavefield::simulation_field::forward) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(elements_forward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ + } \ + if ((wavefield == specfem::wavefield::simulation_field::backward) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(elements_backward, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ + } \ + if ((wavefield == specfem::wavefield::simulation_field::adjoint) && \ + (medium == GET_TAG(MEDIUM_TAG)) && \ + (property == GET_TAG(PROPERTY_TAG)) && \ + (boundary == GET_TAG(BOUNDARY_TAG))) { \ + return CREATE_VARIABLE_NAME(elements_adjoint, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)); \ + } - Kokkos::deep_copy(indices, h_indices); + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + RETURN_VALUE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) - return indices; +#undef RETURN_VALUE } diff --git a/src/compute/coupled_interfaces.cpp b/src/compute/coupled_interfaces.cpp index 255d532c5..d25bf5721 100644 --- a/src/compute/coupled_interfaces.cpp +++ b/src/compute/coupled_interfaces.cpp @@ -532,14 +532,14 @@ specfem::compute::coupled_interfaces::coupled_interfaces( const specfem::compute::points &points, const specfem::compute::quadrature &quadrature, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, const specfem::compute::mesh_to_compute_mapping &mapping) : elastic_acoustic(mesh, points, quadrature, partial_derivatives, - properties, mapping), + element_types, mapping), elastic_poroelastic(mesh, points, quadrature, partial_derivatives, - properties, mapping), + element_types, mapping), acoustic_poroelastic(mesh, points, quadrature, partial_derivatives, - properties, mapping) {} + element_types, mapping) {} // Explicit template instantiation diff --git a/src/compute/element_types/element_types.cpp b/src/compute/element_types/element_types.cpp new file mode 100644 index 000000000..94a3a3882 --- /dev/null +++ b/src/compute/element_types/element_types.cpp @@ -0,0 +1,361 @@ +#include "compute/element_types/element_types.hpp" + +specfem::compute::element_types::element_types( + const int nspec, const int ngllz, const int ngllx, + const specfem::compute::mesh_to_compute_mapping &mapping, + const specfem::mesh::tags &tags) + : nspec(nspec), + medium_tags("specfem::compute::element_types::medium_tags", nspec), + property_tags("specfem::compute::element_types::property_tags", nspec), + boundary_tags("specfem::compute::element_types::boundary_tags", nspec) { + + for (int ispec = 0; ispec < nspec; ispec++) { + const int ispec_mesh = mapping.compute_to_mesh(ispec); + medium_tags(ispec) = tags.tags_container(ispec_mesh).medium_tag; + property_tags(ispec) = tags.tags_container(ispec_mesh).property_tag; + boundary_tags(ispec) = tags.tags_container(ispec_mesh).boundary_tag; + } + +#define COUNT_MEDIUM_TAG_INDICES(DIMENSION_TAG, MEDIUM_TAG) \ + int CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG)) { \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) \ + ++; \ + } \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + COUNT_MEDIUM_TAG_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef COUNT_MEDIUM_TAG_INDICES + +#define ALLOCATE_MEDIUM_TAG_VIEWS(DIMENSION_TAG, MEDIUM_TAG) \ + this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) = \ + IndexViewType("specfem::compute::element_types::elements", \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG))); + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + ALLOCATE_MEDIUM_TAG_VIEWS, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef ALLOCATE_MEDIUM_TAG_VIEWS + +#define ASSIGN_MEDIUM_TAG_INDICES(DIMENSION_TAG, MEDIUM_TAG) \ + int CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG)) { \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG))(CREATE_VARIABLE_NAME( \ + index, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)) \ + ++; \ + } \ + } \ + Kokkos::deep_copy( \ + this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)), \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG))); + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + ASSIGN_MEDIUM_TAG_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef ASSIGN_MEDIUM_TAG_INDICES + +#define COUNT_MATERIAL_SYSTEM_INDICES(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + int CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG) && \ + property_tags(ispec) == GET_TAG(PROPERTY_TAG)) { \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) \ + ++; \ + } \ + } + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + COUNT_MATERIAL_SYSTEM_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef COUNT_MATERIAL_SYSTEM_INDICES + +#define ALLOCATE_MATERIAL_SYSTEM_VIEWS(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = \ + IndexViewType("specfem::compute::element_types::elements", \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG))); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + ALLOCATE_MATERIAL_SYSTEM_VIEWS, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef ALLOCATE_MATERIAL_SYSTEM_VIEWS + +#define ASSIGN_MATERIAL_SYSTEM_INDICES(DIMENSION_TAG, MEDIUM_TAG, \ + PROPERTY_TAG) \ + int CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG) && \ + property_tags(ispec) == GET_TAG(PROPERTY_TAG)) { \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG))(CREATE_VARIABLE_NAME( \ + index, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)) \ + ++; \ + } \ + } \ + Kokkos::deep_copy(this->CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG)), \ + this->CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG))); + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + ASSIGN_MATERIAL_SYSTEM_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef ASSIGN_MATERIAL_SYSTEM_INDICES + +#define COUNT_ELEMENT_TYPES_INDICES(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + int CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG) && \ + property_tags(ispec) == GET_TAG(PROPERTY_TAG) && \ + boundary_tags(ispec) == GET_TAG(BOUNDARY_TAG)) { \ + CREATE_VARIABLE_NAME(count, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + COUNT_ELEMENT_TYPES_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef COUNT_ELEMENT_TYPES_INDICES + +#define ALLOCATE_ELEMENT_TYPES_VIEWS(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + IndexViewType("specfem::compute::element_types::elements", \ + CREATE_VARIABLE_NAME( \ + count, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))); \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = \ + Kokkos::create_mirror_view(this->CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))); + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + ALLOCATE_ELEMENT_TYPES_VIEWS, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef ALLOCATE_ELEMENT_TYPES_VIEWS + +#define ASSIGN_ELEMENT_TYPES_INDICES(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + int CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) = 0; \ + for (int ispec = 0; ispec < nspec; ispec++) { \ + if (medium_tags(ispec) == GET_TAG(MEDIUM_TAG) && \ + property_tags(ispec) == GET_TAG(PROPERTY_TAG) && \ + boundary_tags(ispec) == GET_TAG(BOUNDARY_TAG)) { \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))(CREATE_VARIABLE_NAME( \ + index, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG))) = ispec; \ + CREATE_VARIABLE_NAME(index, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)) \ + ++; \ + } \ + } \ + Kokkos::deep_copy( \ + this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG)), \ + this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), GET_NAME(PROPERTY_TAG), \ + GET_NAME(BOUNDARY_TAG))); + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + ASSIGN_ELEMENT_TYPES_INDICES, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef ASSIGN_ELEMENT_TYPES_INDICES +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_host( + const specfem::element::medium_tag medium_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag) { \ + return this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)); \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef RETURN_VARIABLE +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_device( + const specfem::element::medium_tag medium_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag) { \ + return this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG)); \ + } + + CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + +#undef RETURN_VARIABLE +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_host( + const specfem::element::medium_tag medium_tag, + const specfem::element::property_tag property_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag && \ + GET_TAG(PROPERTY_TAG) == property_tag) { \ + return this->CREATE_VARIABLE_NAME(h_elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); \ + } + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef RETURN_VARIABLE +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_device( + const specfem::element::medium_tag medium_tag, + const specfem::element::property_tag property_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag && \ + GET_TAG(PROPERTY_TAG) == property_tag) { \ + return this->CREATE_VARIABLE_NAME(elements, GET_NAME(DIMENSION_TAG), \ + GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG)); \ + } + + CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef RETURN_VARIABLE +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_host( + const specfem::element::medium_tag medium_tag, + const specfem::element::property_tag property_tag, + const specfem::element::boundary_tag boundary_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, BOUNDARY_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag && \ + GET_TAG(PROPERTY_TAG) == property_tag && \ + GET_TAG(BOUNDARY_TAG) == boundary_tag) { \ + return this->CREATE_VARIABLE_NAME( \ + h_elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG)); \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef RETURN_VARIABLE +} + +Kokkos::View +specfem::compute::element_types::get_elements_on_device( + const specfem::element::medium_tag medium_tag, + const specfem::element::property_tag property_tag, + const specfem::element::boundary_tag boundary_tag) const { + +#define RETURN_VARIABLE(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, BOUNDARY_TAG) \ + if (GET_TAG(MEDIUM_TAG) == medium_tag && \ + GET_TAG(PROPERTY_TAG) == property_tag && \ + GET_TAG(BOUNDARY_TAG) == boundary_tag) { \ + return this->CREATE_VARIABLE_NAME( \ + elements, GET_NAME(DIMENSION_TAG), GET_NAME(MEDIUM_TAG), \ + GET_NAME(PROPERTY_TAG), GET_NAME(BOUNDARY_TAG)); \ + } + + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + RETURN_VARIABLE, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef RETURN_VARIABLE +} diff --git a/src/compute/fields/fields.cpp b/src/compute/fields/fields.cpp index 5ecd406da..57ce69433 100644 --- a/src/compute/fields/fields.cpp +++ b/src/compute/fields/fields.cpp @@ -18,14 +18,15 @@ template class specfem::compute::simulation_field< template class specfem::compute::simulation_field< specfem::wavefield::simulation_field::buffer>; -specfem::compute::fields::fields(const specfem::compute::mesh &mesh, - const specfem::compute::properties &properties, - const specfem::simulation::type simulation) +specfem::compute::fields::fields( + const specfem::compute::mesh &mesh, + const specfem::compute::element_types &element_types, + const specfem::simulation::type simulation) : // Initialize the forward field only if the simulation type is forward forward([&]() -> specfem::compute::simulation_field< specfem::wavefield::simulation_field::forward> { if (simulation == specfem::simulation::type::forward) { - return { mesh, properties }; + return { mesh, element_types }; } else if (simulation == specfem::simulation::type::combined) { return {}; } else { @@ -38,7 +39,7 @@ specfem::compute::fields::fields(const specfem::compute::mesh &mesh, if (simulation == specfem::simulation::type::forward) { return {}; } else if (simulation == specfem::simulation::type::combined) { - return { mesh, properties }; + return { mesh, element_types }; } else { throw std::runtime_error("Invalid simulation type"); } @@ -49,7 +50,7 @@ specfem::compute::fields::fields(const specfem::compute::mesh &mesh, if (simulation == specfem::simulation::type::forward) { return {}; } else if (simulation == specfem::simulation::type::combined) { - return { mesh, properties }; + return { mesh, element_types }; } else { throw std::runtime_error("Invalid simulation type"); } @@ -58,9 +59,9 @@ specfem::compute::fields::fields(const specfem::compute::mesh &mesh, buffer([&]() -> specfem::compute::simulation_field< specfem::wavefield::simulation_field::buffer> { if (simulation == specfem::simulation::type::forward) { - return { mesh, properties }; + return { mesh, element_types }; } else if (simulation == specfem::simulation::type::combined) { - return { mesh, properties }; + return { mesh, element_types }; } else { throw std::runtime_error("Invalid simulation type"); } diff --git a/src/compute/impl/element_types.cpp b/src/compute/impl/element_types.cpp deleted file mode 100644 index 6feb161c3..000000000 --- a/src/compute/impl/element_types.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include "compute/impl/element_types.hpp" - -specfem::compute::impl::element_types::element_types( - const int nspec, const int ngllz, const int ngllx, - const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags) - : nspec(nspec), ngllz(ngllz), ngllx(ngllx), - boundary_tags("specfem::compute::boundaries::boundary_tags", nspec), - medium_tags("specfem::compute::properties::medium_tags", nspec), - h_medium_tags(Kokkos::create_mirror_view(medium_tags)), - property_index_mapping( - "specfem::compute::properties::property_index_mapping", nspec), - property_tags("specfem::compute::properties::property_tags", nspec), - h_property_tags(Kokkos::create_mirror_view(property_tags)), - h_property_index_mapping( - Kokkos::create_mirror_view(property_index_mapping)) { - Kokkos::deep_copy(property_index_mapping, h_property_index_mapping); - Kokkos::deep_copy(medium_tags, h_medium_tags); - Kokkos::deep_copy(property_tags, h_property_tags); - return; -} - -Kokkos::View -specfem::compute::impl::element_types::get_elements_on_host( - const specfem::element::medium_tag medium) const { - - const int nspec = this->nspec; - - int nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium) { - nelements++; - } - } - - Kokkos::View elements( - "specfem::compute::properties::get_elements_on_host", nelements); - - nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium) { - elements(nelements) = ispec; - nelements++; - } - } - - return elements; -} - -Kokkos::View -specfem::compute::impl::element_types::get_elements_on_device( - const specfem::element::medium_tag medium) const { - - // If the elements have not been computed, compute them. - // The elements need to be computed in serial on the host. - // This function computes the host elements on host and then - // copies them to the device. - const auto host_elements = this->get_elements_on_host(medium); - - Kokkos::View - elements("specfem::compute::properties::get_elements_on_device", - host_elements.extent(0)); - - Kokkos::deep_copy(elements, host_elements); - - return elements; -} - -Kokkos::View -specfem::compute::impl::element_types::get_elements_on_host( - const specfem::element::medium_tag medium, - const specfem::element::property_tag property) const { - - const int nspec = this->nspec; - - int nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium && h_property_tags(ispec) == property) { - nelements++; - } - } - - Kokkos::View elements( - "specfem::compute::properties::get_elements_on_host", nelements); - - nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium && h_property_tags(ispec) == property) { - elements(nelements) = ispec; - nelements++; - } - } - - return elements; -} - -Kokkos::View -specfem::compute::impl::element_types::get_elements_on_device( - const specfem::element::medium_tag medium, - const specfem::element::property_tag property) const { - - // If the elements have not been computed, compute them. - // The elements need to be computed in serial on the host. - // This function computes the host elements on host and then - // copies them to the device. - const auto host_elements = this->get_elements_on_host(medium, property); - - Kokkos::View - elements("specfem::compute::properties::get_elements_on_device", - host_elements.extent(0)); - - Kokkos::deep_copy(elements, host_elements); - - return elements; -} - -Kokkos::View -specfem::compute::impl::element_types::get_elements_on_host( - const specfem::element::medium_tag medium, - const specfem::element::boundary_tag boundary) const { - - const int nspec = this->nspec; - - int nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium && boundary_tags(ispec) == boundary) { - nelements++; - } - } - - Kokkos::View elements( - "specfem::compute::properties::get_elements_on_host", nelements); - - nelements = 0; - for (int ispec = 0; ispec < nspec; ispec++) { - if (h_medium_tags(ispec) == medium && boundary_tags(ispec) == boundary) { - elements(nelements) = ispec; - nelements++; - } - } - - return elements; -} diff --git a/src/compute/impl/value_containers.cpp b/src/compute/impl/value_containers.cpp deleted file mode 100644 index fb9526a78..000000000 --- a/src/compute/impl/value_containers.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "compute/impl/value_containers.hpp" - -void specfem::compute::impl::compute_number_of_elements_per_medium( - const int nspec, const specfem::compute::mesh_to_compute_mapping &mapping, - const specfem::mesh::tags &tags, - const specfem::kokkos::HostView1d - &h_medium_tags, - const specfem::kokkos::HostView1d - &h_property_tags, - int &n_elastic_isotropic, int &n_elastic_anisotropic, int &n_acoustic) { - - Kokkos::parallel_reduce( - "specfem::compute::impl::compute_number_of_elements_per_medium", - specfem::kokkos::HostRange(0, nspec), - [=](const int ispec, int &n_elastic_isotropic, int &n_elastic_anisotropic, - int &n_acoustic) { - const int ispec_mesh = mapping.compute_to_mesh(ispec); - if (tags.tags_container(ispec_mesh).medium_tag == - specfem::element::medium_tag::elastic) { - h_medium_tags(ispec) = specfem::element::medium_tag::elastic; - if (tags.tags_container(ispec_mesh).property_tag == - specfem::element::property_tag::isotropic) { - n_elastic_isotropic++; - h_property_tags(ispec) = specfem::element::property_tag::isotropic; - } else if (tags.tags_container(ispec_mesh).property_tag == - specfem::element::property_tag::anisotropic) { - n_elastic_anisotropic++; - h_property_tags(ispec) = - specfem::element::property_tag::anisotropic; - } else { - std::cout << "Unknown property tag: " - << "File: " << __FILE__ << " Line: " << __LINE__ - << std::endl; - throw std::runtime_error("Unknown property tag"); - } - } else if (tags.tags_container(ispec_mesh).medium_tag == - specfem::element::medium_tag::acoustic) { - n_acoustic++; - h_medium_tags(ispec) = specfem::element::medium_tag::acoustic; - if (tags.tags_container(ispec_mesh).property_tag == - specfem::element::property_tag::isotropic) { - h_property_tags(ispec) = specfem::element::property_tag::isotropic; - } else { - std::cout << "Unknown property tag: " - << "File: " << __FILE__ << " Line: " << __LINE__ - << std::endl; - throw std::runtime_error("Unknown property tag"); - } - } - }, - n_elastic_isotropic, n_elastic_anisotropic, n_acoustic); - - if (n_elastic_isotropic + n_elastic_anisotropic + n_acoustic != nspec) - throw std::runtime_error("Number of elements per medium does not match " - "total number of elements"); - - return; -} - -// template class specfem::compute::impl::value_containers< -// specfem::medium::material_kernels>; - -// template class specfem::compute::impl::value_containers< -// specfem::medium::material_properties>; diff --git a/src/domain/domain.cpp b/src/domain/domain.cpp deleted file mode 100644 index d8076f021..000000000 --- a/src/domain/domain.cpp +++ /dev/null @@ -1,72 +0,0 @@ - -#include "domain/domain.hpp" -#include "domain/domain.tpp" - -// Explicit template instantiation - -namespace { -using static_5 = - specfem::enums::element::quadrature::static_quadrature_points<5>; -using static_8 = - specfem::enums::element::quadrature::static_quadrature_points<8>; -} // namespace - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; - -template class specfem::domain::domain< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; diff --git a/src/domain/impl/elements/kernel.cpp b/src/domain/impl/elements/kernel.cpp deleted file mode 100644 index 50c756f35..000000000 --- a/src/domain/impl/elements/kernel.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "domain/impl/elements/kernel.hpp" -#include "domain/impl/elements/kernel.tpp" -#include "enumerations/material_definitions.hpp" - -constexpr static auto dim2 = specfem::dimension::type::dim2; - -constexpr static auto forward = specfem::wavefield::simulation_field::forward; -constexpr static auto adjoint = specfem::wavefield::simulation_field::adjoint; -constexpr static auto backward = specfem::wavefield::simulation_field::backward; - -#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ - BOUNDARY_TAG) \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - forward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - adjoint, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - backward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - forward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - adjoint, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; \ - template class specfem::domain::impl::kernels::element_kernel_base< \ - backward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - forward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - adjoint, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - backward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 5>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - forward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - adjoint, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; \ - template class specfem::domain::impl::kernels::element_kernel< \ - backward, GET_TAG(DIMENSION_TAG), GET_TAG(MEDIUM_TAG), \ - GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG), 8>; - -CALL_MACRO_FOR_ALL_ELEMENT_TYPES( - INSTANTIATION_MACRO, - WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) - WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) - WHERE(BOUNDARY_TAG_NONE, BOUNDARY_TAG_STACEY, - BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, - BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) diff --git a/src/domain/impl/kernels.cpp b/src/domain/impl/kernels.cpp deleted file mode 100644 index 28692e58d..000000000 --- a/src/domain/impl/kernels.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "domain/impl/kernels.hpp" -#include "domain/impl/kernels.tpp" - -namespace { - -using static_5 = - specfem::enums::element::quadrature::static_quadrature_points<5>; -using static_8 = - specfem::enums::element::quadrature::static_quadrature_points<8>; - -} // namespace - -// Explicit template instantiation - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_5>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - static_8>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; - -template class specfem::domain::impl::kernels::kernels< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, - static_8>; diff --git a/src/kernels/frechet_kernels.cpp b/src/kernels/frechet_kernels.cpp deleted file mode 100644 index b4f317f63..000000000 --- a/src/kernels/frechet_kernels.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "kernels/frechet_kernels.hpp" -#include "kernels/frechet_kernels.tpp" - -#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ - /** instantiation for NGLL = 5 */ \ - template void specfem::kernels::impl:: \ - compute_material_derivatives(const specfem::compute::assembly &, const type_real &); \ - /** instantiation for NGLL = 8 */ \ - template void specfem::kernels::impl:: \ - compute_material_derivatives(const specfem::compute::assembly &, const type_real &); - -CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( - INSTANTIATION_MACRO, - WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) - WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) - -#undef INSTANTIATION_MACRO - -// Explicit template instantiation -template class specfem::kernels::frechet_kernels; - -template class specfem::kernels::frechet_kernels; diff --git a/src/kernels/kernels.cpp b/src/kernels/kernels.cpp deleted file mode 100644 index 55fe1c46c..000000000 --- a/src/kernels/kernels.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "kernels/kernels.hpp" - -// Explicit template instantiation -template class specfem::kernels::kernels< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, - specfem::enums::element::quadrature::static_quadrature_points<5> >; - -template class specfem::kernels::kernels< - specfem::wavefield::simulation_field::adjoint, - specfem::dimension::type::dim2, - specfem::enums::element::quadrature::static_quadrature_points<5> >; - -template class specfem::kernels::kernels< - specfem::wavefield::simulation_field::backward, - specfem::dimension::type::dim2, - specfem::enums::element::quadrature::static_quadrature_points<5> >; - -// template class kernels>; - -// template class kernels>; - -// template class kernels>; diff --git a/src/kokkos_kernels/frechet_kernels.cpp b/src/kokkos_kernels/frechet_kernels.cpp new file mode 100644 index 000000000..313f318ae --- /dev/null +++ b/src/kokkos_kernels/frechet_kernels.cpp @@ -0,0 +1,8 @@ +#include "kokkos_kernels/frechet_kernels.hpp" + +// Explicit template instantiation +template class specfem::kokkos_kernels::frechet_kernels< + specfem::dimension::type::dim2, 5>; + +template class specfem::kokkos_kernels::frechet_kernels< + specfem::dimension::type::dim2, 8>; diff --git a/src/kokkos_kernels/impl/compute_mass_matrix.cpp b/src/kokkos_kernels/impl/compute_mass_matrix.cpp new file mode 100644 index 000000000..db83442ee --- /dev/null +++ b/src/kokkos_kernels/impl/compute_mass_matrix.cpp @@ -0,0 +1,39 @@ +#include "kokkos_kernels/impl/compute_mass_matrix.hpp" +#include "kokkos_kernels/impl/compute_mass_matrix.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::compute_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const type_real &, const specfem::compute::assembly &); + +CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/compute_material_derivatives.cpp b/src/kokkos_kernels/impl/compute_material_derivatives.cpp new file mode 100644 index 000000000..6672872b4 --- /dev/null +++ b/src/kokkos_kernels/impl/compute_material_derivatives.cpp @@ -0,0 +1,19 @@ +#include "kokkos_kernels/impl/compute_material_derivatives.hpp" +#include "kokkos_kernels/impl/compute_material_derivatives.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + /** instantiation for NGLL = 5 */ \ + template void specfem::kokkos_kernels::impl::compute_material_derivatives< \ + GET_TAG(DIMENSION_TAG), 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + const specfem::compute::assembly &, const type_real &); \ + /** instantiation for NGLL = 8 */ \ + template void specfem::kokkos_kernels::impl::compute_material_derivatives< \ + GET_TAG(DIMENSION_TAG), 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + const specfem::compute::assembly &, const type_real &); + +CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/compute_seismogram.cpp b/src/kokkos_kernels/impl/compute_seismogram.cpp new file mode 100644 index 000000000..93838ffb9 --- /dev/null +++ b/src/kokkos_kernels/impl/compute_seismogram.cpp @@ -0,0 +1,38 @@ +#include "kokkos_kernels/impl/compute_seismogram.hpp" +#include "enumerations/material_definitions.hpp" +#include "kokkos_kernels/impl/compute_seismogram.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ + /** instantiation for NGLL = 5 */ \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + /** instantiation for NGLL = 8 */ \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_seismograms< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG)>( \ + specfem::compute::assembly &, const int &); + +CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( + INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/compute_source_interaction.cpp b/src/kokkos_kernels/impl/compute_source_interaction.cpp new file mode 100644 index 000000000..2e26ebadf --- /dev/null +++ b/src/kokkos_kernels/impl/compute_source_interaction.cpp @@ -0,0 +1,42 @@ +#include "kokkos_kernels/impl/compute_source_interaction.hpp" +#include "enumerations/material_definitions.hpp" +#include "kokkos_kernels/impl/compute_source_interaction.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + /** instantiation for NGLL = 5 */ \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + /** instantiation for NGLL = 8 */ \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_source_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + specfem::compute::assembly &, const int &); + +CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/compute_stiffness_interaction.cpp b/src/kokkos_kernels/impl/compute_stiffness_interaction.cpp new file mode 100644 index 000000000..25bb002ef --- /dev/null +++ b/src/kokkos_kernels/impl/compute_stiffness_interaction.cpp @@ -0,0 +1,42 @@ +#include "kokkos_kernels/impl/compute_stiffness_interaction.hpp" +#include "enumerations/material_definitions.hpp" +#include "kokkos_kernels/impl/compute_stiffness_interaction.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG, \ + BOUNDARY_TAG) \ + /** instantiation for NGLL = 5 */ \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 5, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); \ + /** instantiation for NGLL = 8 */ \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); \ + template void specfem::kokkos_kernels::impl::compute_stiffness_interaction< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + 8, GET_TAG(MEDIUM_TAG), GET_TAG(PROPERTY_TAG), GET_TAG(BOUNDARY_TAG)>( \ + const specfem::compute::assembly &, const int &); + +CALL_MACRO_FOR_ALL_ELEMENT_TYPES( + INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) + WHERE(BOUNDARY_TAG_STACEY, BOUNDARY_TAG_NONE, + BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/divide_mass_matrix.cpp b/src/kokkos_kernels/impl/divide_mass_matrix.cpp new file mode 100644 index 000000000..bd62d00c6 --- /dev/null +++ b/src/kokkos_kernels/impl/divide_mass_matrix.cpp @@ -0,0 +1,20 @@ +#include "kokkos_kernels/impl/divide_mass_matrix.hpp" +#include "kokkos_kernels/impl/divide_mass_matrix.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG) \ + template void specfem::kokkos_kernels::impl::divide_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::divide_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::divide_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); + +CALL_MACRO_FOR_ALL_MEDIUM_TAGS(INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) + WHERE(MEDIUM_TAG_ELASTIC, + MEDIUM_TAG_ACOUSTIC)) + +#undef INSTANTIATION_MACRO diff --git a/src/kokkos_kernels/impl/invert_mass_matrix.cpp b/src/kokkos_kernels/impl/invert_mass_matrix.cpp new file mode 100644 index 000000000..d1ee4d94c --- /dev/null +++ b/src/kokkos_kernels/impl/invert_mass_matrix.cpp @@ -0,0 +1,20 @@ +#include "kokkos_kernels/impl/invert_mass_matrix.hpp" +#include "kokkos_kernels/impl/invert_mass_matrix.tpp" + +#define INSTANTIATION_MACRO(DIMENSION_TAG, MEDIUM_TAG) \ + template void specfem::kokkos_kernels::impl::invert_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::forward, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::invert_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::backward, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); \ + template void specfem::kokkos_kernels::impl::invert_mass_matrix< \ + GET_TAG(DIMENSION_TAG), specfem::wavefield::simulation_field::adjoint, \ + GET_TAG(MEDIUM_TAG)>(const specfem::compute::assembly &); + +CALL_MACRO_FOR_ALL_MEDIUM_TAGS(INSTANTIATION_MACRO, + WHERE(DIMENSION_TAG_DIM2) + WHERE(MEDIUM_TAG_ELASTIC, + MEDIUM_TAG_ACOUSTIC)) + +#undef INSTANTIATION_MACRO diff --git a/src/mesh/mpi_interfaces/mpi_interfaces.cpp b/src/mesh/mpi_interfaces/mpi_interfaces.cpp deleted file mode 100644 index dd6c25dde..000000000 --- a/src/mesh/mpi_interfaces/mpi_interfaces.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "mesh/mpi_interfaces/mpi_interfaces.hpp" -#include "IO/fortranio/interface.hpp" -#include "kokkos_abstractions.h" -#include "specfem_mpi/interface.hpp" -#include - -specfem::mesh::interfaces::interface::interface(const int ninterfaces, - const int max_interface_size) { - - this->ninterfaces = ninterfaces; - this->max_interface_size = max_interface_size; - -#ifdef MPI_PARALLEL - if (ninterfaces > 0) { - this->my_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_neighbors", ninterfaces); - this->my_nelmnts_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_nelmnts_neighbors", ninterfaces); - this->my_interfaces = specfem::kokkos::HostView3d( - "specfem::mesh::interfaces::my_interfaces", ninterfaces, - max_interface_size, 4); - - // initialize values - for (int i = 0; i < ninterfaces; i++) { - this->my_neighbors(i) = -1; - this->my_nelmnts_neighbors(i) = 0; - for (int j = 0; j < max_interface_size; j++) { - for (int k = 0; k < 4; k++) { - this->my_interfaces(i, j, k) = -1; - } - } - } - } else { - this->my_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_neighbors", 1); - this->my_nelmnts_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_nelmnts_neighbors", 1); - this->my_interfaces = specfem::kokkos::HostView3d( - "specfem::mesh::interfaces::my_interfaces", 1, 1, 1); - - // initialize values - this->my_neighbors(1) = -1; - this->my_nelmnts_neighbors(1) = 0; - this->my_interfaces(1, 1, 1) = -1; - } -#else - if (ninterfaces > 0) - throw std::runtime_error("Found interfaces but SPECFEM compiled without " - "MPI. Compile SPECFEM with MPI"); - this->my_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_neighbors", 1); - this->my_nelmnts_neighbors = specfem::kokkos::HostView1d( - "specfem::mesh::interfaces::my_nelmnts_neighbors", 1); - this->my_interfaces = specfem::kokkos::HostView3d( - "specfem::mesh::interfaces::my_interfaces", 1, 1, 1); - - // initialize values - this->my_neighbors(1) = -1; - this->my_nelmnts_neighbors(1) = 0; - this->my_interfaces(1, 1, 1) = -1; -#endif - - return; -} - -specfem::mesh::interfaces::interface::interface(std::ifstream &stream, - const specfem::MPI::MPI *mpi) { - - // read number of interfaces - // Where these 2 values are written needs to change in new database format - int ninterfaces, max_interface_size; - specfem::IO::fortran_read_line(stream, &ninterfaces, &max_interface_size); - - // mpi->cout("Number of interaces = " + std::to_string(ninterfaces)); - - // allocate interface variables - *this = specfem::mesh::interfaces::interface(ninterfaces, max_interface_size); - - // note: for serial simulations, ninterface will be zero. - // thus no further reading will be done below - - // reads in interfaces -#ifdef MPI_PARALLEL - - std::cout << "Compiling with MPI" << std::endl; - for (int num_interface = 0; num_interface < this->ninterfaces; - num_interface++) { - // format: #process_interface_id #number_of_elements_on_interface - // where - // process_interface_id = rank of (neighbor) process to share MPI - // interface with number_of_elements_on_interface = number of interface - // elements - specfem::IO::fortran_read_line(stream, &this->my_neighbors(num_interface), - &this->my_nelmnts_neighbors(num_interface)); - // loops over interface elements - for (int ie = 0; ie < this->my_nelmnts_neighbors(num_interface); ie++) { - // format: #(1)spectral_element_id #(2)interface_type #(3)node_id1 - // #(4)node_id2 - - // interface types: - // 1 - corner point only - // 2 - element edge - specfem::IO::fortran_read_line( - stream, &this->my_interfaces(num_interface, ie, 0), - &this->my_interfaces(num_interface, ie, 1), - &this->my_interfaces(num_interface, ie, 2), - &this->my_interfaces(num_interface, ie, 3)); - } - } -#endif - - return; -} diff --git a/src/parameter_parser/solver/solver.cpp b/src/parameter_parser/solver/solver.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/parameter_parser/time_scheme/solver.cpp b/src/parameter_parser/time_scheme/solver.cpp deleted file mode 100644 index 432b86d60..000000000 --- a/src/parameter_parser/time_scheme/solver.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "parameter_parser/interface.hpp" -#include "timescheme/interface.hpp" -#include "yaml-cpp/yaml.h" - -std::shared_ptr -specfem::runtime_configuration::solver::solver::instantiate( - const int nstep_between_samples) { - std::shared_ptr it; - - throw std::runtime_error( - "Could not instantiate solver : Error reading parameter file"); - - return it; -}; diff --git a/src/plotter/plot_wavefield.cpp b/src/plotter/plot_wavefield.cpp index 465b014d6..0c2cbf7ff 100644 --- a/src/plotter/plot_wavefield.cpp +++ b/src/plotter/plot_wavefield.cpp @@ -74,7 +74,7 @@ double sigmoid(double x) { return (1 / (1 + std::exp(-100 * x)) - 0.5) * 1.5; } vtkSmartPointer map_materials_with_color(const specfem::compute::assembly &assembly) { - const auto &properties = assembly.properties; + const auto &element_types = assembly.element_types; const std::unordered_map > material_colors = { @@ -114,7 +114,7 @@ map_materials_with_color(const specfem::compute::assembly &assembly) { } cells->InsertNextCell(quad); - const auto material = properties.h_medium_tags(icell); + const auto material = element_types.get_medium_tag(icell); const auto color = material_colors.at(material); unsigned char color_uc[3] = { static_cast(color[0]), static_cast(color[1]), diff --git a/src/point/boundaries.cpp b/src/point/boundaries.cpp deleted file mode 100644 index e9048f943..000000000 --- a/src/point/boundaries.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "enumerations/specfem_enums.hpp" -#include "macros.hpp" -#include "point/boundary.hpp" - -void specfem::point::boundary::update_boundary( - const specfem::enums::boundaries::type &type, - const specfem::element::boundary_tag &tag) { - if (type == specfem::enums::boundaries::type::TOP) { - top = tag; - } else if (type == specfem::enums::boundaries::type::BOTTOM) { - bottom = tag; - } else if (type == specfem::enums::boundaries::type::LEFT) { - left = tag; - } else if (type == specfem::enums::boundaries::type::RIGHT) { - right = tag; - } else if (type == specfem::enums::boundaries::type::BOTTOM_RIGHT) { - bottom_right = tag; - } else if (type == specfem::enums::boundaries::type::BOTTOM_LEFT) { - bottom_left = tag; - } else if (type == specfem::enums::boundaries::type::TOP_RIGHT) { - top_right = tag; - } else if (type == specfem::enums::boundaries::type::TOP_LEFT) { - top_left = tag; - } else { - ASSERT(false, "Error: Unknown boundary type"); - } -} - -KOKKOS_FUNCTION -bool specfem::point::is_on_boundary(const specfem::element::boundary_tag &tag, - const specfem::point::boundary &type, - const int &iz, const int &ix, - const int &ngllz, const int &ngllx) { - - return (type.top == tag && iz == ngllz - 1) || - (type.bottom == tag && iz == 0) || (type.left == tag && ix == 0) || - (type.right == tag && ix == ngllx - 1) || - (type.bottom_right == tag && iz == 0 && ix == ngllx - 1) || - (type.bottom_left == tag && iz == 0 && ix == 0) || - (type.top_right == tag && iz == ngllz - 1 && ix == ngllx - 1) || - (type.top_left == tag && iz == ngllz - 1 && ix == 0); -} diff --git a/src/solver/time_marching.cpp b/src/solver/time_marching.cpp index 2f8315363..76f33b82d 100644 --- a/src/solver/time_marching.cpp +++ b/src/solver/time_marching.cpp @@ -1,24 +1,18 @@ #include "solver/time_marching.hpp" #include "enumerations/dimension.hpp" -#include "enumerations/quadrature.hpp" #include "enumerations/simulation.hpp" #include "solver/time_marching.tpp" -namespace { -using qp5 = specfem::enums::element::quadrature::static_quadrature_points<5>; -using qp8 = specfem::enums::element::quadrature::static_quadrature_points<8>; -} // namespace - // Explcit template instantiation template class specfem::solver::time_marching< - specfem::simulation::type::forward, specfem::dimension::type::dim2, qp5>; + specfem::simulation::type::forward, specfem::dimension::type::dim2, 5>; template class specfem::solver::time_marching< - specfem::simulation::type::forward, specfem::dimension::type::dim2, qp8>; + specfem::simulation::type::forward, specfem::dimension::type::dim2, 8>; template class specfem::solver::time_marching< - specfem::simulation::type::combined, specfem::dimension::type::dim2, qp5>; + specfem::simulation::type::combined, specfem::dimension::type::dim2, 5>; template class specfem::solver::time_marching< - specfem::simulation::type::combined, specfem::dimension::type::dim2, qp8>; + specfem::simulation::type::combined, specfem::dimension::type::dim2, 8>; diff --git a/src/source/adjoint_source.cpp b/src/source/adjoint_source.cpp index cf4c8c082..a46a83a23 100644 --- a/src/source/adjoint_source.cpp +++ b/src/source/adjoint_source.cpp @@ -5,7 +5,7 @@ void specfem::sources::adjoint_source::compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) { specfem::point::global_coordinates coord( @@ -16,7 +16,7 @@ void specfem::sources::adjoint_source::compute_source_array( const auto gamma = mesh.quadratures.gll.h_xi; const auto N = mesh.quadratures.gll.N; - const auto el_type = properties.h_medium_tags(lcoord.ispec); + const auto el_type = element_types.get_medium_tag(lcoord.ispec); const int ncomponents = source_array.extent(0); // Compute lagrange interpolants at the source location diff --git a/src/source/external.cpp b/src/source/external.cpp index 87c5c7a70..bcf6131a4 100644 --- a/src/source/external.cpp +++ b/src/source/external.cpp @@ -18,7 +18,7 @@ void specfem::sources::external::compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) { specfem::point::global_coordinates coord( @@ -29,7 +29,7 @@ void specfem::sources::external::compute_source_array( const auto gamma = mesh.quadratures.gll.h_xi; const auto N = mesh.quadratures.gll.N; - const auto el_type = properties.h_medium_tags(lcoord.ispec); + const auto el_type = element_types.get_medium_tag(lcoord.ispec); const int ncomponents = source_array.extent(0); // Compute lagrange interpolants at the source location diff --git a/src/source/force_source.cpp b/src/source/force_source.cpp index 059c29486..150f26f9d 100644 --- a/src/source/force_source.cpp +++ b/src/source/force_source.cpp @@ -1,7 +1,7 @@ #include "algorithms/locate_point.hpp" #include "compute/compute_mesh.hpp" #include "compute/compute_partial_derivatives.hpp" -#include "compute/properties/properties.hpp" +#include "compute/element_types/element_types.hpp" #include "enumerations/specfem_enums.hpp" #include "globals.h" #include "kokkos_abstractions.h" @@ -18,7 +18,7 @@ void specfem::sources::force::compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) { specfem::point::global_coordinates coord( @@ -29,7 +29,7 @@ void specfem::sources::force::compute_source_array( const auto gamma = mesh.quadratures.gll.h_xi; const auto N = mesh.quadratures.gll.N; - const auto el_type = properties.h_medium_tags(lcoord.ispec); + const auto el_type = element_types.get_medium_tag(lcoord.ispec); const int ncomponents = source_array.extent(0); // Compute lagrange interpolants at the source location diff --git a/src/source/moment_tensor_source.cpp b/src/source/moment_tensor_source.cpp index 0c276f3ce..1b8e79ac7 100644 --- a/src/source/moment_tensor_source.cpp +++ b/src/source/moment_tensor_source.cpp @@ -19,14 +19,14 @@ void specfem::sources::moment_tensor::compute_source_array( const specfem::compute::mesh &mesh, const specfem::compute::partial_derivatives &partial_derivatives, - const specfem::compute::properties &properties, + const specfem::compute::element_types &element_types, specfem::kokkos::HostView3d source_array) { specfem::point::global_coordinates coord( this->x, this->z); auto lcoord = specfem::algorithms::locate_point(coord, mesh); - const auto el_type = properties.h_medium_tags(lcoord.ispec); + const auto el_type = element_types.get_medium_tag(lcoord.ispec); if (el_type == specfem::element::medium_tag::acoustic) { throw std::runtime_error( diff --git a/src/source/utilities.cpp b/src/source/utilities.cpp deleted file mode 100644 index 17db1ee31..000000000 --- a/src/source/utilities.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "kokkos_abstractions.h" -#include "source_time_function/interface.hpp" - -KOKKOS_INLINE_FUNCTION -specfem::forcing_function::stf *assign_stf(std::string forcing_type, - type_real f0, type_real tshift, - type_real factor, type_real dt, - bool use_trick_for_better_pressure) { - - specfem::forcing_function::stf *forcing_function; - if (forcing_type == "Dirac") { - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::Dirac)); - - f0 = 1.0 / (10.0 * dt); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::Dirac( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - } else if (forcing_type == "Ricker") { - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::Ricker)); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::Ricker( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - } else if (forcing_type == "dGaussian") { - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::dGaussian)); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::dGaussian( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - } else { - assert(false && "Unknown forcing type"); - } - - return forcing_function; -} - -KOKKOS_INLINE_FUNCTION -specfem::forcing_function::stf * -assign_dirac(YAML::Node &Dirac, type_real dt, - bool use_trick_for_better_pressure) { - - specfem::forcing_function::stf *forcing_function; - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::Dirac)); - - type_real f0 = 1.0 / (10.0 * dt); - type_real tshift = Dirac["tshift"].as(); - type_real factor = Dirac["factor"].as(); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::Dirac( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - - return forcing_function; -} - -KOKKOS_INLINE_FUNCTION -specfem::forcing_function::stf * -assign_ricker(YAML::Node &Ricker, type_real dt, - bool use_trick_for_better_pressure) { - - specfem::forcing_function::stf *forcing_function; - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::Ricker)); - - type_real f0 = Ricker["f0"].as(); - type_real tshift = Ricker["tshift"].as(); - type_real factor = Ricker["factor"].as(); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::Ricker( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - - return forcing_function; -} - -KOKKOS_INLINE_FUNCTION -specfem::forcing_function::stf * -assign_gaussian_der(YAML::Node &dGaussian, type_real dt, - bool use_trick_for_better_pressure) { - - specfem::forcing_function::stf *forcing_function; - forcing_function = (specfem::forcing_function::stf *) - Kokkos::kokkos_malloc( - sizeof(specfem::forcing_function::dGaussian)); - - type_real f0 = dGaussian["f0"].as(); - type_real tshift = dGaussian["tshift"].as(); - type_real factor = dGaussian["factor"].as(); - - Kokkos::parallel_for( - "specfem::sources::moment_tensor::moment_tensor::allocate_stf", - specfem::kokkos::DeviceRange(0, 1), KOKKOS_LAMBDA(const int &) { - new (forcing_function) specfem::forcing_function::dGaussian( - f0, tshift, factor, use_trick_for_better_pressure); - }); - - Kokkos::fence(); - - return forcing_function; -} diff --git a/src/specfem2d.cpp b/src/specfem2d.cpp index 221031d20..f9076cdf2 100644 --- a/src/specfem2d.cpp +++ b/src/specfem2d.cpp @@ -220,9 +220,8 @@ void execute(const YAML::Node ¶meter_dict, const YAML::Node &default_dict, // -------------------------------------------------------------- // Instantiate Solver // -------------------------------------------------------------- - specfem::enums::element::quadrature::static_quadrature_points<5> qp5; std::shared_ptr solver = - setup.instantiate_solver(dt, assembly, time_scheme, qp5, plotters); + setup.instantiate_solver<5>(dt, assembly, time_scheme, plotters); // -------------------------------------------------------------- // -------------------------------------------------------------- diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index cc7bf07c0..ff4660bde 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -136,6 +136,43 @@ target_link_libraries( -lpthread -lm ) +# add_executable( +# compute_elastic_tests +# compute/elastic/compute_properties_tests.cpp +# ) + +# target_link_libraries( +# compute_elastic_tests +# mesh +# compute +# quadrature +# mpi_environment +# kokkos_environment +# yaml-cpp +# compare_arrays +# Boost::filesystem +# # material_class +# -lpthread -lm +# ) + +# add_executable( +# compute_acoustic_tests +# compute/acoustic/compute_properties_tests.cpp +# ) + +# target_link_libraries( +# compute_acoustic_tests +# mesh +# compute +# quadrature +# mpi_environment +# kokkos_environment +# yaml-cpp +# compare_arrays +# # material_class +# -lpthread -lm +# ) + add_executable( compute_tests compute/index/compute_tests.cpp @@ -286,7 +323,6 @@ target_link_libraries( compare_arrays point algorithms - domain IO coupled_interface plotter @@ -314,7 +350,7 @@ target_link_libraries( edge algorithms coupled_interface - domain + kokkos_kernels solver plotter -lpthread -lm @@ -393,6 +429,8 @@ if (NOT MPI_PARALLEL) gtest_discover_tests(IO_tests) gtest_discover_tests(mesh_tests) gtest_discover_tests(compute_partial_derivatives_tests) + # gtest_discover_tests(compute_elastic_tests) + # # gtest_discover_tests(compute_acoustic_tests) # gtest_discover_tests(compute_coupled_interfaces_tests) gtest_discover_tests(compute_tests) gtest_discover_tests(assembly_tests) diff --git a/tests/unit-tests/assembly/compute_wavefield/compute_wavefield.cpp b/tests/unit-tests/assembly/compute_wavefield/compute_wavefield.cpp index 2f115dad8..f7928e18b 100644 --- a/tests/unit-tests/assembly/compute_wavefield/compute_wavefield.cpp +++ b/tests/unit-tests/assembly/compute_wavefield/compute_wavefield.cpp @@ -18,10 +18,10 @@ void test_element_wavefield( &wavefield, specfem::compute::assembly &assembly) { - const auto properties = assembly.properties; + const auto element_types = assembly.element_types; - const auto medium = properties.h_medium_tags(ispec); - const auto property = properties.h_property_tags(ispec); + const auto medium = element_types.get_medium_tag(ispec); + const auto property = element_types.get_property_tag(ispec); if ((medium == specfem::element::medium_tag::elastic) && (property == specfem::element::property_tag::isotropic)) { diff --git a/tests/unit-tests/assembly/compute_wavefield/generate_data.hpp b/tests/unit-tests/assembly/compute_wavefield/generate_data.hpp index ad302b7f6..a3a6d1255 100644 --- a/tests/unit-tests/assembly/compute_wavefield/generate_data.hpp +++ b/tests/unit-tests/assembly/compute_wavefield/generate_data.hpp @@ -21,7 +21,7 @@ void generate_data(specfem::compute::assembly &assembly, const int ngllz = assembly.mesh.ngllz; const auto elements = - assembly.properties.get_elements_on_host(medium, property); + assembly.element_types.get_elements_on_host(medium, property); constexpr int num_components = specfem::element::attributes -void check_to_value(const specfem::compute::kernels kernels, +void check_to_value(const specfem::compute::element_types &element_types, + const specfem::compute::kernels kernels, const IndexViewType &ispecs, const ValueViewType &values_to_store) { const int nspec = kernels.nspec; const int ngllx = kernels.ngllx; const int ngllz = kernels.ngllz; - std::vector elements; - - const auto medium_tags = kernels.h_medium_tags; - const auto property_tags = kernels.h_property_tags; - - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { - elements.push_back(ispec); - } - } + const auto elements = + element_types.get_elements_on_host(MediumTag, PropertyTag); constexpr int simd_size = specfem::datatype::simd::size(); @@ -266,8 +258,8 @@ void check_to_value(const specfem::compute::kernels kernels, for (int iz = 0; iz < ngllz; iz++) { for (int ix = 0; ix < ngllx; ix++) { const int ielement = ispecs(i); - const int n_simd_elements = (simd_size + ielement > elements.size()) - ? elements.size() - ielement + const int n_simd_elements = (simd_size + ielement > elements.extent(0)) + ? elements.extent(0) - ielement : simd_size; for (int j = 0; j < n_simd_elements; j++) { const auto point_kernel = get_point_kernel( @@ -336,27 +328,20 @@ void execute_store_or_add(specfem::compute::kernels &kernels, template -void check_store_and_add(specfem::compute::kernels &kernels) { +void check_store_and_add(specfem::compute::kernels &kernels, + const specfem::compute::element_types &element_types) { const int nspec = kernels.nspec; const int ngllx = kernels.ngllx; const int ngllz = kernels.ngllz; - std::vector elements; - - const auto medium_tags = kernels.h_medium_tags; - const auto property_tags = kernels.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { - elements.push_back(ispec); - } - } + const auto elements = + element_types.get_elements_on_host(MediumTag, PropertyTag); // Evaluate at N evenly spaced points constexpr int N = 20; - if (elements.size() < N) { + if (elements.extent(0) < N) { return; } @@ -366,15 +351,15 @@ void check_store_and_add(specfem::compute::kernels &kernels) { auto ispecs_h = Kokkos::create_mirror_view(ispecs); auto values_to_store_h = Kokkos::create_mirror_view(values_to_store); - const int element_size = elements.size(); + const int element_size = elements.extent(0); const int step = element_size / N; for (int i = 0; i < N; i++) { - ispecs_h(i) = elements[i * step]; + ispecs_h(i) = elements(i * step); values_to_store_h(i) = 10.5 + i; } - ispecs_h(N - 1) = elements[element_size - 5]; // check when simd is not full + ispecs_h(N - 1) = elements(element_size - 5); // check when simd is not full Kokkos::deep_copy(ispecs, ispecs_h); Kokkos::deep_copy(values_to_store, values_to_store_h); @@ -382,8 +367,8 @@ void check_store_and_add(specfem::compute::kernels &kernels) { execute_store_or_add( kernels, element_size, ispecs, values_to_store); - check_to_value(kernels, ispecs_h, - values_to_store_h); + check_to_value( + element_types, kernels, ispecs_h, values_to_store_h); execute_store_or_add( kernels, element_size, ispecs, values_to_store); @@ -392,32 +377,26 @@ void check_store_and_add(specfem::compute::kernels &kernels) { values_to_store_h(i) *= 2; } - check_to_value(kernels, ispecs_h, - values_to_store_h); + check_to_value( + element_types, kernels, ispecs_h, values_to_store_h); } template -void check_load_on_device(specfem::compute::kernels &kernels) { +void check_load_on_device( + specfem::compute::kernels &kernels, + const specfem::compute::element_types &element_types) { const int nspec = kernels.nspec; const int ngllx = kernels.ngllx; const int ngllz = kernels.ngllz; - std::vector elements; - - const auto medium_tags = kernels.h_medium_tags; - const auto property_tags = kernels.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { - elements.push_back(ispec); - } - } + const auto elements = + element_types.get_elements_on_host(MediumTag, PropertyTag); // Evaluate at N evenly spaced points constexpr int N = 20; - if (elements.size() < N) { + if (elements.extent(0) < N) { return; } @@ -430,15 +409,15 @@ void check_load_on_device(specfem::compute::kernels &kernels) { auto ispecs_h = Kokkos::create_mirror_view(ispecs); auto values_to_store_h = Kokkos::create_mirror_view(values_to_store); - const int element_size = elements.size(); + const int element_size = elements.extent(0); const int step = element_size / N; for (int i = 0; i < N; i++) { - ispecs_h(i) = elements[i * step]; + ispecs_h(i) = elements(i * step); values_to_store_h(i) = 2 * (10.5 + i); } - ispecs_h(N - 1) = elements[element_size - 5]; // check when simd is not full + ispecs_h(N - 1) = elements(element_size - 5); // check when simd is not full Kokkos::deep_copy(ispecs, ispecs_h); @@ -513,17 +492,18 @@ void check_load_on_device(specfem::compute::kernels &kernels) { void test_kernels(specfem::compute::assembly &assembly) { + const auto &element_types = assembly.element_types; auto &kernels = assembly.kernels; #define TEST_STORE_AND_ADD(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ check_store_and_add( \ - kernels); \ + kernels, element_types); \ check_load_on_device( \ - kernels); \ + kernels, element_types); \ check_store_and_add( \ - kernels); \ + kernels, element_types); \ check_load_on_device( \ - kernels); + kernels, element_types); CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( TEST_STORE_AND_ADD, diff --git a/tests/unit-tests/assembly/properties/properties.cpp b/tests/unit-tests/assembly/properties/properties.cpp index 0de250a1a..c047bb029 100644 --- a/tests/unit-tests/assembly/properties/properties.cpp +++ b/tests/unit-tests/assembly/properties/properties.cpp @@ -1,13 +1,13 @@ #include "../test_fixture/test_fixture.hpp" #include "IO/ASCII/ASCII.hpp" +#include "IO/property/reader.hpp" +#include "IO/property/writer.hpp" #include "datatypes/simd.hpp" #include "enumerations/dimension.hpp" #include "enumerations/material_definitions.hpp" #include "parallel_configuration/chunk_config.hpp" #include "policies/chunk.hpp" -#include "IO/property/reader.hpp" #include "specfem_setup.hpp" -#include "IO/property/writer.hpp" #include inline void error_message_header(std::ostringstream &message, @@ -237,8 +237,10 @@ get_point_property( } template -void check_eq(const typename specfem::datatype::simd::datatype &p1, - const typename specfem::datatype::simd::datatype &p2, const int &n_simd_elements) { +void check_eq( + const typename specfem::datatype::simd::datatype &p1, + const typename specfem::datatype::simd::datatype &p2, + const int &n_simd_elements) { if constexpr (using_simd) { for (int i = 0; i < n_simd_elements; i++) { if (p1[i] != p2[i]) { @@ -266,26 +268,46 @@ void check_eq(const typename specfem::datatype::simd::dat template -void check_point_properties(const specfem::point::properties &p1, const specfem::point::properties &p2, const int &n_simd_elements); - -template -void check_point_properties(const specfem::point::properties &p1, const specfem::point::properties &p2, const int &n_simd_elements) { +void check_point_properties( + const specfem::point::properties &p1, + const specfem::point::properties &p2, + const int &n_simd_elements); + +template +void check_point_properties( + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, + specfem::element::property_tag::isotropic, using_simd> &p1, + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, + specfem::element::property_tag::isotropic, using_simd> &p2, + const int &n_simd_elements) { check_eq(p1.rho, p2.rho, n_simd_elements); check_eq(p1.mu, p2.mu, n_simd_elements); check_eq(p1.lambdaplus2mu, p2.lambdaplus2mu, n_simd_elements); - check_eq(p1.lambda, p2.lambdaplus2mu - (static_cast::datatype>(2.0)) * p2.mu, n_simd_elements); - check_eq(p1.rho_vp, Kokkos::sqrt(p2.rho * p2.lambdaplus2mu), n_simd_elements); - check_eq(p1.rho_vs, Kokkos::sqrt(p2.rho * p2.mu), n_simd_elements); + check_eq(p1.lambda, + p2.lambdaplus2mu - + (static_cast::datatype>(2.0)) * + p2.mu, + n_simd_elements); + check_eq(p1.rho_vp, Kokkos::sqrt(p2.rho * p2.lambdaplus2mu), + n_simd_elements); + check_eq(p1.rho_vs, Kokkos::sqrt(p2.rho * p2.mu), + n_simd_elements); } -template -void check_point_properties(const specfem::point::properties &p1, const specfem::point::properties &p2, const int &n_simd_elements) { +template +void check_point_properties( + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, + specfem::element::property_tag::anisotropic, using_simd> &p1, + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, + specfem::element::property_tag::anisotropic, using_simd> &p2, + const int &n_simd_elements) { check_eq(p1.rho, p2.rho, n_simd_elements); check_eq(p1.c11, p2.c11, n_simd_elements); check_eq(p1.c13, p2.c13, n_simd_elements); @@ -293,26 +315,40 @@ void check_point_properties(const specfem::point::properties(p1.c33, p2.c33, n_simd_elements); check_eq(p1.c35, p2.c35, n_simd_elements); check_eq(p1.c55, p2.c55, n_simd_elements); - check_eq(p1.rho_vp, Kokkos::sqrt(p2.rho * p2.c33), n_simd_elements); - check_eq(p1.rho_vs, Kokkos::sqrt(p2.rho * p2.c55), n_simd_elements); + check_eq(p1.rho_vp, Kokkos::sqrt(p2.rho * p2.c33), + n_simd_elements); + check_eq(p1.rho_vs, Kokkos::sqrt(p2.rho * p2.c55), + n_simd_elements); } - -template -void check_point_properties(const specfem::point::properties &p1, const specfem::point::properties &p2, const int &n_simd_elements) { +template +void check_point_properties( + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, + specfem::element::property_tag::isotropic, using_simd> &p1, + const specfem::point::properties< + specfem::dimension::type::dim2, specfem::element::medium_tag::acoustic, + specfem::element::property_tag::isotropic, using_simd> &p2, + const int &n_simd_elements) { check_eq(p1.rho_inverse, p2.rho_inverse, n_simd_elements); check_eq(p1.kappa, p2.kappa, n_simd_elements); - check_eq(p1.kappa_inverse, (static_cast::datatype>(1.0)) / p2.kappa, n_simd_elements); - check_eq(p1.rho_vpinverse, Kokkos::sqrt(p2.rho_inverse * p2.kappa_inverse), n_simd_elements); + check_eq( + p1.kappa_inverse, + (static_cast< + typename specfem::datatype::simd::datatype>( + 1.0)) / + p2.kappa, + n_simd_elements); + check_eq(p1.rho_vpinverse, + Kokkos::sqrt(p2.rho_inverse * p2.kappa_inverse), + n_simd_elements); } - template void check_to_value(const specfem::compute::properties properties, + specfem::compute::element_types element_types, const IndexViewType &ispecs, const ValueViewType &values_to_store) { const int nspec = properties.nspec; @@ -321,12 +357,9 @@ void check_to_value(const specfem::compute::properties properties, std::vector elements; - const auto medium_tags = properties.h_medium_tags; - const auto property_tags = properties.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { + if ((element_types.get_medium_tag(ispec) == MediumTag) && + (element_types.get_property_tag(ispec) == PropertyTag)) { elements.push_back(ispec); } } @@ -371,18 +404,16 @@ void check_compute_to_mesh( const auto &properties = assembly.properties; const auto &mapping = assembly.mesh.mapping; const auto &materials = mesh.materials; + const auto &element_types = assembly.element_types; const int nspec = properties.nspec; const int ngllx = properties.ngllx; const int ngllz = properties.ngllz; std::vector elements; - const auto medium_tags = properties.h_medium_tags; - const auto property_tags = properties.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { + if ((element_types.get_medium_tag(ispec) == MediumTag) && + (element_types.get_property_tag(ispec) == PropertyTag)) { elements.push_back(ispec); } } @@ -432,19 +463,17 @@ void check_compute_to_mesh( template -void check_store_load_on_host(specfem::compute::properties &properties) { +void check_store_on_host(specfem::compute::properties &properties, + specfem::compute::element_types &element_types) { const int nspec = properties.nspec; const int ngllx = properties.ngllx; const int ngllz = properties.ngllz; std::vector elements; - const auto medium_tags = properties.h_medium_tags; - const auto property_tags = properties.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { + if ((element_types.get_medium_tag(ispec) == MediumTag) && + (element_types.get_property_tag(ispec) == PropertyTag)) { elements.push_back(ispec); } } @@ -490,30 +519,29 @@ void check_store_load_on_host(specfem::compute::properties &properties) { PointType point_loaded; specfem::compute::store_on_host(index, properties, point); specfem::compute::load_on_host(index, properties, point_loaded); - check_point_properties(point, point_loaded, n_simd_elements); + check_point_properties(point, point_loaded, + n_simd_elements); } } } - check_to_value(properties, ispecs_h, - values_to_store_h); + check_to_value( + properties, element_types, ispecs_h, values_to_store_h); properties.copy_to_device(); } template -void check_load_on_device(specfem::compute::properties &properties) { +void check_load_on_device(specfem::compute::properties &properties, + specfem::compute::element_types &element_types) { const int nspec = properties.nspec; const int ngllx = properties.ngllx; const int ngllz = properties.ngllz; std::vector elements; - const auto medium_tags = properties.h_medium_tags; - const auto property_tags = properties.h_property_tags; - for (int ispec = 0; ispec < nspec; ispec++) { - if ((medium_tags(ispec) == MediumTag) && - (property_tags(ispec) == PropertyTag)) { + if ((element_types.get_medium_tag(ispec) == MediumTag) && + (element_types.get_property_tag(ispec) == PropertyTag)) { elements.push_back(ispec); } } @@ -622,6 +650,7 @@ void test_properties( const specfem::mesh::mesh &mesh) { auto &properties = assembly.properties; + auto &element_types = assembly.element_types; // stage 1: check if properties are correctly constructed from the assembly #define TEST_COMPUTE_TO_MESH(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ @@ -640,14 +669,14 @@ void test_properties( // stage 3: modify properties and check store_on_host and load_on_device #define TEST_STORE_AND_LOAD(DIMENSION_TAG, MEDIUM_TAG, PROPERTY_TAG) \ - check_store_load_on_host( \ - properties); \ + check_store_on_host( \ + properties, element_types); \ check_load_on_device( \ - properties); \ - check_store_load_on_host( \ - properties); \ + properties, element_types); \ + check_store_on_host( \ + properties, element_types); \ check_load_on_device( \ - properties); + properties, element_types); CALL_MACRO_FOR_ALL_MATERIAL_SYSTEMS( TEST_STORE_AND_LOAD, @@ -657,7 +686,8 @@ void test_properties( #undef TEST_STORE_AND_LOAD // stage 4: restore properties to initial value from disk - specfem::IO::property_reader > reader("."); + specfem::IO::property_reader > reader( + "."); reader.read(assembly); // stage 5: check if properties are correctly written and read diff --git a/tests/unit-tests/assembly/sources/sources.cpp b/tests/unit-tests/assembly/sources/sources.cpp index 596d130e5..441000fc7 100644 --- a/tests/unit-tests/assembly/sources/sources.cpp +++ b/tests/unit-tests/assembly/sources/sources.cpp @@ -10,6 +10,8 @@ template void check_store(specfem::compute::assembly &assembly) { @@ -17,8 +19,8 @@ void check_store(specfem::compute::assembly &assembly) { const int ngllz = assembly.mesh.ngllz; const int ngllx = assembly.mesh.ngllx; - const auto elements = - assembly.sources.get_elements_on_device(MediumTag, WavefieldType); + const auto elements = assembly.sources.get_elements_on_device( + MediumTag, PropertyTag, BoundaryTag, WavefieldType); const int nelements = elements.size(); @@ -32,10 +34,14 @@ void check_store(specfem::compute::assembly &assembly) { Kokkos::View values_to_store( "values_to_store", nelements); + const auto h_values_to_store = Kokkos::create_mirror_view(values_to_store); + for (int i = 0; i < nelements; i++) { - values_to_store(i) = 1.0 + i; + h_values_to_store(i) = 1.0 + i; } + Kokkos::deep_copy(values_to_store, h_values_to_store); + using PointType = specfem::point::source; Kokkos::parallel_for( @@ -52,8 +58,8 @@ void check_store(specfem::compute::assembly &assembly) { specfem::datatype::ScalarPointViewType lagrange_interpolant; for (int ic = 0; ic < num_components; ic++) { - stf(ic) = 1.0; - lagrange_interpolant(ic) = 1.0; + stf(ic) = values_to_store(i); + lagrange_interpolant(ic) = values_to_store(i); } PointType point(stf, lagrange_interpolant); specfem::compute::store_on_device(index, point, sources); @@ -64,6 +70,8 @@ void check_store(specfem::compute::assembly &assembly) { template void check_load(specfem::compute::assembly &assembly) { @@ -71,8 +79,8 @@ void check_load(specfem::compute::assembly &assembly) { const int ngllz = assembly.mesh.ngllz; const int ngllx = assembly.mesh.ngllx; - const auto elements = - sources.get_elements_on_device(MediumTag, WavefieldType); + const auto elements = sources.get_elements_on_device( + MediumTag, PropertyTag, BoundaryTag, WavefieldType); const int nelements = elements.size(); @@ -122,7 +130,7 @@ void check_load(specfem::compute::assembly &assembly) { const auto &point_kernel = h_point_sources(iz, ix, i); for (int ic = 0; ic < num_components; ic++) { const auto stf = point_kernel.stf(ic); - const auto expected = values_to_store(i); + const auto expected = h_values_to_store(i); if (expected != stf) { std::ostringstream message; message << "Error in source computation: \n" @@ -176,7 +184,7 @@ void check_assembly_source_construction( const auto lcoord = specfem::algorithms::locate_point(coord, assembly.mesh); - if (assembly.properties.h_medium_tags(lcoord.ispec) != MediumTag) { + if (assembly.element_types.get_medium_tag(lcoord.ispec) != MediumTag) { continue; } @@ -184,9 +192,9 @@ void check_assembly_source_construction( "source_array", components, assembly.mesh.ngllz, assembly.mesh.ngllx); source->compute_source_array(assembly.mesh, assembly.partial_derivatives, - assembly.properties, source_array); - Kokkos::View stf("stf", 1, - components); + assembly.element_types, source_array); + Kokkos::View stf( + "stf", 1, components); source->compute_source_time_function(1.0, 0.0, 1, stf); @@ -194,7 +202,7 @@ void check_assembly_source_construction( for (int ix = 0; ix < ngllx; ix++) { specfem::point::index index(lcoord.ispec, iz, ix); PointSourceType point; - specfem::compute::load_on_device(index, assembly.sources, point); + specfem::compute::load_on_host(index, assembly.sources, point); for (int ic = 0; ic < components; ic++) { const auto lagrange_interpolant = point.lagrange_interpolant(ic); @@ -249,15 +257,20 @@ void test_assembly_source_construction( void test_sources(specfem::compute::assembly &assembly) { -#define TEST_STORE_LOAD(Dimension, MediumTag) \ - check_store(assembly); \ - check_load(assembly); + check_store(assembly); - CALL_MACRO_FOR_ALL_MEDIUM_TAGS( + CALL_MACRO_FOR_ALL_ELEMENT_TYPES( TEST_STORE_LOAD, - WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC)) + WHERE(DIMENSION_TAG_DIM2) WHERE(MEDIUM_TAG_ELASTIC, MEDIUM_TAG_ACOUSTIC) + WHERE(PROPERTY_TAG_ISOTROPIC, PROPERTY_TAG_ANISOTROPIC) WHERE( + BOUNDARY_TAG_NONE, BOUNDARY_TAG_ACOUSTIC_FREE_SURFACE, + BOUNDARY_TAG_STACEY, BOUNDARY_TAG_COMPOSITE_STACEY_DIRICHLET)) #undef TEST_STORE_LOAD } diff --git a/tests/unit-tests/displacement_tests/Newmark/newmark_tests.cpp b/tests/unit-tests/displacement_tests/Newmark/newmark_tests.cpp index 91ea419d8..4b1ba11fa 100644 --- a/tests/unit-tests/displacement_tests/Newmark/newmark_tests.cpp +++ b/tests/unit-tests/displacement_tests/Newmark/newmark_tests.cpp @@ -5,7 +5,6 @@ #include "IO/seismogram/reader.hpp" #include "compute/interface.hpp" #include "constants.hpp" -#include "domain/domain.hpp" #include "mesh/mesh.hpp" #include "parameter_parser/interface.hpp" #include "quadrature/interface.hpp" @@ -233,9 +232,8 @@ TEST(DISPLACEMENT_TESTS, newmark_scheme_tests) { if (mpi->main_proc()) std::cout << *it << std::endl; - specfem::enums::element::quadrature::static_quadrature_points<5> qp5; std::shared_ptr solver = - setup.instantiate_solver(setup.get_dt(), assembly, it, qp5, {}); + setup.instantiate_solver<5>(setup.get_dt(), assembly, it, {}); solver->run(); diff --git a/tests/unit-tests/domain/rmass_inverse_tests.cpp b/tests/unit-tests/domain/rmass_inverse_tests.cpp index 6125f6c10..4ad3cf85d 100644 --- a/tests/unit-tests/domain/rmass_inverse_tests.cpp +++ b/tests/unit-tests/domain/rmass_inverse_tests.cpp @@ -4,7 +4,7 @@ #include "IO/interface.hpp" #include "compute/interface.hpp" #include "constants.hpp" -#include "domain/domain.hpp" +#include "kokkos_kernels/domain_kernels.hpp" #include "mesh/mesh.hpp" #include "parameter_parser/interface.hpp" #include "quadrature/interface.hpp" @@ -133,25 +133,14 @@ TEST(DOMAIN_TESTS, rmass_inverse) { try { - specfem::enums::element::quadrature::static_quadrature_points<5> qp5; - const type_real dt = setup.get_dt(); - specfem::domain::domain< - specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, specfem::element::medium_tag::elastic, - specfem::enums::element::quadrature::static_quadrature_points<5> > - elastic_domain_static(dt, assembly, qp5); - - specfem::domain::domain< + specfem::kokkos_kernels::domain_kernels< specfem::wavefield::simulation_field::forward, - specfem::dimension::type::dim2, - specfem::element::medium_tag::acoustic, - specfem::enums::element::quadrature::static_quadrature_points<5> > - acoustic_domain_static(dt, assembly, qp5); + specfem::dimension::type::dim2, 5> + kernels(assembly); - elastic_domain_static.invert_mass_matrix(); - acoustic_domain_static.invert_mass_matrix(); + kernels.initialize(dt); Kokkos::deep_copy(assembly.fields.forward.elastic.h_mass_inverse, assembly.fields.forward.elastic.mass_inverse); @@ -194,7 +183,7 @@ TEST(DOMAIN_TESTS, rmass_inverse) { ispec, iz, ix); const int ispec_mesh = assembly.mesh.mapping.compute_to_mesh(ispec); - if (assembly.properties.h_medium_tags(ispec) == + if (assembly.element_types.get_medium_tag(ispec) == specfem::element::medium_tag::elastic) { constexpr int components = 2; @@ -254,7 +243,7 @@ TEST(DOMAIN_TESTS, rmass_inverse) { ispec, iz, ix); const int ispec_mesh = assembly.mesh.mapping.compute_to_mesh(ispec); - if (assembly.properties.h_medium_tags(ispec) == + if (assembly.element_types.get_medium_tag(ispec) == specfem::element::medium_tag::acoustic) { constexpr int components = 1;