@dokken thank you for being patient with me here is the corrected code:
import gmsh
import sys
import pyvista
from dolfinx import mesh, fem, plot, io, default_scalar_type
from dolfinx.fem.petsc import LinearProblem
from mpi4py import MPI
import ufl
import numpy as np
import matplotlib.pyplot as plt
import dolfinx
import time
def make_layers(n):
length = 1000;width = 1000; thickness= 0.5
gmsh.initialize()
gmsh.option.setNumber("General.Verbosity",0)
gmsh.model.add("plate")
for i in range(n):
gmsh.model.occ.addBox(0,0,i*thickness,length,width,thickness)
gmsh.model.occ.synchronize()
vols = gmsh.model.getEntities(3)
for i in range(n-1):
gmsh.model.occ.fragment([vols[i]],[vols[i+1]],removeObject=True,removeTool=True)
gmsh.model.occ.synchronize()
lines = gmsh.model.getEntities(1)
lengths = []
for i in lines:
lengths.append(gmsh.model.occ.getMass(1,i[1]))
surf = gmsh.model.getEntities(2)
vols = gmsh.model.getEntities(3)
for i in range(len(lines)):
if lengths[i] == length:
gmsh.model.mesh.setTransfiniteCurve(lines[i][1],2)
else:
gmsh.model.mesh.setTransfiniteCurve(lines[i][1],0)
for i in surf:
gmsh.model.mesh.setTransfiniteSurface(i[1])
gmsh.model.mesh.setRecombine(i[0],i[1])
for i in vols:
gmsh.model.mesh.setTransfiniteVolume(i[1])
f_surfaces = gmsh.model.getEntitiesInBoundingBox(-length/2,-width/2,-thickness/2,length/2,(n+1)*width,(n+1)*thickness,2)
l_surfaces = gmsh.model.getEntitiesInBoundingBox(length/2,-width/2,-thickness/2,2*length,(n+1)*width,(n+1)*thickness,2)
fixed_surfaces = []
load_surfaces = []
vol_count = 1000
for i in range(n):
fixed_surfaces.append(f_surfaces[i][1])
load_surfaces.append(l_surfaces[i][1])
gmsh.model.addPhysicalGroup(3,[i+1],vol_count)
gmsh.model.setPhysicalName(3,vol_count,"volume"+ str(i+1))
vol_count += 1
gmsh.model.addPhysicalGroup(2,fixed_surfaces,101)
gmsh.model.setPhysicalName(2,101,"fixed_surface")
#print(fixed_surfaces)
gmsh.model.addPhysicalGroup(2,load_surfaces,102)
gmsh.model.setPhysicalName(2,102,"force_surface")
#print(load_surfaces)
gmsh.model.mesh.generate(3)
gmsh.model.mesh.refine()
# if '-nopopup' not in sys.argv:
# gmsh.fltk.run()
domain, markers, facets = io.gmshio.model_to_mesh(gmsh.model, MPI.COMM_WORLD, 0, gdim=3)
gmsh.finalize()
return domain,markers,facets
def fe_case(n):
domain,markers,facets = make_layers(n)
E = 1.1e9;nu = 0.3
stiffness_matrix = ufl.as_matrix([[float((E/((1+nu)*(1-2*nu)))*(1-nu)), float((E/((1+nu)*(1-2*nu)))*nu), float((E/((1+nu)*(1-2*nu)))*nu), 0, 0, 0],
[float((E/((1+nu)*(1-2*nu)))*nu), float((E/((1+nu)*(1-2*nu)))*(1-nu)), float((E/((1+nu)*(1-2*nu)))*nu), 0, 0, 0],
[float((E/((1+nu)*(1-2*nu)))*nu), float((E/((1+nu)*(1-2*nu)))*nu), float((E/((1+nu)*(1-2*nu)))*(1-nu)), 0, 0, 0],
[ 0, 0, 0, float(E/(1+nu)), 0, 0],
[ 0, 0, 0, 0, float(E/(1+nu)), 0],
[ 0, 0, 0, 0, 0, float(E/(1+nu))]])
C = stiffness_matrix*np.ones(n) # all stiffness matrices are same just for simplicity , ideally the values would be different for different subdomains
def epsilon(v):
return ufl.sym(ufl.grad(v))
def strain2voigt(e):
return ufl.as_vector([e[0,0],e[1,1],e[2,2],2*e[1,2], 2*e[0,2],2*e[0,1]])
def voigt2stress(s):
return ufl.as_tensor([
[s[0], s[5], s[4]],
[s[5], s[1], s[3]],
[s[4], s[3], s[2]]
])
def sigma(v,C):
return voigt2stress(ufl.dot(C, strain2voigt(epsilon(v))))
# Create mesh and define function space
V = fem.functionspace(domain, ("Lagrange", 1, (3,)))
bc_dofs = fem.locate_dofs_topological(V, 2, facets.find(101))
bcs = fem.dirichletbc(np.zeros((3,)), bc_dofs, V)
ds = ufl.Measure("ds", domain=domain,subdomain_data=facets)
dx = ufl.Measure("dx", domain=domain,subdomain_data=markers)
normal = ufl.FacetNormal(domain)
u = ufl.TrialFunction(V)
d = domain.geometry.dim
v = ufl.TestFunction(V)
f = fem.Constant(domain, default_scalar_type((0, 0, 0)))
T = fem.Constant(domain,-1.0e6)
a = 0
start = time.time()
for i in range(n):
a += ufl.inner(sigma(u,C[i]), epsilon(v))*dx(1000+i)
end = time.time()
print(end - start)
L = ufl.dot(f, v)*ufl.dx + ufl.dot(T*normal, v)*ds(102)
# Compute solution
#u = fem.Function(V)
start = time.time()
problem = LinearProblem(a, L, bcs=[bcs], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
end = time.time()
print(end - start)
start = time.time()
uh = problem.solve()
end = time.time()
print(end - start)
pyvista.start_xvfb()
# Create plotter and pyvista grid
p = pyvista.Plotter()
topology, cell_types, geometry = plot.vtk_mesh(V)
grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)
# Attach vector values to grid and warp grid by vector
grid["u"] = uh.x.array.reshape((geometry.shape[0], 3))
actor_0 = p.add_mesh(grid, style="wireframe", color="k")
warped = grid.warp_by_vector("u", factor=1)
actor_1 = p.add_mesh(warped, show_edges=True)
p.show_axes()
if not pyvista.OFF_SCREEN:
p.show()
print(uh.vector.max())
return uh.x.array.max()
fe_case(4000)