htcp

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

test_htcp_load_from_file.c (6242B)


      1 /* Copyright (C) 2018, 2020-2023, 2025, 2025 |Méso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2018 Centre National de la Recherche Scientifique
      3  * Copyright (C) 2018 Université Paul Sabatier
      4  *
      5  * This program is free software: you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation, either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     17 
     18 #define _POSIX_C_SOURCE 200112L /* snprintf support */
     19 
     20 #include "htcp.h"
     21 #include "test_htcp_utils.h"
     22 
     23 #include <rsys/cstr.h>
     24 #include <rsys/double3.h>
     25 #include <rsys/math.h>
     26 #include <string.h>
     27 
     28 /* Potential temperature to temperature
     29  *  T = THT * (PABST/P0)^(R/(M_DA*Cp0)) */
     30 static FINLINE double
     31 THT_to_T(const double THT, const size_t i /*Id of THT*/, const void* ctx)
     32 {
     33   const double* PABST = ctx;
     34   const double P0 = 101325;
     35 #if 0
     36   const double R = 8.3144598; /* In kg.m^2.s^-2.mol^-1.K */
     37   const double M_DA = 28.9644E-3; /* In kg.mol^-1 */
     38   const double Cp0 = 1.005E+3; /* In J/kg/K */
     39 #endif
     40   const double exponent = 0.28562974993698609; /* R/M_DA*cp0 */
     41   return THT * pow(PABST[i]/P0, exponent);
     42 }
     43 
     44 static void
     45 check_descriptor
     46   (const struct htcp_desc* desc,
     47    const char* path, /* Path where the reference values are */
     48    const char* basename) /* Basename of the reference files */
     49 {
     50   char buf[128];
     51   double nx, ny, nz, ntimes;
     52   FILE* fp = NULL;
     53   size_t i;
     54 
     55   printf("Check the descriptor\n");
     56 
     57   CHK(desc && path && basename);
     58 
     59   i = (size_t)snprintf(buf, sizeof(buf), "%s/%s_desc", path, basename);
     60   CHK(i < sizeof(buf));
     61   CHK(fp = fopen(buf, "r"));
     62   CHK(fscanf(fp, "%lg %lg %lg %lg", &nx, &ny, &nz, &ntimes) == 4);
     63   CHK(fscanf(fp, "%*g") == EOF);
     64   CHK(fclose(fp) == 0);
     65 
     66   CHK(desc->spatial_definition[0] == nx);
     67   CHK(desc->spatial_definition[1] == ny);
     68   CHK(desc->spatial_definition[2] == nz);
     69   CHK(desc->time_definition == ntimes);
     70 }
     71 
     72 static void
     73 check_variable
     74   (const double* loaded_data,
     75    const size_t ndata,
     76    const char* var, /* Name of the variable to check */
     77    const char* path, /* Path where the reference values are */
     78    const char* basename, /* Basename of the reference files */
     79    double (*convert)(const double, const size_t, const void*), /* May be NULL */
     80    const void* ctx)
     81 {
     82   char buf[128];
     83   FILE* fp = NULL;
     84   size_t i;
     85 
     86   printf("Check the %s variable\n", var);
     87 
     88   CHK(loaded_data && ndata && var && path && basename);
     89 
     90   i = (size_t)snprintf(buf, sizeof(buf), "%s/%s_%s", path, basename, var);
     91   CHK(i < sizeof(buf));
     92   CHK(fp = fopen(buf, "r"));
     93   FOR_EACH(i, 0, ndata) {
     94     double val;
     95     CHK(fscanf(fp, "%lg", &val) == 1);
     96     if(convert) val = convert(val, i, ctx);
     97     CHK(eq_eps(val, loaded_data[i], loaded_data[i]*1.e-6));
     98   }
     99   CHK(fscanf(fp, "%*g") == EOF);
    100   CHK(fclose(fp) == 0);
    101 }
    102 
    103 static void
    104 check_misc(const struct htcp* htcp)
    105 {
    106   struct htcp_desc desc;
    107   double low[3], upp[3];
    108   size_t x, y, z;
    109 
    110   printf("Check miscellaneous\n");
    111 
    112   CHK(htcp_get_desc(htcp, &desc) == RES_OK);
    113   CHK(desc.irregular_z || desc.coord_z == NULL);
    114 
    115   FOR_EACH(x, 0, desc.spatial_definition[0]) {
    116     low[0] = (double)x * desc.vxsz_x;
    117     upp[0] = low[0] + desc.vxsz_x;
    118     FOR_EACH(y, 0, desc.spatial_definition[1]) {
    119       low[1] = (double)y * desc.vxsz_y;
    120       upp[1] = low[1] + desc.vxsz_y;
    121       FOR_EACH(z, 0, desc.spatial_definition[2]) {
    122         double vox_low[3];
    123         double vox_upp[3];
    124         if(!desc.irregular_z) {
    125           low[2] = (double)z * desc.vxsz_z[0];
    126           upp[2] = low[2] + desc.vxsz_z[0];
    127         } else {
    128           size_t i;
    129           low[2] = desc.lower[2];
    130           FOR_EACH(i, 0, z) low[2] += desc.vxsz_z[i];
    131           CHK(eq_eps(low[2], desc.coord_z[z], 1.e-6));
    132           upp[2] = low[2] + desc.vxsz_z[z];
    133         }
    134         htcp_desc_get_voxel_aabb(&desc, x, y, z, vox_low, vox_upp);
    135         CHK(d3_eq_eps(vox_low, low, 1.e-6));
    136         CHK(d3_eq_eps(vox_upp, upp, 1.e-6));
    137       }
    138     }
    139   }
    140 
    141   upp[0] = desc.lower[0] + desc.vxsz_x * (double)desc.spatial_definition[0];
    142   upp[1] = desc.lower[1] + desc.vxsz_y * (double)desc.spatial_definition[1];
    143   if(!desc.irregular_z) {
    144     upp[2] = desc.lower[2] + desc.vxsz_z[0] * (double)desc.spatial_definition[2];
    145   } else {
    146     upp[2] = desc.lower[2];
    147     FOR_EACH(z, 0, desc.spatial_definition[2]) {
    148       upp[2] += desc.vxsz_z[z];
    149     }
    150   }
    151   CHK(d3_eq_eps(upp, desc.upper, 1.e-6));
    152 }
    153 
    154 int
    155 main(int argc, char** argv)
    156 {
    157   struct htcp* htcp = NULL;
    158   struct htcp_desc desc = HTCP_DESC_NULL;
    159   double fp_to_meter = 1.0;
    160   char* filename = NULL;
    161   char* path = NULL;
    162   char* base = NULL;
    163   char* p = NULL;
    164   size_t n;
    165 
    166   if(argc < 3) {
    167     fprintf(stderr, "Usage: %s <htcp> <ref-data-path> [fp-to-meter]\n", argv[0]);
    168     return -1;
    169   }
    170   if(argc > 3) {
    171     CHK(cstr_to_double(argv[3], &fp_to_meter) == RES_OK);
    172   }
    173 
    174   filename = argv[1];
    175   path = argv[2];
    176 
    177   CHK(htcp_create(NULL, &mem_default_allocator, 1, &htcp) == RES_OK);
    178   CHK(htcp_load(htcp, filename) == RES_OK);
    179 
    180   CHK(htcp_get_desc(htcp, &desc) == RES_OK);
    181 
    182   /* Compute the basename of the ref file from the submitted htcp file */
    183   base = filename;
    184   p = strrchr(filename, '/');
    185   if(p) base = p+1;
    186   p = strrchr(filename, '.');
    187   if(p) *p = '\0';
    188 
    189   n = desc.spatial_definition[0]
    190     * desc.spatial_definition[1]
    191     * desc.spatial_definition[2]
    192     * desc.time_definition;
    193 
    194   printf("Irregular Z: %i\n", desc.irregular_z);
    195   check_descriptor(&desc, path, base);
    196   check_misc(htcp);
    197   check_variable(desc.RVT, n, "RVT", path, base, NULL, NULL);
    198   check_variable(desc.RCT, n, "RCT", path, base, NULL, NULL);
    199   check_variable(desc.PABST, n, "PABST", path, base, NULL, NULL);
    200   check_variable(desc.T, n, "THT", path, base, THT_to_T, desc.PABST);
    201 
    202   CHK(htcp_ref_put(htcp) == RES_OK);
    203   check_memory_allocator(&mem_default_allocator);
    204   CHK(mem_allocated_size() == 0);
    205   return 0;
    206 }