Как записывать набор данных каждые N итераций с использованием HDF5 в C

#c #dataset #hdf5 #montecarlo

#c #набор данных #hdf5 #монтекарло

Вопрос:

Я пишу код мембраны методом Монте-Карло и хочу использовать HDF5 для экспорта данных, содержащих высоты каждого узла решетки.

Следуя примерам в документации, я могу записать поле высоты в набор данных и экспортировать его в виде файла .h5. Обратите внимание, что поле высоты — это класс, представляющий 2D-сетку (или матрицу, если хотите). Реализация такова, что 2D-сетка хранится в 1D-массиве.

Теперь я хочу иметь возможность отображать поверхность мембраны на несколько временных шагов. Как я могу добавить поле высоты следующего временного шага к существующему файлу?

Я знаю, что мой вопрос несколько общий и не содержит кода, поэтому я ожидаю ответов, которые подсказывают, что искать. Например, являются ли группы тем, что я должен изучить? Или так называемые слябы? Любые советы о том, где искать, заметны.

Редактировать:

Следуя примеру на странице документации, я написал следующий код.

 int main()
{
  /* Initialize field */
  int N_x = 6;
  int N_y = 6;
  int N_ghost = 2;
  Mesh2D sfield(N_x,N_y,N_ghost);
  
  /* Prepare */
  hsize_t rows = N_y   2*N_ghost; //write the ghost zones as well
  hsize_t cols = N_x   2*N_ghost;
  
  hsize_t dims[2] = {rows,cols}; // data set dimensions at creation (10X10)
  hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
  hsize_t chunk_dims[2] = {rows,cols};

  /* Variables for extending and writing to the extended portion of the dataset */
  hsize_t size[2];
  size[0] = rows;
  size[1] = cols;
  hsize_t offset[2];
  offset[0] = 0;
  offset[1] = 0;
  hsize_t dimsext[2] = {rows,cols}; //extend dimensions

  /*Try block to detect exceptions raised by any of the calls inside it */
  try{
    // Turn off the auto-printing when failure occurs so that we can
    // handle the errors appropriately
    Exception::dontPrint();

    // Create a new file using the default property lists.
    H5File file(FILE_NAME, H5F_ACC_TRUNC);

    // Create the data space for the dataset. Note the use of pointer
    // for the instance 'dataspace'. It can be deleted and used again
    // later for another dataspace. An HDF5 identifier can be closed
    // by the destructor or the method 'close()'.
    DataSpace *dataspace = new DataSpace(2, dims, maxdims);

    // Modify dataset creation property to enable chunking
    DSetCreatPropList prop;
    prop.setChunk(2, chunk_dims);

    // Create the chunked dataset. Note the use of pointer.
    DataSet *dataset =
    new DataSet(file.createDataSet(DATASETNAME, PredType::NATIVE_DOUBLE, *dataspace, prop));

    // Start iterations.
    DataSpace *filespace;
    DataSpace *memspace;
    int maxiter = 5;
    for (int iter = 0; iter<maxiter; iter  )
      {
    
    // Change the values of the field.
    sfield.meshfill(iter 1);
    
    // Extend the dataset. Dataset becomes 20 x 10, 30 x 10, etc.
    size[0]  = dimsext[0];
    size[1] = dims[1];
    dataset->extend(size);

    // Select a hyperslab in extended portion of the dataset.
    filespace = new DataSpace(dataset->getSpace());
    offset[0] = iter*rows;
    filespace->selectHyperslab(H5S_SELECT_SET, dimsext, offset);

    // Define memory space.
    memspace = new DataSpace(2, dimsext, NULL);
    
    // Write data to the extended portion of the dataset.
    dataset->write(sfield.getmemory(), PredType::NATIVE_DOUBLE, *memspace, *filespace);

    delete filespace;
    delete memspace;
      }
    
    // Close all objects and file.
    prop.close();
    delete dataspace;
    delete dataset;
    file.close();

  }// End of try block.

  // Catch failure caused by the H5File operations.
  catch (FileIException error) {
    error.printErrorStack();
    return -1;
  }

  // Catch failure caused by the DataSet operations.
  catch (DataSetIException error) {
    error.printErrorStack();
    return -1;
  }

  // Catch failure caused by the DataSpace operations.
  catch (DataSpaceIException error) {
    error.printErrorStack();
    return -1;
  }

  return 0; // Successfully terminated.

}
 

Когда я читаю файл с помощью python, я получаю:

        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])


 

Как вы можете видеть, внизу есть дополнительный «кусок», полный нулей, который мне не нужен. Я думаю, это происходит потому, что я расширяю набор данных на каждой итерации. Я попытался установить начальные размеры набора данных равными нулю, т.Е. hsize_t dims[2] = {0,0}; полагая, что в начале итерации это увеличит размеры набора данных, а затем запишет мои данные, но вместо этого я получаю следующее.

array([], shape=(20, 0), dtype=float64)

Комментарии:

1. Нам нужно увидеть ваш код, чтобы мы могли помочь вам его отладить.

2. Вы должны создать расширяемый набор данных HDF5, чтобы вы могли добавлять к нему данные, не перезаписывая существующие данные (с помощью гиперслабов).