test_sdis_solve_probe.c (23624B)
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 "sdis.h" 17 #include "test_sdis_utils.h" 18 19 #include <star/ssp.h> 20 #include <rsys/math.h> 21 22 #include <string.h> 23 24 /* 25 * The scene is composed of a solid cube with unknown temperature. The 26 * surrounding fluid has a fixed constant temperature. 27 * 28 * (1,1,1) 29 * +-------+ 30 * /' /| _\ 31 * +-------+ | / / 32 * | +.....|.+ \__/ 33 * |, |/ 34 * +-------+ 35 * (0,0,0) 36 */ 37 38 /******************************************************************************* 39 * Geometry 40 ******************************************************************************/ 41 struct context { 42 const double* positions; 43 const size_t* indices; 44 struct sdis_interface* interf; 45 }; 46 47 static void 48 get_indices(const size_t itri, size_t ids[3], void* context) 49 { 50 struct context* ctx = context; 51 ids[0] = ctx->indices[itri*3+0]; 52 ids[1] = ctx->indices[itri*3+1]; 53 ids[2] = ctx->indices[itri*3+2]; 54 } 55 56 static void 57 get_position(const size_t ivert, double pos[3], void* context) 58 { 59 struct context* ctx = context; 60 pos[0] = ctx->positions[ivert*3+0]; 61 pos[1] = ctx->positions[ivert*3+1]; 62 pos[2] = ctx->positions[ivert*3+2]; 63 } 64 65 static void 66 get_interface(const size_t itri, struct sdis_interface** bound, void* context) 67 { 68 struct context* ctx = context; 69 (void)itri; 70 *bound = ctx->interf; 71 } 72 73 /******************************************************************************* 74 * Fluid medium 75 ******************************************************************************/ 76 struct fluid { 77 double temperature; 78 }; 79 80 static double 81 fluid_get_temperature 82 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 83 { 84 CHK(data != NULL && vtx != NULL); 85 return ((const struct fluid*)sdis_data_cget(data))->temperature; 86 } 87 88 /******************************************************************************* 89 * Solid medium 90 ******************************************************************************/ 91 struct solid { 92 double cp; 93 double lambda; 94 double rho; 95 double delta; 96 double temperature; 97 }; 98 99 static double 100 solid_get_calorific_capacity 101 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 102 { 103 CHK(data != NULL && vtx != NULL); 104 return ((const struct solid*)sdis_data_cget(data))->cp; 105 } 106 107 static double 108 solid_get_thermal_conductivity 109 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 110 { 111 CHK(data != NULL && vtx != NULL); 112 return ((const struct solid*)sdis_data_cget(data))->lambda; 113 } 114 115 static double 116 solid_get_volumic_mass 117 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 118 { 119 CHK(data != NULL && vtx != NULL); 120 return ((const struct solid*)sdis_data_cget(data))->rho; 121 } 122 123 static double 124 solid_get_delta 125 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 126 { 127 CHK(data != NULL && vtx != NULL); 128 return ((const struct solid*)sdis_data_cget(data))->delta; 129 } 130 131 static double 132 solid_get_temperature 133 (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) 134 { 135 CHK(data != NULL && vtx != NULL); 136 return ((const struct solid*)sdis_data_cget(data))->temperature; 137 } 138 139 /******************************************************************************* 140 * Interface 141 ******************************************************************************/ 142 struct interf { 143 double hc; 144 double epsilon; 145 double specular_fraction; 146 double reference_temperature; 147 }; 148 149 static double 150 interface_get_convection_coef 151 (const struct sdis_interface_fragment* frag, struct sdis_data* data) 152 { 153 CHK(data != NULL && frag != NULL); 154 return ((const struct interf*)sdis_data_cget(data))->hc; 155 } 156 157 static double 158 interface_get_emissivity 159 (const struct sdis_interface_fragment* frag, 160 const unsigned source_id, 161 struct sdis_data* data) 162 { 163 (void)source_id; 164 CHK(data != NULL && frag != NULL); 165 return ((const struct interf*)sdis_data_cget(data))->epsilon; 166 } 167 168 static double 169 interface_get_specular_fraction 170 (const struct sdis_interface_fragment* frag, 171 const unsigned source_id, 172 struct sdis_data* data) 173 { 174 (void)source_id; 175 CHK(data != NULL && frag != NULL); 176 return ((const struct interf*)sdis_data_cget(data))->specular_fraction; 177 } 178 179 static double 180 interface_get_reference_temperature 181 (const struct sdis_interface_fragment* frag, struct sdis_data* data) 182 { 183 CHK(data != NULL && frag != NULL); 184 return ((const struct interf*)sdis_data_cget(data))->reference_temperature; 185 } 186 187 /******************************************************************************* 188 * Radiative environment 189 ******************************************************************************/ 190 struct radenv { 191 double temperature; /* [K] */ 192 double reference; /* [K] */ 193 }; 194 195 static double 196 radenv_get_temperature 197 (const struct sdis_radiative_ray* ray, 198 struct sdis_data* data) 199 { 200 (void)ray; 201 return ((const struct radenv*)sdis_data_cget(data))->temperature; 202 } 203 204 static double 205 radenv_get_reference_temperature 206 (const struct sdis_radiative_ray* ray, 207 struct sdis_data* data) 208 { 209 (void)ray; 210 return ((const struct radenv*)sdis_data_cget(data))->reference; 211 } 212 213 static struct sdis_radiative_env* 214 create_radenv 215 (struct sdis_device* dev, 216 const double temperature, /* [K] */ 217 const double reference) /* [K] */ 218 { 219 struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; 220 struct sdis_radiative_env* radenv = NULL; 221 struct sdis_data* data = NULL; 222 struct radenv* radenv_args = NULL; 223 224 OK(sdis_data_create(dev, sizeof(struct radenv), ALIGNOF(radenv), NULL, &data)); 225 radenv_args = sdis_data_get(data); 226 radenv_args->temperature = temperature; 227 radenv_args->reference = reference; 228 229 shader.temperature = radenv_get_temperature; 230 shader.reference_temperature = radenv_get_reference_temperature; 231 OK(sdis_radiative_env_create(dev, &shader, data, &radenv)); 232 OK(sdis_data_ref_put(data)); 233 return radenv; 234 } 235 236 /******************************************************************************* 237 * Helper functions 238 ******************************************************************************/ 239 struct dump_path_context { 240 FILE* stream; 241 size_t offset; 242 size_t nfailures; 243 size_t nsuccesses; 244 }; 245 static const struct dump_path_context DUMP_PATH_CONTEXT_NULL = {NULL, 0, 0, 0}; 246 247 static res_T 248 dump_vertex_pos(const struct sdis_heat_vertex* vert, void* context) 249 { 250 struct dump_path_context* ctx = context; 251 CHK(vert && context); 252 fprintf(ctx->stream, "v %g %g %g\n", SPLIT3(vert->P)); 253 return RES_OK; 254 } 255 256 static res_T 257 process_heat_path(const struct sdis_heat_path* path, void* context) 258 { 259 struct dump_path_context* ctx = context; 260 struct sdis_heat_vertex vert = SDIS_HEAT_VERTEX_NULL; 261 enum sdis_heat_path_flag status = SDIS_HEAT_PATH_NONE; 262 size_t i; 263 size_t n; 264 (void)context; 265 266 CHK(path && context); 267 268 BA(sdis_heat_path_get_line_strips_count(NULL, &n)); 269 BA(sdis_heat_path_get_line_strips_count(path, NULL)); 270 OK(sdis_heat_path_get_line_strips_count(path, &n)); 271 CHK(n == 1); 272 273 BA(sdis_heat_path_get_status(NULL, &status)); 274 BA(sdis_heat_path_get_status(path, NULL)); 275 OK(sdis_heat_path_get_status(path, &status)); 276 CHK(status == SDIS_HEAT_PATH_SUCCESS || status == SDIS_HEAT_PATH_FAILURE); 277 278 switch(status) { 279 case SDIS_HEAT_PATH_FAILURE: ++ctx->nfailures; break; 280 case SDIS_HEAT_PATH_SUCCESS: ++ctx->nsuccesses; break; 281 default: FATAL("Unreachable code.\n"); break; 282 } 283 284 BA(sdis_heat_path_line_strip_get_vertices_count(NULL, 0, &n)); 285 BA(sdis_heat_path_line_strip_get_vertices_count(path, 1, &n)); 286 BA(sdis_heat_path_line_strip_get_vertices_count(path, 0, NULL)); 287 OK(sdis_heat_path_line_strip_get_vertices_count(path, 0, &n)); 288 CHK(n != 0); 289 290 BA(sdis_heat_path_line_strip_get_vertex(NULL, 0, 0, &vert)); 291 BA(sdis_heat_path_line_strip_get_vertex(path, 1, 1, &vert)); 292 BA(sdis_heat_path_line_strip_get_vertex(path, 0, n, &vert)); 293 BA(sdis_heat_path_line_strip_get_vertex(path, 0, 0, NULL)); 294 295 FOR_EACH(i, 0, n) { 296 OK(sdis_heat_path_line_strip_get_vertex(path, 0, i, &vert)); 297 CHK(vert.type == SDIS_HEAT_VERTEX_CONVECTION 298 || vert.type == SDIS_HEAT_VERTEX_CONDUCTION 299 || vert.type == SDIS_HEAT_VERTEX_RADIATIVE); 300 } 301 302 BA(sdis_heat_path_line_strip_for_each_vertex(NULL, 0, dump_vertex_pos, context)); 303 BA(sdis_heat_path_line_strip_for_each_vertex(path, 1, dump_vertex_pos, context)); 304 BA(sdis_heat_path_line_strip_for_each_vertex(path, 0, NULL, context)); 305 OK(sdis_heat_path_line_strip_for_each_vertex(path, 0, dump_vertex_pos, context)); 306 307 FOR_EACH(i, 0, n-1) { 308 fprintf(ctx->stream, "l %lu %lu\n", 309 (unsigned long)(i+1 + ctx->offset), 310 (unsigned long)(i+2 + ctx->offset)); 311 } 312 313 ctx->offset += n; 314 315 return RES_OK; 316 } 317 318 /******************************************************************************* 319 * Test 320 ******************************************************************************/ 321 int 322 main(int argc, char** argv) 323 { 324 struct mem_allocator allocator; 325 struct sdis_mc T = SDIS_MC_NULL; 326 struct sdis_mc F = SDIS_MC_NULL; 327 struct sdis_mc time = SDIS_MC_NULL; 328 struct sdis_device* dev = NULL; 329 struct sdis_medium* solid = NULL; 330 struct sdis_medium* fluid = NULL; 331 struct sdis_interface* interf = NULL; 332 struct sdis_radiative_env* radenv = NULL; 333 struct sdis_scene* scn = NULL; 334 struct sdis_data* data = NULL; 335 struct sdis_estimator* estimator = NULL; 336 struct sdis_estimator* estimator2 = NULL; 337 struct sdis_estimator* estimator3 = NULL; 338 struct sdis_green_function* green = NULL; 339 const struct sdis_heat_path* path = NULL; 340 struct sdis_device_create_args dev_args = SDIS_DEVICE_CREATE_ARGS_DEFAULT; 341 struct sdis_green_function_create_from_stream_args green_args = 342 SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT; 343 struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT; 344 struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; 345 struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; 346 struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; 347 struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; 348 struct dump_path_context dump_ctx = DUMP_PATH_CONTEXT_NULL; 349 struct context ctx; 350 struct radenv* radenv_args; 351 struct fluid* fluid_args; 352 struct solid* solid_args; 353 struct interf* interface_args; 354 struct ssp_rng* rng_state = NULL; 355 enum sdis_estimator_type type; 356 FILE* stream = NULL; 357 double t_range[2]; 358 double ref; 359 const size_t N = 1000; 360 const size_t N_dump = 10; 361 size_t nreals; 362 size_t nfails; 363 size_t n; 364 (void)argc, (void)argv; 365 366 OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); 367 dev_args.allocator = &allocator; 368 OK(sdis_device_create(&dev_args, &dev)); 369 370 /* Create the fluid medium */ 371 OK(sdis_data_create 372 (dev, sizeof(struct fluid), ALIGNOF(struct fluid), NULL, &data)); 373 fluid_args = sdis_data_get(data); 374 fluid_args->temperature = 300; 375 fluid_shader.temperature = fluid_get_temperature; 376 OK(sdis_fluid_create(dev, &fluid_shader, data, &fluid)); 377 OK(sdis_data_ref_put(data)); 378 379 /* Create the solid medium */ 380 OK(sdis_data_create 381 (dev, sizeof(struct solid), ALIGNOF(struct solid), NULL, &data)); 382 solid_args = sdis_data_get(data); 383 solid_args->cp = 1.0; 384 solid_args->lambda = 0.1; 385 solid_args->rho = 1.0; 386 solid_args->delta = 1.0/20.0; 387 solid_args->temperature = SDIS_TEMPERATURE_NONE; /* Unknown temperature */ 388 solid_shader.calorific_capacity = solid_get_calorific_capacity; 389 solid_shader.thermal_conductivity = solid_get_thermal_conductivity; 390 solid_shader.volumic_mass = solid_get_volumic_mass; 391 solid_shader.delta = solid_get_delta; 392 solid_shader.temperature = solid_get_temperature; 393 OK(sdis_solid_create(dev, &solid_shader, data, &solid)); 394 OK(sdis_data_ref_put(data)); 395 396 /* Create the solid/fluid interface */ 397 OK(sdis_data_create(dev, sizeof(struct interf), 398 ALIGNOF(struct interf), NULL, &data)); 399 interface_args = sdis_data_get(data); 400 interface_args->hc = 0.5; 401 interface_args->epsilon = 0; 402 interface_args->specular_fraction = 0; 403 interface_shader.convection_coef = interface_get_convection_coef; 404 interface_shader.front = SDIS_INTERFACE_SIDE_SHADER_NULL; 405 interface_shader.back.temperature = NULL; 406 interface_shader.back.emissivity = interface_get_emissivity; 407 interface_shader.back.specular_fraction = interface_get_specular_fraction; 408 interface_shader.back.reference_temperature = interface_get_reference_temperature; 409 OK(sdis_interface_create 410 (dev, solid, fluid, &interface_shader, data, &interf)); 411 OK(sdis_data_ref_put(data)); 412 413 /* Release the media */ 414 OK(sdis_medium_ref_put(solid)); 415 OK(sdis_medium_ref_put(fluid)); 416 417 /* Create the radiative environment */ 418 radenv = create_radenv(dev, SDIS_TEMPERATURE_NONE, SDIS_TEMPERATURE_NONE); 419 radenv_args = sdis_data_get(sdis_radiative_env_get_data(radenv)); 420 421 /* Create the scene */ 422 ctx.positions = box_vertices; 423 ctx.indices = box_indices; 424 ctx.interf = interf; 425 scn_args.get_indices = get_indices; 426 scn_args.get_interface = get_interface; 427 scn_args.get_position = get_position; 428 scn_args.nprimitives = box_ntriangles; 429 scn_args.nvertices = box_nvertices; 430 scn_args.radenv = radenv; 431 scn_args.context = &ctx; 432 OK(sdis_scene_create(dev, &scn_args, &scn)); 433 434 OK(sdis_interface_ref_put(interf)); 435 436 /* Test the solver */ 437 solve_args.nrealisations = N; 438 solve_args.position[0] = 0.5; 439 solve_args.position[1] = 0.5; 440 solve_args.position[2] = 0.5; 441 solve_args.time_range[0] = INF; 442 solve_args.time_range[1] = INF; 443 444 BA(sdis_solve_probe(NULL, &solve_args, &estimator)); 445 BA(sdis_solve_probe(scn, NULL, &estimator)); 446 BA(sdis_solve_probe(scn, &solve_args, NULL)); 447 solve_args.nrealisations = 0; 448 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 449 solve_args.nrealisations = N; 450 solve_args.time_range[0] = solve_args.time_range[1] = -1; 451 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 452 solve_args.time_range[0] = 1; 453 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 454 solve_args.time_range[1] = 0; 455 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 456 solve_args.time_range[0] = solve_args.time_range[1] = INF; 457 solve_args.picard_order = 0; 458 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 459 solve_args.picard_order = 1; 460 solve_args.diff_algo = SDIS_DIFFUSION_NONE; 461 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 462 solve_args.diff_algo = SDIS_DIFFUSION_DELTA_SPHERE; 463 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 464 465 BA(sdis_estimator_get_type(estimator, NULL)); 466 BA(sdis_estimator_get_type(NULL, &type)); 467 OK(sdis_estimator_get_type(estimator, &type)); 468 CHK(type == SDIS_ESTIMATOR_TEMPERATURE); 469 470 /* Fluxes aren't available after sdis_solve_probe */ 471 BA(sdis_estimator_get_convective_flux(estimator, NULL)); 472 BA(sdis_estimator_get_convective_flux(NULL, &F)); 473 BA(sdis_estimator_get_convective_flux(estimator, &F)); 474 475 BA(sdis_estimator_get_radiative_flux(estimator, NULL)); 476 BA(sdis_estimator_get_radiative_flux(NULL, &F)); 477 BA(sdis_estimator_get_radiative_flux(estimator, &F)); 478 479 BA(sdis_estimator_get_total_flux(estimator, NULL)); 480 BA(sdis_estimator_get_total_flux(NULL, &F)); 481 BA(sdis_estimator_get_total_flux(estimator, &F)); 482 483 BA(sdis_estimator_get_realisation_count(estimator, NULL)); 484 BA(sdis_estimator_get_realisation_count(NULL, &nreals)); 485 OK(sdis_estimator_get_realisation_count(estimator, &nreals)); 486 487 BA(sdis_estimator_get_failure_count(estimator, NULL)); 488 BA(sdis_estimator_get_failure_count(NULL, &nfails)); 489 OK(sdis_estimator_get_failure_count(estimator, &nfails)); 490 491 BA(sdis_estimator_get_temperature(estimator, NULL)); 492 BA(sdis_estimator_get_temperature(NULL, &T)); 493 OK(sdis_estimator_get_temperature(estimator, &T)); 494 495 BA(sdis_estimator_get_realisation_time(estimator, NULL)); 496 BA(sdis_estimator_get_realisation_time(NULL, &time)); 497 OK(sdis_estimator_get_realisation_time(estimator, &time)); 498 499 BA(sdis_estimator_get_rng_state(NULL, &rng_state)); 500 BA(sdis_estimator_get_rng_state(estimator, NULL)); 501 OK(sdis_estimator_get_rng_state(estimator, &rng_state)); 502 503 ref = 300; 504 printf("Temperature at (%g, %g, %g) with Tfluid=%g = %g ~ %g +/- %g\n", 505 SPLIT3(solve_args.position), fluid_args->temperature, ref, T.E, T.SE); 506 printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); 507 printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); 508 509 CHK(nfails + nreals == N); 510 CHK(nfails < N/1000); 511 CHK(eq_eps(T.E, ref, T.SE)); 512 513 BA(sdis_estimator_ref_get(NULL)); 514 OK(sdis_estimator_ref_get(estimator)); 515 BA(sdis_estimator_ref_put(NULL)); 516 OK(sdis_estimator_ref_put(estimator)); 517 OK(sdis_estimator_ref_put(estimator)); 518 519 /* The external fluid cannot have an unknown temperature */ 520 fluid_args->temperature = SDIS_TEMPERATURE_NONE; 521 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 522 523 fluid_args->temperature = 300; 524 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 525 526 BA(sdis_solve_probe_green_function(NULL, &solve_args, &green)); 527 BA(sdis_solve_probe_green_function(scn, NULL, &green)); 528 BA(sdis_solve_probe_green_function(scn, &solve_args, NULL)); 529 solve_args.nrealisations = 0; 530 BA(sdis_solve_probe_green_function(scn, &solve_args, &green)); 531 solve_args.nrealisations = N; 532 OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); 533 534 BA(sdis_green_function_solve(NULL, &estimator2)); 535 BA(sdis_green_function_solve(green, NULL)); 536 BA(sdis_green_function_solve(NULL, NULL)); 537 OK(sdis_green_function_solve(green, &estimator2)); 538 539 check_green_function(green); 540 check_estimator_eq(estimator, estimator2); 541 542 OK(sdis_estimator_ref_put(estimator)); 543 OK(sdis_estimator_ref_put(estimator2)); 544 printf("\n"); 545 546 /* Check same green used at a different temperature */ 547 fluid_args->temperature = 500; 548 549 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 550 OK(sdis_estimator_get_realisation_count(estimator, &nreals)); 551 OK(sdis_estimator_get_failure_count(estimator, &nfails)); 552 OK(sdis_estimator_get_temperature(estimator, &T)); 553 OK(sdis_estimator_get_realisation_time(estimator, &time)); 554 555 ref = 500; 556 printf("Temperature at (%g, %g, %g) with Tfluid=%g = %g ~ %g +/- %g\n", 557 SPLIT3(solve_args.position), fluid_args->temperature, ref, T.E, T.SE); 558 printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); 559 printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); 560 561 CHK(nfails + nreals == N); 562 CHK(nfails < N / 1000); 563 CHK(eq_eps(T.E, ref, T.SE)); 564 565 OK(sdis_green_function_solve(green, &estimator2)); 566 check_green_function(green); 567 check_estimator_eq(estimator, estimator2); 568 569 stream = tmpfile(); 570 CHK(stream); 571 BA(sdis_green_function_write(NULL, stream)); 572 BA(sdis_green_function_write(green, NULL)); 573 OK(sdis_green_function_write(green, stream)); 574 575 BA(sdis_green_function_ref_get(NULL)); 576 OK(sdis_green_function_ref_get(green)); 577 BA(sdis_green_function_ref_put(NULL)); 578 OK(sdis_green_function_ref_put(green)); 579 OK(sdis_green_function_ref_put(green)); 580 581 rewind(stream); 582 green_args.scene = NULL; 583 green_args.stream = stream; 584 BA(sdis_green_function_create_from_stream(&green_args, &green)); 585 green_args.scene = scn; 586 green_args.stream = NULL; 587 BA(sdis_green_function_create_from_stream(&green_args, &green)); 588 green_args.scene = scn; 589 green_args.stream = stream; 590 BA(sdis_green_function_create_from_stream(&green_args, NULL)); 591 OK(sdis_green_function_create_from_stream(&green_args, &green)); 592 CHK(!fclose(stream)); 593 594 OK(sdis_green_function_solve(green, &estimator3)); 595 check_green_function(green); 596 check_estimator_eq_strict(estimator2, estimator3); 597 OK(sdis_green_function_ref_put(green)); 598 OK(sdis_estimator_ref_put(estimator3)); 599 600 CHK(stream = tmpfile()); 601 hash_sha256("Hello, world!", strlen("Hello, world!"), solve_args.signature); 602 OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); 603 OK(sdis_green_function_write(green, stream)); 604 OK(sdis_green_function_ref_put(green)); 605 606 green_args.scene = scn; 607 green_args.stream = stream; 608 rewind(stream); 609 BA(sdis_green_function_create_from_stream(&green_args, &green)); 610 memcpy(green_args.signature, solve_args.signature, sizeof(hash256_T)); 611 rewind(stream); 612 OK(sdis_green_function_create_from_stream(&green_args, &green)); 613 CHK(!fclose(stream)); 614 615 OK(sdis_green_function_solve(green, &estimator3)); 616 check_estimator_eq_strict(estimator2, estimator3); 617 OK(sdis_green_function_ref_put(green)); 618 OK(sdis_estimator_ref_put(estimator3)); 619 620 OK(sdis_estimator_ref_put(estimator)); 621 OK(sdis_estimator_ref_put(estimator2)); 622 623 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 624 BA(sdis_estimator_get_paths_count(NULL, &n)); 625 BA(sdis_estimator_get_paths_count(estimator, NULL)); 626 OK(sdis_estimator_get_paths_count(estimator, &n)); 627 CHK(n == 0); 628 OK(sdis_estimator_ref_put(estimator)); 629 630 solve_args.nrealisations = N_dump; 631 solve_args.register_paths = SDIS_HEAT_PATH_ALL; 632 633 /* Check simulation error handling when paths are registered */ 634 fluid_args->temperature = SDIS_TEMPERATURE_NONE; 635 BA(sdis_solve_probe(scn, &solve_args, &estimator)); 636 637 fluid_args->temperature = 300; 638 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 639 OK(sdis_estimator_get_paths_count(estimator, &n)); 640 CHK(n == N_dump); 641 642 BA(sdis_estimator_get_path(NULL, 0, &path)); 643 BA(sdis_estimator_get_path(estimator, n, &path)); 644 BA(sdis_estimator_get_path(estimator, 0, NULL)); 645 OK(sdis_estimator_get_path(estimator, 0, &path)); 646 647 dump_ctx.stream = stderr; 648 BA(sdis_estimator_for_each_path(NULL, process_heat_path, &dump_ctx)); 649 BA(sdis_estimator_for_each_path(estimator, NULL, &dump_ctx)); 650 OK(sdis_estimator_for_each_path(estimator, process_heat_path, &dump_ctx)); 651 652 OK(sdis_estimator_ref_put(estimator)); 653 654 printf("\n"); 655 656 /* Green and ambient radiative temperature */ 657 solve_args.nrealisations = N; 658 radenv_args->temperature = 300; 659 radenv_args->reference = 300; 660 t_range[0] = 300; 661 t_range[1] = 300; 662 OK(sdis_scene_set_temperature_range(scn, t_range)); 663 664 interface_args->epsilon = 1; 665 interface_args->reference_temperature = 300; 666 667 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 668 OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); 669 OK(sdis_green_function_solve(green, &estimator2)); 670 671 check_green_function(green); 672 check_estimator_eq(estimator, estimator2); 673 674 OK(sdis_estimator_ref_put(estimator)); 675 OK(sdis_estimator_ref_put(estimator2)); 676 677 /* Check same green used at different ambient radiative temperature */ 678 radenv_args->temperature = 300; 679 t_range[0] = 300; 680 t_range[1] = 600; 681 OK(sdis_scene_set_temperature_range(scn, t_range)); 682 683 OK(sdis_solve_probe(scn, &solve_args, &estimator)); 684 OK(sdis_green_function_solve(green, &estimator2)); 685 686 check_green_function(green); 687 check_estimator_eq(estimator, estimator2); 688 689 OK(sdis_estimator_ref_put(estimator)); 690 OK(sdis_estimator_ref_put(estimator2)); 691 OK(sdis_green_function_ref_put(green)); 692 OK(sdis_radiative_env_ref_put(radenv)); 693 694 OK(sdis_scene_ref_put(scn)); 695 OK(sdis_device_ref_put(dev)); 696 697 check_memory_allocator(&allocator); 698 mem_shutdown_proxy_allocator(&allocator); 699 CHK(mem_allocated_size() == 0); 700 return 0; 701 } 702