Homog1#

Conduct homogenization using an example outlined in Computational Homogenization of Heterogeneous Materials with Finite Elements.

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

Total running time of the script: (0 minutes 1.091 seconds)

Gallery generated by Sphinx-Gallery