LShape#

Damage simulation for a L-part.

LShape
  • $\phi$
  • TRI3: Ne = 4234, Nn = 2178
  • Boundary conditions
  • LShape
  • LShape
  • Summary
/home/docs/checkouts/readthedocs.org/user_builds/easyfea/checkouts/v1.7.2/examples/PhaseField/results/LShape2D/Test/Miehe_AT1_CP_optimMesh nL=50   1 : 0.000 mm, [0.00e+00; 0.00e+00], 1:0.086 s, tol=0.00e+00
   2 : 0.040 mm, [0.00e+00; 0.00e+00], 1:0.076 s, tol=1.00e+00  4.00 % -> 1.83 s
   3 : 0.080 mm, [0.00e+00; 0.00e+00], 1:0.076 s, tol=9.95e-01  8.00 % -> 1.74 s
   4 : 0.120 mm, [0.00e+00; 0.00e+00], 1:0.079 s, tol=5.56e-01  12.00 % -> 1.73 s
   5 : 0.160 mm, [0.00e+00; 0.00e+00], 1:0.076 s, tol=4.38e-01  16.00 % -> 1.60 s
   6 : 0.200 mm, [0.00e+00; 0.00e+00], 1:0.078 s, tol=3.60e-01  20.00 % -> 1.56 s
   7 : 0.240 mm, [0.00e+00; 0.00e+00], 1:0.078 s, tol=3.06e-01  24.00 % -> 1.49 s
   8 : 0.280 mm, [0.00e+00; 8.98e-03], 1:0.078 s, tol=2.65e-01  28.00 % -> 1.41 s
   9 : 0.320 mm, [0.00e+00; 4.57e-02], 1:0.078 s, tol=2.32e-01  32.00 % -> 1.33 s
  10 : 0.360 mm, [0.00e+00; 1.10e-01], 1:0.076 s, tol=2.07e-01  36.00 % -> 1.22 s
  11 : 0.400 mm, [0.00e+00; 2.07e-01], 1:0.076 s, tol=1.86e-01  40.00 % -> 1.14 s
  12 : 0.440 mm, [0.00e+00; 3.48e-01], 1:0.076 s, tol=1.69e-01  44.00 % -> 1.06 s
  13 : 0.480 mm, [0.00e+00; 5.46e-01], 1:0.076 s, tol=1.55e-01  48.00 % -> 985.50 ms
  14 : 0.520 mm, [0.00e+00; 7.78e-01], 1:0.076 s, tol=1.62e-01  52.00 % -> 908.14 ms
  15 : 0.540 mm, [0.00e+00; 9.48e-01], 1:0.079 s, tol=2.22e-01  54.00 % -> 940.31 ms
  16 : 0.560 mm, [0.00e+00; 9.93e-01], 1:0.076 s, tol=3.80e-01  56.00 % -> 895.73 ms
  17 : 0.580 mm, [0.00e+00; 1.00e+00], 1:0.077 s, tol=4.44e-01  58.00 % -> 893.31 ms
  18 : 0.600 mm, [0.00e+00; 1.00e+00], 1:0.076 s, tol=3.82e-01  60.00 % -> 857.24 ms
  19 : 0.620 mm, [0.00e+00; 1.00e+00], 1:0.076 s, tol=3.28e-01  62.00 % -> 838.11 ms
  20 : 0.640 mm, [0.00e+00; 1.00e+00], 1:0.076 s, tol=2.91e-01  64.00 % -> 811.41 ms
  21 : 0.660 mm, [0.00e+00; 1.00e+00], 1:0.076 s, tol=2.78e-01  66.00 % -> 780.78 ms
  22 : 0.680 mm, [0.00e+00; 1.00e+00], 1:0.079 s, tol=2.54e-01  68.00 % -> 782.62 ms
  23 : 0.700 mm, [0.00e+00; 1.00e+00], 1:0.078 s, tol=2.53e-01  70.00 % -> 732.73 ms
  24 : 0.720 mm, [0.00e+00; 1.00e+00], 1:0.078 s, tol=2.02e-01  72.00 % -> 701.33 ms
  25 : 0.740 mm, [0.00e+00; 1.00e+00], 1:0.080 s, tol=1.76e-01  74.00 % -> 670.93 ms
  26 : 0.760 mm, [0.00e+00; 1.00e+00], 1:0.080 s, tol=1.87e-01  76.00 % -> 627.87 ms
  27 : 0.780 mm, [0.00e+00; 1.00e+00], 1:0.086 s, tol=1.72e-01  78.00 % -> 632.56 ms
  28 : 0.800 mm, [0.00e+00; 1.00e+00], 1:0.080 s, tol=1.65e-01  80.00 % -> 541.78 ms
  29 : 0.820 mm, [0.00e+00; 1.00e+00], 1:0.084 s, tol=1.90e-01  82.00 % -> 513.74 ms
  30 : 0.840 mm, [0.00e+00; 1.00e+00], 1:0.082 s, tol=1.65e-01  84.00 % -> 453.44 ms
  31 : 0.860 mm, [0.00e+00; 1.00e+00], 1:0.090 s, tol=1.51e-01  86.00 % -> 439.31 ms
  32 : 0.880 mm, [0.00e+00; 1.00e+00], 1:0.088 s, tol=1.15e-01  88.00 % -> 370.49 ms
  33 : 0.900 mm, [0.00e+00; 1.00e+00], 1:0.083 s, tol=1.10e-01  90.00 % -> 294.40 ms
  34 : 0.920 mm, [0.00e+00; 1.00e+00], 1:0.087 s, tol=9.93e-02  92.00 % -> 250.96 ms
  35 : 0.940 mm, [0.00e+00; 1.00e+00], 1:0.084 s, tol=9.94e-02  94.00 % -> 182.24 ms
  36 : 0.960 mm, [0.00e+00; 1.00e+00], 1:0.084 s, tol=9.12e-02  96.00 % -> 122.12 ms
  37 : 0.980 mm, [0.00e+00; 1.00e+00], 1:0.085 s, tol=1.02e-01  98.00 % -> 62.74 ms
  38 : 1.000 mm, [0.00e+00; 1.00e+00], 1:0.088 s, tol=9.35e-02  100.00 % -> -0.00 µs
Saved:
/home/docs/checkouts/readthedocs.org/user_builds/easyfea/checkouts/v1.7.2/examples/PhaseField/results/LShape2D/Test/Miehe_AT1_CP_optimMesh nL=50/force-displacement.pickle
Saved:
/home/docs/checkouts/readthedocs.org/user_builds/easyfea/checkouts/v1.7.2/examples/PhaseField/results/LShape2D/Test/Miehe_AT1_CP_optimMesh nL=50/simulation.pickle
Saved:
/home/docs/checkouts/readthedocs.org/user_builds/easyfea/checkouts/v1.7.2/examples/PhaseField/results/LShape2D/Test/Miehe_AT1_CP_optimMesh nL=50/summary.txt
Loaded:
/home/docs/checkouts/readthedocs.org/user_builds/easyfea/checkouts/v1.7.2/examples/PhaseField/results/LShape2D/Test/Miehe_AT1_CP_optimMesh nL=50/force-displacement.pickle

Generate movie 01/38 (2.63 %) 3.84 s
Generate movie 02/38 (5.26 %) 3.20 s
Generate movie 03/38 (7.89 %) 3.00 s
Generate movie 04/38 (10.53 %) 2.99 s
Generate movie 05/38 (13.16 %) 2.90 s
Generate movie 06/38 (15.79 %) 2.75 s
Generate movie 07/38 (18.42 %) 2.72 s
Generate movie 08/38 (21.05 %) 2.58 s
Generate movie 09/38 (23.68 %) 2.54 s
Generate movie 10/38 (26.32 %) 2.44 s
Generate movie 11/38 (28.95 %) 2.34 s
Generate movie 12/38 (31.58 %) 2.36 s
Generate movie 13/38 (34.21 %) 2.15 s
Generate movie 14/38 (36.84 %) 2.15 s
Generate movie 15/38 (39.47 %) 1.97 s
Generate movie 16/38 (42.11 %) 1.88 s
Generate movie 17/38 (44.74 %) 1.84 s
Generate movie 18/38 (47.37 %) 1.76 s
Generate movie 19/38 (50.00 %) 1.67 s
Generate movie 20/38 (52.63 %) 1.55 s
Generate movie 21/38 (55.26 %) 1.46 s
Generate movie 22/38 (57.89 %) 1.39 s
Generate movie 23/38 (60.53 %) 1.29 s
Generate movie 24/38 (63.16 %) 1.20 s
Generate movie 25/38 (65.79 %) 1.11 s
Generate movie 26/38 (68.42 %) 1.02 s
Generate movie 27/38 (71.05 %) 935.84 ms
Generate movie 28/38 (73.68 %) 851.79 ms
Generate movie 29/38 (76.32 %) 761.90 ms
Generate movie 30/38 (78.95 %) 686.06 ms
Generate movie 31/38 (81.58 %) 614.92 ms
Generate movie 32/38 (84.21 %) 522.13 ms
Generate movie 33/38 (86.84 %) 440.04 ms
Generate movie 34/38 (89.47 %) 351.44 ms
Generate movie 35/38 (92.11 %) 262.06 ms
Generate movie 36/38 (94.74 %) 170.85 ms
Generate movie 37/38 (97.37 %) 85.49 ms
Generate movie 38/38 (100.00 %) 0.00 µs

 13 import matplotlib.pyplot as plt
 14 import numpy as np
 15
 16 from EasyFEA import (
 17     Display,
 18     Folder,
 19     Models,
 20     Tic,
 21     ElemType,
 22     Simulations,
 23     Paraview,
 24     PyVista,
 25 )
 26 from EasyFEA.Geoms import Point, Points, Domain, Circle
 27
 28 if __name__ == "__main__":
 29     Display.Clear()
 30
 31     # ----------------------------------------------
 32     # Configuration
 33     # ----------------------------------------------
 34
 35     # simu options
 36     doSimu = True
 37     meshTest = True
 38     optimMesh = True
 39
 40     # outputs
 41     folder = Folder.Results_Dir()
 42     pltIter = False
 43     pltLoad = False
 44     makeMovie = True
 45     makeParaview = False
 46
 47     # geom
 48     dim = 2
 49     L = 250  # mm
 50     nL = 50
 51     ep = 100
 52
 53     # model
 54     E = 2e4  # MPa
 55     v = 0.18
 56
 57     split = "Miehe"
 58     regu = "AT1"
 59     Gc = 130  # J/m2
 60     Gc *= 1000 / 1e6  # mJ/mm2
 61
 62     # convergence
 63     tolConv = 1e-0
 64     convOption = 2
 65
 66     # load
 67     uMax = 1  # mm
 68     inc0 = uMax / 25
 69     inc1 = inc0 / 2
 70
 71     config = f"""
 72     uMax = {uMax}
 73
 74     inc0 = {inc0}
 75     inc1 = {inc1}
 76
 77     while ud <= uMax:
 78
 79     ud += inc0 if simu.damage.max() < 0.6 else inc1
 80
 81     simu.add_dirichlet(nodes_circle, [0], ['d'], "damage")
 82     simu.add_dirichlet(nodes_y0, [0]*dim, simu.Get_dofs())
 83     simu.add_dirichlet(nodes_load, [ud], ['y'])
 84     """
 85
 86     # ----------------------------------------------
 87     # Mesh
 88     # ----------------------------------------------
 89     l0 = L / nL
 90
 91     if meshTest:
 92         hC = l0
 93     else:
 94         hC = 0.5
 95         # hC = 0.25
 96
 97     p1 = Point()
 98     p2 = Point(L, 0)
 99     p3 = Point(L, L)
100     p4 = Point(2 * L - 30, L)
101     p5 = Point(2 * L, L)
102     p6 = Point(2 * L, 2 * L)
103     p7 = Point(0, 2 * L)
104     if optimMesh:
105         # hauteur zone rafinée
106         h = 100
107         refineDomain = Domain(Point(0, L - h / 3), Point(L + h / 3, L + h), hC)
108         hD = hC * 5
109     else:
110         refineDomain = None
111         hD = hC
112
113     contour = Points([p1, p2, p3, p4, p5, p6, p7], hD)
114
115     circle = Circle(p5, 100)
116
117     if dim == 2:
118         mesh = contour.Mesh_2D([], ElemType.TRI3, refineGeoms=[refineDomain])
119     else:
120         mesh = contour.Mesh_Extrude(
121             [], [0, 0, -ep], [3], ElemType.HEXA8, refineGeoms=[refineDomain]
122         )
123
124     # Display.Plot_Mesh(mesh)
125     # Display.Plot_Tags(mesh)
126     # from EasyFEA import PyVista
127     # PyVista.Plot_Mesh(mesh).show()
128
129     nodes_y0 = mesh.Nodes_Conditions(lambda x, y, z: y == 0)
130     nodes_load = mesh.Nodes_Conditions(lambda x, y, z: (y == L) & (x >= 2 * L - 30))
131     node3 = mesh.Nodes_Point(p3)
132     node4 = mesh.Nodes_Point(p4)
133     nodes_circle = mesh.Nodes_Cylinder(circle, direction=[0, 0, ep])
134     nodes_edges = mesh.Nodes_Conditions(lambda x, y, z: (x == 0) | (y == 0))
135
136     # ----------------------------------------------
137     # Simulation
138     # ----------------------------------------------
139     material = Models.Elastic.Isotropic(dim, E, v, True, ep)
140     pfm = Models.PhaseField(material, split, regu, Gc, l0)
141
142     folder_save = Simulations.PhaseField.Folder(
143         f"{folder}{dim}D",
144         "",
145         pfm.split,
146         pfm.regularization,
147         "CP",
148         tolConv,
149         "",
150         meshTest,
151         optimMesh,
152         nL=nL,
153     )
154
155     Display.MyPrint(folder_save, "green")
156
157     if doSimu:
158         simu = Simulations.PhaseField(mesh, pfm)
159         simu.Results_Set_Bc_Summary(config)
160
161         dofsY_load = simu.Bc_dofs_nodes(nodes_load, ["y"])
162
163         if pltIter:
164             axIter = Display.Plot_Result(simu, "damage")
165
166             axLoad = Display.Init_Axes()
167             axLoad.set_xlabel("displacement [mm]")
168             axLoad.set_ylabel("load [kN]")
169
170         displacement = []
171         force = []
172         ud = -inc0
173         iter = -1
174
175         while ud <= uMax:
176             # update displacement
177             iter += 1
178             ud += inc0 if simu.damage.max() < 0.6 else inc1
179
180             # update boundary conditions
181             simu.Bc_Init()
182             simu.add_dirichlet(nodes_circle, [0], ["d"], "damage")
183             simu.add_dirichlet(nodes_y0, [0] * dim, simu.Get_unknowns())
184             simu.add_dirichlet(nodes_load, [ud], ["y"])
185
186             # solve
187             u, d, Ku, convergence = simu.Solve(tolConv, 500, convOption)
188             # calc load
189             fr = np.sum(Ku[dofsY_load, :] @ u)
190
191             # saves load and displacement
192             displacement.append(ud)
193             force.append(fr)
194
195             # print iter
196             simu.Results_Set_Iteration_Summary(iter, ud, "mm", ud / uMax, True)
197
198             # saves iteration
199             simu.Save_Iter()
200
201             if pltIter:
202                 plt.figure(axIter.figure)
203                 Display.Plot_Result(simu, "damage", ax=axIter)
204                 plt.pause(1e-12)
205
206                 plt.figure(axLoad.figure)
207                 axLoad.scatter(ud, fr / 1000, c="black")
208                 plt.pause(1e-12)
209
210             if not convergence or np.max(d[nodes_edges]) >= 1:
211                 # stops simulation if damage occurs on edges or convergence has not been reached
212                 break
213
214         # saves load and displacement
215         displacement = np.asarray(displacement)
216         force = np.asarray(force)
217         Simulations.Save_pickle(
218             (force, displacement), folder_save, "force-displacement"
219         )
220
221         # saves the simulation
222         simu.Save(folder_save)
223
224     else:
225         simu = Simulations.Load_Simu(folder_save)
226         mesh = simu.mesh
227
228     force, displacement = Simulations.Load_pickle(folder_save, "force-displacement")
229
230     # ----------------------------------------------
231     # Results
232     # ----------------------------------------------
233     Display.Plot_Result(simu, "damage", folder=folder_save)
234     Display.Plot_Mesh(simu)
235     Display.Plot_BoundaryConditions(simu)
236
237     axLoad = Display.Init_Axes()
238     axLoad.set_xlabel("displacement [mm]")
239     axLoad.set_ylabel("load [kN]")
240     axLoad.plot(displacement, force / 1000, c="blue")
241     Display.Save_fig(folder_save, "forcedep")
242
243     Display.Plot_Iter_Summary(simu, folder_save)
244
245     if makeMovie:
246         simu.Set_Iter(-1)
247         depMax = simu.Result("displacement_norm").max()
248         deformFactor = L * 0.05 / depMax
249
250         iterations = np.arange(0, simu.Niter, simu.Niter // 20)
251
252         def Func(plotter, iter):
253             simu.Set_Iter(iterations[iter])
254
255             grid = PyVista._pvMesh(simu, "damage", deformFactor)
256
257             tresh = grid.threshold((0, 0.8))
258
259             PyVista.Plot(
260                 tresh,
261                 "damage",
262                 deformFactor,
263                 plotMesh=True,
264                 plotter=plotter,
265                 clim=(0, 1),
266             )
267
268         PyVista.Movie_func(Func, iterations.size, folder_save, "damage.gif")
269
270     if makeParaview:
271         Paraview.Save_simu(simu, folder_save)
272
273     if doSimu:
274         Tic.Plot_History(folder_save, False)
275
276     plt.show()

Total running time of the script: (0 minutes 10.095 seconds)

Gallery generated by Sphinx-Gallery