sdis_medium_c.h (10643B)
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_MEDIUM_C_H 17 #define SDIS_MEDIUM_C_H 18 19 #include "sdis.h" 20 #include "sdis_log.h" 21 22 #include <rsys/free_list.h> 23 #include <rsys/math.h> 24 #include <rsys/ref_count.h> 25 26 struct sdis_medium { 27 enum sdis_medium_type type; 28 union { 29 struct sdis_solid_shader solid; 30 struct sdis_fluid_shader fluid; 31 } shader; 32 33 struct sdis_data* data; 34 struct fid id; /* Unique identifier of the medium */ 35 36 ref_T ref; 37 struct sdis_device* dev; 38 }; 39 40 struct fluid_props { 41 double rho; /* Volumic mass */ 42 double cp; /* Calorific capacity */ 43 double temperature; 44 double t0; /* Initial time */ 45 }; 46 #define FLUID_PROPS_NULL__ {0,0,0,0} 47 static const struct fluid_props FLUID_PROPS_NULL = FLUID_PROPS_NULL__; 48 49 struct solid_props { 50 double lambda; /* Conductivity */ 51 double rho; /* Volumic mass */ 52 double cp; /* Calorific capacity */ 53 double delta; /* Random walk step */ 54 double power; /* Volumic power */ 55 double temperature; 56 double t0; /* Initial time */ 57 }; 58 #define SOLID_PROPS_NULL__ {0,0,0,0,0,0,0} 59 static const struct solid_props SOLID_PROPS_NULL = SOLID_PROPS_NULL__; 60 61 #define MDM_TYPE(Mdm) CONCAT(MDM_TYPE_, Mdm) 62 #define MDM_TYPE_solid SDIS_SOLID 63 #define MDM_TYPE_fluid SDIS_FLUID 64 65 #define PROP_STR(Prop) CONCAT(PROP_STR_, Prop) 66 #define PROP_STR_calorific_capacity "calorific capacity" 67 #define PROP_STR_conductivity "conductivity" 68 #define PROP_STR_delta "delta" 69 #define PROP_STR_temperature "temperature" 70 #define PROP_STR_thermal_conductivity "thermal conductivity" 71 #define PROP_STR_volumic_mass "volumic mass" 72 #define PROP_STR_volumic_power "volumic power" 73 74 #define DEFINE_MDM_GET_PROP_FUNC(Mdm, Prop) \ 75 static INLINE double \ 76 Mdm##_get_##Prop \ 77 (const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx) \ 78 { \ 79 ASSERT(mdm && mdm->type == MDM_TYPE(Mdm)); \ 80 return mdm->shader.Mdm.Prop(vtx, mdm->data); \ 81 } 82 83 #define DEFINE_MDM_CHK_PROP_FUNC(Mdm, Prop, Low, Upp, LowIsInc, UppIsInc) \ 84 static INLINE res_T \ 85 Mdm##_check_##Prop \ 86 (struct sdis_device* dev, \ 87 const double val, /* Value of the property */ \ 88 const double pos[], /* Position at which the property was queried */ \ 89 const double time) /* Time at which the property was queried */ \ 90 { \ 91 const int low_test = LowIsInc ? Low <= val : Low < val; \ 92 const int upp_test = UppIsInc ? Upp >= val : Upp > val; \ 93 const char low_char = LowIsInc ? '[' : ']'; \ 94 const char upp_char = UppIsInc ? ']' : '['; \ 95 ASSERT(dev && pos); \ 96 \ 97 if(!low_test || !upp_test) { \ 98 log_err(dev, \ 99 "invalid "STR(Mdm)" "PROP_STR(Prop)" '%g': it must be in %c%g, %g%c " \ 100 "-- position=%g, %g, %g; time=%g\n", \ 101 val, low_char, (double)Low, (double)Upp, upp_char, SPLIT3(pos), time); \ 102 return RES_BAD_ARG; \ 103 } \ 104 return RES_OK; \ 105 } 106 107 /******************************************************************************* 108 * Fluid local functions 109 ******************************************************************************/ 110 DEFINE_MDM_CHK_PROP_FUNC(fluid, calorific_capacity, 0, INF, 0, 1) 111 DEFINE_MDM_CHK_PROP_FUNC(fluid, volumic_mass, 0, INF, 0, 1) 112 DEFINE_MDM_CHK_PROP_FUNC(fluid, temperature, -INF, INF, 1, 1) 113 114 DEFINE_MDM_GET_PROP_FUNC(fluid, calorific_capacity) 115 DEFINE_MDM_GET_PROP_FUNC(fluid, volumic_mass) 116 DEFINE_MDM_GET_PROP_FUNC(fluid, temperature) 117 118 static INLINE double 119 fluid_get_t0(const struct sdis_medium* mdm) 120 { 121 ASSERT(mdm && mdm->type == SDIS_FLUID); 122 ASSERT(0 <= mdm->shader.fluid.t0 && mdm->shader.fluid.t0 < INF); 123 return mdm->shader.fluid.t0; 124 } 125 126 static INLINE res_T 127 fluid_check_properties 128 (struct sdis_device* dev, 129 const struct fluid_props* props, 130 const double pos[], 131 const double time) 132 { 133 res_T res = RES_OK; 134 ASSERT(dev && props); 135 136 #define CHK_PROP(Prop, Val) { \ 137 res = fluid_check_##Prop(dev, Val, pos, time); \ 138 if(res != RES_OK) return res; \ 139 } (void)0 140 CHK_PROP(volumic_mass, props->rho); 141 CHK_PROP(calorific_capacity, props->cp); 142 #undef CHK_PROP 143 144 return RES_OK; 145 } 146 147 static INLINE res_T 148 fluid_get_properties 149 (const struct sdis_medium* mdm, 150 const struct sdis_rwalk_vertex* vtx, 151 struct fluid_props* props) 152 { 153 ASSERT(mdm && mdm->type == SDIS_FLUID); 154 props->rho = fluid_get_volumic_mass(mdm, vtx); 155 props->cp = fluid_get_calorific_capacity(mdm, vtx); 156 props->temperature = fluid_get_temperature(mdm, vtx); 157 return fluid_check_properties(mdm->dev, props, vtx->P, vtx->time); 158 } 159 160 /******************************************************************************* 161 * Solid local functions 162 ******************************************************************************/ 163 DEFINE_MDM_CHK_PROP_FUNC(solid, calorific_capacity, 0, INF, 0, 1) 164 DEFINE_MDM_CHK_PROP_FUNC(solid, thermal_conductivity, 0, INF, 0, 1) 165 DEFINE_MDM_CHK_PROP_FUNC(solid, volumic_mass, 0, INF, 0, 1) 166 DEFINE_MDM_CHK_PROP_FUNC(solid, delta, 0, INF, 0, 1) 167 DEFINE_MDM_CHK_PROP_FUNC(solid, volumic_power, -INF, INF, 1, 1) 168 DEFINE_MDM_CHK_PROP_FUNC(solid, temperature, -INF, INF, 1, 1) 169 170 DEFINE_MDM_GET_PROP_FUNC(solid, calorific_capacity) 171 DEFINE_MDM_GET_PROP_FUNC(solid, thermal_conductivity) 172 DEFINE_MDM_GET_PROP_FUNC(solid, volumic_mass) 173 DEFINE_MDM_GET_PROP_FUNC(solid, delta) 174 DEFINE_MDM_GET_PROP_FUNC(solid, temperature) 175 176 static INLINE double 177 solid_get_volumic_power 178 (const struct sdis_medium* mdm, 179 const struct sdis_rwalk_vertex* vtx) 180 { 181 ASSERT(mdm && mdm->type == SDIS_SOLID); 182 return mdm->shader.solid.volumic_power 183 ? mdm->shader.solid.volumic_power(vtx, mdm->data) 184 : SDIS_VOLUMIC_POWER_NONE; 185 } 186 187 static INLINE double 188 solid_get_t0(const struct sdis_medium* mdm) 189 { 190 ASSERT(mdm && mdm->type == SDIS_SOLID); 191 return mdm->shader.solid.t0; 192 } 193 194 static INLINE res_T 195 solid_check_properties 196 (struct sdis_device* dev, 197 const struct solid_props* props, 198 const double pos[], 199 const double time) 200 { 201 res_T res = RES_OK; 202 ASSERT(dev && props); 203 204 #define CHK_PROP(Prop, Val) { \ 205 res = solid_check_##Prop(dev, Val, pos, time); \ 206 if(res != RES_OK) return res; \ 207 } (void)0 208 CHK_PROP(calorific_capacity, props->cp); 209 CHK_PROP(thermal_conductivity, props->lambda); 210 CHK_PROP(volumic_mass, props->rho); 211 CHK_PROP(delta, props->delta); 212 CHK_PROP(volumic_power, props->power); 213 #undef CHK_PROP 214 215 /* Do not check the temperature. An invalid temperature means that the 216 * temperature is unknown */ 217 218 return RES_OK; 219 } 220 221 static INLINE res_T 222 solid_get_properties 223 (const struct sdis_medium* mdm, 224 const struct sdis_rwalk_vertex* vtx, 225 struct solid_props* props) 226 { 227 ASSERT(mdm && mdm->type == SDIS_SOLID); 228 props->lambda = solid_get_thermal_conductivity(mdm, vtx); 229 props->rho = solid_get_volumic_mass(mdm, vtx); 230 props->cp = solid_get_calorific_capacity(mdm, vtx); 231 props->delta = solid_get_delta(mdm, vtx); 232 props->power = solid_get_volumic_power(mdm, vtx); 233 props->temperature = solid_get_temperature(mdm, vtx); 234 props->t0 = solid_get_t0(mdm); 235 return solid_check_properties(mdm->dev, props, vtx->P, vtx->time); 236 } 237 238 /******************************************************************************* 239 * Generic functions 240 ******************************************************************************/ 241 static INLINE double 242 medium_get_temperature 243 (const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx) 244 { 245 double temp; 246 ASSERT(mdm); 247 switch(mdm->type) { 248 case SDIS_FLUID: temp = fluid_get_temperature(mdm, vtx); break; 249 case SDIS_SOLID: temp = solid_get_temperature(mdm, vtx); break; 250 default: FATAL("Unreachable code.\n"); break; 251 } 252 return temp; 253 } 254 255 static INLINE double 256 medium_get_t0(const struct sdis_medium* mdm) 257 { 258 double t0; 259 ASSERT(mdm); 260 switch(mdm->type) { 261 case SDIS_FLUID: t0 = fluid_get_t0(mdm); break; 262 case SDIS_SOLID: t0 = solid_get_t0(mdm); break; 263 default: FATAL("Unreachable code.\n"); break; 264 } 265 return t0; 266 } 267 268 static INLINE unsigned 269 medium_get_id(const struct sdis_medium* mdm) 270 { 271 ASSERT(mdm); 272 return mdm->id.index; 273 } 274 275 static INLINE const char* 276 medium_type_to_string(const enum sdis_medium_type type) 277 { 278 const char* str = "none"; 279 switch(type) { 280 case SDIS_FLUID: str = "fluid"; break; 281 case SDIS_SOLID: str = "solid"; break; 282 default: FATAL("Unreachable code.\n"); break; 283 } 284 return str; 285 } 286 287 #undef MDM_TYPE 288 #undef MDM_TYPE_solid 289 #undef MDM_TYPE_fluid 290 #undef PROP_STR 291 #undef PROP_STR_calorific_capacity 292 #undef PROP_STR_conductivity 293 #undef PROP_STR_delta 294 #undef PROP_STR_temperature 295 #undef PROP_STR_thermal_conductivity 296 #undef PROP_STR_volumic_mass 297 #undef PROP_STR_volumic_power 298 #undef DEFINE_MDM_CHK_PROP_FUNC 299 #undef DEFINE_MDM_GET_PROP_FUNC 300 301 #endif /* SDIS_MEDIUM_C_H */ 302