Hello folks,
I’m trying to import the results of an OpenFoam calculation result as a dolfinx Function on a MixedSpace. I have a VTK-like file format with point values that I would like to read and use in dolfinx. I’m having a surprisingly hard time doing it.
I’ve used this ppt (p18) as a source of inspiration first. I’ve exported my OpenFoam results in the .vtk format using legacy options, then tried to open them in dolfinx. Unfortunately it seems dolfinx.io.VTKFile does not support reading yet (according to this old docs).
I’ve moved to meshio for reading the file but it seems to be unable to handle POLYDATA VTK files.
So I’ve tried reading the OpenFoam output into Paraview then convert it into .xdmf (for some reason my Paraview actually produces a .xmf and a .h5 file, specifying point values only). dolfinx.io cannot read .xmf files either (as said in this question), but meshio seems to handle it fine.
Then, I write the mesh and read it again as a dolfinx object, and attempt to directly map the values from meshio onto it, with the added complexity of node reordering and vector ordering from this old post. This also seems to work, but fails when I try to print it for a sanity check with the unexpected traceback :
Traceback (most recent call last):
File "/home/shared/src/tset.py", line 40, in <module>
xdmf.write_function(p)
File "/usr/local/dolfinx-real/lib/python3.8/dist-packages/dolfinx/io.py", line 46, in write_function
super().write_function(u_cpp, t, mesh_xpath)
RuntimeError: Newton method failed to converge for non-affine geometry
My MWE follow, inside a dolfinx container with pip3 install --no-binary=h5py h5py meshio
prior execution :
import meshio, ufl
import numpy as np
import dolfinx as dfx
from dolfinx.io import XDMFFile
from mpi4py.MPI import COMM_WORLD
# Read the mesh, recreate it using meshio magic to make it dolfinx friendly
def create_mesh(mesh, cell_type):
cells = mesh.get_cells_type(cell_type)
out_mesh = meshio.Mesh(points=mesh.points, cells={cell_type: cells})
return out_mesh
in_mesh = meshio.read("front3.xmf")
out_mesh = create_mesh(in_mesh, "quad")
meshio.write("mesh.xdmf", out_mesh)
with XDMFFile(COMM_WORLD, "mesh.xdmf", "r") as file:
mesh = file.read_mesh(name="Grid")
# Handling reordering
idcs = np.argsort(mesh.geometry.input_global_indices).astype('int32')
vec_idcs = np.vstack((idcs,idcs+np.max(idcs),idcs+2*np.max(idcs)))
# Create useful dolfinx objects
FE_vector=ufl.VectorElement("Lagrange",mesh.ufl_cell(),1,3)
FE_scalar=ufl.FiniteElement("Lagrange",mesh.ufl_cell(),1)
p_Space=dfx.FunctionSpace(mesh,FE_scalar)
p = dfx.Function(p_Space)
u_Space=dfx.FunctionSpace(mesh,FE_vector)
U = dfx.Function(u_Space)
# Map one onto the other
p.vector[ idcs] = in_mesh.point_data['p']
U.vector[vec_idcs] = in_mesh.point_data['U'].reshape(-1,order='F')
# Print to make human readable
with XDMFFile(COMM_WORLD, "sanity_check.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
xdmf.write_function(p)
xdmf.write_function(U)
My front3 files are available here.