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 }