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

Gallery generated by Sphinx-Gallery