Alamo
PFCZM.H
Go to the documentation of this file.
1#ifndef MODEL_INTERFACE_CRACK_PFCZM_H
2#define MODEL_INTERFACE_CRACK_PFCZM_H
3
4#include <iostream>
5#include <fstream>
6#include <cmath>
7
8#include "AMReX.H"
9#include "Crack.H"
10#include "Set/Set.H"
11#include "Util/Util.H"
12
13namespace Model
14{
15namespace Interface
16{
17namespace Crack
18{
19class PFCZM : public Crack
20{
21public:
23
24 PFCZM() = default;
25 virtual ~PFCZM() = default;
26
27 // In Wu 2024 formulation, Gc is scaled by a constant C_alpha.
28 // $C_\alpha = 4 \int_0^1 \sqrt{\alpha(\beta)} d\beta$
29 // where $\alpha$ is the geometric function defined in the code as w_phi
30 // For the optimal function chosen in Wu 2024, $C_\alpha = \pi$
31 Set::Scalar Gc (Set::Scalar /*ratio*/) { return _Gc / _c_alpha; }
33 Set::Scalar l_w() { return _l_w; }
34
35 // this hould check if we need to do mixed mode loading.
36 bool mixed_mode() { return _mixed_mode; }
38
39 // added functions for mixed mode - Wang 2023 surface
42 Set::Scalar chi() { return _chi; }
44 Set::Scalar sig_t() { return _sig_t; }
45 Set::Scalar tau_s() { return _tau_s; }
46
47 // added functions for mixed mode - mohr columb surface
50
51 // For now, we are storing things like youngs modulus stuff here.
52 // ideally, they should be moved to Material -> Solid -> Affine.
53 Set::Scalar DGc (Set::Scalar /*theta*/) { return 0.0; }
54 Set::Scalar DDGc (Set::Scalar /*theta*/) { return 0.0; }
55 Set::Scalar Zeta(Set::Scalar /*theta*/) { return zeta; }
58
59private:
61 Set::Scalar _c_alpha = pi; // scaling factor.
62 Set::Scalar _l_w = 1.e-5; //irwing length
66
69
70 bool _mixed_mode = false;
72
75
76 // Parameters specific to WANG 2023 failure surface
82
83 // Parameters specific to MC failure surface
86
87public:
88 static void Parse(PFCZM & value, IO::ParmParse & pp)
89 {
90 pp.query_default("czm_order", value.czm_order, 1.0); //Order 1, 1.5, or 2 (Wu 2024, JMPS)
91 pp.query_default("G_c",value._Gc,1.0e3); // Fracture energy in N/m
92 pp.query_default("zeta",value.zeta,1.e-5); // Lengthscale regularization in m
93
94 Set::Scalar fracture_strength = NAN;
95
96 Set::Scalar youngs = NAN;
97 Set::Scalar nu = NAN;
98 Set::Scalar tensile_strength = 2.e8;
99 Set::Scalar shear_strength = 1.41e8;
100 Set::Scalar compressive_strength = NAN;
101
102 // Toggle to determine mixed mode
103 pp.query_default("mixed_mode", value._mixed_mode, false);
104
105 if (value._mixed_mode)
106 {
107 // Young's modulus
108 pp.query_default("E", youngs, 2.e11);
109
110 // Poisson's ratio $\nu$
111 pp.query_default("nu", nu, 0.3);
112
113 // shear modulus
114 Set::Scalar mu = 0.5 * youngs / (1. + nu);
115
116 std::string fail_surf_type = "";
117 // type of failure surface
118 pp.query_validate("failure_surface", fail_surf_type, {"wang2023", "mohr", "mc", "columb"}); // degradation function. For now, we only have linear softening
119 std::map<std::string,FSType> fs_map;
120 fs_map["wang2023"] = FSType::WANG2023;
121 fs_map["mohr"] = FSType::MC;
122 fs_map["mc"] = FSType::MC;
123 fs_map["columb"] = FSType::MC;
124 value._failure_surface = fs_map[fail_surf_type];
125
127 {
128 // Fracture strength
129 pp.query_default("fracture_strength", fracture_strength, 1.e6);
130
131 // $\chi$ value
132 pp.query_default("chi", value._chi, 1.0);
133
134 // Compressive strength
135 pp.query_default("compressive_strength", compressive_strength,4.e8);
136 value.k1 = ( value._chi < 1/std::sqrt(2) ) ? ( 2 * value._chi * std::sqrt(1.0 - value._chi*value._chi) ) : 1.0;
137
138 tensile_strength = fracture_strength / value.k1;
139 shear_strength = value._chi * tensile_strength;
140 value._beta_bar = (1.0 / (value._chi * value._chi)) - (compressive_strength * compressive_strength / (4.0 * value._chi * value._chi * shear_strength * shear_strength));
141
142 value._GcI_bar = value._Gc/(value.k1*value.k1);
143 value._GcII_bar = value._GcI_bar * youngs * value._chi * value._chi / mu ;
144 fracture_strength = tensile_strength * value.k1;
145
146 Util::Message(INFO, "Chi = ", value._chi);
147 Util::Message(INFO, "mu = ", mu);
148 Util::Message(INFO, "k1 = ", value.k1);
149 Util::Message(INFO, "beta_bar = ", value._beta_bar);
150 Util::Message(INFO, "GcI_bar = ", value._GcI_bar);
151 Util::Message(INFO, "GcII_bar = ", value._GcII_bar);
152 Util::Message(INFO, "f_t = ", fracture_strength);
153 Util::Message(INFO, "f_c = ", compressive_strength);
154 Util::Message(INFO, "sig_t = ", tensile_strength);
155 Util::Message(INFO, "tau_s = ", shear_strength);
156
157 value._sig_t = tensile_strength;
158 value._tau_s = shear_strength;
159 }
160 else if (value._failure_surface == FSType::MC)
161 {
162 // cohesion coefficient for MC FS type
163 pp.query_default("cohesion", value._cohesion, 1.0);
164 // friction coefficient for MC FS type
165 pp.query_default("friction", value._friction, 0.5);
166
167 Set::Scalar phi = std::atan(value._friction);
168 fracture_strength = 2.0 * value._cohesion * std::cos(phi) / (1.0 + std::sin(phi));
169 }
170
171 }
172 else
173 {
174 // Young's modulus
175 pp.query_default("E", youngs, 2.e11);
176 // fracture strength beyond which softening starts [Pa]
177 pp.query_default("fracture_strength", fracture_strength,1.e6);
178 }
179
180 Set::Scalar irwing_length = youngs * value._Gc / (fracture_strength * fracture_strength);
181 value.czm_a0 = 4.0 * irwing_length / (pi * value.zeta);
182 Util::Message(INFO, "irwing_length = ", irwing_length, ", a0 = ", value.czm_a0);
183 value._l_w = irwing_length;
184
185 if (value.zeta > 0.33 * irwing_length) Util::Warning(INFO, "Zeta value is greater than irwing length. Consider reducing it.");
186
187 pp.query_default("mobility",value.mobility,1.0e-2); // Mobility (speed)
188 pp.query_default("threshold", value.threshold,0.0); // Threshold
189
190 std::string gtype = "";
191 std::string wtype = "";
192 pp.query_validate("gtype", gtype, {"wu_linear"}); // degradation function. For now, we only have linear softening
193 pp.query_validate("wtype", wtype, {"wu"}); // geometric function. no choice except for the optimal one for now.
194
195 std::map<std::string,Model::Interface::Crack::Crack::GType> g_map;
197
198 std::map<std::string,Model::Interface::Crack::Crack::WType> w_map;
200
201 value.SetGType(g_map[gtype]);
202 value.SetWType(w_map[wtype]);
203
204 if (w_map[wtype] == Model::Interface::Crack::Crack::WType::WU) value._c_alpha = pi;
205
206 value.SetPFCZMConstants(value.czm_order, value.czm_a0);
207 }
208};
209}
210}
211}
212#endif
#define INFO
Definition Util.H:21
int query_default(std::string name, T &value, T defaultvalue, std::string="", std::string="", int=-1)
Definition ParmParse.H:203
int query_validate(std::string name, int &value, std::vector< int > possibleintvals, std::string file="", std::string func="", int line=-1)
Definition ParmParse.H:213
void SetPFCZMConstants(const Set::Scalar a_pf_czm_order, const Set::Scalar a_pf_czm_a0)
Definition Crack.H:175
void SetWType(const WType a_type)
Definition Crack.H:160
static constexpr Set::Scalar pi
Definition Crack.H:182
void SetGType(const GType a_type)
Definition Crack.H:155
Set::Scalar Mobility(Set::Scalar)
Definition PFCZM.H:56
Set::Scalar DGc(Set::Scalar)
Definition PFCZM.H:53
static void Parse(PFCZM &value, IO::ParmParse &pp)
Definition PFCZM.H:88
Set::Scalar DDGc(Set::Scalar)
Definition PFCZM.H:54
Set::Scalar Zeta(Set::Scalar)
Definition PFCZM.H:55
Set::Scalar Gc(Set::Scalar)
Definition PFCZM.H:31
Set::Scalar DrivingForceThreshold(Set::Scalar)
Definition PFCZM.H:57
amrex::Real Scalar
Definition Base.H:18
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:166
void Message(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:126