Note
Go to the end to download the full example code.
MeshOptim2#
Mesh optimization with the ZZ1 criterion for a bending part.







/home/docs/checkouts/readthedocs.org/user_builds/easyfea/envs/v1.6.1/lib/python3.11/site-packages/EasyFEA/utilities/PyVista.py:950: PyVistaDeprecationWarning:
../../../../envs/v1.6.1/lib/python3.11/site-packages/EasyFEA/utilities/PyVista.py:950: Arguments 'pointa', 'pointb', 'center' must be passed as keyword arguments to function 'CircularArc'.
From version 0.50, passing these as positional arguments will result in a TypeError.
return pv.CircularArc(
error = 90.460 %
error = 89.395 %
error = 40.821 %
error = 21.594 %
error = 9.857 %
error = 4.697 %
error = 1.326 %
error = 0.502 %
Generate movie 0/7
Generate movie 1/7 (14.29 %) 1.34 s
Generate movie 2/7 (28.57 %) 1.11 s
Generate movie 3/7 (42.86 %) 891.99 ms
Generate movie 4/7 (57.14 %) 682.80 ms
Generate movie 5/7 (71.43 %) 476.21 ms
Generate movie 6/7 (85.71 %) 264.72 ms
Generate movie 7/7 (100.00 %) 0.00 µs
12 from EasyFEA import (
13 Display,
14 Folder,
15 Models,
16 Tic,
17 plt,
18 np,
19 Mesher,
20 ElemType,
21 Mesh,
22 Simulations,
23 Paraview,
24 PyVista,
25 )
26 from EasyFEA.Geoms import Point, Points
27 from EasyFEA.fem import Calc_projector
28
29 if __name__ == "__main__":
30 Display.Clear()
31
32 # ----------------------------------------------
33 # Configuration
34 # ----------------------------------------------
35 dim = 2
36
37 # geom
38 L = 120
39 h = L * 2 / 3
40 b = h
41 r = h / (2 + 1e-2)
42 e = (L - 2 * r) / 2
43
44 # outputs
45 folder = Folder.Join(Folder.RESULTS_DIR, "Meshes", "MeshOptim2")
46 plotProj = False
47 makeMovie = True
48 makeParaview = False
49
50 # load
51 P = 800 # N
52 lineLoad = P / h # N/mm
53 surfLoad = P / h / b # N/mm2
54
55 # criteria
56 threshold = (
57 1 / 100 if dim == 2 else 0.04
58 ) # Target error for the optimization process
59 iterMax = 20 # Maximum number of iterations
60 coef = 1 / 10 # Scaling coefficient for the optimization process
61
62 # ----------------------------------------------
63 # Mesh
64 # ----------------------------------------------
65 if dim == 2:
66 elemType = ElemType.TRI3
67 else:
68 elemType = ElemType.TETRA4
69 meshSize = h / 10
70
71 pt1 = Point()
72 pt2 = Point(e, 0)
73 pt3 = Point(e, r, r=r)
74 pt4 = Point(L - e, r, r=r)
75 pt5 = Point(L - e, 0)
76 pt6 = Point(L, 0)
77
78 pt7 = Point(L, h)
79 pt8 = Point(L - e, h)
80 pt9 = Point(L - e, h - r, r=r)
81 pt10 = Point(e, h - r, r=r)
82 pt11 = Point(e, h)
83 pt12 = Point(0, h)
84
85 points = Points(
86 [pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, pt9, pt10, pt11, pt12], meshSize
87 )
88 inclusions = []
89
90 PyVista.Plot_Geoms(points.Get_Contour()).show()
91
92 def DoMesh(refineGeom=None) -> Mesh:
93 """Function used to generate the mesh."""
94 if dim == 2:
95 return Mesher().Mesh_2D(points, inclusions, elemType, [], [refineGeom])
96 else:
97 return Mesher().Mesh_Extrude(
98 points, inclusions, [0, 0, b], [], elemType, [], [refineGeom]
99 )
100
101 # Construct the initial mesh
102 mesh = DoMesh()
103 PyVista.Plot_Mesh(mesh).show()
104
105 # ----------------------------------------------
106 # Material and Simulation
107 # ----------------------------------------------
108 material = Models.ElasIsot(dim, E=210000, v=0.3, thickness=b)
109 simu = Simulations.ElasticSimu(mesh, material)
110 simu.rho = 8100 * 1e-9
111
112 def DoSimu(refineGeom: str):
113 simu.mesh = DoMesh(refineGeom)
114
115 # get the nodes
116 nodes_Fixed = simu.mesh.Nodes_Conditions(lambda x, y, z: x == 0)
117 nodes_Load = simu.mesh.Nodes_Conditions(lambda x, y, z: x == L)
118
119 # do the simulation
120 simu.Bc_Init()
121 simu.add_dirichlet(
122 nodes_Fixed, [0] * dim, simu.Get_unknowns(), description="Fixed"
123 )
124 simu.add_surfLoad(nodes_Load, [-surfLoad], ["y"])
125
126 simu.Solve()
127
128 simu.Save_Iter()
129
130 return simu
131
132 simu = Simulations.Mesh_Optim_ZZ1(DoSimu, folder, threshold, iterMax, 1 / 10)
133 PyVista.Plot_BoundaryConditions(simu).show()
134
135 # ----------------------------------------------
136 # Results
137 # ----------------------------------------------
138 PyVista.Plot_Mesh(simu.mesh).show()
139 PyVista.Plot(simu, "ZZ1_e", nodeValues=False, nColors=11).show()
140
141 if plotProj:
142 simu.Set_Iter(0)
143 mesh0 = simu.mesh
144 u0 = np.reshape(simu.displacement, (mesh0.Nn, -1))
145
146 simu.Set_Iter(1)
147 mesh1 = simu.mesh
148
149 proj = Calc_projector(mesh0, mesh1)
150 uProj = np.zeros((mesh1.Nn, dim), dtype=float)
151 for d in range(dim):
152 uProj[:, d] = proj @ u0[:, d]
153
154 ax = Display.Plot_Result(
155 mesh0, np.linalg.norm(u0, axis=1), plotMesh=True, title="u0"
156 )
157 ax.plot(*mesh1.coord[:, :dim].T, ls="", marker="+", c="k", label="new nodes")
158 ax.legend()
159 Display.Plot_Result(
160 mesh1, np.linalg.norm(uProj, axis=1), plotMesh=True, title="uProj"
161 )
162
163 if makeParaview:
164 Paraview.Save_simu(simu, folder, nodeFields=["ZZ1_e"])
165
166 if makeMovie:
167
168 def func(plotter, n):
169 simu.Set_Iter(n)
170
171 PyVista.Plot_Mesh(simu, plotter=plotter)
172
173 zz1 = simu._Calc_ZZ1()[0]
174
175 plotter.add_title(f"ZZ1 = {zz1 * 100:.2f} %")
176
177 PyVista.Movie_func(func, len(simu.results), folder, "lmt.gif")
178
179 Tic.Plot_History()
180 plt.show()
Total running time of the script: (0 minutes 10.265 seconds)