stardis-intface.c (29208B)
1 /* Copyright (C) 2018-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 "stardis-intface.h" 17 #include "stardis-app.h" 18 #include "stardis-compute.h" 19 #include "stardis-output.h" 20 #include "stardis-solid.h" 21 #include "stardis-hbound.h" 22 #include "stardis-hbound-prog.h" 23 #include "stardis-hfbound.h" 24 #include "stardis-hfbound-prog.h" 25 #include "stardis-tbound.h" 26 #include "stardis-tbound-prog.h" 27 #include "stardis-fbound.h" 28 #include "stardis-fbound-prog.h" 29 #include "stardis-ssconnect.h" 30 #include "stardis-ssconnect-prog.h" 31 #include "stardis-sfconnect.h" 32 #include "stardis-sfconnect-prog.h" 33 34 #include <sdis.h> 35 36 /******************************************************************************* 37 * Local Functions 38 ******************************************************************************/ 39 40 static double 41 interface_get_convection_coef 42 (const struct sdis_interface_fragment* frag, 43 struct sdis_data* data) 44 { 45 const struct intface* interface_props = sdis_data_cget(data); 46 (void)frag; 47 return interface_props->hc; 48 } 49 50 static double 51 interface_get_temperature 52 (const struct sdis_interface_fragment* frag, 53 struct sdis_data* data) 54 { 55 const struct intface* interface_props = sdis_data_cget(data); 56 (void)frag; 57 return interface_props->imposed_temperature; 58 } 59 60 static double 61 interface_get_flux 62 (const struct sdis_interface_fragment* frag, 63 struct sdis_data* data) 64 { 65 const struct intface* interface_props = sdis_data_cget(data); 66 (void)frag; 67 return interface_props->imposed_flux; 68 } 69 70 static double 71 interface_get_ref_temperature 72 (const struct sdis_interface_fragment* frag, 73 struct sdis_data* data) 74 { 75 const struct intface* interface_props = sdis_data_cget(data); 76 (void)frag; 77 return interface_props->ref_temperature; 78 } 79 80 static double 81 interface_get_emissivity 82 (const struct sdis_interface_fragment* frag, 83 const unsigned source_id, 84 struct sdis_data* data) 85 { 86 const struct intface* interface_props = sdis_data_cget(data); 87 (void)frag, (void)source_id; 88 return interface_props->emissivity; 89 } 90 91 static double 92 interface_get_alpha 93 (const struct sdis_interface_fragment* frag, 94 const unsigned source_id, 95 struct sdis_data* data) 96 { 97 const struct intface* interface_props = sdis_data_cget(data); 98 (void)frag, (void)source_id; 99 return interface_props->alpha; 100 } 101 102 static double 103 interface_get_tcr 104 (const struct sdis_interface_fragment* frag, 105 struct sdis_data* data) 106 { 107 const struct intface* interface_props = sdis_data_cget(data); 108 (void)frag; 109 return interface_props->tcr; 110 } 111 112 static double 113 emissivity_1 114 (const struct stardis_interface_fragment* frag, 115 const unsigned src_id, 116 void* data) 117 { 118 (void)frag, (void)src_id, (void)data; 119 return 1; 120 } 121 122 static double 123 intface_prog_get_temp 124 (const struct sdis_interface_fragment* frag, 125 struct sdis_data* data) 126 { 127 const struct intface* interface_props = sdis_data_cget(data); 128 struct stardis_interface_fragment f; 129 double temp; 130 d3_set(f.P, frag->P); 131 d3_set(f.Ng, frag->Ng); 132 d3_set(f.uv, frag->uv); 133 f.time = frag->time; 134 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 135 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 136 temp = interface_props->get_temp(&f, interface_props->prog_data); 137 return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE; 138 } 139 140 static double 141 intface_prog_get_flux 142 (const struct sdis_interface_fragment* frag, 143 struct sdis_data* data) 144 { 145 const struct intface* interface_props = sdis_data_cget(data); 146 struct stardis_interface_fragment f; 147 double flux; 148 d3_set(f.P, frag->P); 149 d3_set(f.Ng, frag->Ng); 150 d3_set(f.uv, frag->uv); 151 f.time = frag->time; 152 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 153 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 154 flux = interface_props->get_flux(&f, interface_props->prog_data); 155 return flux != STARDIS_FLUX_NONE ? flux : SDIS_FLUX_NONE; 156 } 157 158 static double 159 intface_prog_get_hc 160 (const struct sdis_interface_fragment* frag, 161 struct sdis_data* data) 162 { 163 const struct intface* interface_props = sdis_data_cget(data); 164 struct stardis_interface_fragment f; 165 d3_set(f.P, frag->P); 166 d3_set(f.Ng, frag->Ng); 167 d3_set(f.uv, frag->uv); 168 f.time = frag->time; 169 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 170 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 171 return interface_props->get_hc(&f, interface_props->prog_data); 172 } 173 174 static double 175 intface_prog_get_emissivity 176 (const struct sdis_interface_fragment* frag, 177 const unsigned src_id, 178 struct sdis_data* data) 179 { 180 const struct intface* interface_props = sdis_data_cget(data); 181 struct stardis_interface_fragment f; 182 unsigned id; 183 d3_set(f.P, frag->P); 184 d3_set(f.Ng, frag->Ng); 185 d3_set(f.uv, frag->uv); 186 f.time = frag->time; 187 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 188 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 189 id = src_id != SDIS_INTERN_SOURCE_ID ? src_id : STARDIS_INTERN_SOURCE_ID; 190 return interface_props->get_emissivity(&f, id, interface_props->prog_data); 191 } 192 193 static double 194 intface_prog_get_alpha 195 (const struct sdis_interface_fragment* frag, 196 const unsigned src_id, 197 struct sdis_data* data) 198 { 199 const struct intface* interface_props = sdis_data_cget(data); 200 struct stardis_interface_fragment f; 201 unsigned id; 202 d3_set(f.P, frag->P); 203 d3_set(f.Ng, frag->Ng); 204 d3_set(f.uv, frag->uv); 205 f.time = frag->time; 206 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 207 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 208 id = src_id != SDIS_INTERN_SOURCE_ID ? src_id : STARDIS_INTERN_SOURCE_ID; 209 return interface_props->get_alpha(&f, id, interface_props->prog_data); 210 } 211 212 static double 213 intface_prog_get_ref_temp 214 (const struct sdis_interface_fragment* frag, 215 struct sdis_data* data) 216 { 217 const struct intface* interface_props = sdis_data_cget(data); 218 struct stardis_interface_fragment f; 219 double temp; 220 d3_set(f.P, frag->P); 221 d3_set(f.Ng, frag->Ng); 222 d3_set(f.uv, frag->uv); 223 f.time = frag->time; 224 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 225 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 226 temp = interface_props->get_ref_temp(&f, interface_props->prog_data); 227 return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE; 228 } 229 230 static double 231 intface_prog_get_tcr 232 (const struct sdis_interface_fragment* frag, 233 struct sdis_data* data) 234 { 235 const struct intface* interface_props = sdis_data_cget(data); 236 struct stardis_interface_fragment f; 237 d3_set(f.P, frag->P); 238 d3_set(f.Ng, frag->Ng); 239 d3_set(f.uv, frag->uv); 240 f.time = frag->time; 241 ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); 242 f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; 243 return interface_props->get_tcr(&f, interface_props->prog_data); 244 } 245 246 /******************************************************************************* 247 * Public Functions 248 ******************************************************************************/ 249 250 res_T 251 create_intface 252 (struct stardis* stardis, 253 unsigned itri, 254 struct htable_intface* htable_interfaces) 255 { 256 struct int_descs int_descs = INT_DESCS_NULL; 257 struct sdis_interface** pp_intface; 258 struct sdis_interface* p_intface; 259 struct sdis_medium* front_med = NULL; 260 struct sdis_medium* back_med = NULL; 261 struct sdis_interface_side_shader* fluid_side_shader = NULL; 262 struct sdis_data* data = NULL; 263 unsigned fd, bd, id, descr[SG3D_PROP_TYPES_COUNT__]; 264 int fluid_count = 0, solid_count = 0; 265 int solid_fluid_connection_count = 0, solid_solid_connection_count = 0; 266 int intface_count = 0, boundary_count = 0, prog_count = 0; 267 const struct description* descriptions; 268 struct sdis_medium** media; 269 res_T res = RES_OK; 270 271 ASSERT(stardis && htable_interfaces); 272 273 /* Get the description IDs for this triangle */ 274 ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, 275 itri, descr)); 276 277 descriptions = darray_descriptions_cdata_get(&stardis->descriptions); 278 media = darray_media_ptr_data_get(&stardis->media); 279 280 /* Create key */ 281 int_descs.front = fd = descr[SG3D_FRONT]; 282 int_descs.back = bd = descr[SG3D_BACK]; 283 int_descs.intface = id = descr[SG3D_INTFACE]; 284 285 /* Search if interface already exists, or create it */ 286 pp_intface = htable_intface_find(htable_interfaces, &int_descs); 287 if(pp_intface) { 288 p_intface = *pp_intface; 289 } else { 290 /* create new interface and register */ 291 struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; 292 struct intface* interface_props = NULL; 293 unsigned mid; 294 int front_defined = (fd != SG3D_UNSPECIFIED_PROPERTY); 295 int back_defined = (bd != SG3D_UNSPECIFIED_PROPERTY); 296 int intface_defined = (id != SG3D_UNSPECIFIED_PROPERTY); 297 298 ERR(sdis_data_create(stardis->dev, sizeof(struct intface), 299 ALIGNOF(struct intface), NULL, &data)); 300 interface_props = sdis_data_get(data); 301 interface_props->imposed_temperature = SDIS_TEMPERATURE_NONE; 302 interface_props->imposed_flux = SDIS_FLUX_NONE; 303 interface_props->front_medium_id = UINT_MAX; 304 interface_props->back_medium_id = UINT_MAX; 305 interface_props->desc_id = UINT_MAX; 306 interface_props->get_temp = NULL; 307 interface_props->get_flux = NULL; 308 interface_props->get_hc = NULL; 309 interface_props->get_emissivity = NULL; 310 interface_props->get_alpha = NULL; 311 interface_props->get_ref_temp = NULL; 312 interface_props->get_tcr = NULL; 313 interface_props->prog_data = NULL; 314 315 if(fluid_count == 2) { 316 res = RES_BAD_ARG; 317 goto error; 318 } 319 if(front_defined) { 320 description_get_medium_id(&descriptions[fd], &mid); 321 interface_props->front_medium_id = mid; 322 front_med = media[mid]; 323 switch (descriptions[fd].type) { 324 case DESC_MAT_SOLID_PROG: 325 prog_count++; 326 /* fall through */ 327 case DESC_MAT_SOLID: 328 solid_count++; 329 break; 330 case DESC_MAT_FLUID_PROG: 331 prog_count++; 332 /* fall through */ 333 case DESC_MAT_FLUID: 334 fluid_count++; 335 fluid_side_shader = &interface_shader.front; 336 break; 337 default: 338 FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); 339 } 340 } 341 if(back_defined) { 342 description_get_medium_id(&descriptions[bd], &mid); 343 interface_props->back_medium_id = mid; 344 back_med = media[mid]; 345 switch (descriptions[bd].type) { 346 case DESC_MAT_SOLID_PROG: 347 prog_count++; 348 /* fall through */ 349 case DESC_MAT_SOLID: 350 solid_count++; 351 break; 352 case DESC_MAT_FLUID_PROG: 353 prog_count++; 354 /* fall through */ 355 case DESC_MAT_FLUID: 356 fluid_count++; 357 /* cannot overwrite as the 2-fluid case is an error */ 358 fluid_side_shader = &interface_shader.back; 359 break; 360 default: 361 FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); 362 } 363 } 364 if(intface_defined) { 365 const struct description* intface = descriptions + id; 366 int for_fluid = 0; 367 struct sdis_medium* def_medium = NULL; 368 unsigned ext_id; 369 if(!DESC_IS_CONNECTION(intface) && front_defined == back_defined) { 370 /* not connection implies 1 and only 1 side defined */ 371 res = RES_BAD_ARG; 372 goto error; 373 } 374 /* meaningless if connection (but unused in this case) */ 375 def_medium = front_defined ? front_med : back_med; 376 interface_props->desc_id = id; 377 switch(intface->type) { 378 case DESC_BOUND_H_FOR_FLUID: 379 if(sdis_medium_get_type(def_medium) != SDIS_FLUID) { 380 res = RES_BAD_ARG; 381 goto error; 382 } 383 for_fluid = 1; 384 ASSERT(SDIS_TEMPERATURE_IS_KNOWN(intface->d.h_boundary->imposed_temperature)); 385 interface_props->imposed_temperature 386 = intface->d.h_boundary->imposed_temperature; 387 ASSERT(fluid_side_shader); 388 fluid_side_shader->temperature = interface_get_temperature; 389 /* fall through */ 390 case DESC_BOUND_H_FOR_SOLID: 391 if(!for_fluid) { 392 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 393 res = RES_BAD_ARG; 394 goto error; 395 } 396 ASSERT(!fluid_side_shader); 397 fluid_side_shader = 398 front_defined ? &interface_shader.back : &interface_shader.front; 399 } 400 ext_id = intface->d.h_boundary->mat_id; /* External material id */ 401 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 402 ASSERT(sdis_medium_get_type(media[ext_id]) == 403 (for_fluid ? SDIS_SOLID : SDIS_FLUID)); 404 intface_count++; 405 boundary_count++; 406 if(front_defined) back_med = media[ext_id]; 407 else front_med = media[ext_id]; 408 interface_shader.convection_coef_upper_bound = intface->d.h_boundary->hc; 409 interface_props->hc = intface->d.h_boundary->hc; 410 interface_props->ref_temperature = intface->d.h_boundary->ref_temperature; 411 interface_props->emissivity = intface->d.h_boundary->emissivity; 412 interface_props->alpha = intface->d.h_boundary->specular_fraction; 413 if(intface->d.h_boundary->hc > 0) { 414 interface_shader.convection_coef = interface_get_convection_coef; 415 } 416 fluid_side_shader->reference_temperature = interface_get_ref_temperature; 417 if(intface->d.h_boundary->emissivity > 0) { 418 fluid_side_shader->emissivity = interface_get_emissivity; 419 fluid_side_shader->specular_fraction = interface_get_alpha; 420 } 421 break; 422 case DESC_BOUND_HF_FOR_SOLID: 423 if(!for_fluid) { 424 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 425 res = RES_BAD_ARG; 426 goto error; 427 } 428 ASSERT(!fluid_side_shader); 429 fluid_side_shader = 430 front_defined ? &interface_shader.back : &interface_shader.front; 431 } 432 ext_id = intface->d.hf_boundary->mat_id; /* External material id */ 433 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 434 ASSERT(sdis_medium_get_type(media[ext_id]) == 435 (for_fluid ? SDIS_SOLID : SDIS_FLUID)); 436 intface_count++; 437 boundary_count++; 438 if(front_defined) back_med = media[ext_id]; 439 else front_med = media[ext_id]; 440 interface_shader.convection_coef_upper_bound = intface->d.hf_boundary->hc; 441 interface_props->hc = intface->d.hf_boundary->hc; 442 interface_props->ref_temperature = intface->d.hf_boundary->ref_temperature; 443 interface_props->emissivity = intface->d.hf_boundary->emissivity; 444 interface_props->alpha = intface->d.hf_boundary->specular_fraction; 445 if(intface->d.hf_boundary->hc > 0) { 446 interface_shader.convection_coef = interface_get_convection_coef; 447 } 448 fluid_side_shader->reference_temperature = interface_get_ref_temperature; 449 ASSERT(intface->d.hf_boundary->imposed_flux != SDIS_FLUX_NONE); 450 if(intface->d.hf_boundary->imposed_flux) { 451 interface_props->imposed_flux = intface->d.hf_boundary->imposed_flux; 452 interface_shader.front.flux = interface_get_flux; 453 interface_shader.back.flux = interface_get_flux; 454 } 455 if(intface->d.hf_boundary->emissivity > 0) { 456 fluid_side_shader->emissivity = interface_get_emissivity; 457 fluid_side_shader->specular_fraction = interface_get_alpha; 458 } 459 break; 460 case DESC_BOUND_H_FOR_FLUID_PROG: 461 if(sdis_medium_get_type(def_medium) != SDIS_FLUID) { 462 res = RES_BAD_ARG; 463 goto error; 464 } 465 for_fluid = 1; 466 interface_props->get_temp = intface->d.h_boundary_prog->boundary_temp; 467 ASSERT(fluid_side_shader); 468 fluid_side_shader->temperature = intface_prog_get_temp; 469 /* fall through */ 470 case DESC_BOUND_H_FOR_SOLID_PROG: 471 if(!for_fluid) { 472 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 473 res = RES_BAD_ARG; 474 goto error; 475 } 476 ASSERT(!fluid_side_shader); 477 fluid_side_shader = 478 front_defined ? &interface_shader.back : &interface_shader.front; 479 } 480 ext_id = intface->d.h_boundary_prog->mat_id; /* External material id */ 481 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 482 ASSERT(sdis_medium_get_type(media[ext_id]) == 483 (for_fluid ? SDIS_SOLID : SDIS_FLUID)); 484 prog_count++; 485 intface_count++; 486 boundary_count++; 487 if(front_defined) back_med = media[ext_id]; 488 else front_med = media[ext_id]; 489 interface_shader.convection_coef_upper_bound 490 = h_bound_prog_get_hmax(intface->d.h_boundary_prog); 491 ASSERT(interface_shader.convection_coef_upper_bound >= 0); 492 interface_shader.convection_coef 493 = intface_prog_get_hc; 494 fluid_side_shader->reference_temperature 495 = intface_prog_get_ref_temp; 496 fluid_side_shader->emissivity = intface_prog_get_emissivity; 497 fluid_side_shader->specular_fraction = intface_prog_get_alpha; 498 interface_props->get_hc = intface->d.h_boundary_prog->hc; 499 interface_props->get_emissivity = intface->d.h_boundary_prog->emissivity; 500 interface_props->get_alpha = intface->d.h_boundary_prog->alpha; 501 interface_props->get_ref_temp = intface->d.h_boundary_prog->ref_temp; 502 interface_props->prog_data = intface->d.h_boundary_prog->prog_data; 503 break; 504 case DESC_BOUND_HF_FOR_SOLID_PROG: 505 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 506 res = RES_BAD_ARG; 507 goto error; 508 } 509 ASSERT(!fluid_side_shader); 510 fluid_side_shader = 511 front_defined ? &interface_shader.back : &interface_shader.front; 512 ext_id = intface->d.hf_boundary_prog->mat_id; /* External material id */ 513 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 514 ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID); 515 prog_count++; 516 intface_count++; 517 boundary_count++; 518 if(front_defined) back_med = media[ext_id]; 519 else front_med = media[ext_id]; 520 interface_shader.convection_coef_upper_bound 521 = hf_bound_prog_get_hmax(intface->d.hf_boundary_prog); 522 ASSERT(interface_shader.convection_coef_upper_bound >= 0); 523 interface_shader.convection_coef = intface_prog_get_hc; 524 fluid_side_shader->reference_temperature = intface_prog_get_ref_temp; 525 fluid_side_shader->emissivity = intface_prog_get_emissivity; 526 fluid_side_shader->specular_fraction = intface_prog_get_alpha; 527 interface_shader.front.flux = intface_prog_get_flux; 528 interface_shader.back.flux = intface_prog_get_flux; 529 interface_props->get_hc = intface->d.hf_boundary_prog->hc; 530 interface_props->get_emissivity = intface->d.hf_boundary_prog->emissivity; 531 interface_props->get_alpha = intface->d.hf_boundary_prog->alpha; 532 interface_props->get_flux = intface->d.hf_boundary_prog->flux; 533 interface_props->get_ref_temp = intface->d.hf_boundary_prog->ref_temp; 534 interface_props->prog_data = intface->d.hf_boundary_prog->prog_data; 535 break; 536 case DESC_BOUND_T_FOR_SOLID: 537 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 538 res = RES_BAD_ARG; 539 goto error; 540 } 541 fluid_side_shader = 542 front_defined ? &interface_shader.back : &interface_shader.front; 543 ext_id = intface->d.t_boundary->mat_id; /* External material id */ 544 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 545 ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID); 546 intface_count++; 547 boundary_count++; 548 if(front_defined) { 549 ASSERT(!back_med); 550 back_med = media[ext_id]; 551 } else { 552 ASSERT(!front_med); 553 front_med = media[ext_id]; 554 } 555 /* The imposed T is for the 2 sides (there is no contact resistance) */ 556 interface_shader.front.temperature = interface_get_temperature; 557 interface_shader.back.temperature = interface_get_temperature; 558 /* Set emissivity to 1 to allow radiative paths comming from 559 * a possible external fluid to 'see' the imposed T */ 560 fluid_side_shader->emissivity = interface_get_emissivity; 561 interface_props->emissivity = 1; 562 ASSERT(SDIS_TEMPERATURE_IS_KNOWN(intface->d.t_boundary->imposed_temperature)); 563 interface_props->imposed_temperature = intface->d.t_boundary->imposed_temperature; 564 /* Temporarily set the reference temperature to the set temperature. 565 * TODO use a different reference temperature when the file format is 566 * updated to allow explicit definition by the user. */ 567 fluid_side_shader->reference_temperature = interface_get_ref_temperature; 568 interface_props->ref_temperature = intface->d.t_boundary->imposed_temperature; 569 break; 570 case DESC_BOUND_T_FOR_SOLID_PROG: 571 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 572 res = RES_BAD_ARG; 573 goto error; 574 } 575 fluid_side_shader = 576 front_defined ? &interface_shader.back : &interface_shader.front; 577 ext_id = intface->d.t_boundary_prog->mat_id; /* External material id */ 578 ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); 579 ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID); 580 prog_count++; 581 intface_count++; 582 boundary_count++; 583 if(front_defined) { 584 ASSERT(!back_med); 585 back_med = media[ext_id]; 586 } else { 587 ASSERT(!front_med); 588 front_med = media[ext_id]; 589 } 590 /* The imposed T is for the 2 sides (there is no contact resistance) */ 591 interface_shader.front.temperature = intface_prog_get_temp; 592 interface_shader.back.temperature = intface_prog_get_temp; 593 /* Set emissivity to 1 to allow radiative paths comming from 594 * a possible external fluid to 'see' the imposed T */ 595 fluid_side_shader->emissivity = intface_prog_get_emissivity; 596 interface_props->get_emissivity = emissivity_1; 597 interface_props->get_temp = intface->d.t_boundary_prog->temperature; 598 interface_props->prog_data = intface->d.t_boundary_prog->prog_data; 599 /* Temporarily set the reference temperature to the set temperature. 600 * TODO use a different reference temperature when the file format is 601 * updated to allow explicit definition by the user. */ 602 fluid_side_shader->reference_temperature = intface_prog_get_temp; 603 break; 604 case DESC_BOUND_F_FOR_SOLID: 605 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 606 res = RES_BAD_ARG; 607 goto error; 608 } 609 intface_count++; 610 boundary_count++; 611 if(front_defined) { 612 back_med = media[intface->d.f_boundary->mat_id]; 613 } else { 614 front_med = media[intface->d.f_boundary->mat_id]; 615 } 616 interface_shader.front.flux = interface_get_flux; 617 interface_shader.back.flux = interface_get_flux; 618 ASSERT(intface->d.f_boundary->imposed_flux != SDIS_FLUX_NONE); 619 interface_props->imposed_flux = intface->d.f_boundary->imposed_flux; 620 break; 621 case DESC_BOUND_F_FOR_SOLID_PROG: 622 if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { 623 res = RES_BAD_ARG; 624 goto error; 625 } 626 prog_count++; 627 intface_count++; 628 boundary_count++; 629 if(front_defined) { 630 back_med = media[intface->d.f_boundary_prog->mat_id]; 631 } else { 632 front_med = media[intface->d.f_boundary_prog->mat_id]; 633 } 634 interface_shader.front.flux = intface_prog_get_flux; 635 interface_shader.back.flux = intface_prog_get_flux; 636 interface_props->get_flux = intface->d.f_boundary_prog->flux; 637 interface_props->prog_data = intface->d.f_boundary_prog->prog_data; 638 break; 639 case DESC_SOLID_FLUID_CONNECT: 640 /* Both front and back should be defined */ 641 if(solid_count != 1 || fluid_count != 1) { 642 res = RES_BAD_ARG; 643 goto error; 644 } 645 ASSERT(front_defined && back_defined); 646 intface_count++; 647 solid_fluid_connection_count++; 648 interface_shader.convection_coef_upper_bound = intface->d.sf_connect->hc; 649 interface_props->hc = intface->d.sf_connect->hc; 650 interface_props->ref_temperature = intface->d.sf_connect->ref_temperature; 651 interface_props->emissivity = intface->d.sf_connect->emissivity; 652 interface_props->alpha = intface->d.sf_connect->specular_fraction; 653 interface_props->imposed_flux = intface->d.sf_connect->flux; 654 if(intface->d.sf_connect->hc > 0) { 655 interface_shader.convection_coef = interface_get_convection_coef; 656 } 657 if(intface->d.sf_connect->flux != SDIS_FLUX_NONE) { 658 interface_shader.front.flux = interface_get_flux; 659 interface_shader.back.flux = interface_get_flux; 660 } 661 ASSERT(fluid_side_shader); 662 fluid_side_shader->reference_temperature = interface_get_ref_temperature; 663 fluid_side_shader->specular_fraction = interface_get_alpha; 664 if(intface->d.sf_connect->emissivity > 0) { 665 fluid_side_shader->emissivity = interface_get_emissivity; 666 } 667 break; 668 case DESC_SOLID_FLUID_CONNECT_PROG: 669 /* Both front and back should be defined */ 670 if(solid_count != 1 || fluid_count != 1) { 671 res = RES_BAD_ARG; 672 goto error; 673 } 674 ASSERT(front_defined && back_defined); 675 prog_count++; 676 intface_count++; 677 solid_fluid_connection_count++; 678 interface_shader.convection_coef_upper_bound 679 = sf_connect_prog_get_hmax(intface->d.sf_connect_prog); 680 ASSERT(interface_shader.convection_coef_upper_bound >= 0); 681 interface_props->get_ref_temp = intface->d.sf_connect_prog->ref_temp; 682 interface_props->get_hc = intface->d.sf_connect_prog->hc; 683 interface_props->get_emissivity 684 = intface->d.sf_connect_prog->emissivity; 685 interface_props->get_alpha = intface->d.sf_connect_prog->alpha; 686 interface_shader.convection_coef = intface_prog_get_hc; 687 if(intface->d.sf_connect_prog->flux) { 688 interface_props->get_flux = intface->d.sf_connect_prog->flux; 689 interface_shader.front.flux = intface_prog_get_flux; 690 interface_shader.back.flux = intface_prog_get_flux; 691 } 692 ASSERT(fluid_side_shader); 693 fluid_side_shader->emissivity = intface_prog_get_emissivity; 694 fluid_side_shader->specular_fraction = intface_prog_get_alpha; 695 fluid_side_shader->reference_temperature = intface_prog_get_ref_temp; 696 interface_props->prog_data = intface->d.sf_connect_prog->prog_data; 697 break; 698 case DESC_SOLID_SOLID_CONNECT: 699 /* Both front and back should be defined */ 700 if(solid_count != 2 || fluid_count != 0) { 701 res = RES_BAD_ARG; 702 goto error; 703 } 704 ASSERT(front_defined && back_defined); 705 intface_count++; 706 solid_solid_connection_count++; 707 interface_props->tcr = intface->d.ss_connect->tcr; 708 if(intface->d.ss_connect->tcr > 0) { 709 interface_shader.thermal_contact_resistance = interface_get_tcr; 710 } 711 break; 712 case DESC_SOLID_SOLID_CONNECT_PROG: 713 /* Both front and back should be defined */ 714 if(solid_count != 2 || fluid_count != 0) { 715 res = RES_BAD_ARG; 716 goto error; 717 } 718 ASSERT(front_defined && back_defined); 719 prog_count++; 720 intface_count++; 721 solid_solid_connection_count++; 722 interface_props->get_tcr = intface->d.ss_connect_prog->tcr; 723 interface_shader.thermal_contact_resistance = intface_prog_get_tcr; 724 interface_props->prog_data = intface->d.ss_connect_prog->prog_data; 725 break; 726 default: 727 FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); 728 } 729 } 730 731 if((fluid_count + solid_count + intface_count < 2) 732 || (boundary_count && (fluid_count + solid_count != 1))) 733 { 734 res = RES_BAD_ARG; 735 goto error; 736 } 737 738 ERR(sdis_interface_create(stardis->dev, front_med, back_med, 739 &interface_shader, data, &p_intface)); 740 SDIS(data_ref_put(data)); data = NULL; 741 ERR(darray_interface_ptrs_push_back(&stardis->geometry.interfaces, &p_intface)); 742 ERR(htable_intface_set(htable_interfaces, &int_descs, &p_intface)); 743 } 744 ERR(darray_interface_ptrs_push_back(&stardis->geometry.interf_bytrg, &p_intface)); 745 746 end: 747 if(data) SDIS(data_ref_put(data)); 748 return res; 749 error: 750 goto end; 751 } 752