52 const double trialTolerance =
argc > 1 ? std::stod(
argv[1]) : 1.e-4;
53 const M Q = Eigen::AngleAxisd(0.71,
V(1, 2, 3).normalized()).toRotationMatrix();
54 const std::vector<V> geometries = {
V(1, 1, 1),
V(3, 2, 1),
V(10, 1, 0.1),
V(100, 1, 1),
V(1, 1, 0.01)};
55 std::mt19937 rng(123);
56 std::normal_distribution<double> normal;
57 std::vector<V> directions;
58 for(
int k = 0;
k < 512; ++
k)
60 const V direction(normal(rng), normal(rng), normal(rng));
61 directions.push_back(direction.normalized());
64 mixed << 0.01, 0.003, -0.002, 0.003, -0.006, 0.001, -0.002, 0.001, 0.004;
65 std::cout <<
"SPEED\naxes,region,sphere_ns,baseline_1e10_ns,loose_ns,speedup,loose_over_sphere\n";
66 for(
const V &lengths : geometries)
73 for(
double factor : {0.5, 1.000001, 2.0, 10.0})
75 std::vector<V> points;
76 for(
const V &direction : directions)
80 points.push_back(0.5 * lengths.minCoeff() * direction);
84 points.push_back(
Q * (factor * lengths.cwiseProduct(direction)));
90 std::vector<double> st, ft, lt;
91 for(
int trial = 0; trial < 7; ++trial)
96 ft.push_back(
measure(fine, points));
97 lt.push_back(
measure(loose, points));
101 lt.push_back(
measure(loose, points));
102 ft.push_back(
measure(fine, points));
105 std::sort(st.begin(), st.end());
106 std::sort(ft.begin(), ft.end());
107 std::sort(lt.begin(), lt.end());
108 const char *region = factor < 1 ?
"interior"
109 : factor < 1.1 ?
"near_surface"
110 : factor < 3 ?
"2x_surface"
112 std::cout << lengths.transpose() <<
',' << region <<
',' << std::setprecision(8) << st[3] <<
',' << ft[3]
113 <<
',' << lt[3] <<
',' << ft[3] / lt[3] <<
',' << lt[3] / st[3] << std::endl;
117 <<
"ACCURACY\naxes,count,max_relative,p95_relative,baseline_1e10_max_relative,interior_max_relative,sphere_max_"
118 "relative,worst_factor,worst_nu,worst_mode\n";
119 for(
const V &lengths : geometries)
122 for(
double nu : {-0.8, 0.31, 0.49})
124 for(
int mode = 0; mode < 8; ++mode)
126 M strain = M::Zero();
129 strain(mode, mode) = 0.01;
133 const int i = mode == 5 ? 1 : 0;
134 const int j = mode == 3 ? 1 : 2;
135 strain(
i,
j) = strain(
j,
i) = 0.01;
139 strain = 0.01 * M::Identity();
150 nullptr, trialTolerance);
152 for(
double factor : {0.0, 1.0 + 1.e-12, 1.0 + 1.e-8, 1.001, 1.1, 2.0, 10.0, 1.e3, 1.e6})
154 const int samples = factor == 0 ? 1 : 32;
160 direction = V::Unit(
k);
164 direction = directions[
k];
166 const V point =
Q * (factor * lengths.cwiseProduct(direction));
167 const M reference = ref.
stress(point), approx = loose.
stress(point);
168 const double norm = std::max(1.e-300, reference.norm());
169 const double error = (approx - reference).norm() / norm;
170 const double defaultError = (fine.
stress(point) - reference).norm() / norm;
171 if(!std::isfinite(error) || !std::isfinite(defaultError))
173 throw std::runtime_error(
"Nonfinite accuracy metric");
181 if(errors.
loose.empty() ||
182 error > *std::max_element(errors.
loose.begin(), errors.
loose.end()))
188 errors.
loose.push_back(error);
191 if((lengths - V::Ones()).norm() == 0.0)
200 std::sort(errors.
loose.begin(), errors.
loose.end());
201 std::cout << lengths.transpose() <<
',' << errors.
loose.size() <<
',' << std::setprecision(12)
202 << errors.
loose.back() <<
','
203 << errors.
loose[
static_cast<std::size_t
>(0.95 * (errors.
loose.size() - 1))] <<
','