netxsimdg
Loading...
Searching...
No Matches
RectGridIO.cpp
Go to the documentation of this file.
1
9
13#include "include/ModelArray.hpp"
15#include "include/NZLevels.hpp"
17#include "include/gridNames.hpp"
18
19#include <ncDim.h>
20#include <ncDouble.h>
21#include <ncFile.h>
22#include <ncVar.h>
23
24#include <list>
25#include <map>
26#include <string>
27#include <vector>
28
29namespace Nextsim {
30
31void dimensionSetter(
32 const netCDF::NcGroup& dataGroup, const std::string& fieldName, ModelArray::Type type)
33{
34 size_t nDims = dataGroup.getVar(fieldName).getDimCount();
35 ModelArray::MultiDim dims;
36 dims.resize(nDims);
37 for (size_t d = 0; d < nDims; ++d) {
38 dims[d] = dataGroup.getVar(fieldName).getDim(d).getSize();
39 }
40 // A special case for Type::Z: use NZLevels for the third dimension
41 if (type == ModelArray::Type::Z)
42 dims[2] = NZLevels::get();
43 ModelArray::setDimensions(type, dims);
44}
45
46ModelState RectGridIO::getModelState(const std::string& filePath)
47{
48 ModelState state;
49 netCDF::NcFile ncFile(filePath, netCDF::NcFile::read);
50 netCDF::NcGroup dataGroup(ncFile.getGroup(IStructure::dataNodeName()));
51
52 // Get the sizes of the four types of field
53 // HField from hice
54 dimensionSetter(dataGroup, hiceName, ModelArray::Type::H);
55 // UField from hice TODO replace with u velocity once it is present
56 dimensionSetter(dataGroup, hiceName, ModelArray::Type::U);
57 // VField from hice TODO replace with v velocity once it is present
58 dimensionSetter(dataGroup, hiceName, ModelArray::Type::V);
59 // ZField from tice
60 dimensionSetter(dataGroup, ticeName, ModelArray::Type::Z);
61
62 state.data[maskName] = ModelArray::HField();
63 dataGroup.getVar(maskName).getVar(&state.data[maskName][0]);
64 state.data[hiceName] = ModelArray::HField();
65 dataGroup.getVar(hiceName).getVar(&state.data[hiceName][0]);
66 state.data[ciceName] = ModelArray::HField();
67 dataGroup.getVar(ciceName).getVar(&state.data[ciceName][0]);
68 state.data[hsnowName] = ModelArray::HField();
69 dataGroup.getVar(hsnowName).getVar(&state.data[hsnowName][0]);
70 // Since the ZFierld might not have the same dimensions as the tice field
71 // in the file, a little more work is required.
72 state.data[ticeName] = ModelArray::ZField();
73 std::vector<size_t> startVector = { 0, 0, 0 };
74 std::vector<size_t> zArrayDims = ModelArray::dimensions(ModelArray::Type::Z);
75 dataGroup.getVar(ticeName).getVar(startVector, zArrayDims, &state.data[ticeName][0]);
76
77 ncFile.close();
78 return state;
79}
80
81void RectGridIO::dumpModelState(const ModelState& state, const ModelMetadata& metadata,
82 const std::string& filePath, bool isRestart) const
83{
84 netCDF::NcFile ncFile(filePath, netCDF::NcFile::replace);
85
87 netCDF::NcGroup metaGroup = ncFile.addGroup(IStructure::metadataNodeName());
88 netCDF::NcGroup dataGroup = ncFile.addGroup(IStructure::dataNodeName());
89
91 typedef ModelArray::Type Type;
92
93 int nx = ModelArray::dimensions(Type::H)[0];
94 int ny = ModelArray::dimensions(Type::H)[1];
95 int nz = ModelArray::dimensions(Type::Z)[2];
96
97 std::vector<std::string> dimensionNames = { "x", "y", "z", "t", "component", "u", "v", "w" };
98
99 // Create the dimension data, since it has to be in the same group as the
100 // data or the parent group
101 netCDF::NcDim xDim = dataGroup.addDim(dimensionNames[0], nx);
102 netCDF::NcDim yDim = dataGroup.addDim(dimensionNames[1], ny);
103 std::vector<netCDF::NcDim> dims2 = { xDim, yDim };
104 netCDF::NcDim zDim = dataGroup.addDim(dimensionNames[2], nz);
105 std::vector<netCDF::NcDim> dims3 = { xDim, yDim, zDim };
106
107 for (const auto entry : state.data) {
108 const std::string& name = entry.first;
109 if (entry.second.getType() == ModelArray::Type::H && entry.second.trueSize() > 0) {
110 netCDF::NcVar var(dataGroup.addVar(name, netCDF::ncDouble, dims2));
111 var.putAtt(mdiName, netCDF::ncDouble, MissingData::value);
112 var.putVar(entry.second.getData());
113 } else if (entry.second.getType() == ModelArray::Type::Z && entry.second.trueSize() > 0) {
114 netCDF::NcVar var(dataGroup.addVar(name, netCDF::ncDouble, dims3));
115 var.putAtt(mdiName, netCDF::ncDouble, MissingData::value);
116 var.putVar(entry.second.getData());
117 }
118 }
119
120 ncFile.close();
121}
122
123} /* namespace Nextsim */
static netCDF::NcGroup & writeRestartMetadata(netCDF::NcGroup &metaGroup, const ModelMetadata &metadata)
Writes the standard restart file metadata to a metadata node.
static netCDF::NcGroup & writeStructureType(netCDF::NcFile &rootGroup, const ModelMetadata &metadata)
Writes the structure type to the root of the restart file for future retrieval.
static const std::string dataNodeName()
Returns the name of the data node.
static const std::string metadataNodeName()
Returns the name of the metadata node.
const MultiDim & dimensions() const
Returns a vector<size_t> of the size of each dimension of this type of ModelArray.
static void setDimensions(Type, const MultiDim &)
Sets the number and size of the dimensions of a specified type of ModelArray.
void dumpModelState(const ModelState &state, const ModelMetadata &metadata, const std::string &filePath, bool isRestart) const override
Dumps the given ModelState to the given file path.