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


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





