Note
Go to the end to download the full example code.
Homog1#
Conduct homogenization using an example outlined in ‘Computational Homogenization of Heterogeneous Materials with Finite Elements’.
Reference: https://doi.org/10.1007/978-3-030-18383-7 Section 4.7 with corrected values on page 89 (Erratum).
f = 0.4
c1111 = 6.743336039055451
c1122 = 4.5944253955082095
c1212 = 0.6256584299841418
15 from EasyFEA import Display, Models, plt, np, ElemType, Simulations
16 from EasyFEA.Geoms import Points, Circle
17 from EasyFEA.fem import LagrangeCondition, FeArray
18 from typing import Optional
19
20
21 def Compute_ukl(
22 simu: Simulations.ElasticSimu,
23 nodes_border: np.ndarray,
24 Ekl: np.ndarray,
25 paired_nodes: Optional[np.ndarray] = None,
26 pltSol=False,
27 useMean0=False,
28 ):
29 simu.Bc_Init()
30 mesh = simu.mesh
31 coord = mesh.coordGlob
32
33 usePER = paired_nodes is not None
34
35 def func_ux(x, y, z):
36 return Ekl.dot([x, y])[0]
37
38 def func_uy(x, y, z):
39 return Ekl.dot([x, y])[1]
40
41 simu.add_dirichlet(nodes_border, [func_ux, func_uy], ["x", "y"])
42
43 if usePER:
44 for n0, n1 in paired_nodes:
45 nodes = np.array([n0, n1])
46
47 for direction in ["x", "y"]:
48 dofs = simu.Bc_dofs_nodes(nodes, [direction])
49
50 values = Ekl @ [
51 coord[n0, 0] - coord[n1, 0],
52 coord[n0, 1] - coord[n1, 1],
53 ]
54 value = values[0] if direction == "x" else values[1]
55
56 condition = LagrangeCondition(
57 "elastic", nodes, dofs, [direction], [value], [1, -1]
58 )
59 simu._Bc_Add_Lagrange(condition)
60
61 if useMean0:
62 nodes = mesh.nodes
63 vect = np.ones(mesh.Nn) * 1 / mesh.Nn
64
65 # sum u_i / Nn = 0
66 dofs = simu.Bc_dofs_nodes(nodes, ["x"])
67 condition = LagrangeCondition("elastic", nodes, dofs, ["x"], [0], [vect])
68 simu._Bc_Add_Lagrange(condition)
69
70 # sum v_i / Nn = 0
71 dofs = simu.Bc_dofs_nodes(nodes, ["y"])
72 condition = LagrangeCondition("elastic", nodes, dofs, ["y"], [0], [vect])
73 simu._Bc_Add_Lagrange(condition)
74
75 ukl = simu.Solve()
76
77 simu.Save_Iter()
78
79 if pltSol:
80 Display.Plot_Result(simu, "ux", deformFactor=0.3)
81 Display.Plot_Result(simu, "uy", deformFactor=0.3)
82
83 Display.Plot_Result(simu, "Sxx", deformFactor=0.3)
84 Display.Plot_Result(simu, "Syy", deformFactor=0.3)
85 Display.Plot_Result(simu, "Sxy", deformFactor=0.3)
86
87 return ukl
88
89
90 if __name__ == "__main__":
91 Display.Clear()
92
93 # ----------------------------------------------
94 # Configuration
95 # ----------------------------------------------
96
97 # use Periodic boundary conditions ?
98 usePER = True # FALSE mean KUBC
99
100 # ----------------------------------------------
101 # Mesh
102 # ----------------------------------------------
103 meshSize = 1 / 15
104
105 p0 = (-1 / 2, -1 / 2)
106 p1 = (1 / 2, -1 / 2)
107 p2 = (1 / 2, 1 / 2)
108 p3 = (-1 / 2, 1 / 2)
109 pts = [p0, p1, p2, p3]
110 contour = Points(pts, meshSize)
111
112 # inclusion
113 f = 0.4
114 r = 1 * np.sqrt(f / np.pi)
115 inclusion = Circle((0, 0), 2 * r, meshSize, isHollow=False)
116
117 mesh = contour.Mesh_2D([inclusion], ElemType.TRI6)
118
119 Display.Plot_Mesh(mesh, title="RVE")
120
121 if usePER:
122 nodes_border = mesh.Nodes_Tags(["P0", "P1", "P2", "P3"])
123 paired_nodes = mesh.Get_Paired_Nodes(nodes_border, True)
124 else:
125 nodes_border = mesh.Nodes_Tags(["L0", "L1", "L2", "L3"])
126 paired_nodes = None
127
128 # ----------------------------------------------
129 # Material and Simulation
130 # ----------------------------------------------
131 elements_inclusion = mesh.Elements_Tags(["S1"])
132 elements_matrix = mesh.Elements_Tags(["S0"])
133
134 E = np.zeros_like(mesh.groupElem.elements, dtype=float)
135 v = np.zeros_like(mesh.groupElem.elements, dtype=float)
136
137 E[elements_matrix] = 1 # MPa
138 v[elements_matrix] = 0.45
139
140 if elements_inclusion.size > 0:
141 E[elements_inclusion] = 50
142 v[elements_inclusion] = 0.3
143
144 material = Models.ElasIsot(2, E, v, planeStress=False)
145
146 simu = Simulations.ElasticSimu(mesh, material)
147
148 Display.Plot_Result(simu, E, nodeValues=False, title="E [MPa]")
149 Display.Plot_Result(simu, v, nodeValues=False, title="v")
150
151 # ----------------------------------------------
152 # Homogenization
153 # ----------------------------------------------
154 r2 = np.sqrt(2)
155 E11 = np.array([[1, 0], [0, 0]])
156 E22 = np.array([[0, 0], [0, 1]])
157 E12 = np.array([[0, 1 / r2], [1 / r2, 0]])
158
159 u11 = Compute_ukl(simu, nodes_border, E11, paired_nodes)
160 u22 = Compute_ukl(simu, nodes_border, E22, paired_nodes)
161 u12 = Compute_ukl(simu, nodes_border, E12, paired_nodes, True)
162
163 u11_e = mesh.Locates_sol_e(u11, asFeArray=True)
164 u22_e = mesh.Locates_sol_e(u22, asFeArray=True)
165 u12_e = mesh.Locates_sol_e(u12, asFeArray=True)
166
167 # ----------------------------------------------
168 # Effective elasticity tensor (C_hom)
169 # ----------------------------------------------
170 U_e = FeArray.zeros(*u11_e.shape, 3)
171
172 U_e[..., 0] = u11_e
173 U_e[..., 1] = u22_e
174 U_e[..., 2] = u12_e
175
176 matrixType = "mass"
177 wJ_e_pg = mesh.Get_weightedJacobian_e_pg(matrixType)
178 B_e_pg = mesh.Get_B_e_pg(matrixType)
179
180 C_Mat = Models.Reshape_variable(material.C, *B_e_pg.shape[:2])
181
182 # Be careful here you have to use all the area even if there are holes
183 # if you use the mesh area, multiply C_hom by the porosity (1-f)
184 C_hom = (wJ_e_pg * C_Mat @ B_e_pg @ U_e).sum((0, 1)) / mesh.area
185
186 if inclusion.isHollow and mesh.area != 1:
187 C_hom *= 1 - f
188
189 # Display.Plot_BoundaryConditions(simu)
190
191 print(f"f = {f}")
192 print(f"c1111 = {C_hom[0, 0]}")
193 print(f"c1122 = {C_hom[0, 1]}")
194 print(f"c1212 = {C_hom[2, 2] / 2}")
195
196 plt.show()
Total running time of the script: (0 minutes 1.109 seconds)


![E [MPa]](../../_images/sphx_glr_Homog1_003.png)





