|
| 1 | +from dolfin import * |
| 2 | +parameters["form_compiler"]["cpp_optimize"] = True |
| 3 | +parameters["form_compiler"]["representation"] = "uflacs" |
| 4 | +ffc_options = {"optimize": True, \ |
| 5 | + "eliminate_zeros": True, \ |
| 6 | + "precompute_basis_const": True, \ |
| 7 | + "precompute_ip_const": True} |
| 8 | +parameters["form_compiler"]["quadrature_degree"] = 1 |
| 9 | +set_log_active(False) |
| 10 | +mesh = RectangleMesh(Point(-0.5,-0.5),Point(0.5,0.5), 20, 20) |
| 11 | +cell_markers = MeshFunction("bool", mesh,2) |
| 12 | +cell_markers.set_all(False) |
| 13 | +for cell in cells(mesh): |
| 14 | + p = cell.midpoint() |
| 15 | + if abs(p[1]) < 0.25: |
| 16 | + cell_markers[cell] = True |
| 17 | +mesh = refine(mesh, cell_markers) |
| 18 | +cell_markers = MeshFunction("bool", mesh,2) |
| 19 | +cell_markers.set_all(False) |
| 20 | +for cell in cells(mesh): |
| 21 | + p = cell.midpoint() |
| 22 | + if abs(p[1]) < 0.15: |
| 23 | + cell_markers[cell] = True |
| 24 | +mesh = refine(mesh, cell_markers) |
| 25 | +cell_markers = MeshFunction("bool", mesh,2) |
| 26 | +cell_markers.set_all(False) |
| 27 | +for cell in cells(mesh): |
| 28 | + p = cell.midpoint() |
| 29 | + if abs(p[1]) < 0.1: |
| 30 | + cell_markers[cell] = True |
| 31 | +mesh = refine(mesh, cell_markers) |
| 32 | + |
| 33 | + |
| 34 | +W = VectorFunctionSpace(mesh, 'CG', 1) |
| 35 | +p, q, dp = Function(W), TestFunction(W), TrialFunction(W) |
| 36 | +u, v, du = Function(W), TestFunction(W), TrialFunction(W) |
| 37 | + |
| 38 | +unew, pnew, uold, pold = Function(W), Function(W), Function(W), Function(W) |
| 39 | + |
| 40 | +top = CompiledSubDomain("near(x[1], 0.5) && on_boundary") |
| 41 | +bot = CompiledSubDomain("near(x[1], -0.5) && on_boundary") |
| 42 | +load = Expression("t", t = 0, degree=1) |
| 43 | +bcbot= DirichletBC(W, Constant((0.0,0.0)), bot) |
| 44 | +bctop = DirichletBC(W.sub(1), load, top) |
| 45 | +bc_u = [bcbot, bctop] |
| 46 | +bc_phi = [] |
| 47 | + |
| 48 | +class InitialCondition(UserExpression): |
| 49 | + def eval_cell(self, value, x, ufl_cell): |
| 50 | + if abs(x[1]) < 10e-03 and x[0] <= 0: |
| 51 | + value[0] = 0 |
| 52 | + value[1] = 1 |
| 53 | + else: |
| 54 | + value[0] = 0 |
| 55 | + value[1] = 0 |
| 56 | + def value_shape(self): |
| 57 | + return (2,) |
| 58 | + |
| 59 | +pold.interpolate(InitialCondition()) |
| 60 | +p.interpolate(InitialCondition()) |
| 61 | +pnew.interpolate(InitialCondition()) |
| 62 | + |
| 63 | +Gc, l, lmbda, mu, eta_eps = 1.721/ (100e3), 0.015, 0, 1, 1.e-3 |
| 64 | +Cr = 1.e-3 |
| 65 | +def energy(alpha1, alpha0, beta): |
| 66 | + Energy = mu/2 *(alpha0**2 + alpha1**2 +beta**2 -2)+ h(alpha0*alpha1) |
| 67 | + return Energy |
| 68 | + |
| 69 | +def W0(u): |
| 70 | + I = Identity(len(u)) |
| 71 | + F = variable(I + grad(u)) |
| 72 | + C = F.T*F |
| 73 | + C00, C01, C10, C11 = C[0,0], C[0,1], C[1,0], C[1,1] |
| 74 | + alpha1 = C00**(0.5) |
| 75 | + beta = C01 / alpha1 |
| 76 | + alpha0 = (C11 - beta*beta)**(0.5) |
| 77 | + E = energy(alpha1, alpha0, beta) |
| 78 | + stress = diff(E, F) |
| 79 | + return [E, stress] |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | +def W1(u,d): |
| 84 | + I = Identity(len(u)) |
| 85 | + F = variable (I + grad(u) ) |
| 86 | + d= variable(d) |
| 87 | + n1 ,n2 = d[0]/(sqrt(dot(d,d))) , d[1]/(sqrt(dot(d,d))) |
| 88 | + a1, a2 = F[0,0]*n2 - F[0,1]*n1 , F[1,0]*n2 - F[1,1]*n1 |
| 89 | + alpha1 = sqrt(a1**2 + a2**2) |
| 90 | + alpha0 = (det(F))/sqrt(a1**2 + a2**2) |
| 91 | + alpha0_s = ( ((lmbda*alpha1)**2 +4*mu*lmbda*(alpha1**2)+ 4*mu**2)** (0.5) +\ |
| 92 | + lmbda*alpha1) / (2*(lmbda*(alpha1**2) +mu)) |
| 93 | + E = conditional(lt(alpha0, alpha0_s), energy(alpha1, alpha0, 0), \ |
| 94 | + energy(alpha1, alpha0_s, 0) ) |
| 95 | + stress, dE_dd = diff(E, F) , diff(E, d) |
| 96 | + return [E, stress, dE_dd] |
| 97 | + |
| 98 | +def h(J): |
| 99 | + return (lmbda/2)*(J-1)**2 -mu*ln(J) |
| 100 | + |
| 101 | +def total_energy(u,d): |
| 102 | + E = ((1- conditional(lt(dot(d,d), Cr),0.0, sqrt(dot(d,d))))**2 + eta_eps)*W0(u)[0] +\ |
| 103 | + (1-(1- conditional(lt(dot(d,d), Cr),0.0, sqrt(dot(d,d))))**2 )*\ |
| 104 | + conditional(lt(dot(d,d), Cr),0.0, W1(u,d)[0]) +\ |
| 105 | + Gc* ( dot(d,d)/(2*l) + (l/2)*inner(grad(d), grad(d)) ) |
| 106 | + return E |
| 107 | + |
| 108 | +def elastic_energy(u,d): |
| 109 | + E = ((1- conditional(lt(dot(d,d), Cr),0.0, sqrt(dot(d,d))))**2 + eta_eps)*W0(u)[0] +\ |
| 110 | + (1-(1- conditional(lt(dot(d,d), Cr),0.0, sqrt(dot(d,d))))**2 )*\ |
| 111 | + conditional(lt(dot(d,d), Cr),0.0, W1(u,d)[0]) |
| 112 | + return E |
| 113 | + |
| 114 | +Pi1 = total_energy(u, pold) * dx |
| 115 | +Pi2 = total_energy(unew, p) * dx |
| 116 | + |
| 117 | +E_du = derivative(Pi1, u, v) |
| 118 | +E_phi = derivative(Pi2, p, q) |
| 119 | + |
| 120 | +J_phi = derivative(E_phi, p, dp) |
| 121 | +J_u = derivative(E_du, u, du) |
| 122 | +p_disp = NonlinearVariationalProblem(E_du, u, bc_u, J_u) |
| 123 | +p_phi = NonlinearVariationalProblem(E_phi, p, bc_phi ,J_phi) |
| 124 | +solver_disp = NonlinearVariationalSolver(p_disp) |
| 125 | +solver_phi = NonlinearVariationalSolver(p_phi) |
| 126 | + |
| 127 | +prm1 = solver_disp.parameters |
| 128 | +prm1['newton_solver']['maximum_iterations'] = 1000 |
| 129 | +prm2 = solver_phi.parameters |
| 130 | +prm2['newton_solver']['maximum_iterations'] = 1000 |
| 131 | + |
| 132 | +def preventHeal(pold, pnew): #conserves the direction of old crack |
| 133 | + pold_nodal_values = pold.vector() |
| 134 | + pold_array = pold_nodal_values.get_local() |
| 135 | + pnew_nodal_values = pnew.vector() |
| 136 | + pnew_array = pnew_nodal_values.get_local() |
| 137 | + for i in range(0, len(pold_array), 2): |
| 138 | + pold_mag = sqrt( (pold_array[i])**2 +(pold_array[i+1])**2 ) |
| 139 | + pnew_mag = sqrt( (pnew_array[i])**2 +(pnew_array[i+1])**2 ) |
| 140 | + if pold_mag > 0.95: |
| 141 | + pnew_array[i], pnew_array[i+1] = pold_array[i]/pold_mag, \ |
| 142 | + pold_array[i+1]/pold_mag |
| 143 | + pnew3 = Function(W) |
| 144 | + pnew3.vector()[:] = pnew_array[:] |
| 145 | + return pnew3 |
| 146 | + |
| 147 | +def stress_form(u,d): |
| 148 | + E = ((1- conditional(lt(dot(d,d), Cr), 0, sqrt(dot(d,d))))**2 + eta_eps)*W0(u)[1] +\ |
| 149 | + (1-(1- conditional(lt(dot(d,d), Cr),0, sqrt(dot(d,d))))**2 )*\ |
| 150 | + conditional(lt(dot(d,d), Cr), stress_null, W1(u,d)[1]) |
| 151 | + return E |
| 152 | + |
| 153 | +TS = TensorFunctionSpace(mesh, "CG", 1) |
| 154 | +stress = Function(TS) |
| 155 | +stress_null = Function(TS) |
| 156 | + |
| 157 | +V = FunctionSpace(mesh, 'DG', 0) |
| 158 | +energy_total = Function(V) |
| 159 | +energy_elastic = Function(V) |
| 160 | + |
| 161 | +CrackVector_file = File ("./Result/crack_vector.pvd") |
| 162 | +Displacement_file = File ("./Result/displacement.pvd") |
| 163 | +TotalEnergy_file = File ("./Result/total_energy.pvd") |
| 164 | +ElasticEnergy_file = File ("./Result/elastic_energy.pvd") |
| 165 | +Stress_file = File("./Result/stress.pvd") |
| 166 | + |
| 167 | +t = 0 |
| 168 | +u_r = 0.003 |
| 169 | +deltaT = 0.1 |
| 170 | +tol = 1e-3 |
| 171 | + |
| 172 | +while t<= 1.8: |
| 173 | + if t>= 1.45: |
| 174 | + deltaT = 1.e-2 |
| 175 | + t += deltaT |
| 176 | + load.t=t*u_r |
| 177 | + iter = 0 |
| 178 | + err = 1 |
| 179 | + while err > tol: |
| 180 | + iter += 1 |
| 181 | + solver_disp.solve() |
| 182 | + unew.assign(u) |
| 183 | + solver_phi.solve() |
| 184 | + p_new = preventHeal(pold, p) |
| 185 | + pnew.assign(p_new) |
| 186 | + err_u = errornorm(unew,uold,norm_type = 'l2',mesh = None) |
| 187 | + err_phi = errornorm(pnew,pold,norm_type = 'l2',mesh = None) |
| 188 | + err = max(err_u,err_phi) |
| 189 | + uold.assign(unew) |
| 190 | + pold.assign(pnew) |
| 191 | + if err <= tol: |
| 192 | + print ('Iterations:', iter, ', Total time', t) |
| 193 | + StoringDisplacement_file = File ("./Result/saved_u"+str(t)+ ".xml") |
| 194 | + StoringCrack_file = File ("./Result/saved_p"+str(t)+ ".xml") |
| 195 | + pnew.rename("d", "crack_vector") |
| 196 | + CrackVector_file << pnew |
| 197 | + Displacement_file << unew |
| 198 | + StoringCrack_file << pnew |
| 199 | + StoringDisplacement_file << unew |
| 200 | + energy_total = project( total_energy(unew, pnew) ,V) |
| 201 | + energy_total.rename("energy_total", "energy_total") |
| 202 | + TotalEnergy_file << energy_total |
| 203 | + |
| 204 | + energy_elastic = project( elastic_energy(unew, pnew) ,V) |
| 205 | + energy_elastic.rename("energy_elastic", "energy_elastic") |
| 206 | + ElasticEnergy_file << energy_elastic |
| 207 | + |
| 208 | + stress = project( stress_form(unew, pnew), TS) |
| 209 | + stress.rename("stress", "stress") |
| 210 | + Stress_file << stress |
| 211 | +print ('Simulation completed') |
0 commit comments