Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 44 additions & 47 deletions core/src/Xios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,16 @@ namespace Nextsim {

static const std::string xOutputPfx = "XiosOutput";
static const std::string xInputPfx = "XiosInput";
static const std::string xDiagonsticPfx = "XiosDiagnostic";
static const std::string xDiagnosticPfx = "XiosDiagnostic";
static const std::string xForcingPfx = "XiosForcing";
static const std::map<int, std::string> keyMap = { { Xios::ENABLED_KEY, "xios.enable" },
{ Xios::OUTPUT_FIELD_NAMES_KEY, xOutputPfx + ".field_names" },
{ Xios::INPUT_FIELD_NAMES_KEY, xInputPfx + ".field_names" },
{ Xios::DIAGNOSTIC_PERIOD_KEY, xDiagonsticPfx + ".period" },
{ Xios::DIAGNOSTIC_FILE_KEY, xDiagonsticPfx + ".filename" },
{ Xios::DIAGNOSTIC_FIELD_NAMES_KEY, xDiagonsticPfx + ".field_names" },
{ Xios::OUTPUT_SPLITFREQ_KEY, xOutputPfx + ".split_period" },
{ Xios::DIAGNOSTIC_PERIOD_KEY, xDiagnosticPfx + ".period" },
{ Xios::DIAGNOSTIC_FILE_KEY, xDiagnosticPfx + ".filename" },
{ Xios::DIAGNOSTIC_FIELD_NAMES_KEY, xDiagnosticPfx + ".field_names" },
{ Xios::DIAGNOSTIC_SPLITFREQ_KEY, xDiagnosticPfx + ".split_period" },
{ Xios::FORCING_PERIOD_KEY, xForcingPfx + ".period" },
{ Xios::FORCING_FILE_KEY, xForcingPfx + ".filename" },
{ Xios::FORCING_FIELD_NAMES_KEY, xForcingPfx + ".field_names" } };
Expand Down Expand Up @@ -1371,28 +1373,33 @@ void Xios::createFile(const std::string fileId, const int fieldType)
setFileType(fileId, "one_file");
setFileParAccess(fileId, "collective");

// Set the input or output period based on the model configuration
// Get the fieldIds
std::set<std::string> fieldIds;
if (fieldType == INPUT_RESTART) {
fieldIds = configGetInputRestartFieldNames();
} else if (fieldType == OUTPUT_RESTART) {
fieldIds = configGetOutputRestartFieldNames();
} else if (fieldType == FORCING) {
fieldIds = configGetForcingFieldNames();
} else if (fieldType == DIAGNOSTIC) {
fieldIds = configGetDiagnosticFieldNames();
}

// Set the file output frequency
std::string periodStr;
ModelMetadata& metadata = ModelMetadata::getInstance();
if (fieldType == INPUT_RESTART || fieldType == OUTPUT_RESTART) {
setFileOutputFreq(fileId, metadata.restartPeriod());
if (fieldType == INPUT_RESTART) {
fieldIds = configGetInputRestartFieldNames();
} else {
fieldIds = configGetOutputRestartFieldNames();
}
} else {
std::string periodStr;
if (fieldType == FORCING) {
istringstream(
Configured::getConfiguration(keyMap.at(FORCING_PERIOD_KEY), std::string()))
>> periodStr;
fieldIds = configGetForcingFieldNames();
} else {
istringstream(
Configured::getConfiguration(keyMap.at(DIAGNOSTIC_PERIOD_KEY), std::string()))
>> periodStr;
fieldIds = configGetDiagnosticFieldNames();
}
if (periodStr.empty() || periodStr == "0") {
setFileOutputFreq(fileId, metadata.runLength());
Expand All @@ -1401,6 +1408,31 @@ void Xios::createFile(const std::string fileId, const int fieldType)
}
}

// Set the output file splitting frequency
if (fieldType == OUTPUT_RESTART || fieldType == DIAGNOSTIC) {
std::string splitStr;
if (fieldType == OUTPUT_RESTART) {
istringstream(
Configured::getConfiguration(keyMap.at(OUTPUT_SPLITFREQ_KEY), std::string()))
>> splitStr;
} else if (fieldType == DIAGNOSTIC) {
istringstream(
Configured::getConfiguration(keyMap.at(DIAGNOSTIC_SPLITFREQ_KEY), std::string()))
>> splitStr;
}
if (!splitStr.empty()) {
xios::CFile* file = getFile(fileId);
if (cxios_is_defined_file_split_freq(file)) {
Logged::warning("Xios: Split frequency already set for file '" + fileId + "'");
}
cxios_set_file_split_freq(file, convertDurationToXios(Duration(splitStr)));
if (!cxios_is_defined_file_split_freq(file)) {
throw std::runtime_error(
"Xios: Failed to set split frequency for file '" + fileId + "'");
}
}
}

// XiosOutput.field_names, XiosInput.field_names, XiosDiagnostic.field_names, or
// XiosForcing.field_names entries in the config.
for (std::string fieldId : fieldIds) {
Expand Down Expand Up @@ -1453,24 +1485,6 @@ void Xios::setFileOutputFreq(const std::string fileId, const Duration freq)
}
}

/*!
* Set the split frequency of a file with a given ID
*
* @param the file ID
* @param split frequency to set
*/
void Xios::setFileSplitFreq(const std::string fileId, const Duration freq)
{
xios::CFile* file = getFile(fileId);
if (cxios_is_defined_file_split_freq(file)) {
Logged::warning("Xios: Split frequency already set for file '" + fileId + "'");
}
cxios_set_file_split_freq(file, convertDurationToXios(freq));
if (!cxios_is_defined_file_split_freq(file)) {
throw std::runtime_error("Xios: Failed to set split frequency for file '" + fileId + "'");
}
}

/*!
* Set the mode of a file with a given ID
*
Expand Down Expand Up @@ -1541,23 +1555,6 @@ Duration Xios::getFileOutputFreq(const std::string fileId)
return convertDurationFromXios(duration);
}

/*!
* Get the split frequency of a file with a given ID
*
* @param the file ID
* @return split frequency of the corresponding file
*/
Duration Xios::getFileSplitFreq(const std::string fileId)
{
xios::CFile* file = getFile(fileId);
if (!cxios_is_defined_file_split_freq(file)) {
throw std::runtime_error("Xios: Undefined split frequency for file '" + fileId + "'");
}
cxios_duration duration;
cxios_get_file_split_freq(file, &duration);
return convertDurationFromXios(duration);
}

/*!
* Get the mode of a file with a given ID
*
Expand Down
4 changes: 2 additions & 2 deletions core/src/include/Xios.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,9 @@ class Xios : public Configured<Xios> {
void createFile(const std::string fileId, const int fieldType);
void setFileType(const std::string fileId, const std::string fileType);
void setFileOutputFreq(const std::string fileId, const Duration outputFreq);
void setFileSplitFreq(const std::string fileId, const Duration splitFreq);
void setFileParAccess(const std::string fileId, const std::string parAccess);
std::string getFileType(const std::string fileId);
Duration getFileOutputFreq(const std::string fileId);
Duration getFileSplitFreq(const std::string fileId);
std::string getFileMode(const std::string fileId);
std::string getFileParAccess(const std::string fileId);
void fileAddField(const std::string fileId, const std::string fieldId);
Expand All @@ -118,10 +116,12 @@ class Xios : public Configured<Xios> {
enum {
ENABLED_KEY,
OUTPUT_FIELD_NAMES_KEY,
OUTPUT_SPLITFREQ_KEY,
INPUT_FIELD_NAMES_KEY,
DIAGNOSTIC_PERIOD_KEY,
DIAGNOSTIC_FILE_KEY,
DIAGNOSTIC_FIELD_NAMES_KEY,
DIAGNOSTIC_SPLITFREQ_KEY,
FORCING_PERIOD_KEY,
FORCING_FILE_KEY,
FORCING_FIELD_NAMES_KEY,
Expand Down
1 change: 0 additions & 1 deletion core/src/include/xios_c_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ void cxios_set_file_mode(xios::CFile* file_hdl, const char* mode, int mode_size)
void cxios_set_file_par_access(xios::CFile* file_hdl, const char* par_access, int par_access_size);
void cxios_get_file_type(xios::CFile* file_hdl, char* type, int type_size);
void cxios_get_file_output_freq(xios::CFile* file_hdl, cxios_duration* output_freq_c);
void cxios_get_file_split_freq(xios::CFile* file_hdl, cxios_duration* split_freq_c);
void cxios_get_file_mode(xios::CFile* file_hdl, char* mode, int mode_size);
void cxios_get_file_par_access(xios::CFile* file_hdl, char* par_access, int par_access_size);
bool cxios_is_defined_file_name(xios::CFile* file_hdl);
Expand Down
18 changes: 1 addition & 17 deletions core/test/XiosFile_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,6 @@ MPI_TEST_CASE("TestXiosFile", 2)
// NOTE: This is set based off the XiosInput.period and XiosOutput.period entries when a file
// is created
REQUIRE(xiosHandler.getFileOutputFreq(outFileId).seconds() == 3.0 * 60 * 60);
// Split frequency
REQUIRE_THROWS_WITH(xiosHandler.getFileSplitFreq(outFileId),
"Xios: Undefined split frequency for file 'xios_test_output'");
ModelMetadata& metadata = ModelMetadata::getInstance();
xiosHandler.setFileSplitFreq(outFileId, metadata.stepLength());
REQUIRE(xiosHandler.getFileSplitFreq(outFileId).seconds() == 1.5 * 60 * 60);
// File mode
// NOTE: setFileMode is set based off the XiosInput.filename and XiosOutput.filename entries
// when a file is created
Expand All @@ -115,7 +109,7 @@ MPI_TEST_CASE("TestXiosFile", 2)
REQUIRE(outputIds[0] == "hice");

// Create a new file for each time unit to check more thoroughly that XIOS interprets output
// frequency and split frequency correctly.
// frequency correctly.
// (If we reused the same file then the XIOS interface would raise warnings.)
const std::string prefix = "unittest";
const std::string yearId = prefix + "_year";
Expand All @@ -125,29 +119,19 @@ MPI_TEST_CASE("TestXiosFile", 2)
const std::string secondId = prefix + "_second";
xiosHandler.createFile(yearId, xiosHandler.OUTPUT_RESTART);
xiosHandler.setFileOutputFreq(yearId, Duration("P1-0T00:00:00"));
xiosHandler.setFileSplitFreq(yearId, Duration("P2-0T00:00:00"));
REQUIRE(xiosHandler.getFileOutputFreq(yearId).seconds() == 365 * 24 * 60 * 60);
REQUIRE(xiosHandler.getFileSplitFreq(yearId).seconds() == 2 * 365 * 24 * 60 * 60);
xiosHandler.createFile(dayId, xiosHandler.OUTPUT_RESTART);
xiosHandler.setFileOutputFreq(dayId, Duration("P0-1T00:00:00"));
xiosHandler.setFileSplitFreq(dayId, Duration("P0-2T00:00:00"));
REQUIRE(xiosHandler.getFileOutputFreq(dayId).seconds() == 24 * 60 * 60);
REQUIRE(xiosHandler.getFileSplitFreq(dayId).seconds() == 2 * 24 * 60 * 60);
xiosHandler.createFile(hourId, xiosHandler.OUTPUT_RESTART);
xiosHandler.setFileOutputFreq(hourId, Duration("P0-0T01:00:00"));
xiosHandler.setFileSplitFreq(hourId, Duration("P0-0T02:00:00"));
REQUIRE(xiosHandler.getFileOutputFreq(hourId).seconds() == 60 * 60);
REQUIRE(xiosHandler.getFileSplitFreq(hourId).seconds() == 2 * 60 * 60);
xiosHandler.createFile(minuteId, xiosHandler.OUTPUT_RESTART);
xiosHandler.setFileOutputFreq(minuteId, Duration("P0-0T00:01:00"));
xiosHandler.setFileSplitFreq(minuteId, Duration("P0-0T00:02:00"));
REQUIRE(xiosHandler.getFileOutputFreq(minuteId).seconds() == 60);
REQUIRE(xiosHandler.getFileSplitFreq(minuteId).seconds() == 2 * 60);
xiosHandler.createFile(secondId, xiosHandler.OUTPUT_RESTART);
xiosHandler.setFileOutputFreq(secondId, Duration("P0-0T00:00:01"));
xiosHandler.setFileSplitFreq(secondId, Duration("P0-0T00:00:02"));
REQUIRE(xiosHandler.getFileOutputFreq(secondId).seconds() == 1);
REQUIRE(xiosHandler.getFileSplitFreq(secondId).seconds() == 2);

xiosHandler.close_context_definition();
xiosHandler.context_finalize();
Expand Down
6 changes: 1 addition & 5 deletions core/test/XiosWrite_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ MPI_TEST_CASE("TestXiosWrite", 2)
config << "field_names = " << maskName << "," << coordsName << "," << hiceName << ","
<< ticeName << "," << uName << std::endl;
config << "period = P0-0T01:30:00" << std::endl;
config << "split_period = P0-0T03:00:00" << std::endl;
config << "[XiosDiagnostic]" << std::endl;
config << "filename = " << diagnosticFilename << std::endl;
config << "field_names = " << hsnowName << std::endl;
Expand Down Expand Up @@ -108,11 +109,6 @@ MPI_TEST_CASE("TestXiosWrite", 2)
xiosHandler.setFieldType(uName, ModelArray::Type::CG);
xiosHandler.setFieldType(hsnowName, ModelArray::Type::H);

// Set file split frequency for restarts (but not diagnostics)
// NOTE: Files are created when the XIOS handler is constructed
const std::string fileId = "xios_test_output";
xiosHandler.setFileSplitFreq(fileId, Duration("P0-0T03:00:00"));

xiosHandler.close_context_definition();

// Create some fake data to test writing methods
Expand Down
Loading
Loading