- changed milestone to 1.4
Saving multiple functions to a File gives incorrect results without any error message
It is not clear to me if saving multiple functions to a file through the
File
interface is intended to be supported. However the current behavior is not acceptable.
The following example shows that one can save multiple functions to a file without getting any error message. However, when trying to visualize the result with Paraview
one gets that:
-
with
pvd
format all the fields appear in theParaview
menu but only the last saved is non-null. -
with
xdmf
format one gets an error message when dying to open the file inParaview
.
from dolfin import *
mesh = UnitSquareMesh(4,4)
# Create named functions
U = FunctionSpace(mesh, "CG", 1)
u1 = Function(U, name = "u1")
u2 = Function(U, name = "u2")
u1.interpolate(Expression("x[0]"))
u2.interpolate(Expression("x[1]"))
# Save to file
file_xdmf = File("my_file.xdmf")
file_pvd = File("my_file.pvd")
file_xdmf << (u1,0.)
file_xdmf << (u2,0.)
file_pvd << (u1,0.)
file_pvd << (u2,0.)
##
## Uncomment to test also vector-valued functions
##
#V = VectorFunctionSpace(mesh, "CG", 1)
#v = Function(V, name = "v")
#v.interpolate(Expression(("x[0]","x[1]")))
#file_xdmf << (v,0.)
#file_xdmf << (v,0.)
#file_pvd << (v,0.)
del file_pvd
del file_xdmf
Comments (31)
-
-
- changed milestone to 1.5
-
It is probably possible to divert each
Function
into a different block of XML in the XDMF format, e.g. by putting theFunction
name as part of the GridName
attribute for theTimeSeries
. -
-
assigned issue to
-
assigned issue to
-
- changed milestone to 1.4
New functionality now in branch chris/xdmf-multiple-function
-
- changed milestone to 1.5
-
XDMF now supports multiple functions per file, though it is not clear if ParaView accepts them correctly. More testing is probably needed.
PVD file support will be more difficult. I'm going to postpone any more changes to 1.6
-
- changed milestone to 1.6
- changed title to Saving multiple functions to a File gives incorrect results without any error message
-
Using the example given by @cmaurini, the XDMF output obtained gives in ParaView a correct
u2(x,y)=y
field but produces an uniformu1(x,y)=1
. Same case for the PVD format. -
@tianyikillua - my experience is that it is possible to get ParaView to display both fields, but it is not easy. You have to fiddle around with the Properties panel, under "Point Arrays" and "Hierarchy" and "Coloring". If you can find a flaw in the produced XDMF and suggest a fix, I'm happy to include it...
To be honest, I think it is better just to keep each field in a separate file.
-
- marked as minor
-
Another example of this problem.
It is not clear what a suitable user interface should look like. In most cases, what is required is a way to save multiple
Function
s at the same timestep.We could implement
XDMFFile::write(std::vector<std::shared_ptr<const Function> >, double time)
I suppose. -
A python script can be found here, which will parse the
xdmf
file and transform it so that Paraview can properly understand its contents.I would say this should be only a temporary solution. Perhaps that script could be transformed into a utility method in
dolfin
.As to the interface, I would stick with the practice:
file << (u1, t) file << (u2, t)
because
u2
above can in fact be the sameFunction
u1
, but with updated values. Ifvector<const Function*>
is required, then this is no longer possible to do. -
@allanmulin - I'm not sure what you mean about the interface. My suggestion would result in:
file << ([u1, u2, u3], 0.0) file << ([u1, u2, u3], 1.0)
etc. The problem at the moment is that there is no guarantee of two functions having the same set of times in their time series.
-
@chris_richardson Consider the example:
u = Function(U) while t < T: for i in range(10): u.interpolate(Expression("i*x[0] + x[1]/i", i=i)) u.rename('u' + str(i)) file << (u, t)
Note that only one instance of
Function
is necessary. Now, if one has to dofile << ([u1, u2, u3, ..., u10], t)
, then this becomes a burden to the user - in that specific case, for example, there would be 9 unnecessaryFunction
instances to manage.I believe that reading one pair
(Function, double)
at a time like infile << (u, t)
is the most flexible solution. -
We should stop using the
<<
syntax.Function
s are not streams, and we should be able to stick any data we want in a HDF5 file (with a tag) and pull it out with a tag. -
Generally agree with Garth. But I'd remind that a tag could be derived from a combination of object name/id and/or time it it helps anywhere.
-
@chris_richardson, what about just modifying the destructor of class
XDMFFile
? You keep everything else as it is for now, and when the file is no longer going to be written, you apply this python script to the created filexdmf
file. One would only need to use the C++ librarypugixml
instead of the python libraryElementTree
.This way, we can save one function at a time (with a tag if needed) like how I described earlier.
As to @garth-wells, a
double
, say3.14
, isn't a stream like aFunction
, and still it is quite obvious and standard whatstd::cout << 3.14;
means. I find the functionality provided byoperator<<
in classFile
quite intuitive. However, I would not see a problem to usefile.write(u, tag)
andfile.read(u, tag)
. -
Thanks for the feedback. I'm sure we'll find a more suitable fix for the next release.
-
@allanleal It's not that
Function
is a stream either. The design ofFile
andFile::operator<<
is flawed, which we have to live with now but we shouldn't perpetuate the design mistake, because we end up in even more of a knot.HDF5 (and to a lesser extend XDMF) is a very powerful format and shouldn't go through the
File
interface. TheFile
interface 'works' if all file backend have the same functionality and are suited to the same interface, which they aren't. TheFile
interface is one of the reasons DOLFIN has never properly supported hierarchical file formats, despite some formats being designed to do this. e.g. XML and HDF5. -
What Garth said. Let's not use << for anything else than legacy simple writing of an object to file.
-
What is the currently recommended way for storing data then? (Most (all?) examples from documtation use
File
.) -
@nschloe You can use
File
. In developing DOLFIN, we just shouldn't make theFile
interface 'support' features that are not appropriate for the interface. -
- marked as trivial
- removed milestone
-
Just a note about a previous comment:
Using the example given by Corrado Maurini, the XDMF output obtained gives in ParaView a correct u2(x,y)=y field but produces an uniform u1(x,y)=1. Same case for the PVD format.
What is happening is that the pvd file points to multiple vtu files per time step. Since these vtu files all contain the mesh there will be multiple meshes per time step. If you see a uniform field then you are looking at a mesh belonging to another function. You can right click on the mesh and select "Hide Block" to see what is below. You can play with "Hide Block" and "Show All Blocks" to see all fields. This is inconvenient, but it may be how it must be unless multiple functions end up on the same vtu file.
-
Using
master
branch, the XDMF now produces the correct output, and uses the same mesh for both u1 and u2 (at least, it does for me with the code above). -
I can confirm this. XDMF works, PVD does not (without hiding and showing meshes).
-
- changed status to resolved
Closing this, as it now broadly works for XDMF. If PVD is an issue, then it can be reopened as a new issue, but I suggest deprecating PVD where possible.
-
Does PVD throw an error?
-
I guess it doesn't throw an error, but the usage is a bit strange, anyway. This is could be considered a symptom of
<<
. -
Could it throw an error, or does the interface prevent this? First write could store the reference to the
Function
. - Log in to comment