stardis-solver

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

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