Newbie here. I tried to follow some tutorials and wrote the following code for a cantilever beam under a uniform load. However, I am not able to output the stresses to a xdmf file. I tried to write a syntax similar to what I found for displacement in the tutorials, but that does not help.
Here is the code snippet
problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()
stress = sigma(uh)
with io.XDMFFile(domain.comm, "simple_beam.xdmf", "w") as xdmf:
xdmf.write_mesh(domain)
uh.name = "Deformation"
xdmf.write_function(uh)
sigma.name = 'Stresses'
xdmf.write_function(sigma)
Here is the error message
Traceback (most recent call last):
File "/Users/aaquib/Desktop/fenics/test1.py", line 60, in <module>
xdmf.write_function(sigma)
File "/Users/aaquib/opt/anaconda3/envs/fenicsx-env/lib/python3.10/site-packages/dolfinx/io/utils.py", line 150, in write_function
super().write_function(getattr(u, "_cpp_object", u), t, mesh_xpath)
TypeError: write_function(): incompatible function arguments. The following argument types are supported:
1. (self: dolfinx.cpp.io.XDMFFile, function: dolfinx.cpp.fem.Function_float64, t: float, mesh_xpath: str) -> None
2. (self: dolfinx.cpp.io.XDMFFile, function: dolfinx.cpp.fem.Function_complex128, t: float, mesh_xpath: str) -> None
Invoked with: <dolfinx.io.utils.XDMFFile object at 0x166518900>, <function sigma at 0x1664e4430>, 0.0, "/Xdmf/Domain/Grid[@GridType='Uniform'][1]"
I saw some old questions based on legacy version of fenics, where TensorFunctionSpace was recommended, but apparently that does not work with fenicsx?
You should use dolfinx.fem.Expression to interpolate the stress into a suitable function space (DG of some order) and use dolfinx.io.VTXWriter to write it to file preserving the function space.
You can see how B is computed in Electromagnetics example — FEniCSx tutorial
E.g.
W = VectorFunctionSpace(mesh, ("DG", 0))
B = Function(W)
B_expr = Expression(as_vector((A_z.dx(1), -A_z.dx(0))), W.element.interpolation_points())
B.interpolate(B_expr)
As you can see, I am trying to save each component of the stress as a scalar (here I just give the code for one component). The first three lines compile successfully, but the fourth gives the following error
Traceback (most recent call last):
File "/Users/aaquib/Desktop/fenics/test1.py", line 61, in <module>
sigma_xx.interpolate(sigma_xx_exp)
File "/Users/aaquib/opt/anaconda3/envs/fenicsx-env/lib/python3.10/site-packages/dolfinx/fem/function.py", line 343, in interpolate
_interpolate(u, cells)
File "/Users/aaquib/opt/anaconda3/envs/fenicsx-env/lib/python3.10/functools.py", line 889, in wrapper
return dispatch(args[0].__class__)(*args, **kw)
File "/Users/aaquib/opt/anaconda3/envs/fenicsx-env/lib/python3.10/site-packages/dolfinx/fem/function.py", line 334, in _
self._cpp_object.interpolate(expr._cpp_object, cells)
RuntimeError: Function value size not equal to Expression value size
Thank you both @nav and @dokken ! This solved my issue and its unfortunate that this site wont allow me to mark both of your comments as solution…
Anyhow, I am just attaching what worked for me so that people who come in later can benefit