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).

  • RVE
  • Periodic boundary conditions
  • E [MPa]
  • v
  • $ux$
  • $uy$
  • $\sigma_{xx}$
  • $\sigma_{yy}$
  • $\sigma_{xy}$
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.289 seconds)

Gallery generated by Sphinx-Gallery