shtr.h (11449B)
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/rsys.h> 23 24 #include <float.h> 25 #include <limits.h> 26 27 /* Library symbol management */ 28 #if defined(SHTR_SHARED_BUILD) /* Build shared library */ 29 #define SHTR_API extern EXPORT_SYM 30 #elif defined(SHTR_STATIC) /* Use/build static library */ 31 #define SHTR_API extern LOCAL_SYM 32 #else 33 #define SHTR_API extern IMPORT_SYM 34 #endif 35 36 /* Helper macro that asserts if the invocation of the shtr function `Func' 37 * returns an error. One should use this macro on shtr function calls for which 38 * no explicit error checking is performed */ 39 #ifndef NDEBUG 40 #define SHTR(Func) ASSERT(shtr_ ## Func == RES_OK) 41 #else 42 #define SHTR(Func) shtr_ ## Func 43 #endif 44 45 /* List of HITRAN species. They are classified as in the HITRAN database ,i.e. 46 * their value corresponds to that of HITRAN. Note that they start at 1 rather 47 * than zero and therefore do not strictly correspond to a C array index */ 48 enum shtr_molecule_id { 49 SHTR_MOLECULE_ID_NULL = 0, 50 51 SHTR_H2O, SHTR_CO2, SHTR_O3, SHTR_N2O, SHTR_CO, SHTR_CH4, 52 SHTR_O2, SHTR_NO, SHTR_SO2, SHTR_NO2, SHTR_NH3, SHTR_HNO3, 53 SHTR_OH, SHTR_HF, SHTR_HCl, SHTR_HBr, SHTR_HI, SHTR_ClO, 54 SHTR_OCS, SHTR_H2CO, SHTR_HOCl, SHTR_N2, SHTR_HCN, SHTR_CH3Cl, 55 SHTR_H2O2, SHTR_C2H2, SHTR_C2H6, SHTR_PH3, SHTR_COF2, SHTR_SF6, 56 SHTR_H2S, SHTR_HCOOH, SHTR_HO2, SHTR_O, SHTR_ClONO2, SHTR_NOplus, 57 SHTR_HOBr, SHTR_C2H4, SHTR_CH3OH, SHTR_CH3Br, SHTR_CH3CN, SHTR_CF4, 58 SHTR_C4H2, SHTR_HC3N, SHTR_H2, SHTR_CS, SHTR_SO3, SHTR_C2N2, 59 SHTR_COCl2, SHTR_SO, SHTR_CH3F, SHTR_GeH4, SHTR_CS2, SHTR_CH3I, 60 SHTR_NF3, 61 62 SHTR_MAX_MOLECULE_COUNT 63 }; 64 65 /* Table that associates the molecule ID with its name */ 66 static const char* SHTR_MOLECULE_CSTR__[SHTR_MAX_MOLECULE_COUNT] = { 67 NULL, /* SHTR_MOLECULE_ID_NULL__ */ 68 69 "H2O", "CO2", "O3", "N2O", "CO", "CH4", 70 "O2", "NO", "SO2", "NO2", "NH3", "HNO3", 71 "OH", "HF", "HCl", "HBr", "HI", "ClO", 72 "OCS", "H2CO", "HOCl", "N2", "HCN", "CH3Cl", 73 "H2O2", "C2H2", "C2H6", "PH3", "COF2", "SF6", 74 "H2S", "HCOOH", "HO2", "O", "ClONO2", "NO+", 75 "HOBr", "C2H4", "CH3OH", "CH3Br", "CH3CN", "CF4", 76 "C4H2", "HC3N", "H2", "CS", "SO3", "C2N2", 77 "COCl2", "SO", "CH3F", "GeH4", "CS2", "CH3I", 78 "NF3" 79 }; 80 81 static INLINE const char* 82 shtr_molecule_cstr(const enum shtr_molecule_id id) 83 { 84 ASSERT(id < SHTR_MAX_MOLECULE_COUNT); 85 return SHTR_MOLECULE_CSTR__[id]; 86 } 87 88 struct shtr_isotope { 89 double abundance; /* in ]0, 1] */ 90 double Q296K; /* Partition function at Tref = 296K */ 91 double molar_mass; /* In g.mol^-1 */ 92 93 /* Local idx of the molecule to which the isotope belongs */ 94 size_t molecule_id_local; 95 96 int gj; /* State independent degeneracy factor */ 97 int id; /* Identifier of the isotope <=> Global index */ 98 }; 99 #define SHTR_ISOTOPE_NULL__ {0,0,0,0,0,-1} 100 static const struct shtr_isotope SHTR_ISOTOPE_NULL = 101 SHTR_ISOTOPE_NULL__; 102 103 struct shtr_molecule { 104 const char* name; 105 size_t nisotopes; /* Number of isotopes */ 106 const struct shtr_isotope* isotopes; 107 enum shtr_molecule_id id; /* Unique identifier */ 108 }; 109 #define SHTR_MOLECULE_NULL__ {NULL, 0, NULL, SHTR_MOLECULE_ID_NULL} 110 static const struct shtr_molecule SHTR_MOLECULE_NULL = 111 SHTR_MOLECULE_NULL__; 112 113 #define SHTR_MOLECULE_IS_NULL(Molecule) \ 114 ((Molecule)->id == SHTR_MOLECULE_NULL.id) 115 116 struct shtr_line { 117 double wavenumber; /* Central wavenumber in vacuum [cm^-1] */ 118 double intensity; /* Reference intensity [cm^-1/(molec.cm^2)] */ 119 double gamma_air; /* Air broadening half-width [cm^-1.atm^-1] */ 120 double gamma_self; /* Self broadening half-width [cm^-1.atm^-1] */ 121 double lower_state_energy; /* [cm^-1] */ 122 double n_air; /* Temperature-dependant exponent */ 123 double delta_air; /* Air-pressure wavenumber shift [cm^-1.atm^-1] */ 124 125 enum shtr_molecule_id molecule_id; 126 127 /* The value of the following isotopic index is _not_ the value of the 128 * isotopic index read from the HITRAN file. The original value is in [0, 9] 129 * with 0 actually meaning 10. Thus, once decoded, the index is located in 130 * [1, 10]. The next member variable simply stores this index but decremented 131 * by one in order to make it compatible with C indexing. As a result, it 132 * can be used directly to index the 'isotopes' array of a 'shtr_molecule' 133 * data structure loaded from an isotope metadata file */ 134 int32_t isotope_id_local; 135 }; 136 #define SHTR_LINE_NULL__ {0,0,0,0,0,0,0,-1,-1} 137 static const struct shtr_line SHTR_LINE_NULL = SHTR_LINE_NULL__; 138 139 static INLINE int 140 shtr_line_eq(const struct shtr_line* line0, const struct shtr_line* line1) 141 { 142 ASSERT(line0 && line1); 143 return line0->wavenumber == line1->wavenumber 144 && line0->intensity == line1->intensity 145 && line0->gamma_air == line1->gamma_air 146 && line0->gamma_self == line1->gamma_self 147 && line0->lower_state_energy == line1->lower_state_energy 148 && line0->n_air == line1->n_air 149 && line0->delta_air == line1->delta_air 150 && line0->molecule_id == line1->molecule_id 151 && line0->isotope_id_local == line1->isotope_id_local; 152 } 153 154 struct shtr_line_param_info { 155 double range[2]; 156 double err; /* Encoding error */ 157 }; 158 #define SHTR_LINE_PARAM_INFO_NULL__ {{DBL_MAX,-DBL_MAX}, 0} 159 static const struct shtr_line_param_info SHTR_LINE_PARAM_INFO_NULL = 160 SHTR_LINE_PARAM_INFO_NULL__; 161 162 /* Information on a list of lines */ 163 struct shtr_line_list_info { 164 struct shtr_line_param_info wavenumber; 165 struct shtr_line_param_info intensity; 166 struct shtr_line_param_info gamma_air; 167 struct shtr_line_param_info gamma_self; 168 struct shtr_line_param_info lower_state_energy; 169 struct shtr_line_param_info n_air; 170 struct shtr_line_param_info delta_air; 171 }; 172 #define SHTR_LINE_LIST_INFO_NULL__ { \ 173 SHTR_LINE_PARAM_INFO_NULL__, \ 174 SHTR_LINE_PARAM_INFO_NULL__, \ 175 SHTR_LINE_PARAM_INFO_NULL__, \ 176 SHTR_LINE_PARAM_INFO_NULL__, \ 177 SHTR_LINE_PARAM_INFO_NULL__, \ 178 SHTR_LINE_PARAM_INFO_NULL__, \ 179 SHTR_LINE_PARAM_INFO_NULL__, \ 180 } 181 static const struct shtr_line_list_info SHTR_LINE_LIST_INFO_NULL = 182 SHTR_LINE_LIST_INFO_NULL__; 183 184 /* Forward declarations of opaque data structures */ 185 struct shtr; 186 struct shtr_isotope_metadata; 187 struct shtr_line_list; 188 struct shtr_line_view; 189 190 /******************************************************************************* 191 * Input arguments for API functions 192 ******************************************************************************/ 193 struct shtr_create_args { 194 struct logger* logger; /* May be NULL <=> default logger */ 195 struct mem_allocator* allocator; /* NULL <=> use default allocator */ 196 int verbose; /* Verbosity level */ 197 }; 198 #define SHTR_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0} 199 static const struct shtr_create_args SHTR_CREATE_ARGS_DEFAULT = 200 SHTR_CREATE_ARGS_DEFAULT__; 201 202 struct shtr_line_list_load_args { 203 const char* filename; /* Name of the file to load or of the provided stream */ 204 FILE* file; /* Stream from where data are loaded. NULL <=> load from file */ 205 }; 206 #define SHTR_LINE_LIST_LOAD_ARGS_NULL__ {NULL, NULL} 207 static const struct shtr_line_list_load_args SHTR_LINE_LIST_LOAD_ARGS_NULL = 208 SHTR_LINE_LIST_LOAD_ARGS_NULL__; 209 210 BEGIN_DECLS 211 212 /******************************************************************************* 213 * Device API 214 ******************************************************************************/ 215 SHTR_API res_T 216 shtr_create 217 (const struct shtr_create_args* args, 218 struct shtr** shtr); 219 220 SHTR_API res_T 221 shtr_ref_get 222 (struct shtr* shtr); 223 224 SHTR_API res_T 225 shtr_ref_put 226 (struct shtr* shtr); 227 228 /******************************************************************************* 229 * Isotope metadata API 230 ******************************************************************************/ 231 SHTR_API res_T 232 shtr_isotope_metadata_load 233 (struct shtr* shtr, 234 const char* path, 235 struct shtr_isotope_metadata** metadata); 236 237 SHTR_API res_T 238 shtr_isotope_metadata_load_stream 239 (struct shtr* shtr, 240 FILE* stream, 241 const char* stream_name, /* NULL <=> use default stream name */ 242 struct shtr_isotope_metadata** metadata); 243 244 /* Load the isotope metadata serialized with the "shtr_isotope_metadata_write" 245 * function */ 246 SHTR_API res_T 247 shtr_isotope_metadata_create_from_stream 248 (struct shtr* shtr, 249 FILE* stream, 250 struct shtr_isotope_metadata** metadata); 251 252 SHTR_API res_T 253 shtr_isotope_metadata_ref_get 254 (struct shtr_isotope_metadata* metadata); 255 256 SHTR_API res_T 257 shtr_isotope_metadata_ref_put 258 (struct shtr_isotope_metadata* metadata); 259 260 SHTR_API res_T 261 shtr_isotope_metadata_get_molecules_count 262 (const struct shtr_isotope_metadata* metadata, 263 size_t* nmolecules); 264 265 SHTR_API res_T 266 shtr_isotope_metadata_get_isotopes_count 267 (const struct shtr_isotope_metadata* metadata, 268 size_t* nisotopes); 269 270 SHTR_API res_T 271 shtr_isotope_metadata_get_molecule 272 (const struct shtr_isotope_metadata* metadata, 273 const size_t imolecule, /* Local index of the molecule in [0, molecules_count[ */ 274 struct shtr_molecule* molecule); 275 276 /* `molecule' is set to SHTR_MOLECULE_NULL if `molecule_id' is not found */ 277 SHTR_API res_T 278 shtr_isotope_metadata_find_molecule 279 (struct shtr_isotope_metadata* metadata, 280 const int molecule_id, /* Unique identifier of the molecule <=> Global index */ 281 struct shtr_molecule* molecule); 282 283 SHTR_API res_T 284 shtr_isotope_metadata_write 285 (const struct shtr_isotope_metadata* metadata, 286 FILE* stream); 287 288 /******************************************************************************* 289 * Lines API 290 ******************************************************************************/ 291 SHTR_API res_T 292 shtr_line_list_load 293 (struct shtr* shtr, 294 const struct shtr_line_list_load_args* args, 295 struct shtr_line_list** list); 296 297 /* Load the line list serialized with the "shtr_line_list_write" function */ 298 SHTR_API res_T 299 shtr_line_list_create_from_stream 300 (struct shtr* shtr, 301 FILE* stream, 302 struct shtr_line_list** list); 303 304 SHTR_API res_T 305 shtr_line_list_ref_get 306 (struct shtr_line_list* list); 307 308 SHTR_API res_T 309 shtr_line_list_ref_put 310 (struct shtr_line_list* list); 311 312 SHTR_API res_T 313 shtr_line_list_get_size 314 (const struct shtr_line_list* list, 315 size_t* nlines); 316 317 SHTR_API res_T 318 shtr_line_list_at 319 (struct shtr_line_list* list, 320 const size_t i, 321 struct shtr_line* line); 322 323 SHTR_API res_T 324 shtr_line_list_write 325 (const struct shtr_line_list* list, 326 FILE* stream); 327 328 SHTR_API res_T 329 shtr_line_list_get_info 330 (const struct shtr_line_list* list, 331 struct shtr_line_list_info* info); 332 333 END_DECLS 334 335 #endif /* SHTR_H */