test_sdis_enclosure_limit_conditions.c (9129B)
1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "test_sdis_utils.h" 17 18 /* This test verifies multi-material enclosures, i.e. enclosures whose 19 * interfaces refer to several media, whereas an enclosure should only cover 20 * one. This configuration remains valid, however, if these enclosures are used 21 * to define boundary conditions, such as convective exchange with several 22 * fluids at known temperature. Although they are valid, it is forbidden to 23 * place a probe in these enclosures. 24 * 25 * +----------------------+ 26 * | | 27 * | +----------------+ | 28 * | | T2 | | 29 * | | | | T4 30 * | | __\ | | __\ 31 * | | T1 / / T3 | | / / Text 32 * | | \__/ | | \__/ 33 * | | | | 34 * | | T0 | | 35 * | +----------------+ | 36 * Y | | 37 * | +----------------------+ 38 * o--X */ 39 40 #define CONVECTION_COEF 10 41 #define DELTA 0.00625 42 #define NREALISATIONS 10000 43 #define Text 360.0 44 45 /******************************************************************************* 46 * Media 47 ******************************************************************************/ 48 #define DEFINE_MEDIUM_GETTER(Func, Val) \ 49 static double \ 50 Func(const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) \ 51 { \ 52 (void)vtx, (void)data; \ 53 return (Val); \ 54 } 55 DEFINE_MEDIUM_GETTER(solid_get_calorific_capacity, 1) 56 DEFINE_MEDIUM_GETTER(solid_get_thermal_conductivity, 1) 57 DEFINE_MEDIUM_GETTER(solid_get_volumic_mass, 1) 58 DEFINE_MEDIUM_GETTER(solid_get_delta, DELTA) 59 DEFINE_MEDIUM_GETTER(solid_get_temperature, SDIS_TEMPERATURE_NONE) 60 DEFINE_MEDIUM_GETTER(fluid_get_temperature, *((double*)sdis_data_cget(data))) 61 #undef DEFINE_MEDIUM_GETTER 62 63 static struct sdis_medium* 64 create_solid(struct sdis_device* dev) 65 { 66 struct sdis_solid_shader shader = SDIS_SOLID_SHADER_NULL; 67 struct sdis_medium* solid = NULL; 68 69 shader.calorific_capacity = solid_get_calorific_capacity; 70 shader.thermal_conductivity = solid_get_thermal_conductivity; 71 shader.volumic_mass = solid_get_volumic_mass; 72 shader.delta = solid_get_delta; 73 shader.temperature = solid_get_temperature; 74 OK(sdis_solid_create(dev, &shader, NULL, &solid)); 75 return solid; 76 } 77 78 static struct sdis_medium* 79 create_fluid(struct sdis_device* dev, const double temperature) 80 { 81 struct sdis_fluid_shader shader = DUMMY_FLUID_SHADER; 82 struct sdis_medium* fluid = NULL; 83 struct sdis_data* data = NULL; 84 85 OK(sdis_data_create 86 (dev, sizeof(double), ALIGNOF(double), NULL, &data)); 87 shader.temperature = fluid_get_temperature; 88 *((double*)sdis_data_get(data)) = temperature; 89 OK(sdis_fluid_create(dev, &shader, data, &fluid)); 90 OK(sdis_data_ref_put(data)); 91 return fluid; 92 } 93 94 /******************************************************************************* 95 * Interface 96 ******************************************************************************/ 97 static double 98 interface_get_convection_coef 99 (const struct sdis_interface_fragment* frag, struct sdis_data* data) 100 { 101 (void)frag, (void)data; 102 return CONVECTION_COEF; 103 } 104 105 static struct sdis_interface* 106 create_interface 107 (struct sdis_device* dev, 108 struct sdis_medium* front, 109 struct sdis_medium* back) 110 { 111 struct sdis_interface_shader shader = SDIS_INTERFACE_SHADER_NULL; 112 struct sdis_interface* interf = NULL; 113 114 shader.convection_coef = interface_get_convection_coef; 115 shader.convection_coef_upper_bound = CONVECTION_COEF; 116 OK(sdis_interface_create(dev, front, back, &shader, NULL, &interf)); 117 return interf; 118 } 119 120 /******************************************************************************* 121 * Scene 122 ******************************************************************************/ 123 static void 124 get_position(const size_t ivert, double pos[2], void* context) 125 { 126 (void)context; 127 if(ivert < square_nvertices) { 128 /* Hole */ 129 pos[0] = square_vertices[ivert*2 + 0]*0.5 + 0.25; 130 pos[1] = square_vertices[ivert*2 + 1]*0.5 + 0.25; 131 } else { 132 /* Border */ 133 pos[0] = square_vertices[(ivert-square_nvertices)*2 + 0]; 134 pos[1] = square_vertices[(ivert-square_nvertices)*2 + 1]; 135 } 136 } 137 138 static void 139 get_indices(const size_t iseg, size_t ids[2], void* context) 140 { 141 (void)context; 142 if(iseg < square_nsegments) { 143 /* Hole */ 144 ids[0] = square_indices[iseg*2 + 0]; 145 ids[1] = square_indices[iseg*2 + 1]; 146 } else { 147 /* Border */ 148 ids[0] = square_indices[(iseg-square_nsegments)*2 + 0] + square_nvertices; 149 ids[1] = square_indices[(iseg-square_nsegments)*2 + 1] + square_nvertices; 150 } 151 } 152 153 static void 154 get_interface(const size_t iseg, struct sdis_interface** bound, void* context) 155 { 156 struct sdis_interface** interfs = context; 157 (void)context; 158 if(iseg < square_nsegments) { 159 *bound = interfs[iseg]; /* Hole */ 160 } else { 161 *bound = interfs[4]; /* Border */ 162 } 163 } 164 165 static struct sdis_scene* 166 create_scene_2d(struct sdis_device* dev) 167 { 168 struct sdis_scene_create_args args = SDIS_SCENE_CREATE_ARGS_DEFAULT; 169 struct sdis_interface* interfaces[5] = {NULL}; 170 struct sdis_medium* fluid[5] = {NULL}; 171 struct sdis_medium* solid = NULL; 172 struct sdis_scene* scn = NULL; 173 174 fluid[0] = create_fluid(dev, 280); 175 fluid[1] = create_fluid(dev, 300); 176 fluid[2] = create_fluid(dev, 320); 177 fluid[3] = create_fluid(dev, 340); 178 fluid[4] = create_fluid(dev, Text); 179 solid = create_solid(dev); 180 181 interfaces[0] = create_interface(dev, fluid[0], solid); 182 interfaces[1] = create_interface(dev, fluid[1], solid); 183 interfaces[2] = create_interface(dev, fluid[2], solid); 184 interfaces[3] = create_interface(dev, fluid[3], solid); 185 interfaces[4] = create_interface(dev, solid, fluid[4]); 186 187 args.get_indices = get_indices; 188 args.get_interface = get_interface; 189 args.get_position = get_position; 190 args.nprimitives = square_nsegments*2/*border + hole*/; 191 args.nvertices = square_nvertices*2/*border + hole*/; 192 args.context = interfaces; 193 OK(sdis_scene_2d_create(dev, &args, &scn)); 194 195 OK(sdis_interface_ref_put(interfaces[0])); 196 OK(sdis_interface_ref_put(interfaces[1])); 197 OK(sdis_interface_ref_put(interfaces[2])); 198 OK(sdis_interface_ref_put(interfaces[3])); 199 OK(sdis_interface_ref_put(interfaces[4])); 200 OK(sdis_medium_ref_put(fluid[0])); 201 OK(sdis_medium_ref_put(fluid[1])); 202 OK(sdis_medium_ref_put(fluid[2])); 203 OK(sdis_medium_ref_put(fluid[3])); 204 OK(sdis_medium_ref_put(fluid[4])); 205 OK(sdis_medium_ref_put(solid)); 206 return scn; 207 } 208 209 /******************************************************************************* 210 * Check 211 ******************************************************************************/ 212 static void 213 solve_probe(struct sdis_scene* scn) 214 { 215 struct sdis_solve_probe_args args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; 216 struct sdis_mc T = SDIS_MC_NULL; 217 struct sdis_estimator* estimator = NULL; 218 219 args.position[0] = 0.5; 220 args.position[1] = 0.5; 221 args.position[2] = 0; 222 args.nrealisations = NREALISATIONS; 223 CHK(sdis_solve_probe(scn, &args, &estimator) == RES_BAD_OP); 224 225 args.position[0] = 2; 226 args.position[1] = 0.5; 227 args.position[2] = 0; 228 args.nrealisations = NREALISATIONS; 229 OK(sdis_solve_probe(scn, &args, &estimator)); 230 OK(sdis_estimator_get_temperature(estimator, &T)); 231 OK(sdis_estimator_ref_put(estimator)); 232 CHK(Text == T.E); /* Zero variance */ 233 234 args.position[0] = 0.1; 235 args.position[1] = 0.1; 236 args.position[2] = 0; 237 args.nrealisations = NREALISATIONS; 238 OK(sdis_solve_probe(scn, &args, &estimator)); 239 OK(sdis_estimator_get_temperature(estimator, &T)); 240 OK(sdis_estimator_ref_put(estimator)); 241 printf("T(%g, %g) ~ %g +/- %g\n", SPLIT2(args.position), T.E, T.SE); 242 } 243 244 /******************************************************************************* 245 * Test 246 ******************************************************************************/ 247 int 248 main(int argc, char** argv) 249 { 250 struct sdis_device* dev = NULL; 251 struct sdis_scene* scn_2d = NULL; 252 (void)argc, (void)argv; 253 254 OK(sdis_device_create(&SDIS_DEVICE_CREATE_ARGS_DEFAULT, &dev)); 255 scn_2d = create_scene_2d(dev); 256 257 solve_probe(scn_2d); 258 259 OK(sdis_device_ref_put(dev)); 260 OK(sdis_scene_ref_put(scn_2d)); 261 262 CHK(mem_allocated_size() == 0); 263 return 0; 264 }