16 inline T pow2(T
x) {
return x *
x; }
21 T reentrant_corner(T
x, T
y,
double omega)
23 const double alpha = M_PI / omega;
24 const T r = sqrt(
x *
x +
y *
y);
25 const T theta = atan2(
y,
x) + (
y < 0 ? 2.0 * M_PI : 0.0);
26 return pow(r, alpha) * sin(alpha * theta);
30 std::array<T, 2> linear_elasticity_mode_1(T
x, T
y,
double nu,
double E,
double lambda,
double Q)
32 const double kappa = 3.0 - 4.0 * nu;
33 const double G = E / (2.0 * (1.0 + nu));
34 const T r = sqrt(
x *
x +
y *
y);
35 const T theta = atan2(
y,
x) + (
y < 0 ? 2.0 * M_PI : 0.0);
37 1.0 / (2.0 * G) * pow(r, lambda) * ((kappa - Q * (lambda + 1)) * cos(lambda * theta) - lambda * cos((lambda - 2) * theta)),
38 1.0 / (2.0 * G) * pow(r, lambda) * ((kappa + Q * (lambda + 1)) * sin(lambda * theta) + lambda * sin((lambda - 2) * theta)),
43 std::array<T, 2> linear_elasticity_mode_2(T
x, T
y,
double nu,
double E,
double lambda,
double Q)
45 const double kappa = 3.0 - 4.0 * nu;
46 const double G = E / (2.0 * (1.0 + nu));
47 const T r = sqrt(
x *
x +
y *
y);
48 const T theta = atan2(
y,
x) + (
y < 0 ? 2.0 * M_PI : 0.0);
50 1.0 / (2.0 * G) * pow(r, lambda) * ((kappa - Q * (lambda + 1)) * sin(lambda * theta) - lambda * sin((lambda - 2) * theta)),
51 1.0 / (2.0 * G) * pow(r, lambda) * ((kappa + Q * (lambda + 1)) * cos(lambda * theta) + lambda * cos((lambda - 2) * theta)),
56 T peak(T
x, T
y,
double x_c,
double y_c,
double alpha)
58 return exp(-alpha * (pow2(
x - x_c) + pow2(
y - y_c)));
62 T boundary_line_singularity(T
x, T
y,
double alpha)
68 T wave_front(T
x, T
y,
double x_c,
double y_c,
double r_0,
double alpha)
70 const T r = sqrt(pow2(
x - x_c) + pow2(
y - y_c));
71 return atan2(alpha * (r - r_0),
T(1.0));
75 T interior_line_singularity(T
x, T
y,
double alpha,
double beta)
77 if (
x <= beta * (
y + 1))
79 return cos(M_PI *
y / 2);
83 return cos(M_PI *
y / 2) + pow(
x - beta * (
y + 1), alpha);
88 T multiple_difficulties(T
x, T
y,
double omega,
double x_w,
double y_w,
double r_0,
double alpha_w,
89 double x_p,
double y_p,
double alpha_p,
double eps)
91 const T r = sqrt(
x *
x +
y *
y);
92 const T theta = atan2(
y,
x) + (
y < 0 ? 2.0 * M_PI : 0.0);
93 return pow(r, M_PI / omega) * sin(theta * M_PI / omega)
94 + atan2(alpha_w * (sqrt(pow2(
x - x_w) + pow2(
y - y_w)) - r_0),
T(1.0))
95 + exp(-alpha_p * (pow2(
x - x_p) + pow2(
y - y_p)))
96 + exp(-(1 +
y) / eps);
105#define PARAM(x) (params_[#x].get<double>())
113 {
"type",
"reentrant_corner"},
114 {
"omega", 7.0 * M_PI / 4.0},
115 {
"is_scalar",
true}};
118 template <
typename T>
122 if (
params_[
"type"] ==
"reentrant_corner")
124 res(0) = reentrant_corner(pt(0), pt(1),
PARAM(omega));
126 else if (
params_[
"type"] ==
"linear_elasticity_mode_1")
132 else if (
params_[
"type"] ==
"linear_elasticity_mode_2")
138 else if (
params_[
"type"] ==
"peak")
142 else if (
params_[
"type"] ==
"boundary_line_singularity")
144 res(0) = boundary_line_singularity(pt(0), pt(1),
PARAM(alpha));
146 else if (
params_[
"type"] ==
"wave_front")
150 else if (
params_[
"type"] ==
"interior_line_singularity")
152 res(0) = interior_line_singularity(pt(0), pt(1),
PARAM(alpha),
PARAM(beta));
154 else if (
params_[
"type"] ==
"multiple_difficulties")
156 res(0) = multiple_difficulties(pt(0), pt(1),
166 assert(!params.is_null());
T eval_impl(const T &pt) const
bool is_scalar() const override
TestProblem(const std::string &name)
void set_parameters(const json ¶ms) override