Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
benchmarkStress.cpp
Go to the documentation of this file.
1// Build with EllipsoidalInclusion.cpp, reference/SphericalInclusion.cpp,
2// and the MoDELib base (or tests/support headers). Use -O3 -DNDEBUG.
5#include <Eigen/Geometry>
6#include <algorithm>
7#include <chrono>
8#include <iomanip>
9#include <iostream>
10#include <random>
11#include <vector>
12
13using V = Eigen::Vector3d;
14using M = Eigen::Matrix3d;
16using Clock = std::chrono::steady_clock;
17volatile double benchmarkSink = 0.0;
18
19// Separate translation units and no LTO keep stress() calls out of the timing loop.
20double measure(const Base &inclusion, const std::vector<V> &points)
21{
22 const auto start = Clock::now();
23 double checksum = 0.0;
24 std::size_t calls = 0;
25 double seconds = 0.0;
26 do
27 {
28 for(const auto &point : points)
29 {
30 checksum += inclusion.stress(point).sum();
31 }
32 calls += points.size();
33 seconds = std::chrono::duration<double>(Clock::now() - start).count();
34 } while(seconds < 0.02);
35 benchmarkSink = checksum;
36 return seconds * 1.e9 / calls;
37}
38
39int main()
40{
41 M strain;
42 strain << 0.01, 0.003, -0.002, 0.003, -0.006, 0.001, -0.002, 0.001, 0.004;
43 const M Q = Eigen::AngleAxisd(0.71, V(1, 2, 3).normalized()).toRotationMatrix();
44 std::mt19937 rng(123);
45 std::normal_distribution<double> normal;
46 std::vector<V> directions;
47 for(int k = 0; k < 512; ++k)
48 {
49 const V direction(normal(rng), normal(rng), normal(rng));
50 directions.push_back(direction.normalized());
51 }
52 std::cout << "axes,region,sphere_ns,ellipsoid_ns,ratio,ellipsoid_min_ns,ellipsoid_max_ns\n";
53 for(const V &lengths : {V(1, 1, 1), V(3, 2, 1), V(10, 1, 0.1), V(100, 1, 1)})
54 {
55 // The spherical reference radius is the shortest semiaxis so every
56 // comparison uses the same interior/exterior branch at the same point.
57 model::SphericalInclusion<3> sphere(V::Zero(), lengths.minCoeff(), strain, 0.31, 43.0, 1.0, 0, nullptr);
58 model::EllipsoidalInclusion<3> ellipsoid(V::Zero(), Q * lengths.asDiagonal(), strain, 0.31, 43.0, 1.0, 0,
59 nullptr, 1.e-10);
60 for(const double radialFactor : {0.5, 1.000001, 2.0, 10.0})
61 {
62 std::vector<V> points;
63 for(const auto &direction : directions)
64 {
65 if(radialFactor < 1.0)
66 {
67 points.push_back(0.5 * lengths.minCoeff() * direction);
68 }
69 else
70 {
71 points.push_back(Q * (radialFactor * lengths.cwiseProduct(direction)));
72 }
73 }
74 measure(sphere, points);
75 measure(ellipsoid, points);
76 std::vector<double> sphereTimes, ellipsoidTimes;
77 for(int repeat = 0; repeat < 7; ++repeat)
78 {
79 if(repeat % 2 == 0)
80 {
81 sphereTimes.push_back(measure(sphere, points));
82 ellipsoidTimes.push_back(measure(ellipsoid, points));
83 }
84 else
85 {
86 ellipsoidTimes.push_back(measure(ellipsoid, points));
87 sphereTimes.push_back(measure(sphere, points));
88 }
89 }
90 std::sort(sphereTimes.begin(), sphereTimes.end());
91 std::sort(ellipsoidTimes.begin(), ellipsoidTimes.end());
92 const char *region = radialFactor < 1.0 ? "interior"
93 : radialFactor < 1.1 ? "near_surface"
94 : radialFactor < 3.0 ? "2x_surface"
95 : "10x_surface";
96 std::cout << lengths(0) << ':' << lengths(1) << ':' << lengths(2) << ',' << region << ',' << std::fixed
97 << std::setprecision(2) << sphereTimes[3] << ',' << ellipsoidTimes[3] << ','
98 << ellipsoidTimes[3] / sphereTimes[3] << ',' << ellipsoidTimes.front() << ','
99 << ellipsoidTimes.back() << std::endl;
100 }
101 }
102}
std::chrono::steady_clock Clock
Eigen::Matrix3d M
model::EshelbyInclusionBase< 3 > Base
double measure(const Base &inclusion, const std::vector< V > &points)
volatile double benchmarkSink
Eigen::Vector3d V
int main()
M sphere(const V &r, double a, const M &e, double n=nu, double m=mu)
Q
int k