39 #ifndef GETFEM_CRACK_SIF_H
40 #define GETFEM_CRACK_SIF_H
49 inline dal::bit_vector
50 build_sif_ring_from_mesh(
const mesh &m,
51 base_node center, scalar_type r) {
53 scalar_type r2 = r - 1e-4;
55 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
56 unsigned in1=0, out1=0;
57 unsigned in2=0, out2=0;
58 for (
unsigned i=0; i < m.nb_points_of_convex(cv); ++i) {
59 base_node P = m.points_of_convex(cv)[i];
60 if (gmm::vect_dist2(P, center) < r) ++in1;
else ++out1;
61 if (gmm::vect_dist2(P, center) < r2) ++in2;
else ++out2;
63 if ((in1 && out1) || (in2 && out2)) bv.add(cv);
66 if (in < 3) GMM_WARNING1(
"looks like the radius is too small...");
73 inline void get_crack_tip_and_orientation(
const level_set &,
75 base_small_vector &T, base_small_vector &N) {
76 cerr << GMM_PRETTY_FUNCTION <<
" IS TO BE DONE\n";
78 P.resize(2); P[0] = .5; P[1] = 0;
79 T.resize(2); T[0] = 1; T[1] = 0;
80 N.resize(2); N[0] = 0; N[1] = 1;
86 template <
typename VECT>
87 void compute_crack_stress_intensity_factors(
const level_set &ls,
91 scalar_type ring_radius,
92 scalar_type lambda, scalar_type mu,
93 scalar_type young_modulus,
94 scalar_type &KI, scalar_type &KII) {
95 const mesh &mring = mim.linked_mesh();
96 mesh_fem_global_function mf_mode(mring, 1);
97 mesh_fem mf_q(mring,1);
99 std::vector<pglobal_function> cfun(4);
100 for (
unsigned j=0; j < 4; ++j) {
101 auto s = std::make_shared<crack_singular_xy_function>(j);
102 cfun[j] = global_function_on_level_set(ls, s);
104 mf_mode.set_functions(cfun);
107 mf_q.set_classical_finite_element(1);
110 base_small_vector T, N;
111 get_crack_tip_and_orientation(ls, crack_tip, T, N);
113 dal::bit_vector cvring = build_sif_ring_from_mesh(mring, crack_tip,
118 std::vector<scalar_type> q(mf_q.nb_basic_dof());
119 for (
unsigned d = 0; d < mf_q.nb_basic_dof(); ++d) {
120 base_node P = mf_q.point_of_basic_dof(d);
124 base_vector U_mode(mf_mode.nb_dof()); assert(U_mode.size() == 8);
131 assem(
"lambda=data$1(1); mu=data$2(1); x1=data$3(mdim(#1)); "
132 "U1=data$4(#1); U2=data$5(#2); q=data$6(#3);"
133 "t=U1(i).U2(j).q(k).comp(vGrad(#1).vGrad(#2).Grad(#3))(i,:,:,j,:,:,k,:);"
134 "e1=(t{1,2,:,:,:}+t{2,1,:,:,:})/2;"
135 "e2=(t{:,:,3,4,:}+t{:,:,4,3,:})/2;"
136 "e12=(e1{:,:,3,4,:}+e1{:,:,4,3,:})/2;"
137 "V()+=2*mu(p).e1(i,j,i,k,j).x1(k) + lambda(p).e1(i,i,j,k,j).x1(k);"
138 "V()+=2*mu(p).e2(i,k,i,j,j).x1(k) + lambda(p).e2(j,k,i,i,j).x1(k);"
139 "V()+=-2*mu(p).e12(i,j,i,j,k).x1(k) - lambda(p).e12(i,i,j,j,k).x1(k);");
141 assem.push_mf(mf_mode);
144 base_vector vlambda(1); vlambda[0] = lambda;
145 base_vector vmu(1); vmu[0] = mu;
146 assem.push_data(vlambda);
147 assem.push_data(vmu);
150 assem.push_data(U_mode);
156 for (
unsigned mode = 1; mode <= 2; ++mode) {
157 base_vector::iterator it = U_mode.begin();
158 scalar_type coeff=0.;
161 scalar_type A=2+2*mu/(lambda+2*mu), B=-2*(lambda+mu)/(lambda+2*mu);
163 *it++ = 0; *it++ = A-B;
164 *it++ = A+B; *it++ = 0;
165 *it++ = -B; *it++ = 0;
166 *it++ = 0; *it++ = B;
167 coeff = 1/sqrt(2*M_PI);
170 scalar_type C1 = (lambda+3*mu)/(lambda+mu);
171 *it++ = C1+2-1; *it++ = 0;
172 *it++ = 0; *it++ = -(C1-2+1);
173 *it++ = 0; *it++ = 1;
174 *it++ = 1; *it++ = 0;
175 coeff = 2*(mu+lambda)/(lambda+2*mu)/sqrt(2*M_PI);
178 gmm::scale(U_mode, coeff/young_modulus);
180 cout <<
"assemblig SIFs ..." << std::flush;
181 double time = gmm::uclock_sec();
182 assem.assembly(cvring);
183 cout <<
"done (" << gmm::uclock_sec()-time <<
" sec)\n";
184 V[0] *= young_modulus/2;
185 if (mode == 1) KI = V[0];
else KII = V[0];
191 template <
typename VECT>
192 void estimate_crack_stress_intensity_factors(
const level_set &ls,
193 const mesh_fem &mf,
const VECT &U,
194 scalar_type young_modulus,
196 scalar_type &KII,
double EPS=1e-2) {
198 base_small_vector T(2),N(2);
199 get_crack_tip_and_orientation(ls, P, T, N);
200 base_node P1 = P - EPS*T + EPS/100.*N;
201 base_node P2 = P - EPS*T - EPS/100.*N;
202 std::vector<double> V(4);
203 getfem::mesh_trans_inv mti(mf.linked_mesh());
206 cout <<
"P1 = " << P1 <<
", P2=" << P2 <<
"\n";
209 KI = (V[1] - V[3])/sqrt(EPS/(2*M_PI)) * young_modulus / 8.0;
210 KII = (V[0] - V[2])/sqrt(EPS/(2*M_PI)) * young_modulus / 8.0;
Generic assembly implementation.
Define a getfem::getfem_mesh object.
Define a mesh_fem with base functions which are global functions given by the user.
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2(const V1 &v1, const V2 &v2)
Euclidean distance between two vectors.
GEneric Tool for Finite Element Methods.
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.