shtr.h (13658B)
1 /* Copyright (C) 2022, 2025, 2026 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2025, 2026 Université de Lorraine 3 * Copyright (C) 2022 Centre National de la Recherche Scientifique 4 * Copyright (C) 2022 Université Paul Sabatier 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #ifndef SHTR_H 20 #define SHTR_H 21 22 #include <rsys/hash.h> 23 #include <rsys/rsys.h> 24 25 #include <float.h> 26 #include <limits.h> 27 28 /* Library symbol management */ 29 #if defined(SHTR_SHARED_BUILD) /* Build shared library */ 30 #define SHTR_API extern EXPORT_SYM 31 #elif defined(SHTR_STATIC) /* Use/build static library */ 32 #define SHTR_API extern LOCAL_SYM 33 #else 34 #define SHTR_API extern IMPORT_SYM 35 #endif 36 37 /* Helper macro that asserts if the invocation of the shtr function `Func' 38 * returns an error. One should use this macro on shtr function calls for which 39 * no explicit error checking is performed */ 40 #ifndef NDEBUG 41 #define SHTR(Func) ASSERT(shtr_ ## Func == RES_OK) 42 #else 43 #define SHTR(Func) shtr_ ## Func 44 #endif 45 46 #define SHTR_MAX_ISOTOPE_COUNT 16 47 48 /* List of HITRAN species. They are classified as in the HITRAN database, i.e. 49 * their value corresponds to that of HITRAN. Note that they start at 1 rather 50 * than zero and therefore do not strictly correspond to a C array index */ 51 enum shtr_molecule_id { 52 SHTR_MOLECULE_ID_NULL = 0, 53 54 SHTR_H2O, SHTR_CO2, SHTR_O3, SHTR_N2O, SHTR_CO, SHTR_CH4, 55 SHTR_O2, SHTR_NO, SHTR_SO2, SHTR_NO2, SHTR_NH3, SHTR_HNO3, 56 SHTR_OH, SHTR_HF, SHTR_HCl, SHTR_HBr, SHTR_HI, SHTR_ClO, 57 SHTR_OCS, SHTR_H2CO, SHTR_HOCl, SHTR_N2, SHTR_HCN, SHTR_CH3Cl, 58 SHTR_H2O2, SHTR_C2H2, SHTR_C2H6, SHTR_PH3, SHTR_COF2, SHTR_SF6, 59 SHTR_H2S, SHTR_HCOOH, SHTR_HO2, SHTR_O, SHTR_ClONO2, SHTR_NOplus, 60 SHTR_HOBr, SHTR_C2H4, SHTR_CH3OH, SHTR_CH3Br, SHTR_CH3CN, SHTR_CF4, 61 SHTR_C4H2, SHTR_HC3N, SHTR_H2, SHTR_CS, SHTR_SO3, SHTR_C2N2, 62 SHTR_COCl2, SHTR_SO, SHTR_CH3F, SHTR_GeH4, SHTR_CS2, SHTR_CH3I, 63 SHTR_NF3, SHTR_H3plus, SHTR_CH3, SHTR_S2, SHTR_COFCl, SHTR_HONO, 64 SHTR_ClNO2, 65 66 SHTR_MAX_MOLECULE_COUNT 67 }; 68 69 /* Table that associates the molecule ID with its name */ 70 static const char* SHTR_MOLECULE_CSTR__[SHTR_MAX_MOLECULE_COUNT] = { 71 NULL, /* SHTR_MOLECULE_ID_NULL__ */ 72 73 "H2O", "CO2", "O3", "N2O", "CO", "CH4", 74 "O2", "NO", "SO2", "NO2", "NH3", "HNO3", 75 "OH", "HF", "HCl", "HBr", "HI", "ClO", 76 "OCS", "H2CO", "HOCl", "N2", "HCN", "CH3Cl", 77 "H2O2", "C2H2", "C2H6", "PH3", "COF2", "SF6", 78 "H2S", "HCOOH", "HO2", "O", "ClONO2", "NO+", 79 "HOBr", "C2H4", "CH3OH", "CH3Br", "CH3CN", "CF4", 80 "C4H2", "HC3N", "H2", "CS", "SO3", "C2N2", 81 "COCl2", "SO", "CH3F", "GeH4", "CS2", "CH3I", 82 "NF3", "H3+", "CH3", "S2", "COFCl", "HONO", 83 "ClNO2" 84 }; 85 86 static INLINE const char* 87 shtr_molecule_cstr(const enum shtr_molecule_id id) 88 { 89 ASSERT(id < SHTR_MAX_MOLECULE_COUNT); 90 return SHTR_MOLECULE_CSTR__[id]; 91 } 92 93 struct shtr_isotope { 94 double abundance; /* in ]0, 1] */ 95 double Q296K; /* Partition function at Tref = 296K */ 96 double molar_mass; /* In g.mol^-1 */ 97 98 /* Local idx of the molecule to which the isotope belongs */ 99 size_t molecule_id_local; 100 101 int gj; /* State independent degeneracy factor */ 102 int id; /* Identifier of the isotope <=> Global index */ 103 }; 104 #define SHTR_ISOTOPE_NULL__ {0,0,0,0,0,-1} 105 static const struct shtr_isotope SHTR_ISOTOPE_NULL = 106 SHTR_ISOTOPE_NULL__; 107 108 struct shtr_molecule { 109 const char* name; 110 size_t nisotopes; /* Number of isotopes */ 111 const struct shtr_isotope* isotopes; 112 enum shtr_molecule_id id; /* Unique identifier */ 113 }; 114 #define SHTR_MOLECULE_NULL__ {NULL, 0, NULL, SHTR_MOLECULE_ID_NULL} 115 static const struct shtr_molecule SHTR_MOLECULE_NULL = 116 SHTR_MOLECULE_NULL__; 117 118 #define SHTR_MOLECULE_IS_NULL(Molecule) \ 119 ((Molecule)->id == SHTR_MOLECULE_NULL.id) 120 121 struct shtr_line { 122 double wavenumber; /* Central wavenumber in vacuum [cm^-1] */ 123 double intensity; /* Reference intensity [cm^-1/(molec.cm^2)] */ 124 double gamma_air; /* Air broadening half-width [cm^-1.atm^-1] */ 125 double gamma_self; /* Self broadening half-width [cm^-1.atm^-1] */ 126 double lower_state_energy; /* [cm^-1] */ 127 double n_air; /* Temperature-dependant exponent */ 128 double delta_air; /* Air-pressure wavenumber shift [cm^-1.atm^-1] */ 129 130 enum shtr_molecule_id molecule_id; 131 132 /* The value of the following isotopic index is _not_ the value of the 133 * isotopic index read from the HITRAN file. The original value is in [0, 9] 134 * with 0 actually meaning 10. Thus, once decoded, the index is located in 135 * [1, 10]. The next member variable simply stores this index but decremented 136 * by one in order to make it compatible with C indexing. As a result, it 137 * can be used directly to index the 'isotopes' array of a 'shtr_molecule' 138 * data structure loaded from an isotope metadata file */ 139 int32_t isotope_id_local; 140 }; 141 #define SHTR_LINE_NULL__ {0,0,0,0,0,0,0,-1,-1} 142 static const struct shtr_line SHTR_LINE_NULL = SHTR_LINE_NULL__; 143 144 static INLINE int 145 shtr_line_eq(const struct shtr_line* line0, const struct shtr_line* line1) 146 { 147 ASSERT(line0 && line1); 148 return line0->wavenumber == line1->wavenumber 149 && line0->intensity == line1->intensity 150 && line0->gamma_air == line1->gamma_air 151 && line0->gamma_self == line1->gamma_self 152 && line0->lower_state_energy == line1->lower_state_energy 153 && line0->n_air == line1->n_air 154 && line0->delta_air == line1->delta_air 155 && line0->molecule_id == line1->molecule_id 156 && line0->isotope_id_local == line1->isotope_id_local; 157 } 158 159 struct shtr_line_param_info { 160 double range[2]; 161 double err; /* Encoding error */ 162 }; 163 #define SHTR_LINE_PARAM_INFO_NULL__ {{DBL_MAX,-DBL_MAX}, 0} 164 static const struct shtr_line_param_info SHTR_LINE_PARAM_INFO_NULL = 165 SHTR_LINE_PARAM_INFO_NULL__; 166 167 /* Information on a list of lines */ 168 struct shtr_line_list_info { 169 struct shtr_line_param_info wavenumber; 170 struct shtr_line_param_info intensity; 171 struct shtr_line_param_info gamma_air; 172 struct shtr_line_param_info gamma_self; 173 struct shtr_line_param_info lower_state_energy; 174 struct shtr_line_param_info n_air; 175 struct shtr_line_param_info delta_air; 176 }; 177 #define SHTR_LINE_LIST_INFO_NULL__ { \ 178 SHTR_LINE_PARAM_INFO_NULL__, \ 179 SHTR_LINE_PARAM_INFO_NULL__, \ 180 SHTR_LINE_PARAM_INFO_NULL__, \ 181 SHTR_LINE_PARAM_INFO_NULL__, \ 182 SHTR_LINE_PARAM_INFO_NULL__, \ 183 SHTR_LINE_PARAM_INFO_NULL__, \ 184 SHTR_LINE_PARAM_INFO_NULL__, \ 185 } 186 static const struct shtr_line_list_info SHTR_LINE_LIST_INFO_NULL = 187 SHTR_LINE_LIST_INFO_NULL__; 188 189 /* Forward declarations of opaque data structures */ 190 struct shtr; 191 struct shtr_isotope_metadata; 192 struct shtr_line_list; 193 struct shtr_line_view; 194 195 /******************************************************************************* 196 * Input arguments for API functions 197 ******************************************************************************/ 198 struct shtr_create_args { 199 struct logger* logger; /* May be NULL <=> default logger */ 200 struct mem_allocator* allocator; /* NULL <=> use default allocator */ 201 int verbose; /* Verbosity level */ 202 }; 203 #define SHTR_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0} 204 static const struct shtr_create_args SHTR_CREATE_ARGS_DEFAULT = 205 SHTR_CREATE_ARGS_DEFAULT__; 206 207 /* Load lines saved in HITRAN format */ 208 struct shtr_line_list_load_args { 209 /* Name of the file to load or of the provided stream. 210 * NULL <=> uses a default name for the stream to be loaded, which must 211 * therefore be defined. */ 212 const char* filename; 213 214 /* Stream from where data are loaded. 215 * NULL <=> loading from the file name, which must therefore be defined */ 216 FILE* file; 217 }; 218 #define SHTR_LINE_LIST_LOAD_ARGS_NULL__ {NULL, NULL} 219 static const struct shtr_line_list_load_args SHTR_LINE_LIST_LOAD_ARGS_NULL = 220 SHTR_LINE_LIST_LOAD_ARGS_NULL__; 221 222 /* Read the lines stored in the internal format of the shtr library, i.e., as 223 * they were written by the shtr_line_list_write function */ 224 struct shtr_line_list_read_args { 225 /* Name of the file to read or of the provided stream. 226 * NULL <=> uses a default name for the stream to be read, which must 227 * therefore be defined. */ 228 const char* filename; /* Name of the file to read */ 229 FILE* file; /* Stream from where data are read. NULL <=> read from file */ 230 231 /* Range of line indices to read. The limits are included. 232 * If the lower limit is greater than or equal to the number of lines to read, 233 * no lines are read. 234 * If the upper limit is greater than or equal to the number of lines to read, 235 * all lines from the lower limit are read. 236 * If the range is degenerate, an error is returned. */ 237 size_t range[2]; 238 }; 239 #define SHTR_LINE_LIST_READ_ARGS_NULL__ {NULL, NULL, {0,SIZE_MAX}} 240 static const struct shtr_line_list_read_args SHTR_LINE_LIST_READ_ARGS_NULL = 241 SHTR_LINE_LIST_READ_ARGS_NULL__; 242 243 struct shtr_line_list_write_args { 244 /* Name of the file in which the list of lines is serialized. 245 * NULL <=> uses a default name for the stream to be written, which must 246 * therefore be defined. */ 247 const char* filename; /* Name of the file to read */ 248 249 /* Stream where data is written. 250 * NULL <=> write to the file defined by "filename" */ 251 FILE* file; 252 }; 253 #define SHTR_LINE_LIST_WRITE_ARGS_NULL__ {NULL, NULL} 254 static const struct shtr_line_list_write_args SHTR_LINE_LIST_WRITE_ARGS_NULL = 255 SHTR_LINE_LIST_WRITE_ARGS_NULL__; 256 257 BEGIN_DECLS 258 259 /******************************************************************************* 260 * Device API 261 ******************************************************************************/ 262 SHTR_API res_T 263 shtr_create 264 (const struct shtr_create_args* args, 265 struct shtr** shtr); 266 267 SHTR_API res_T 268 shtr_ref_get 269 (struct shtr* shtr); 270 271 SHTR_API res_T 272 shtr_ref_put 273 (struct shtr* shtr); 274 275 /******************************************************************************* 276 * Isotope metadata API 277 ******************************************************************************/ 278 SHTR_API res_T 279 shtr_isotope_metadata_load 280 (struct shtr* shtr, 281 const char* path, 282 struct shtr_isotope_metadata** metadata); 283 284 SHTR_API res_T 285 shtr_isotope_metadata_load_stream 286 (struct shtr* shtr, 287 FILE* stream, 288 const char* stream_name, /* NULL <=> use default stream name */ 289 struct shtr_isotope_metadata** metadata); 290 291 /* Load the isotope metadata serialized with the "shtr_isotope_metadata_write" 292 * function */ 293 SHTR_API res_T 294 shtr_isotope_metadata_create_from_stream 295 (struct shtr* shtr, 296 FILE* stream, 297 struct shtr_isotope_metadata** metadata); 298 299 SHTR_API res_T 300 shtr_isotope_metadata_ref_get 301 (struct shtr_isotope_metadata* metadata); 302 303 SHTR_API res_T 304 shtr_isotope_metadata_ref_put 305 (struct shtr_isotope_metadata* metadata); 306 307 SHTR_API res_T 308 shtr_isotope_metadata_get_molecules_count 309 (const struct shtr_isotope_metadata* metadata, 310 size_t* nmolecules); 311 312 SHTR_API res_T 313 shtr_isotope_metadata_get_isotopes_count 314 (const struct shtr_isotope_metadata* metadata, 315 size_t* nisotopes); 316 317 SHTR_API res_T 318 shtr_isotope_metadata_get_molecule 319 (const struct shtr_isotope_metadata* metadata, 320 const size_t imolecule, /* Local index of the molecule in [0, molecules_count[ */ 321 struct shtr_molecule* molecule); 322 323 /* `molecule' is set to SHTR_MOLECULE_NULL if `molecule_id' is not found */ 324 SHTR_API res_T 325 shtr_isotope_metadata_find_molecule 326 (struct shtr_isotope_metadata* metadata, 327 const int molecule_id, /* Unique identifier of the molecule <=> Global index */ 328 struct shtr_molecule* molecule); 329 330 SHTR_API res_T 331 shtr_isotope_metadata_write 332 (const struct shtr_isotope_metadata* metadata, 333 FILE* stream); 334 335 SHTR_API res_T 336 shtr_isotope_metadata_hash 337 (const struct shtr_isotope_metadata* metadata, 338 hash256_T hash); 339 340 /******************************************************************************* 341 * Lines API 342 ******************************************************************************/ 343 SHTR_API res_T 344 shtr_line_list_load 345 (struct shtr* shtr, 346 const struct shtr_line_list_load_args* args, 347 struct shtr_line_list** list); 348 349 /* Load the line list serialized with the "shtr_line_list_write" function */ 350 SHTR_API res_T 351 shtr_line_list_read 352 (struct shtr* shtr, 353 const struct shtr_line_list_read_args* args, 354 struct shtr_line_list** list); 355 356 SHTR_API res_T 357 shtr_line_list_ref_get 358 (struct shtr_line_list* list); 359 360 SHTR_API res_T 361 shtr_line_list_ref_put 362 (struct shtr_line_list* list); 363 364 SHTR_API res_T 365 shtr_line_list_get_size 366 (const struct shtr_line_list* list, 367 size_t* nlines); 368 369 SHTR_API res_T 370 shtr_line_list_at 371 (struct shtr_line_list* list, 372 const size_t i, 373 struct shtr_line* line); 374 375 SHTR_API res_T 376 shtr_line_list_write 377 (const struct shtr_line_list* list, 378 const struct shtr_line_list_write_args* args); 379 380 SHTR_API res_T 381 shtr_line_list_get_info 382 (const struct shtr_line_list* list, 383 struct shtr_line_list_info* info); 384 385 SHTR_API res_T 386 shtr_line_list_hash 387 (const struct shtr_line_list* list, 388 hash256_T hash); 389 390 END_DECLS 391 392 #endif /* SHTR_H */