htcp

Properties of water suspended in clouds
git clone git://git.meso-star.fr/htcp.git
Log | Files | Refs | README | LICENSE

commit 2f1ad5f9b325a653562ba43401b168b50acb2d4a
parent fac14d4552cac3da8127d0d202bc375a085930ab
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 13 Jul 2018 16:51:24 +0200

Update the htcp fileformat

Add the pressure (PABST) and temperature (T) data. Update the les2htcp
tool to add these data to the output HTCP file

Diffstat:
Mcmake/les2htcp/CMakeLists.txt | 3+--
Mdoc/htcp.txt | 6++++++
Msrc/htcp.c | 8++++----
Msrc/les2htcp.c | 99++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
4 files changed, 82 insertions(+), 34 deletions(-)

diff --git a/cmake/les2htcp/CMakeLists.txt b/cmake/les2htcp/CMakeLists.txt @@ -54,10 +54,9 @@ rcmake_prepend_path(LES2HTCP_FILES_INC ${LES2HTCP_SOURCE_DIR}) rcmake_prepend_path(LES2HTCP_FILES_DOC ${PROJECT_SOURCE_DIR}/../../) add_executable(les2htcp ${LES2HTCP_FILES_SRC}) -target_link_libraries(les2htcp RSys ${NETCDF_C_LIBRARIES}) +target_link_libraries(les2htcp RSys ${NETCDF_C_LIBRARIES} m) set_target_properties(les2htcp PROPERTIES - DEFINE_SYMBOL LES2HTCP_SHARED_BUILD VERSION ${VERSION} SOVERSION ${VERSION_MAJOR}) diff --git a/doc/htcp.txt b/doc/htcp.txt @@ -14,6 +14,10 @@ <padding> <RCT> # align on pagesize <padding> + <PABST> # align on pagesize + <padding> + <T> # align on pagesize + <padding> <header> ::= <pagesize> <is-Z-irregular> <definition> ::= <#X> <#Y> <#Z> <#time> @@ -21,6 +25,8 @@ <voxel-size> ::= <double3> [DOUBLE ... ] # optionnal double for irregular Z <RVT> ::= DOUBLE [DOUBLE ... ] <RCT> ::= DOUBLE [DOUBLE ... ] +<PABST> ::= DOUBLE [DOUBLE ... ] +<T> ::= DOUBLE [DOUBLE ... ] # Temperature <double3> ::= DOUBLE DOUBLE DOUBLE diff --git a/src/htcp.c b/src/htcp.c @@ -177,15 +177,15 @@ load_stream(struct htcp* htcp, FILE* stream, const char* stream_name) offset = ALIGN_SIZE(ftell(stream), htcp->pagesize); #define MMAP(Var) { \ - htcp->Var = mmap(NULL, map_len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, \ + htcp->Var = mmap(NULL, map_len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, \ fileno(stream), offset); \ - if(htcp->Var == MAP_FAILED) { \ - log_err(htcp, "%s: could not map the "STR(Var)" data -- %s.\n", \ + if(htcp->Var == MAP_FAILED) { \ + log_err(htcp, "%s: could not map the "STR(Var)" data -- %s.\n", \ stream_name, strerror(errno)); \ res = RES_IO_ERR; \ goto error; \ } \ - htcp->Var##_length = map_len; \ + htcp->Var##_length = map_len; \ } (void)0 MMAP(RVT); offset += (off_t)map_len; MMAP(RCT); offset += (off_t)map_len; diff --git a/src/les2htcp.c b/src/les2htcp.c @@ -13,7 +13,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _POSIX_C_SOURCE 200112L /* getopt/close support */ +#define _POSIX_C_SOURCE 200809L /* mmap/getopt/close support */ +#define _DEFAULT_SOURCE 1 /* MAP_POPULATE support */ #include "les2htcp.h" @@ -23,10 +24,12 @@ #include <rsys/rsys.h> #include <alloca.h> +#include <errno.h> #include <netcdf.h> #include <string.h> #include <unistd.h> /* getopt */ #include <fcntl.h> /* open */ +#include <sys/mman.h> /* mmap */ #include <sys/stat.h> /* S_IRUSR & S_IWUSR */ /******************************************************************************* @@ -602,8 +605,7 @@ write_data(int nc, const char* var_name, FILE* stream) { enum { TIME, Z, X, Y, NDIMS }; /* Helper constants */ - char* mem = NULL; /* Memory where NetCDF data are copied */ - char* mem2 = NULL; /* Tmp memory where NetCDF data are converted */ + double* mem = NULL; /* Memory where NetCDF data are copied */ size_t start[NDIMS]; size_t dim_len[NDIMS]; size_t len[NDIMS]; @@ -649,17 +651,13 @@ write_data(int nc, const char* var_name, FILE* stream) goto error; } - /* Alloc the memory space where the variable data wille be copied. Note that, + /* Alloc the memory space where the variable data will be copied. Note that, * in order to reduce memory consumption, only one slice is read at a given * time and Z position. */ slice_len = len[X]*len[Y]; /* # elements per slice */ - mem = mem_alloc(slice_len*sizeof_nctype(type)); - - /* Allocate a temporary memory space to store the variable data converted in - * double precision if they are stored in single precision. */ - mem2 = type==NC_DOUBLE ? mem : mem_alloc(slice_len*sizeof_nctype(NC_DOUBLE)); + mem = mem_alloc(slice_len*sizeof(double)); - if(!mem || !mem2) { + if(!mem) { fprintf(stderr, "Could not allocate memory for the '%s' variable.\n", var_name); res = RES_MEM_ERR; @@ -676,16 +674,10 @@ write_data(int nc, const char* var_name, FILE* stream) size_t n; start[Z] = z; dim_len[Z] = 1; - NC(get_vara(nc, varid, start, dim_len, mem)); /* Fetch the slice data */ - - /* In order to be compliant with the htgop fileformat, single precision - * data must be converted in double precision */ - if(type == NC_FLOAT) { - FOR_EACH(i, 0, slice_len) ((double*)mem2)[i] = ((float*)mem)[i]; - } + NC(get_vara_double(nc, varid, start, dim_len, mem)); /* Fetch the slice data */ /* Write data */ - n = fwrite(mem2, sizeof_nctype(NC_DOUBLE), slice_len, stream); + n = fwrite(mem, sizeof_nctype(NC_DOUBLE), slice_len, stream); if(n != slice_len) { fprintf(stderr, "Error writing data of the '%s' variable -- '%s'.\n", var_name, strerror(errno)); @@ -696,13 +688,28 @@ write_data(int nc, const char* var_name, FILE* stream) } exit: - if(mem2 != mem) mem_rm(mem2); if(mem) mem_rm(mem); return res; error: goto exit; } +/* Convert potential temperature to temperature + * T(i)=THT(i)*(PABST(i)/P0)^(R/(M_DA*Cp0)) */ +static void +THT_to_T(const size_t n, const double* PABST, double* THT) +{ + const double P0 = 101325; /* In Pa */ + const double R = 8.3144598; /* In kg.m^2.s^-2.mol^-1.K */ + const double M_DA = 28.9644e-3; /* In kg.mol^-1 */ + const double Cp0 = 1.005e+3; /* In J/kg/K */ + const double exponent = R/(M_DA * Cp0); + double* T = THT; + size_t i; + ASSERT(n && PABST && THT); + FOR_EACH(i, 0, n) T[i] = THT[i] * pow(PABST[i]/P0, exponent); +} + /******************************************************************************* * Program ******************************************************************************/ @@ -751,9 +758,14 @@ main(int argc, char** argv) } \ } (void)0 if(!args.no_output) { - const int64_t pagesize = (int64_t)args.pagesize; - - WRITE(&pagesize, 1, "page size"); + const int64_t pagesz = (int64_t)args.pagesize; + double* PABST = NULL; + double* THT = NULL; + long PABST_off, THT_off; + size_t PABST_len, THT_len; + size_t n; + + WRITE(&pagesz, 1, "page size"); WRITE(&grid.is_z_irregular, 1, "'irregular' Z boolean"); WRITE(&grid.nx, 1, "X definition"); WRITE(&grid.ny, 1, "Y definition"); @@ -763,14 +775,45 @@ main(int argc, char** argv) WRITE(&grid.vxsz_x, 1, "X voxel size"); WRITE(&grid.vxsz_y, 1, "Y voxel size"); WRITE(grid.vxsz_z, grid.is_z_irregular?(size_t)grid.nz:1, "Z voxel size(s)"); - /* padding */ - fseek(stream, ALIGN_SIZE(ftell(stream), (off_t)pagesize), SEEK_SET); + fseek(stream, ALIGN_SIZE(ftell(stream),(off_t)pagesz), SEEK_SET);/*padding*/ + write_data(nc, "RVT", stream); - /* padding */ - fseek(stream, ALIGN_SIZE(ftell(stream), (off_t)pagesize), SEEK_SET); + fseek(stream, ALIGN_SIZE(ftell(stream),(off_t)pagesz), SEEK_SET);/*padding*/ + write_data(nc, "RCT", stream); - /*padding */ - fseek(stream, ALIGN_SIZE(ftell(stream), (off_t)pagesize), SEEK_SET); + fseek(stream, ALIGN_SIZE(ftell(stream),(off_t)pagesz), SEEK_SET);/*padding*/ + + PABST_off = ftell(stream); + write_data(nc, "PABST", stream); + fseek(stream, ALIGN_SIZE(ftell(stream),(off_t)pagesz), SEEK_SET);/*padding*/ + PABST_len = (size_t)(ftell(stream) - PABST_off); + + THT_off = ftell(stream); + write_data(nc, "THT", stream); + fseek(stream, ALIGN_SIZE(ftell(stream),(off_t)pagesz), SEEK_SET);/*padding*/ + THT_len = (size_t)(ftell(stream) - THT_off); + + CHK(fclose(stream) == 0); + CHK(stream = fopen(args.output, "rw")); + + #define MMAP(Var, Prot) { \ + Var = mmap(NULL, Var##_len, Prot, MAP_PRIVATE|MAP_POPULATE, \ + fileno(stream), Var##_off); \ + if(Var == MAP_FAILED) { \ + fprintf(stderr, "%s: could not map the "STR(Var)" data -- %s.\n", \ + args.input, strerror(errno)); \ + goto error; \ + } \ + } (void)0 + MMAP(PABST, PROT_READ); + MMAP(THT, PROT_READ|PROT_WRITE); + #undef MMAP + + n = (size_t)(grid.nx * grid.ny * grid.nz * grid.ntimes); + THT_to_T(n, PABST, THT); + + CHK(munmap(PABST, PABST_len) == 0); + CHK(munmap(THT, THT_len) == 0); } #undef WRITE