sdis_interface_c.h (9554B)
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 #ifndef SDIS_INTERFACE_C_H 17 #define SDIS_INTERFACE_C_H 18 19 #include "sdis.h" 20 #include "sdis_log.h" 21 22 #include <rsys/free_list.h> 23 #include <rsys/ref_count.h> 24 #include <float.h> 25 26 /* Forward declaration of external type */ 27 struct s2d_hit; 28 struct s3d_hit; 29 30 struct sdis_interface { 31 struct sdis_medium* medium_front; 32 struct sdis_medium* medium_back; 33 struct sdis_interface_shader shader; 34 struct sdis_data* data; 35 struct fid id; /* Unique identifier of the interface */ 36 37 ref_T ref; 38 struct sdis_device* dev; 39 }; 40 41 extern LOCAL_SYM struct sdis_medium* 42 interface_get_medium 43 (const struct sdis_interface* interf, 44 const enum sdis_side side); 45 46 static FINLINE unsigned 47 interface_get_id(const struct sdis_interface* interf) 48 { 49 ASSERT(interf); 50 return interf->id.index; 51 } 52 53 extern LOCAL_SYM void 54 setup_interface_fragment_2d 55 (struct sdis_interface_fragment* frag, 56 const struct sdis_rwalk_vertex* vertex, 57 const struct s2d_hit* hit, 58 const enum sdis_side side); 59 60 extern LOCAL_SYM void 61 setup_interface_fragment_3d 62 (struct sdis_interface_fragment* frag, 63 const struct sdis_rwalk_vertex* vertex, 64 const struct s3d_hit* hit, 65 const enum sdis_side side); 66 67 extern LOCAL_SYM res_T 68 build_interface_fragment_2d 69 (struct sdis_interface_fragment* frag, 70 const struct sdis_scene* scn, 71 const unsigned iprim, 72 const double uv[1], 73 const enum sdis_side side); 74 75 extern LOCAL_SYM res_T 76 build_interface_fragment_3d 77 (struct sdis_interface_fragment* frag, 78 const struct sdis_scene* scn, 79 const unsigned iprim, 80 const double uv[2], 81 const enum sdis_side side); 82 83 static INLINE double 84 interface_get_convection_coef 85 (const struct sdis_interface* interf, 86 const struct sdis_interface_fragment* frag) 87 { 88 ASSERT(interf && frag); 89 return interf->shader.convection_coef 90 ? interf->shader.convection_coef(frag, interf->data) : 0; 91 } 92 93 static INLINE double 94 interface_get_thermal_contact_resistance 95 (const struct sdis_interface* interf, 96 const struct sdis_interface_fragment* frag) 97 { 98 ASSERT(interf && frag); 99 return interf->shader.thermal_contact_resistance 100 ? interf->shader.thermal_contact_resistance(frag, interf->data) : 0; 101 } 102 103 static INLINE double 104 interface_get_convection_coef_upper_bound 105 (const struct sdis_interface* interf) 106 { 107 ASSERT(interf); 108 return interf->shader.convection_coef_upper_bound; 109 } 110 111 static INLINE double 112 interface_side_get_temperature 113 (const struct sdis_interface* interf, 114 const struct sdis_interface_fragment* frag) 115 { 116 const struct sdis_interface_side_shader* shader; 117 ASSERT(interf && frag); 118 switch(frag->side) { 119 case SDIS_FRONT: shader = &interf->shader.front; break; 120 case SDIS_BACK: shader = &interf->shader.back; break; 121 default: FATAL("Unreachable code.\n"); 122 } 123 return shader->temperature 124 ? shader->temperature(frag, interf->data) 125 : SDIS_TEMPERATURE_NONE; 126 } 127 128 static INLINE double 129 interface_side_get_flux 130 (const struct sdis_interface* interf, 131 const struct sdis_interface_fragment* frag) 132 { 133 const struct sdis_interface_side_shader* shader; 134 ASSERT(interf && frag); 135 switch(frag->side) { 136 case SDIS_FRONT: shader = &interf->shader.front; break; 137 case SDIS_BACK: shader = &interf->shader.back; break; 138 default: FATAL("Unreachable code.\n"); 139 } 140 return shader->flux ? shader->flux(frag, interf->data) : SDIS_FLUX_NONE; 141 } 142 143 static INLINE double 144 interface_side_get_emissivity 145 (const struct sdis_interface* interf, 146 const unsigned source_id, 147 const struct sdis_interface_fragment* frag) 148 { 149 const struct sdis_interface_side_shader* shader; 150 ASSERT(interf && frag); 151 switch(frag->side) { 152 case SDIS_FRONT: shader = &interf->shader.front; break; 153 case SDIS_BACK: shader = &interf->shader.back; break; 154 default: FATAL("Unreachable code\n"); break; 155 } 156 return shader->emissivity 157 ? shader->emissivity(frag, source_id, interf->data) 158 : 0; 159 } 160 161 static INLINE double 162 interface_side_get_specular_fraction 163 (const struct sdis_interface* interf, 164 const unsigned source_id, 165 const struct sdis_interface_fragment* frag) 166 { 167 const struct sdis_interface_side_shader* shader; 168 ASSERT(interf && frag); 169 switch(frag->side) { 170 case SDIS_FRONT: shader = &interf->shader.front; break; 171 case SDIS_BACK: shader = &interf->shader.back; break; 172 default: FATAL("Unreachable code\n"); break; 173 } 174 return shader->specular_fraction 175 ? shader->specular_fraction(frag, source_id, interf->data) 176 : 0; 177 } 178 179 static INLINE double 180 interface_side_get_reference_temperature 181 (const struct sdis_interface* interf, 182 const struct sdis_interface_fragment* frag) 183 { 184 const struct sdis_interface_side_shader* shader; 185 ASSERT(interf && frag); 186 switch(frag->side) { 187 case SDIS_FRONT: shader = &interf->shader.front; break; 188 case SDIS_BACK: shader = &interf->shader.back; break; 189 default: FATAL("Unreachable code\n"); break; 190 } 191 return shader->reference_temperature 192 ? shader->reference_temperature(frag, interf->data) 193 : SDIS_TEMPERATURE_NONE; 194 } 195 196 static INLINE int 197 interface_side_is_external_flux_handled 198 (const struct sdis_interface* interf, 199 const struct sdis_interface_fragment* frag) 200 { 201 const struct sdis_interface_side_shader* shader; 202 ASSERT(interf && frag); 203 switch(frag->side) { 204 case SDIS_FRONT: shader = &interf->shader.front; break; 205 case SDIS_BACK: shader = &interf->shader.back; break; 206 default: FATAL("Unreachable code\n"); break; 207 } 208 return shader->handle_external_flux; 209 } 210 211 /******************************************************************************* 212 * Check interface properties 213 ******************************************************************************/ 214 #define DEFINE_INTERF_CHK_PROP_FUNC(Interf, Prop, Low, Upp, LowIsInc, UppIsInc)\ 215 static INLINE res_T \ 216 Interf##_check_##Prop \ 217 (struct sdis_device* dev, \ 218 const double val, /* Value of the property */ \ 219 const double pos[3], /* Position at which the property was queried */ \ 220 const double time) /* Time at which the property was queried */ \ 221 { \ 222 const int low_test = LowIsInc ? Low <= val : Low < val; \ 223 const int upp_test = UppIsInc ? Upp >= val : Upp > val; \ 224 const char low_char = LowIsInc ? '[' : ']'; \ 225 const char upp_char = UppIsInc ? ']' : '['; \ 226 ASSERT(dev && pos); \ 227 \ 228 if(!low_test || !upp_test) { \ 229 log_err(dev, \ 230 "invalid "STR(Interf)" "PROP_STR(Prop)" '%g': " \ 231 "it must be in %c%g, %g%c -- position=%g, %g, %g; time=%g\n", \ 232 val, low_char, (double)Low, (double)Upp, upp_char, SPLIT3(pos), time); \ 233 return RES_BAD_ARG; \ 234 } \ 235 return RES_OK; \ 236 } 237 238 #define PROP_STR(Prop) CONCAT(PROP_STR_, Prop) 239 #define PROP_STR_convection_coef "convection coefficient" 240 #define PROP_STR_thermal_contact_resistance "thermal contact resistance" 241 #define PROP_STR_convection_coef_upper_bound "convection coefficient upper bound" 242 #define PROP_STR_temperature "temperature" 243 #define PROP_STR_flux "net flux" 244 #define PROP_STR_emissivity "emissivity" 245 #define PROP_STR_specular_fraction "specular fraction" 246 #define PROP_STR_reference_temperature "reference temperature" 247 248 DEFINE_INTERF_CHK_PROP_FUNC(interface, convection_coef, 0, INF, 1, 1) 249 DEFINE_INTERF_CHK_PROP_FUNC(interface, thermal_contact_resistance, 0, INF, 1, 1) 250 DEFINE_INTERF_CHK_PROP_FUNC(interface, convection_coef_upper_bound, 0, INF, 1, 1) 251 DEFINE_INTERF_CHK_PROP_FUNC(interface_side, temperature, 0, INF, 1, 1) 252 DEFINE_INTERF_CHK_PROP_FUNC(interface_side, flux, -INF, INF, 1, 1) 253 DEFINE_INTERF_CHK_PROP_FUNC(interface_side, emissivity, 0, 1, 1, 1) 254 DEFINE_INTERF_CHK_PROP_FUNC(interface_side, specular_fraction, 0, 1, 1, 1) 255 DEFINE_INTERF_CHK_PROP_FUNC(interface_side, reference_temperature, 0, INF, 1, 1) 256 257 #undef DEFINE_INTERF_CHK_PROP_FUNC 258 #undef PROP_STR 259 #undef PROP_STR_convection_coef 260 #undef PROP_STR_thermal_contact_resistance 261 #undef PROP_STR_convection_coef_upper_bound 262 #undef PROP_STR_temperature 263 #undef PROP_STR_flux 264 #undef PROP_STR_emissivity 265 #undef PROP_STR_specular_fraction 266 #undef PROP_STR_reference_temperature 267 268 #endif /* SDIS_INTERFACE_C_H */