test_sln_mixture.c (9657B)
1 /* Copyright (C) 2022, 2026 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 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 #include "test_sln_lines.h" 20 #include "sln.h" 21 22 #include <star/shtr.h> 23 #include <rsys/math.h> 24 #include <rsys/mem_allocator.h> 25 26 /******************************************************************************* 27 * Helper function 28 ******************************************************************************/ 29 static void 30 test_mixture 31 (struct sln_device* sln, 32 struct shtr_isotope_metadata* metadata, 33 struct shtr_line_list* line_list) 34 { 35 struct sln_mixture_create_args mixture_args = SLN_MIXTURE_CREATE_ARGS_DEFAULT; 36 struct sln_mixture_desc desc = SLN_MIXTURE_DESC_NULL; 37 struct sln_mixture* mixture = NULL; 38 size_t nlines = 0; 39 40 mixture_args.metadata = metadata; 41 mixture_args.lines = line_list; 42 mixture_args.molecules[0].nisotopes = 0; /* Handle all isotopes */ 43 mixture_args.molecules[0].concentration = 1.0/3.0; 44 mixture_args.molecules[0].cutoff = 25; 45 mixture_args.molecules[0].id = 1; /* H2O */ 46 mixture_args.molecules[1].nisotopes = 0; /* Handle all isotopes */ 47 mixture_args.molecules[1].concentration = 1.0/3.0; 48 mixture_args.molecules[1].cutoff = 50; 49 mixture_args.molecules[1].id = 2; /* CO2 */ 50 mixture_args.molecules[2].nisotopes = 0; /* Handle all isotopes */ 51 mixture_args.molecules[2].concentration = 1.0/3.0; 52 mixture_args.molecules[2].cutoff = 25; 53 mixture_args.molecules[2].id = 3; /* O3 */ 54 mixture_args.nmolecules = 3; 55 mixture_args.wavenumber_range[0] = 0; 56 mixture_args.wavenumber_range[1] = INF; 57 mixture_args.pressure = 1; 58 mixture_args.temperature = 296; 59 CHK(sln_mixture_create(NULL, &mixture_args, &mixture) == RES_BAD_ARG); 60 CHK(sln_mixture_create(sln, NULL, &mixture) == RES_BAD_ARG); 61 CHK(sln_mixture_create(sln, NULL, NULL) == RES_BAD_ARG); 62 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_OK); 63 64 CHK(sln_mixture_get_desc(NULL, &desc) == RES_BAD_ARG); 65 CHK(sln_mixture_get_desc(mixture, NULL) == RES_BAD_ARG); 66 CHK(sln_mixture_get_desc(mixture, &desc) == RES_OK); 67 68 CHK(shtr_line_list_get_size(line_list, &nlines) == RES_OK); 69 70 CHK(desc.wavenumber_range[0] == mixture_args.wavenumber_range[0]); 71 CHK(desc.wavenumber_range[1] == mixture_args.wavenumber_range[1]); 72 CHK(desc.temperature = mixture_args.temperature); 73 CHK(desc.pressure == mixture_args.pressure); 74 CHK(desc.nlines == nlines); /* All the lines are taken into the count */ 75 76 CHK(sln_mixture_ref_get(NULL) == RES_BAD_ARG); 77 CHK(sln_mixture_ref_get(mixture) == RES_OK); 78 CHK(sln_mixture_ref_put(NULL) == RES_BAD_ARG); 79 CHK(sln_mixture_ref_put(mixture) == RES_OK); 80 CHK(sln_mixture_ref_put(mixture) == RES_OK); 81 82 mixture_args.metadata = NULL; 83 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 84 85 mixture_args.metadata = metadata; 86 mixture_args.lines = NULL; 87 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 88 89 mixture_args.metadata = metadata; 90 mixture_args.lines = NULL; 91 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 92 93 mixture_args.lines = line_list; 94 mixture_args.molecules[0].concentration = 1; 95 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 96 97 mixture_args.molecules[0].concentration = -1; 98 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 99 100 mixture_args.molecules[0].concentration = 1.0/3.0; 101 mixture_args.molecules[0].cutoff = 0; 102 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 103 104 mixture_args.molecules[0].cutoff = 25; 105 mixture_args.pressure = -1; 106 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 107 108 mixture_args.pressure = 1; 109 mixture_args.temperature = -1; 110 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 111 mixture_args.temperature = 296; 112 113 mixture_args.molecules[0].nisotopes = 2; 114 mixture_args.molecules[0].isotopes[0].abundance = 0.6; 115 mixture_args.molecules[0].isotopes[0].id_local = 0; 116 mixture_args.molecules[0].isotopes[1].abundance = 0.5; 117 mixture_args.molecules[0].isotopes[1].id_local = 1; 118 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 119 mixture_args.molecules[0].isotopes[0].abundance = 0.5; 120 121 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_OK); 122 CHK(sln_mixture_ref_put(mixture) == RES_OK); 123 124 mixture_args.molecules[0].id = SLN_MAX_MOLECULES_COUNT; 125 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 126 mixture_args.molecules[0].id = 1; 127 mixture_args.molecules[0].isotopes[0].id_local = SLN_MAX_ISOTOPES_COUNT; 128 CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG); 129 } 130 131 static void 132 test_mixture_serialization 133 (struct sln_device* sln, 134 struct shtr* shtr, 135 struct shtr_isotope_metadata* metadata, 136 struct shtr_line_list* line_list) 137 { 138 struct sln_mixture_create_args mixture_args = SLN_MIXTURE_CREATE_ARGS_DEFAULT; 139 struct sln_mixture_desc desc1 = SLN_MIXTURE_DESC_NULL; 140 struct sln_mixture_desc desc2 = SLN_MIXTURE_DESC_NULL; 141 struct sln_mixture* mixture1 = NULL; 142 struct sln_mixture* mixture2 = NULL; 143 FILE* fp = NULL; 144 145 mixture_args.metadata = metadata; 146 mixture_args.lines = line_list; 147 mixture_args.molecules[0].nisotopes = 0; /* Handle all isotopes */ 148 mixture_args.molecules[0].concentration = 1.0/3.0; 149 mixture_args.molecules[0].cutoff = 25; 150 mixture_args.molecules[0].id = 1; /* H2O */ 151 mixture_args.molecules[1].nisotopes = 0; /* Handle all isotopes */ 152 mixture_args.molecules[1].concentration = 1.0/3.0; 153 mixture_args.molecules[1].cutoff = 50; 154 mixture_args.molecules[1].id = 2; /* CO2 */ 155 mixture_args.molecules[2].nisotopes = 0; /* Handle all isotopes */ 156 mixture_args.molecules[2].concentration = 1.0/3.0; 157 mixture_args.molecules[2].cutoff = 25; 158 mixture_args.molecules[2].id = 3; /* O3 */ 159 mixture_args.nmolecules = 3; 160 mixture_args.wavenumber_range[0] = 0; 161 mixture_args.wavenumber_range[1] = INF; 162 mixture_args.pressure = 1; 163 mixture_args.temperature = 296; 164 CHK(sln_mixture_create(sln, &mixture_args, &mixture1) == RES_OK); 165 166 CHK(fp = tmpfile()); 167 CHK(sln_mixture_write(NULL, fp) == RES_BAD_ARG); 168 CHK(sln_mixture_write(mixture1, NULL) == RES_BAD_ARG); 169 CHK(sln_mixture_write(mixture1, fp) == RES_OK); 170 rewind(fp); 171 172 CHK(sln_mixture_create_from_stream(NULL, shtr, fp, &mixture2) == RES_BAD_ARG); 173 CHK(sln_mixture_create_from_stream(sln, NULL, fp, &mixture2) == RES_BAD_ARG); 174 CHK(sln_mixture_create_from_stream(sln, shtr, NULL, &mixture2) == RES_BAD_ARG); 175 CHK(sln_mixture_create_from_stream(sln, shtr, fp, NULL) == RES_BAD_ARG); 176 CHK(sln_mixture_create_from_stream(sln, shtr, fp, &mixture2) == RES_OK); 177 fclose(fp); 178 179 CHK(sln_mixture_get_desc(mixture1, &desc1) == RES_OK); 180 CHK(sln_mixture_get_desc(mixture2, &desc2) == RES_OK); 181 182 CHK(desc1.wavenumber_range[0] == desc2.wavenumber_range[0]); 183 CHK(desc1.wavenumber_range[1] == desc2.wavenumber_range[1]); 184 CHK(desc1.pressure == desc2.pressure); 185 CHK(desc1.temperature == desc2.temperature); 186 CHK(desc1.nlines == desc2.nlines); 187 188 CHK(sln_mixture_ref_put(mixture1) == RES_OK); 189 CHK(sln_mixture_ref_put(mixture2) == RES_OK); 190 } 191 192 /******************************************************************************* 193 * Test function 194 ******************************************************************************/ 195 int 196 main(int argc, char** argv) 197 { 198 struct sln_device_create_args dev_args = SLN_DEVICE_CREATE_ARGS_DEFAULT; 199 200 struct sln_device* sln = NULL; 201 202 struct shtr_create_args shtr_args = SHTR_CREATE_ARGS_DEFAULT; 203 struct shtr* shtr = NULL; 204 struct shtr_line_list* line_list = NULL; 205 struct shtr_isotope_metadata* metadata = NULL; 206 207 FILE* fp_lines = NULL; 208 FILE* fp_mdata = NULL; 209 (void)argc, (void)argv; 210 211 /* Generate the file of the isotope metadata */ 212 CHK(fp_mdata = tmpfile()); 213 fprintf(fp_mdata, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n"); 214 write_shtr_molecule(fp_mdata, &g_H2O); 215 write_shtr_molecule(fp_mdata, &g_CO2); 216 write_shtr_molecule(fp_mdata, &g_O3); 217 rewind(fp_mdata); 218 219 /* Generate the file of lines */ 220 CHK(fp_lines = tmpfile()); 221 write_shtr_lines(fp_lines, g_lines, g_nlines); 222 rewind(fp_lines); 223 224 /* Load the isotope metadata and the lines */ 225 shtr_args.verbose = 1; 226 CHK(shtr_create(&shtr_args, &shtr) == RES_OK); 227 CHK(shtr_isotope_metadata_load_stream(shtr, fp_mdata, NULL, &metadata) == RES_OK); 228 CHK(shtr_line_list_load_stream(shtr, fp_lines, NULL, &line_list) == RES_OK); 229 230 CHK(fclose(fp_lines) == 0); 231 CHK(fclose(fp_mdata) == 0); 232 233 dev_args.verbose = 1; 234 CHK(sln_device_create(&dev_args, &sln) == RES_OK); 235 236 test_mixture(sln, metadata, line_list); 237 test_mixture_serialization(sln, shtr, metadata, line_list); 238 239 CHK(sln_device_ref_put(sln) == RES_OK); 240 CHK(shtr_ref_put(shtr) == RES_OK); 241 CHK(shtr_line_list_ref_put(line_list) == RES_OK); 242 CHK(shtr_isotope_metadata_ref_put(metadata) == RES_OK); 243 CHK(mem_allocated_size() == 0); 244 return 0; 245 }