Commit 71e226d2 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Vertintml: Added memory support for 32-bit float data.

parent 30c526b4
2020-03-24 Uwe Schulzweida
* Vertintml: Added memory support for 32-bit float data.
2020-03-21 Uwe Schulzweida 2020-03-21 Uwe Schulzweida
* Diff: Added memory support for 32-bit float data. * Diff: Added memory support for 32-bit float data.
......
...@@ -370,7 +370,7 @@ Derivepar(void *process) ...@@ -370,7 +370,7 @@ Derivepar(void *process)
if (operatorID == GHEIGHT) if (operatorID == GHEIGHT)
{ {
presh(nullptr, half_press.data(), vct.data(), ps.data(), nhlevf, gridsize); presh((double*)nullptr, half_press.data(), vct.data(), ps.data(), nhlevf, gridsize);
arrayCopy(gridsize, sgeopot.data(), gheight.data() + gridsize * nhlevf); arrayCopy(gridsize, sgeopot.data(), gheight.data() + gridsize * nhlevf);
MakeGeopotHeight(gheight.data(), temp.data(), hum.data(), half_press.data(), gridsize, nhlevf); MakeGeopotHeight(gheight.data(), temp.data(), hum.data(), half_press.data(), gridsize, nhlevf);
......
...@@ -91,6 +91,8 @@ libcdo_la_SOURCES = after_dvtrans.cc \ ...@@ -91,6 +91,8 @@ libcdo_la_SOURCES = after_dvtrans.cc \
fieldmem.cc \ fieldmem.cc \
fieldmer.cc \ fieldmer.cc \
fieldzon.cc \ fieldzon.cc \
field_vinterp.cc \
field_vinterp.h \
fileStream.cc \ fileStream.cc \
fileStream.h \ fileStream.h \
functs.h \ functs.h \
......
...@@ -704,7 +704,7 @@ Remapeta(void *process) ...@@ -704,7 +704,7 @@ Remapeta(void *process)
} }
else if (operatorID == REMAPETAZ) else if (operatorID == REMAPETAZ)
{ {
presh(nullptr, half_press1.data(), vct1.data(), ps1.data(), nhlevf1, gridsize); presh((double*)nullptr, half_press1.data(), vct1.data(), ps1.data(), nhlevf1, gridsize);
for (int k = 0; k < nhlevf1; ++k) for (int k = 0; k < nhlevf1; ++k)
for (size_t i = 0; i < gridsize; ++i) for (size_t i = 0; i < gridsize; ++i)
{ {
...@@ -713,7 +713,7 @@ Remapeta(void *process) ...@@ -713,7 +713,7 @@ Remapeta(void *process)
} }
vertSumw(sum1, vars1[iv], gridsize, nhlevf1, deltap1); vertSumw(sum1, vars1[iv], gridsize, nhlevf1, deltap1);
presh(nullptr, half_press2.data(), vct2.data(), ps1.data(), nhlevf2, gridsize); presh((double*)nullptr, half_press2.data(), vct2.data(), ps1.data(), nhlevf2, gridsize);
for (int k = 0; k < nhlevf2; ++k) for (int k = 0; k < nhlevf2; ++k)
for (size_t i = 0; i < gridsize; ++i) for (size_t i = 0; i < gridsize; ++i)
{ {
......
...@@ -769,8 +769,16 @@ Verifygrid(void *argument) ...@@ -769,8 +769,16 @@ Verifygrid(void *argument)
cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_NUMBEROFGRIDUSED, &number); cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_NUMBEROFGRIDUSED, &number);
if (number > 0) if (number > 0)
{ {
gridID = referenceToGrid(gridID); auto newgridID = referenceToGrid(gridID);
if (gridID == -1) cdoAbort("Reference to source grid not found!"); if (newgridID == -1)
{
lgeo = false;
cdoPrint("Reference to source grid not found!");
}
else
{
gridID = newgridID;
}
} }
} }
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "cdo_options.h" #include "cdo_options.h"
#include "process_int.h" #include "process_int.h"
#include "cdo_vlist.h" #include "cdo_vlist.h"
#include "vertical_interp.h" #include "field_vinterp.h"
#include "stdnametable.h" #include "stdnametable.h"
#include "util_string.h" #include "util_string.h"
#include "const.h" #include "const.h"
...@@ -90,46 +90,6 @@ calc_half_press(const Field3D &full_press, Field3D &half_press) ...@@ -90,46 +90,6 @@ calc_half_press(const Field3D &full_press, Field3D &half_press)
calc_half_press(full_press.gridsize, full_press.nlevels, full_press.vec_d, half_press.nlevels, half_press.vec_d); calc_half_press(full_press.gridsize, full_press.nlevels, full_press.vec_d, half_press.nlevels, half_press.vec_d);
} }
static void
genind(std::vector<int> &vert_index, Varray<double> &plev, Field3D &full_press, size_t gridsize)
{
const auto nplev = plev.size();
const auto nhlevf = full_press.nlevels;
if (full_press.memType == MemType::Float)
genind(vert_index.data(), plev.data(), full_press.vec_f.data(), gridsize, nplev, nhlevf);
else
genind(vert_index.data(), plev.data(), full_press.vec_d.data(), gridsize, nplev, nhlevf);
}
static void
genindmiss(std::vector<int> &vert_index, Varray<double> &plev, size_t gridsize, Field &ps_prog, std::vector<size_t> &pnmiss)
{
const auto nplev = plev.size();
if (ps_prog.memType == MemType::Float)
genindmiss(vert_index.data(), plev.data(), gridsize, nplev, ps_prog.vec_f.data(), pnmiss.data());
else
genindmiss(vert_index.data(), plev.data(), gridsize, nplev, ps_prog.vec_d.data(), pnmiss.data());
}
static void
vertical_interp_X(size_t nlevels, Field3D &full_press, Field3D &half_press, Field3D &field1, Field3D &field2, std::vector<int> &vert_index, Varray<double> &plev, size_t gridsize)
{
const auto nplev = plev.size();
const auto missval = field1.missval;
if (field1.memType == MemType::Float)
{
const auto &hyb_press = (nlevels == full_press.nlevels) ? full_press.vec_f : half_press.vec_f;
vertical_interp_X(field1.vec_f.data(), field2.vec_f.data(), hyb_press.data(), &vert_index[0], plev.data(), nplev,
gridsize, nlevels, missval);
}
else
{
const auto &hyb_press = (nlevels == full_press.nlevels) ? full_press.vec_d : half_press.vec_d;
vertical_interp_X(field1.vec_d.data(), field2.vec_d.data(), hyb_press.data(), &vert_index[0], plev.data(), nplev,
gridsize, nlevels, missval);
}
}
void * void *
Vertintap(void *process) Vertintap(void *process)
{ {
...@@ -145,7 +105,7 @@ Vertintap(void *process) ...@@ -145,7 +105,7 @@ Vertintap(void *process)
}; };
int nrecs; int nrecs;
int varID, levelID; int varID, levelID;
int nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel; int nhlev = 0, nhlevf = 0, nhlevh = 0;
int apressID = -1, dpressID = -1; int apressID = -1, dpressID = -1;
int psID = -1, tempID = -1; int psID = -1, tempID = -1;
char stdname[CDI_MAX_NAME]; char stdname[CDI_MAX_NAME];
...@@ -251,24 +211,24 @@ Vertintap(void *process) ...@@ -251,24 +211,24 @@ Vertintap(void *process)
if (zaxisID == varList1[apressID].zaxisID) if (zaxisID == varList1[apressID].zaxisID)
{ {
bool mono_level = true; bool mono_level = true;
nlevel = zaxisInqSize(zaxisID); int nlevels = zaxisInqSize(zaxisID);
if (is_height_axis(zaxisID, nlevel)) if (is_height_axis(zaxisID, nlevels))
{ {
Varray<double> level(nlevel); Varray<double> level(nlevels);
cdoZaxisInqLevels(zaxisID, &level[0]); cdoZaxisInqLevels(zaxisID, &level[0]);
int l; int l;
for (l = 0; l < nlevel; l++) for (l = 0; l < nlevels; l++)
{ {
if ((l + 1) != (int) (level[l] + 0.5)) break; if ((l + 1) != (int) (level[l] + 0.5)) break;
} }
if (l == nlevel) mono_level = true; if (l == nlevels) mono_level = true;
} }
if (is_height_axis(zaxisID, nlevel) && mono_level) if (is_height_axis(zaxisID, nlevels) && mono_level)
{ {
zaxisIDh = zaxisID; zaxisIDh = zaxisID;
nhlev = nlevel; nhlev = nlevels;
nhlevf = nhlev; nhlevf = nhlev;
nhlevh = nhlevf + 1; nhlevh = nhlevf + 1;
...@@ -311,7 +271,7 @@ Vertintap(void *process) ...@@ -311,7 +271,7 @@ Vertintap(void *process)
full_press.init(var3Df); full_press.init(var3Df);
var3Dh.gridsize = gridsize; var3Dh.gridsize = gridsize;
var3Dh.nlevels = nhlevf; var3Dh.nlevels = nhlevh;
var3Dh.memType = memtype; var3Dh.memType = memtype;
half_press.init(var3Dh); half_press.init(var3Dh);
} }
...@@ -336,14 +296,14 @@ Vertintap(void *process) ...@@ -336,14 +296,14 @@ Vertintap(void *process)
{ {
const auto gridID = varList1[varID].gridID; const auto gridID = varList1[varID].gridID;
const auto zaxisID = varList1[varID].zaxisID; const auto zaxisID = varList1[varID].zaxisID;
const auto nlevel = varList1[varID].nlevels; const auto nlevels = varList1[varID].nlevels;
if (gridInqType(gridID) == GRID_SPECTRAL) cdoAbort("Spectral data unsupported!"); if (gridInqType(gridID) == GRID_SPECTRAL) cdoAbort("Spectral data unsupported!");
vardata1[varID].init(varList1[varID]); vardata1[varID].init(varList1[varID]);
varinterp[varID] varinterp[varID]
= (zaxisID == zaxisIDh || (is_height_axis(zaxisID, nlevel) && zaxisIDh != -1 && (nlevel == nhlevh || nlevel == nhlevf))); = (zaxisID == zaxisIDh || (is_height_axis(zaxisID, nlevels) && zaxisIDh != -1 && (nlevels == nhlevh || nlevels == nhlevf)));
if (varinterp[varID]) if (varinterp[varID])
{ {
...@@ -352,10 +312,10 @@ Vertintap(void *process) ...@@ -352,10 +312,10 @@ Vertintap(void *process)
} }
else else
{ {
if (is_height_axis(zaxisID, nlevel) && zaxisIDh != -1 && nlevel > 1) if (is_height_axis(zaxisID, nlevels) && zaxisIDh != -1 && nlevels > 1)
cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)", varID + 1, varList1[varID].name, nlevel); cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)", varID + 1, varList1[varID].name, nlevels);
varnmiss[varID].resize(nlevel); varnmiss[varID].resize(nlevels);
} }
} }
...@@ -382,8 +342,8 @@ Vertintap(void *process) ...@@ -382,8 +342,8 @@ Vertintap(void *process)
for (varID = 0; varID < nvars; ++varID) for (varID = 0; varID < nvars; ++varID)
{ {
vars[varID] = false; vars[varID] = false;
nlevel = varList1[varID].nlevels; int nlevels = varList1[varID].nlevels;
for (levelID = 0; levelID < nlevel; levelID++) varnmiss[varID][levelID] = 0; for (levelID = 0; levelID < nlevels; levelID++) varnmiss[varID][levelID] = 0;
} }
taxisCopyTimestep(taxisID2, taxisID1); taxisCopyTimestep(taxisID2, taxisID1);
...@@ -391,9 +351,9 @@ Vertintap(void *process) ...@@ -391,9 +351,9 @@ Vertintap(void *process)
for (int recID = 0; recID < nrecs; recID++) for (int recID = 0; recID < nrecs; recID++)
{ {
vars[varID] = true;
cdoInqRecord(streamID1, &varID, &levelID); cdoInqRecord(streamID1, &varID, &levelID);
cdoReadRecord(streamID1, vardata1[varID], levelID, &varnmiss[varID][levelID]); cdoReadRecord(streamID1, vardata1[varID], levelID, &varnmiss[varID][levelID]);
vars[varID] = true;
} }
for (varID = 0; varID < nvars; varID++) for (varID = 0; varID < nvars; varID++)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "cdo_options.h" #include "cdo_options.h"
#include "process_int.h" #include "process_int.h"
#include "cdo_vlist.h" #include "cdo_vlist.h"
#include "vertical_interp.h" #include "field_vinterp.h"
#include "stdnametable.h" #include "stdnametable.h"
#include "constants.h" #include "constants.h"
#include "util_string.h" #include "util_string.h"
...@@ -183,12 +183,14 @@ Vertintml(void *process) ...@@ -183,12 +183,14 @@ Vertintml(void *process)
VarList varList1, varList2; VarList varList1, varList2;
varListInit(varList1, vlistID1); varListInit(varList1, vlistID1);
varListInit(varList2, vlistID2); varListInit(varList2, vlistID2);
varListSetUniqueMemtype(varList1);
const auto memtype = varList1[0].memType;
const auto nvars = vlistNvars(vlistID1); const auto nvars = vlistNvars(vlistID1);
std::vector<bool> vars(nvars), varinterp(nvars); std::vector<bool> vars(nvars), varinterp(nvars);
std::vector<std::vector<size_t>> varnmiss(nvars); std::vector<std::vector<size_t>> varnmiss(nvars);
Varray2D<double> vardata1(nvars), vardata2(nvars); Field3DVector vardata1(nvars), vardata2(nvars);
const int maxlev = nhlevh > nplev ? nhlevh : nplev; const int maxlev = nhlevh > nplev ? nhlevh : nplev;
...@@ -203,13 +205,23 @@ Vertintml(void *process) ...@@ -203,13 +205,23 @@ Vertintml(void *process)
} }
std::vector<int> vert_index; std::vector<int> vert_index;
Varray<double> ps_prog, full_press, half_press;
Field3D full_press, half_press;
if (zaxisIDh != -1 && gridsize > 0) if (zaxisIDh != -1 && gridsize > 0)
{ {
vert_index.resize(gridsize * nplev); vert_index.resize(gridsize * nplev);
ps_prog.resize(gridsize);
full_press.resize(gridsize * nhlevf); CdoVar var3Df, var3Dh;
half_press.resize(gridsize * nhlevh);
var3Df.gridsize = gridsize;
var3Df.nlevels = nhlevf;
var3Df.memType = memtype;
full_press.init(var3Df);
var3Dh.gridsize = gridsize;
var3Dh.nlevels = nhlevh;
var3Dh.memType = memtype;
half_press.init(var3Dh);
} }
else else
cdoWarning("No 3D variable with hybrid sigma pressure coordinate found!"); cdoWarning("No 3D variable with hybrid sigma pressure coordinate found!");
...@@ -246,8 +258,7 @@ Vertintml(void *process) ...@@ -246,8 +258,7 @@ Vertintml(void *process)
const auto gridID = varList1[varID].gridID; const auto gridID = varList1[varID].gridID;
const auto zaxisID = varList1[varID].zaxisID; const auto zaxisID = varList1[varID].zaxisID;
const auto zaxistype = zaxisInqType(zaxisID); const auto zaxistype = zaxisInqType(zaxisID);
// gridsize = gridInqSize(gridID); const auto nlevels = varList1[varID].nlevels;
const auto nlevel = zaxisInqSize(zaxisID);
const auto instNum = institutInqCenter(vlistInqVarInstitut(vlistID1, varID)); const auto instNum = institutInqCenter(vlistInqVarInstitut(vlistID1, varID));
const auto tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID)); const auto tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID));
...@@ -272,9 +283,8 @@ Vertintml(void *process) ...@@ -272,9 +283,8 @@ Vertintml(void *process)
echam_gribcodes(&gribcodes); echam_gribcodes(&gribcodes);
} }
// KNMI: HIRLAM model version 7.2 uses tableNum=1 (LAMH_D11*) // KNMI: HIRLAM model version 7.2 uses tableNum=1 (LAMH_D11*)
// KNMI: HARMONIE model version 36 uses tableNum=1 (grib*) // KNMI: HARMONIE model version 36 uses tableNum=1 (grib*) (opreational NWP version)
// (opreational NWP version) KNMI: HARMONIE model version 38 uses // KNMI: HARMONIE model version 38 uses tableNum=253 (grib,grib_md) and tableNum=1 (grib_sfx) (research version)
// tableNum=253 (grib,grib_md) and tableNum=1 (grib_sfx) (research version)
else if (tableNum == 1 || tableNum == 253) else if (tableNum == 1 || tableNum == 253)
{ {
mode = ModelMode::HIRLAM; mode = ModelMode::HIRLAM;
...@@ -320,21 +330,21 @@ Vertintml(void *process) ...@@ -320,21 +330,21 @@ Vertintml(void *process)
if (mode == ModelMode::ECHAM) if (mode == ModelMode::ECHAM)
{ {
// clang-format off // clang-format off
if (code == gribcodes.geopot && nlevel == 1) sgeopotID = varID; if (code == gribcodes.geopot && nlevels == 1) sgeopotID = varID;
else if (code == gribcodes.geopot && nlevel == nhlevf) geopotID = varID; else if (code == gribcodes.geopot && nlevels == nhlevf) geopotID = varID;
else if (code == gribcodes.temp && nlevel == nhlevf) tempID = varID; else if (code == gribcodes.temp && nlevels == nhlevf) tempID = varID;
else if (code == gribcodes.ps && nlevel == 1) psID = varID; else if (code == gribcodes.ps && nlevels == 1) psID = varID;
else if (code == gribcodes.lsp && nlevel == 1) lnpsID = varID; else if (code == gribcodes.lsp && nlevels == 1) lnpsID = varID;
else if (code == gribcodes.gheight && nlevel == nhlevf) gheightID = varID; else if (code == gribcodes.gheight && nlevels == nhlevf) gheightID = varID;
// clang-format on // clang-format on
} }
else if (mode == ModelMode::WMO || mode == ModelMode::HIRLAM) else if (mode == ModelMode::WMO || mode == ModelMode::HIRLAM)
{ {
// clang-format off // clang-format off
if (code == gribcodes.geopot && nlevel == 1) sgeopotID = varID; if (code == gribcodes.geopot && nlevels == 1) sgeopotID = varID;
else if (code == gribcodes.geopot && nlevel == nhlevf) geopotID = varID; else if (code == gribcodes.geopot && nlevels == nhlevf) geopotID = varID;
else if (code == gribcodes.temp && nlevel == nhlevf) tempID = varID; else if (code == gribcodes.temp && nlevels == nhlevf) tempID = varID;
else if (code == gribcodes.ps && nlevel == 1) psID = varID; else if (code == gribcodes.ps && nlevels == 1) psID = varID;
// clang-format on // clang-format on
} }
...@@ -342,27 +352,27 @@ Vertintml(void *process) ...@@ -342,27 +352,27 @@ Vertintml(void *process)
if (gridInqType(gridID) == GRID_SPECTRAL) cdoAbort("Spectral data unsupported!"); if (gridInqType(gridID) == GRID_SPECTRAL) cdoAbort("Spectral data unsupported!");
const size_t maxlevel = (varID == gheightID) ? (nlevel + 1) : nlevel; if (varID == gheightID) varList1[varID].nlevels = nlevels + 1;
vardata1[varID].resize(gridsize * maxlevel); vardata1[varID].init(varList1[varID]);
// varinterp[varID] = ( zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && nlevel == nhlev ); // varinterp[varID] = ( zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && nlevels == nhlev );
varinterp[varID] varinterp[varID]
= (zaxisID == zaxisIDh || (zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && (nlevel == nhlevh || nlevel == nhlevf))); = (zaxisID == zaxisIDh || (zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && (nlevels == nhlevh || nlevels == nhlevf)));
if (varinterp[varID]) if (varinterp[varID])
{ {
vardata2[varID].resize(gridsize * nplev);
varnmiss[varID].resize(maxlev, 0); varnmiss[varID].resize(maxlev, 0);
vardata2[varID].init(varList2[varID]);
} }
else else
{ {
if (zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && nlevel > 1) if (zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && nlevels > 1)
{ {
vlistInqVarName(vlistID1, varID, varname); vlistInqVarName(vlistID1, varID, varname);
cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)", varID + 1, varname, nlevel); cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)", varID + 1, varname, nlevels);
} }
varnmiss[varID].resize(nlevel); varnmiss[varID].resize(nlevels);
} }
} }
...@@ -382,23 +392,6 @@ Vertintml(void *process) ...@@ -382,23 +392,6 @@ Vertintml(void *process)
if (tempID != -1 || gheightID != -1) sgeopot_needed = true; if (tempID != -1 || gheightID != -1) sgeopot_needed = true;
Varray<double> sgeopot;
if (zaxisIDh != -1 && sgeopot_needed)
{
sgeopot.resize(gridsize);
if (sgeopotID == -1)
{
if (extrapolate)
{
if (geopotID == -1)
cdoWarning("%s not found - set to zero!", var_stdname(surface_geopotential));
else
cdoPrint("%s not found - using bottom layer of %s!", var_stdname(surface_geopotential), var_stdname(geopotential));
}
varrayFill(sgeopot, 0.0);
}
}
if (zaxisIDh != -1 && gheightID != -1 && tempID == -1) if (zaxisIDh != -1 && gheightID != -1 && tempID == -1)
cdoAbort("Temperature not found, needed for vertical interpolation of geopotheight!"); cdoAbort("Temperature not found, needed for vertical interpolation of geopotheight!");
...@@ -415,11 +408,30 @@ Vertintml(void *process) ...@@ -415,11 +408,30 @@ Vertintml(void *process)
if (Options::cdoVerbose) if (Options::cdoVerbose)
{ {
vlistInqVarName(vlistID1, presID, varname);
if (presID == lnpsID) if (presID == lnpsID)
cdoPrint("using LOG(%s) from %s", var_stdname(surface_air_pressure), varname); cdoPrint("using LOG(%s) from %s", var_stdname(surface_air_pressure), varList1[presID].name);
else else
cdoPrint("using %s from %s", var_stdname(surface_air_pressure), varname); cdoPrint("using %s from %s", var_stdname(surface_air_pressure), varList1[presID].name);
}
Field ps_prog;
ps_prog.init(varList1[presID]);
Field sgeopot;
if (zaxisIDh != -1 && sgeopot_needed)
{
sgeopot.init(varList1[presID]);
if (sgeopotID == -1)
{
if (extrapolate)
{
if (geopotID == -1)
cdoWarning("%s not found - set to zero!", var_stdname(surface_geopotential));
else
cdoPrint("%s not found - using bottom layer of %s!", var_stdname(surface_geopotential), var_stdname(geopotential));
}
fieldFill(sgeopot, 0.0);
}
} }
// check VCT // check VCT
...@@ -445,15 +457,13 @@ Vertintml(void *process) ...@@ -445,15 +457,13 @@ Vertintml(void *process)
for (int recID = 0; recID < nrecs; recID++) for (int recID = 0; recID < nrecs; recID++)
{ {
cdoInqRecord(streamID1, &varID, &levelID); cdoInqRecord(streamID1, &varID, &levelID);
// gridsize = varList1[varID].gridsize;
const auto zaxisID = varList1[varID].zaxisID; const auto zaxisID = varList1[varID].zaxisID;
const auto nlevel = varList1[varID].nlevels; const auto nlevels = varList1[varID].nlevels;
if (linvertvct && zaxisIDh != -1 && zaxisID == zaxisIDh) levelID = nlevels - 1 - levelID;
if (linvertvct && zaxisIDh != -1 && zaxisID == zaxisIDh) levelID = nlevel - 1 - levelID; cdoReadRecord(streamID1, vardata1[varID], levelID, &varnmiss[varID][levelID]);
const auto offset = gridsize * levelID;
auto single = &vardata1[varID][offset];
cdoReadRecord(streamID1, single, &varnmiss[varID][levelID]);
vars[varID] = true; vars[varID] = true;
} }
...@@ -462,14 +472,14 @@ Vertintml(void *process) ...@@ -462,14 +472,14 @@ Vertintml(void *process)
if (sgeopot_needed) if (sgeopot_needed)
{ {
if (sgeopotID != -1) if (sgeopotID != -1)
varrayCopy(gridsize, vardata1[sgeopotID], sgeopot); fieldCopy(vardata1[sgeopotID], sgeopot);
else if (geopotID != -1) else if (geopotID != -1)
arrayCopy(gridsize, &vardata1[geopotID][gridsize * (nhlevf - 1)], &sgeopot[0]); fieldCopy(vardata1[geopotID], nhlevf - 1, sgeopot);
// check range of surface geopot // check range of surface geopot