Hi,
I’m trying to solve an iterative FEM problem, but I am getting weird results exporting the results to ParaView. The problem needs to be solved for incremental loading, but for certain timesteps, the XDMF file appears to get inf & nan values. Here is an example result of a single step, where the part on the right looks OK, but there are regions with nan & inf values.
When I export to PDFs using pyvista, the result looks much better:
I’m still poorly understanding the whole FunctionSpace → Function → Interpolate process when I already have a mesh and the solution values, so I’m guessing I am doing something incorrect there.
Here is the code:
import os
import numpy as np
import ufl
import dolfinx
from dolfinx import mesh, fem, io
from dolfinx.io import XDMFFile
from dolfinx.plot import vtk_mesh
from dolfinx.fem.petsc import LinearProblem
from mpi4py import MPI
from petsc4py import PETSc
import pyvista as pv
print(f"dolfinx version: {dolfinx.__version__}")
# Read the mesh
mesh_file = 'meshes/L.xdmf'
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, mesh_file, "r") as xdmf_file:
mesh_domain = xdmf_file.read_mesh(name="Grid")
tdim = mesh_domain.topology.dim - 1
# Vector function space for displacement field
element = ufl.VectorElement("CG", mesh_domain.ufl_cell(), 1)
V = fem.FunctionSpace(mesh_domain, element)
# Define trial and test functions
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
# Define material properties (Young's modulus, Poisson's ratio)
E = 210e9 # Example: 210 GPa for steel
nu = 0.3
lambda_ = E * nu / ((1 + nu) * (1 - 2 * nu))
mu = E / (2 * (1 + nu))
# Strain and stress
def epsilon(u):
return ufl.sym(ufl.grad(u))
def sigma(u):
return lambda_ * ufl.div(u) * ufl.Identity(len(u)) + 2 * mu * epsilon(u)
#### Dirichlet BC (0 displacement on top boundary)
# Define function for displacement boundary conditions
uD = fem.Function(V)
uD.interpolate(lambda x: np.zeros((3, x.shape[1]))) # zero displacements
def boundary_points(x): # return top boundary points
return np.isclose(x[1], max(x[1]))
boundary_dofs = fem.locate_dofs_geometrical(V, boundary_points)
bc = fem.dirichletbc(value=uD, dofs=boundary_dofs)
##### Neumann BC (stress/force on the right boundary)
def right_boundary(x): # return right boundary points
return np.isclose(x[0], max(x[0]))
load_dofs = mesh.locate_entities_boundary(mesh_domain, tdim, right_boundary)
bound_tag = mesh.MeshTags(load_dofs)
max_load = -6 # Maximum load magnitude
num_increments = 10 # Number of increments
increment = max_load / num_increments # Load increment
g = fem.Constant(mesh_domain, PETSc.ScalarType((0, 0, 0)))
ds = ufl.Measure('ds', subdomain_data=bound_tag)
# Weak form
a = ufl.inner(sigma(u), epsilon(v)) * ufl.dx
f = fem.Constant(mesh_domain, PETSc.ScalarType((0, 0, 0)))
L = ufl.inner(f, v) * ufl.dx + ufl.inner(g, v) * ufl.ds
# Solve the problem for several steps, and save solutions
problem = dolfinx.fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
solutions = []
for step in range(1, num_increments + 1):
# Update bc applied load value:
g.value = PETSc.ScalarType((0, step * increment, 0))
# Solve the problem
uh = problem.solve()
# Store the solution for analysis or post-processing
solutions.append(uh.copy())
# Save results for ParaView
plot_space = fem.FunctionSpace(mesh_domain, ("CG", 1))
u_y = fem.Function(plot_space)
with XDMFFile(mesh_domain.comm, "linEla_debug/linOut.xdmf", "w") as write_file:
write_file.write_mesh(mesh_domain)
for step, uh in enumerate(solutions):
# Plot result to xdmffile
u_y.name = "$u_y$"
u_y.interpolate(lambda x: uh.x.array[1::3]) # [1::3] selects y displacements from 3D vector
write_file.write_function(u_y, step)
# 2D y displacement pdf plots using pyvista instead
u_topology, u_cell_types, u_geometry = vtk_mesh(V)
u_grid = pv.UnstructuredGrid(u_topology, u_cell_types, u_geometry)
u_grid.point_data["u"] = uh.x.array[1::3]
u_grid.set_active_scalars("u")
u_plotter = pv.Plotter()
u_plotter.add_mesh(u_grid, show_edges=True)
u_plotter.view_xy()
u_plotter.save_graphic(f'linEla_debug/linOutCont_y_{step}.pdf')
Many thanks!