Writing ugrid Xdmf3 a time step at a time

I’m trying to write to a Xdmf3 file (with vtkUnstructuredGrid data) over time, and not all at once. I’ve read the vtkTimeSourceExample source, some of the vtkXdmf3Writer source, and some examples of related usage, but still struggling. (Figured out the reader though!)

Where I’m at right now is that I can write a single time step (setting the time also), with what I think is the correct information. From there on, I don’t understand how to use this particular writer, because it has no WriteNextTime function etc. I’m just trying to use the Write function twice and change the time in between.

(I can’t get vtkTimeSourceExample to write multiple steps one at a time either by the way. I understand I can inherit from vtkUnstructuredGridAlgorithm and do my own thing later, but not there yet.)

#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkUnstructuredGrid.h>
#include <vtkXdmf3Writer.h>
#include <vtkInformation.h>
#include <vtkCompositeDataPipeline.h>

int main()
{
    vtkNew<vtkXdmf3Writer> writer;
    writer->SetFileName("1.xdmf");

    vtkNew<vtkPoints> points;
    points->SetDataType(VTK_DOUBLE);
    points->SetNumberOfPoints(2);
    points->SetPoint(0, 1, 2, 3);
    points->SetPoint(1, 4, 5, 6);

    vtkNew<vtkUnstructuredGrid> grid;
    grid->SetPoints(points);

    //  I don't see this get used much, but I think it's fine?
    writer->SetInputData(grid);

    double time_steps[5] {.5, 1, 2, 4, 8};
    double time_range[2] {.5,          8};

    //  How it's done in vtkTimeSourceExample.
    grid->GetInformation()->Set(vtkCompositeDataPipeline::TIME_STEPS(), time_steps, 5);
    grid->GetInformation()->Set(vtkCompositeDataPipeline::TIME_RANGE(), time_range, 2);
    grid->GetInformation()->Set(vtkAlgorithm::CAN_HANDLE_PIECE_REQUEST(), 1);

    std::cout << *grid->GetInformation();
    //  Information about the same as a read vtkUnstructuredGrid from vtkXdmf3Reader.
    /*
        vtkInformation (0x600002650c40)
        Debug: Off
        Modified Time: 132
        Reference Count: 1
        Registered Events: (none)
        CAN_HANDLE_PIECE_REQUEST: 1
        TIME_RANGE: 0.5 8
        TIME_STEPS: 0.5 1 2 4 8
        DATA_NUMBER_OF_GHOST_LEVELS: 0
        DATA_NUMBER_OF_PIECES: 1
        DATA_PIECE_NUMBER: -1
        DATA_EXTENT_TYPE: 0
    */

    grid->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(), time_steps[1]);
    writer->Write();
    //  It wrote the object with the first time equaling time_steps[1], so that works.
    //  Beyond this though, doesn't seem to do anything. I'm sure I'm just using it wrong.
    grid->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(), time_steps[2]);
    writer->Write();

    //  Using 
    //      grid->GetInformation()->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEP(), time_steps[i])
    //  here doesn't work either (writes no time), which I've also seen used some places.
}

Would love some help, this is the last challenge to overcome before I can use VTK in my application. :slight_smile:

I ended up using vtkXMLUnstructuredGridWriter instead. For anyone else trying this, don’t forget to use the Modified() function on the point data in between writing time steps, otherwise it doesn’t update their offset. The same method can be used for some other XML writers (I tested vtkXMLImageData and vtkXMLPolyData).

writer->SetNumberOfTimeSteps(5);
writer->Start();
writer->WriteNextTime(time_steps[0]);
points->Modified();
writer->WriteNextTime(time_steps[1]);
points->Modified();
writer->WriteNextTime(time_steps[2]);
points->Modified();
writer->WriteNextTime(time_steps[3]);
points->Modified();
writer->WriteNextTime(time_steps[4]);
writer->Stop();
1 Like