Skip to content

Commit a6fdc98

Browse files
authored
Merge pull request #1636 from PrincetonUniversity/issue-1595
Issue 1595 - Implement Modulus and scale_factor computation
2 parents 2b3bbd3 + 4f23f16 commit a6fdc98

File tree

7 files changed

+568
-1
lines changed

7 files changed

+568
-1
lines changed

core/specfem/attenuation.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "attenuation/maxwell.hpp"
55
#include "attenuation/compute_tau_eps.hpp"
66
#include "attenuation/compute_tau_eps.tpp"
7+
#include "attenuation/compute_factors.hpp"
8+
#include "attenuation/compute_factors.tpp"
79

810

911
/**
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#pragma once
2+
3+
#include "constants.hpp"
4+
#include "specfem_setup.hpp"
5+
#include <Kokkos_Core.hpp>
6+
7+
namespace specfem {
8+
namespace attenuation {
9+
10+
/**
11+
* @brief Attenuation property values for modulus calculations
12+
*
13+
* Stores coefficients for computing relaxed and unrelaxed moduli:
14+
* - @f$ \beta^{\text{defect}}_i = \tau_{\epsilon_i}/\tau_{\sigma_i} - 1 @f$
15+
* (modulus defect per mechanism)
16+
* - @f$ \text{OneMinusSumBeta} = \sum_i
17+
* \tau_{\epsilon_i}/\tau_{\sigma_i} @f$
18+
*
19+
* @tparam N_SLS Number of standard linear solids
20+
*/
21+
template <int N_SLS> struct AttenuationPropertyValues {
22+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace> beta;
23+
type_real one_minus_sum_beta;
24+
};
25+
26+
/**
27+
* @brief Compute attenuation property values from relaxation times
28+
*
29+
* Computes @f$ \beta^{\text{defect}}_i = \tau_{\epsilon_i}/\tau_{\sigma_i} - 1
30+
* @f$ and
31+
* @f$ \text{OneMinusSumBeta} = 1 - \sum_i \beta_i = \sum_{i=1}^{N\_SLS}
32+
* \tau_{\epsilon_i}/\tau_{\sigma_i} @f$ for each standard linear solid.
33+
*
34+
* @tparam N_SLS Number of standard linear solids
35+
* @param tau_s Stress relaxation times @f$ \tau_\sigma @f$
36+
* @param tau_eps Strain relaxation times @f$ \tau_\epsilon @f$
37+
* @return AttenuationPropertyValues containing @f$ \beta @f$ and
38+
* @f$ \text{one\_minus\_sum\_beta} @f$
39+
*/
40+
template <int N_SLS>
41+
AttenuationPropertyValues<N_SLS> get_attenuation_property_values(
42+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
43+
tau_s,
44+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
45+
tau_eps);
46+
47+
/**
48+
* @brief Compute physical dispersion scaling factor for attenuation
49+
*
50+
* Computes @f$ \Psi @f$ to scale @f$ \mu_0 @f$ to the unrelaxed modulus:
51+
* @f[
52+
* \Psi = \Psi_\mu \times \Psi_{\mu_0}
53+
* @f]
54+
* where:
55+
* - @f$ \Psi_{\mu_0} = 1 + \frac{2}{\pi Q} \ln(f_c / f_0) @f$ corrects for
56+
* logarithmic frequency dependence (Aki & Richards 1980, eq. 5.81)
57+
* - @f$ \Psi_\mu = \frac{\sum(1 + \beta_i/N_{\text{SLS}})}{\sum[1 + \beta_i/(1
58+
* + 1/(\omega\tau_{\sigma_i})^2)/N_{\text{SLS}}]} @f$ accounts for SLS
59+
* frequency dispersion
60+
*
61+
* @tparam N_SLS Number of standard linear solids
62+
* @param f_c_source Central frequency of the source @f$ f_c @f$ (Hz)
63+
* @param tau_eps Strain relaxation times @f$ \tau_\epsilon @f$
64+
* @param tau_sigma Stress relaxation times @f$ \tau_\sigma @f$
65+
* @param Q_val Target quality factor @f$ Q @f$
66+
* @param attenuation_f0_reference Reference frequency @f$ f_0 @f$ (Hz)
67+
* @return Scale factor @f$ \Psi @f$ (expected range [0.5, 1.5])
68+
* @throws std::runtime_error if @f$ \Psi @f$ is outside [0.5, 1.5]
69+
*/
70+
template <int N_SLS>
71+
type_real get_attenuation_scale_factor(
72+
type_real f_c_source,
73+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
74+
tau_eps,
75+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
76+
tau_sigma,
77+
type_real Q_val, type_real attenuation_f0_reference);
78+
79+
} // namespace attenuation
80+
} // namespace specfem
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
#include "compute_factors.hpp"
3+
#include "constants.hpp"
4+
#include "specfem_setup.hpp"
5+
#include <Kokkos_Core.hpp>
6+
#include <cmath>
7+
#include <sstream>
8+
#include <stdexcept>
9+
10+
namespace specfem {
11+
namespace attenuation {
12+
13+
template <int N_SLS>
14+
AttenuationPropertyValues<N_SLS> get_attenuation_property_values(
15+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
16+
tau_s,
17+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
18+
tau_eps) {
19+
20+
AttenuationPropertyValues<N_SLS> result;
21+
result.beta =
22+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>(
23+
"beta");
24+
25+
// See Komatitsch & Tromp 1999, eq. (7)
26+
// Coefficients beta = tau_eps / tau_s
27+
for (int i = 0; i < N_SLS; ++i) {
28+
result.beta(i) = tau_eps(i) / tau_s(i);
29+
}
30+
31+
// Sum of coefficients beta, then subtract 1 from each beta
32+
// to get the modulus defect
33+
result.one_minus_sum_beta = 0.0;
34+
for (int i = 0; i < N_SLS; ++i) {
35+
result.one_minus_sum_beta += result.beta(i);
36+
result.beta(i) -= 1.0;
37+
}
38+
39+
return result;
40+
}
41+
42+
template <int N_SLS>
43+
type_real get_attenuation_scale_factor(
44+
type_real f_c_source,
45+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
46+
tau_eps,
47+
Kokkos::View<type_real[N_SLS], Kokkos::LayoutRight, Kokkos::HostSpace>
48+
tau_sigma,
49+
type_real Q_val, type_real attenuation_f0_reference) {
50+
51+
// Quantity by which to scale mu_0 to get mu
52+
// See Liu et al. 1976; Aki & Richards 1980, eq. (5.81)
53+
const type_real factor_scale_mu0 =
54+
1.0 +
55+
2.0 * std::log(f_c_source / attenuation_f0_reference) / (pi * Q_val);
56+
57+
// Quantity by which to scale mu to get mu_unrelaxed
58+
type_real sum_unrelaxed = 1.0;
59+
type_real sum_weighted = 1.0;
60+
61+
for (int i = 0; i < N_SLS; ++i) {
62+
const type_real defect = tau_eps(i) / tau_sigma(i) - 1.0;
63+
sum_unrelaxed += defect / N_SLS;
64+
65+
const type_real omega_tau = 2.0 * pi * f_c_source * tau_sigma(i);
66+
sum_weighted +=
67+
defect / (1.0 + 1.0 / (omega_tau * omega_tau)) / N_SLS;
68+
}
69+
70+
const type_real factor_scale_mu = sum_unrelaxed / sum_weighted;
71+
72+
// Total factor by which to scale mu0 to get mu_unrelaxed
73+
const type_real scale_factor = factor_scale_mu * factor_scale_mu0;
74+
75+
// Check that the correction factor is close to one
76+
if (scale_factor < 0.5 || scale_factor > 1.5) {
77+
std::ostringstream msg;
78+
msg << "Error in get_attenuation_scale_factor(): "
79+
<< "scale factor = " << scale_factor
80+
<< " should be between 0.5 and 1.5. "
81+
<< "factor_scale_mu = " << factor_scale_mu
82+
<< ", factor_scale_mu0 = " << factor_scale_mu0
83+
<< ", Q = " << Q_val
84+
<< ", f_c_source = " << f_c_source
85+
<< ", attenuation_f0_reference = " << attenuation_f0_reference
86+
<< ". Please check your reference frequency.";
87+
throw std::runtime_error(msg.str());
88+
}
89+
90+
return scale_factor;
91+
}
92+
93+
} // namespace attenuation
94+
} // namespace specfem
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
``specfem::attenuation::compute_factors``
2+
=========================================
3+
4+
.. doxygenfunction:: specfem::attenuation::get_attenuation_property_values
5+
6+
.. doxygenfunction:: specfem::attenuation::get_attenuation_scale_factor
7+
8+
.. doxygenstruct:: specfem::attenuation::AttenuationPropertyValues

docs/sections/api/specfem/attenuation/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99

1010
tau_sigma.rst
1111
compute_tau_eps.rst
12+
compute_factors.rst
1213
maxwell.rst
13-
optimization.rst
14+
optimization.rst

tests/unit-tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ add_executable(
118118
attenuation/compute_tau_sigma_tests.cpp
119119
attenuation/maxwell_tests.cpp
120120
attenuation/compute_tau_eps_tests.cpp
121+
attenuation/compute_factors_tests.cpp
121122
)
122123

123124
target_link_libraries(

0 commit comments

Comments
 (0)