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"