stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

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