/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2021 John Helly (j.c.helly@durham.ac.uk)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
******************************************************************************/
/* Config parameters. */
#include
/* Some standard headers. */
#include
#include
#ifdef WITH_MPI
#include
#endif
/* Local headers */
#include "error.h"
/* This object's header */
#include "ic_info.h"
/* Includes */
#include "hdf5_object_to_blob.h"
#include "restart.h"
extern int engine_rank;
/**
* @brief Initialize the ic_info struct
*
* @param ics Pointer to the struct
* @param params The Swift parameter set
*/
void ic_info_init(struct ic_info *ics, struct swift_params *params) {
/* Initially we have no file image */
ics->file_image_length = 0;
ics->file_image_data = NULL;
/* Store the name of the HDF5 group to copy */
parser_get_opt_param_string(params, "InitialConditions:metadata_group_name",
ics->group_name, "ICs_parameters");
}
/**
* @brief Clean up the ic_info struct
*
* @param ics Pointer to the struct
*/
void ic_info_clean(struct ic_info *ics) {
/* Deallocate file image, if it exists */
if (ics->file_image_data) {
free(ics->file_image_data);
ics->file_image_data = NULL;
}
ics->file_image_length = 0;
}
/**
* @brief Dump the ic_info struct to the supplied file
*
* @param ics Pointer to the struct
* @param stream The file to write to
*/
void ic_info_struct_dump(struct ic_info *ics, FILE *stream) {
/* Write the struct */
restart_write_blocks(ics, sizeof(struct ic_info), 1, stream, "ic_info",
"ic_info struct");
/* Write the HDF5 file image if there is one */
if (ics->file_image_data) {
restart_write_blocks(ics->file_image_data, ics->file_image_length, 1,
stream, "ic_info", "ic_info file image");
}
}
/**
* @brief Restore the ic_info struct from the supplied file
*
* @param ics Pointer to the struct
* @param stream The file to read from
*/
void ic_info_struct_restore(struct ic_info *ics, FILE *stream) {
/* Read in the struct */
restart_read_blocks(ics, sizeof(struct ic_info), 1, stream, NULL,
"ic_info struct");
/* Read in the HDF5 file image, if there is one */
if (ics->file_image_data) {
ics->file_image_data = malloc(ics->file_image_length);
restart_read_blocks(ics->file_image_data, ics->file_image_length, 1, stream,
NULL, "ic_info file image");
}
}
/**
* @brief Broadcast the ic_info struct to all MPI ranks
*
* @param ics Pointer to the struct
* @param root The root rank for the broadcast operation
*/
void ic_info_struct_broadcast(struct ic_info *ics, int root) {
#ifdef WITH_MPI
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Broadcast the struct */
MPI_Bcast(ics, sizeof(struct ic_info), MPI_BYTE, root, MPI_COMM_WORLD);
if (ics->file_image_data) {
/* Allocate file image data on other ranks */
if (rank != root) ics->file_image_data = malloc(ics->file_image_length);
/* Broadcast the file image data */
MPI_Bcast(ics->file_image_data, ics->file_image_length, MPI_BYTE, root,
MPI_COMM_WORLD);
}
#endif
}
#ifdef HAVE_HDF5
/**
* @brief Read the ICs metadata from a HDF5 file
*
* @param ics Pointer to the struct
* @param file_id The HDF5 file (or group) to write to
*/
void ic_info_read_hdf5(struct ic_info *ics, hid_t file_id) {
/* Check that the named group exists as a link in the ICs file */
if (H5Lexists(file_id, ics->group_name, H5P_DEFAULT) > 0) {
/* Check that the link resolves to an object */
if (H5Oexists_by_name(file_id, ics->group_name, H5P_DEFAULT) > 0) {
/* Read the HDF5 object into memory */
hdf5_object_to_blob(file_id, ics->group_name, &(ics->file_image_length),
&(ics->file_image_data));
if (engine_rank == 0)
message("Read metadata group %s from ICs file", ics->group_name);
} else {
if (engine_rank == 0)
message("Metadata group %s in ICs file appears to be a broken link",
ics->group_name);
}
} else {
if (engine_rank == 0)
message("Metadata group %s not found in ICs file", ics->group_name);
}
}
/**
* @brief Write the ICs metadata to a HDF5 file
*
* @param ics Pointer to the struct
* @param file_id The HDF5 file (or group) to read from
*/
void ic_info_write_hdf5(struct ic_info *ics, hid_t file_id) {
if (ics->file_image_data) {
blob_to_hdf5_object(ics->file_image_length, ics->file_image_data, file_id,
ics->group_name);
}
}
#endif