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_kubc: 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.coord
32
33 usePBC = 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 directions = ["x", "y"]
42 simu.add_dirichlet(nodes_kubc, [func_ux, func_uy], directions)
43
44 if usePBC:
45 for n0, n1 in paired_nodes:
46 nodes = np.array([n0, n1])
47
48 for d, direction in enumerate(directions):
49 dofs = simu.Bc_dofs_nodes(nodes, [direction])
50
51 values = Ekl @ [
52 coord[n0, 0] - coord[n1, 0],
53 coord[n0, 1] - coord[n1, 1],
54 ]
55 value = values[d]
56
57 condition = LagrangeCondition(
58 "elastic", nodes, dofs, [direction], [value], [1, -1]
59 )
60 simu._Bc_Add_Lagrange(condition)
61
62 if useMean0:
63 nodes = mesh.nodes
64 vect = np.ones(mesh.Nn) * 1 / mesh.Nn
65
66 # sum u_i / Nn = 0
67 dofs = simu.Bc_dofs_nodes(nodes, ["x"])
68 condition = LagrangeCondition("elastic", nodes, dofs, ["x"], [0], [vect])
69 simu._Bc_Add_Lagrange(condition)
70
71 # sum v_i / Nn = 0
72 dofs = simu.Bc_dofs_nodes(nodes, ["y"])
73 condition = LagrangeCondition("elastic", nodes, dofs, ["y"], [0], [vect])
74 simu._Bc_Add_Lagrange(condition)
75
76 ukl = simu.Solve()
77
78 simu.Save_Iter()
79
80 if pltSol:
81 Display.Plot_Result(simu, "ux", deformFactor=0.3)
82 Display.Plot_Result(simu, "uy", deformFactor=0.3)
83
84 Display.Plot_Result(simu, "Sxx", deformFactor=0.3)
85 Display.Plot_Result(simu, "Syy", deformFactor=0.3)
86 Display.Plot_Result(simu, "Sxy", deformFactor=0.3)
87
88 return ukl
89
90
91 if __name__ == "__main__":
92 Display.Clear()
93
94 # ----------------------------------------------
95 # Configuration
96 # ----------------------------------------------
97
98 # use Periodic boundary conditions ?
99 usePBC = True
100
101 # ----------------------------------------------
102 # Mesh
103 # ----------------------------------------------
104 meshSize = 1 / 15
105
106 p0 = (-1 / 2, -1 / 2)
107 p1 = (1 / 2, -1 / 2)
108 p2 = (1 / 2, 1 / 2)
109 p3 = (-1 / 2, 1 / 2)
110 pts = [p0, p1, p2, p3]
111 contour = Points(pts, meshSize)
112
113 # inclusion
114 f = 0.4
115 r = 1 * np.sqrt(f / np.pi)
116 inclusion = Circle((0, 0), 2 * r, meshSize, isHollow=False)
117
118 mesh = contour.Mesh_2D([inclusion], ElemType.TRI6)
119
120 Display.Plot_Mesh(mesh, title="RVE")
121
122 if usePBC:
123 nodes_kubc = mesh.Nodes_Tags(["P0", "P1", "P2", "P3"])
124 paired_nodes = mesh.Get_Paired_Nodes(nodes_kubc, True)
125 else:
126 nodes_kubc = mesh.Nodes_Tags(["L0", "L1", "L2", "L3"])
127 paired_nodes = None
128
129 # ----------------------------------------------
130 # Material and Simulation
131 # ----------------------------------------------
132 elements_inclusion = mesh.Elements_Tags(["S1"])
133 elements_matrix = mesh.Elements_Tags(["S0"])
134
135 E = np.zeros_like(mesh.groupElem.elements, dtype=float)
136 v = np.zeros_like(mesh.groupElem.elements, dtype=float)
137
138 E[elements_matrix] = 1 # MPa
139 v[elements_matrix] = 0.45
140
141 if elements_inclusion.size > 0:
142 E[elements_inclusion] = 50
143 v[elements_inclusion] = 0.3
144
145 material = Models.ElasIsot(2, E, v, planeStress=False)
146
147 simu = Simulations.ElasticSimu(mesh, material)
148
149 Display.Plot_Result(simu, E, nodeValues=False, title="E [MPa]")
150 Display.Plot_Result(simu, v, nodeValues=False, title="v")
151
152 # ----------------------------------------------
153 # Homogenization
154 # ----------------------------------------------
155 r2 = np.sqrt(2)
156 E11 = np.array([[1, 0], [0, 0]])
157 E22 = np.array([[0, 0], [0, 1]])
158 E12 = np.array([[0, 1 / r2], [1 / r2, 0]])
159
160 u11 = Compute_ukl(simu, nodes_kubc, E11, paired_nodes)
161 u22 = Compute_ukl(simu, nodes_kubc, E22, paired_nodes)
162 u12 = Compute_ukl(simu, nodes_kubc, E12, paired_nodes, True)
163
164 u11_e = mesh.Locates_sol_e(u11, asFeArray=True)
165 u22_e = mesh.Locates_sol_e(u22, asFeArray=True)
166 u12_e = mesh.Locates_sol_e(u12, asFeArray=True)
167
168 # ----------------------------------------------
169 # Effective elasticity tensor (C_hom)
170 # ----------------------------------------------
171 U_e = FeArray.zeros(*u11_e.shape, 3)
172
173 U_e[..., 0] = u11_e
174 U_e[..., 1] = u22_e
175 U_e[..., 2] = u12_e
176
177 matrixType = "mass"
178 wJ_e_pg = mesh.Get_weightedJacobian_e_pg(matrixType)
179 B_e_pg = mesh.Get_B_e_pg(matrixType)
180
181 C_Mat = Models.Reshape_variable(material.C, *B_e_pg.shape[:2])
182
183 # Be careful here you have to use all the area even if there are holes
184 # if you use the mesh area, multiply C_hom by the porosity (1-f)
185 C_hom = (wJ_e_pg * C_Mat @ B_e_pg @ U_e).sum((0, 1)) / mesh.area
186
187 if inclusion.isHollow and mesh.area != 1:
188 C_hom *= 1 - f
189
190 # Display.Plot_BoundaryConditions(simu)
191
192 print(f"f = {f}")
193 print(f"c1111 = {C_hom[0, 0]}")
194 print(f"c1122 = {C_hom[0, 1]}")
195 print(f"c1212 = {C_hom[2, 2] / 2}")
196
197 plt.show()
Total running time of the script: (0 minutes 1.117 seconds)


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





