79int main(
int argc,
char *argv[]) {
86 auto opt = [&input](
const char *f,
const std::string &fb) {
90 const std::string model = opt(
"-model",
"PDState");
91 const size_t dim = std::stoul(opt(
"-dim",
"2"));
92 const bool plane_strain = std::stoi(opt(
"-planeStrain",
"0")) != 0;
93 const int influence = std::stoi(opt(
"-influence",
"0"));
94 const double m_ratio = std::stod(opt(
"-m",
"4"));
95 const double h = std::stod(opt(
"-h", dim == 2 ?
"0.02" :
"0.05"));
96 const double tol = std::stod(opt(
"-tol",
"0.02"));
97 const double L = std::stod(opt(
"-L",
"1.0")), horizon = m_ratio * h;
98 const double E = 1.0e5, Gc = 10.;
100 double nu = std::stod(opt(
"-nu",
"0.3"));
101 if (model !=
"PDState")
102 nu = (dim == 2 && !plane_strain) ? 1. / 3. : 0.25;
104 const double mu = E / (2. * (1. + nu));
105 const double lambda = (dim == 2 && !plane_strain)
106 ? E * nu / (1. - nu * nu)
107 : E * nu / ((1. + nu) * (1. - 2. * nu));
109 namespace fs = std::filesystem;
110 struct Check { std::string name;
double got, want; };
113 auto runChecks = [&](
const std::string &mname) {
114 const fs::path out = fs::current_path() /
115 std::format(
"calib_{}_{}d_{}_J{}", mname, dim,
116 plane_strain ?
"pstrain" :
"pstress", influence);
117 fs::create_directories(out);
118 auto deck = std::make_shared<inp::Input>(
119 makeDeck(mname, dim, plane_strain, influence, L, h, horizon, E, nu, Gc,
120 out.string() +
"/"));
126 auto inside = [&](
const util::Point &x,
double margin) {
127 const double c = 0.5 * L - margin - 1.5 * h;
128 return std::abs(x.
d_x) < c && std::abs(x.
d_y) < c &&
129 (dim == 2 || std::abs(x.
d_z) < c);
136 for (
size_t i = 0; i < dem.
d_xRef.size(); i++) {
141 double e = 0., fx = 0., fy = 0.;
142 size_t ne = 0, nf = 0;
143 for (
size_t i = 0; i < dem.
d_xRef.size(); i++) {
144 if (inside(dem.
d_xRef[i], horizon)) {
148 if (inside(dem.
d_xRef[i], 2. * horizon)) {
149 fx += dem.
d_f[i].d_x;
150 fy += dem.
d_f[i].d_y;
154 return std::array<double, 3>{e / ne, fx / nf, fy / nf};
157 const double eps = 1.0e-5, a = 1.0e-5 / L;
158 std::vector<Check> checks;
163 checks.push_back({
"energy uniaxial strain", r[0],
164 0.5 * (lambda + 2. * mu) * eps * eps});
167 checks.push_back({
"energy equibiaxial", r[0],
168 (mu * dim + 0.5 * lambda * dim * dim) * eps * eps});
171 checks.push_back({
"energy shear", r[0], 2. * mu * eps * eps});
176 checks.push_back({
"force (lambda+2mu)", r[1], (lambda + 2. * mu) * a});
179 checks.push_back({
"force mu", r[2], mu * a});
182 "CALIB model={} dim={} {} J={} delta/h={} nodes={} E={} nu={:.4f}\n",
183 mname, dim, plane_strain ?
"plane_strain" :
"plane_stress", influence,
184 m_ratio, dem.
d_xRef.size(), E, nu));
190 std::vector<Check> checks;
192 checks = runChecks(model);
194 const auto ref = runChecks(input.
getCmdOption(
"-compareModel"));
195 for (
size_t k = 0; k < checks.size(); k++)
196 checks[k].want = ref[k].got;
198 }
catch (
const std::exception &e) {
206 for (
const auto &c : checks) {
207 const double rel = (c.got - c.want) / c.want;
208 const bool pass = std::abs(rel) <= tol;
210 util::io::print(std::format(
" {:<24} got={:+.15e} want={:+.6e} rel={:+.4f} {}\n",
211 c.name, c.got, c.want, rel, pass ?
"OK" :
"FAIL"));
int main(int argc, char *argv[])
json makeDeck(const std::string &model, size_t dim, bool plane_strain, int influence, double L, double h, double horizon, double E, double nu, double Gc, const std::string &out)
Collection of methods and data related to particle object.
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
static json getParticleContactExampleJson(size_t nSets=0)
Returns example JSON object for ModelDeck configuration.
static json getParticleMaterialExampleJson(size_t nSets=0)
Returns example JSON object for ModelDeck configuration.