stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

sdis_heat_path_boundary_Xd_solid_solid.h (6944B)


      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_green.h"
     17 #include "sdis_heat_path_boundary_c.h"
     18 #include "sdis_interface_c.h"
     19 #include "sdis_log.h"
     20 #include "sdis_medium_c.h"
     21 #include "sdis_misc.h"
     22 #include "sdis_scene_c.h"
     23 
     24 #include <star/ssp.h>
     25 
     26 #include "sdis_Xd_begin.h"
     27 
     28 /*******************************************************************************
     29  * Boundary path between a solid and a fluid
     30  ******************************************************************************/
     31 res_T
     32 XD(solid_solid_boundary_path)
     33   (struct sdis_scene* scn,
     34    struct rwalk_context* ctx,
     35    const struct sdis_interface_fragment* frag,
     36    struct rwalk* rwalk,
     37    struct ssp_rng* rng,
     38    struct temperature* T)
     39 {
     40   /* Input/output arguments of the function used to sample a reinjection */
     41   struct sample_reinjection_step_args samp_reinject_step_frt_args =
     42     SAMPLE_REINJECTION_STEP_ARGS_NULL;
     43   struct sample_reinjection_step_args samp_reinject_step_bck_args =
     44     SAMPLE_REINJECTION_STEP_ARGS_NULL;
     45   struct reinjection_step reinject_step_frt = REINJECTION_STEP_NULL;
     46   struct reinjection_step reinject_step_bck = REINJECTION_STEP_NULL;
     47   struct reinjection_step* reinject_step = NULL;
     48 
     49   /* Reinjection arguments */
     50   struct solid_reinjection_args solid_reinject_args =
     51     SOLID_REINJECTION_ARGS_NULL;
     52 
     53   /* Data attached to the boundary */
     54   unsigned enc_ids[2] = {ENCLOSURE_ID_NULL, ENCLOSURE_ID_NULL};
     55   struct sdis_interface* interf = NULL;
     56   struct sdis_medium* solid_frt = NULL;
     57   struct sdis_medium* solid_bck = NULL;
     58   unsigned solid_enc_id = ENCLOSURE_ID_NULL; /* Solid to re-inject */
     59 
     60   double lambda_frt;
     61   double lambda_bck;
     62   double delta_boundary_frt;
     63   double delta_boundary_bck;
     64 
     65   double proba;
     66   double r;
     67   double tcr;
     68 
     69   res_T res = RES_OK;
     70   ASSERT(scn && ctx && frag && rwalk && rng && T);
     71   ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag) == RES_OK);
     72   (void)frag, (void)ctx;
     73 
     74   /* Retrieve the two enclosures and associated media split by the boundary */
     75   scene_get_enclosure_ids(scn, rwalk->XD(hit).prim.prim_id, enc_ids);
     76   interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id);
     77   solid_frt = interface_get_medium(interf, SDIS_FRONT);
     78   solid_bck = interface_get_medium(interf, SDIS_BACK);
     79   ASSERT(solid_frt->type == SDIS_SOLID);
     80   ASSERT(solid_bck->type == SDIS_SOLID);
     81 
     82   /* Retrieve the thermal contact resistance */
     83   tcr = interface_get_thermal_contact_resistance(interf, frag);
     84 
     85   /* Fetch the properties of the media */
     86   lambda_frt = solid_get_thermal_conductivity(solid_frt, &rwalk->vtx);
     87   lambda_bck = solid_get_thermal_conductivity(solid_bck, &rwalk->vtx);
     88 
     89   /* Note that the reinjection distance is *FIXED*. It MUST ensure that the
     90    * orthogonal distance from the boundary to the reinjection point is at most
     91    * equal to delta. */
     92   delta_boundary_frt = solid_get_delta(solid_frt, &rwalk->vtx) * sqrt(DIM);
     93   delta_boundary_bck = solid_get_delta(solid_bck, &rwalk->vtx) * sqrt(DIM);
     94 
     95   /* Sample a front/back reinjection steps */
     96   samp_reinject_step_frt_args.rng = rng;
     97   samp_reinject_step_bck_args.rng = rng;
     98   samp_reinject_step_frt_args.solid_enc_id = enc_ids[SDIS_FRONT];
     99   samp_reinject_step_bck_args.solid_enc_id = enc_ids[SDIS_BACK];
    100   samp_reinject_step_frt_args.rwalk = rwalk;
    101   samp_reinject_step_bck_args.rwalk = rwalk;
    102   samp_reinject_step_frt_args.distance = delta_boundary_frt;
    103   samp_reinject_step_bck_args.distance = delta_boundary_bck;
    104   samp_reinject_step_frt_args.side = SDIS_FRONT;
    105   samp_reinject_step_bck_args.side = SDIS_BACK;
    106   res = XD(sample_reinjection_step_solid_solid)
    107     (scn,
    108      &samp_reinject_step_frt_args,
    109      &samp_reinject_step_bck_args,
    110      &reinject_step_frt,
    111      &reinject_step_bck);
    112   if(res != RES_OK) goto error;
    113 
    114   r = ssp_rng_canonical(rng);
    115   if(tcr == 0) { /* No thermal contact resistance */
    116     /* Define the reinjection side. Note that the proba should be : Lf/Df' /
    117      * (Lf/Df' + Lb/Db')
    118      *
    119      * with L<f|b> the lambda of the <front|back> side and D<f|b>' the adjusted
    120      * delta of the <front|back> side, i.e. : D<f|b>' =
    121      * reinject_dst_<front|back> / sqrt(DIM)
    122      *
    123      * Anyway, one can avoid to compute the adjusted delta by directly using the
    124      * adjusted reinjection distance since the resulting proba is strictly the
    125      * same; sqrt(DIM) can be simplified. */
    126     const double tmp_frt = lambda_frt / reinject_step_frt.distance;
    127     const double tmp_bck = lambda_bck / reinject_step_bck.distance;
    128     proba = tmp_frt / (tmp_frt + tmp_bck);
    129   } else {
    130     const double delta_frt = reinject_step_frt.distance/sqrt(DIM);
    131     const double delta_bck = reinject_step_bck.distance/sqrt(DIM);
    132     const double tmp_frt = lambda_frt/delta_frt;
    133     const double tmp_bck = lambda_bck/delta_bck;
    134     const double tmp_tcr = tcr*tmp_frt*tmp_bck;
    135     switch(rwalk->hit_side) {
    136       case SDIS_BACK:
    137         /* When coming from the BACK side, the probability to be reinjected on
    138          * the FRONT side depends on the thermal contact resistance: it
    139          * decreases when the TCR increases (and tends to 0 when TCR -> +inf) */
    140         proba = tmp_frt / (tmp_frt + tmp_bck + tmp_tcr);
    141         break;
    142       case SDIS_FRONT:
    143         /* Same thing when coming from the FRONT side: the probability of
    144          * reinjection on the FRONT side depends on the thermal contact
    145          * resistance: it increases when the TCR increases (and tends to 1 when
    146          * the TCR -> +inf) */
    147         proba = (tmp_frt + tmp_tcr) / (tmp_frt + tmp_bck + tmp_tcr);
    148         break;
    149       default: FATAL("Unreachable code.\n"); break;
    150     }
    151   }
    152 
    153   if(r < proba) { /* Reinject in front */
    154     reinject_step = &reinject_step_frt;
    155     solid_enc_id = enc_ids[SDIS_FRONT];
    156   } else { /* Reinject in back */
    157     reinject_step = &reinject_step_bck;
    158     solid_enc_id = enc_ids[SDIS_BACK];
    159   }
    160 
    161   /* Perform the reinjection into the solid */
    162   solid_reinject_args.reinjection = reinject_step;
    163   solid_reinject_args.rng = rng;
    164   solid_reinject_args.rwalk = rwalk;
    165   solid_reinject_args.rwalk_ctx = ctx;
    166   solid_reinject_args.T = T;
    167   solid_reinject_args.fp_to_meter = scn->fp_to_meter;
    168   res = XD(solid_reinjection)(scn, solid_enc_id, &solid_reinject_args);
    169   if(res != RES_OK) goto error;
    170 
    171 exit:
    172   return res;
    173 error:
    174   goto exit;
    175 }
    176 
    177 #include "sdis_Xd_end.h"