stardis-solver

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

test_sdis_enclosure_limit_conditions.c (9129B)


      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 "test_sdis_utils.h"
     17 
     18 /* This test verifies multi-material enclosures, i.e. enclosures whose
     19  * interfaces refer to several media, whereas an enclosure should only cover
     20  * one. This configuration remains valid, however, if these enclosures are used
     21  * to define boundary conditions, such as convective exchange with several
     22  * fluids at known temperature. Although they are valid, it is forbidden to
     23  * place a probe in these enclosures.
     24  *
     25  *        +----------------------+
     26  *        |                      |
     27  *        |  +----------------+  |
     28  *        |  |       T2       |  |
     29  *        |  |                |  | T4
     30  *        |  |       __\      |  |   __\
     31  *        |  | T1   /  /   T3 |  |  /  / Text
     32  *        |  |      \__/      |  |  \__/
     33  *        |  |                |  |
     34  *        |  |       T0       |  |
     35  *        |  +----------------+  |
     36  * Y      |                      |
     37  * |      +----------------------+
     38  * o--X */
     39 
     40 #define CONVECTION_COEF 10
     41 #define DELTA 0.00625
     42 #define NREALISATIONS 10000
     43 #define Text 360.0
     44 
     45 /*******************************************************************************
     46  * Media
     47  ******************************************************************************/
     48 #define DEFINE_MEDIUM_GETTER(Func, Val)                                        \
     49   static double                                                                \
     50   Func(const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)            \
     51   {                                                                            \
     52     (void)vtx, (void)data;                                                     \
     53     return (Val);                                                              \
     54   }
     55 DEFINE_MEDIUM_GETTER(solid_get_calorific_capacity, 1)
     56 DEFINE_MEDIUM_GETTER(solid_get_thermal_conductivity, 1)
     57 DEFINE_MEDIUM_GETTER(solid_get_volumic_mass, 1)
     58 DEFINE_MEDIUM_GETTER(solid_get_delta, DELTA)
     59 DEFINE_MEDIUM_GETTER(solid_get_temperature, SDIS_TEMPERATURE_NONE)
     60 DEFINE_MEDIUM_GETTER(fluid_get_temperature, *((double*)sdis_data_cget(data)))
     61 #undef DEFINE_MEDIUM_GETTER
     62 
     63 static struct sdis_medium*
     64 create_solid(struct sdis_device* dev)
     65 {
     66   struct sdis_solid_shader shader = SDIS_SOLID_SHADER_NULL;
     67   struct sdis_medium* solid = NULL;
     68 
     69   shader.calorific_capacity = solid_get_calorific_capacity;
     70   shader.thermal_conductivity = solid_get_thermal_conductivity;
     71   shader.volumic_mass = solid_get_volumic_mass;
     72   shader.delta = solid_get_delta;
     73   shader.temperature = solid_get_temperature;
     74   OK(sdis_solid_create(dev, &shader, NULL, &solid));
     75   return solid;
     76 }
     77 
     78 static struct sdis_medium*
     79 create_fluid(struct sdis_device* dev, const double temperature)
     80 {
     81   struct sdis_fluid_shader shader = DUMMY_FLUID_SHADER;
     82   struct sdis_medium* fluid = NULL;
     83   struct sdis_data* data = NULL;
     84 
     85   OK(sdis_data_create
     86     (dev, sizeof(double), ALIGNOF(double), NULL, &data));
     87   shader.temperature = fluid_get_temperature;
     88   *((double*)sdis_data_get(data)) = temperature;
     89   OK(sdis_fluid_create(dev, &shader, data, &fluid));
     90   OK(sdis_data_ref_put(data));
     91   return fluid;
     92 }
     93 
     94 /*******************************************************************************
     95  * Interface
     96  ******************************************************************************/
     97 static double
     98 interface_get_convection_coef
     99   (const struct sdis_interface_fragment* frag, struct sdis_data* data)
    100 {
    101   (void)frag, (void)data;
    102   return CONVECTION_COEF;
    103 }
    104 
    105 static struct sdis_interface*
    106 create_interface
    107   (struct sdis_device* dev,
    108    struct sdis_medium* front,
    109    struct sdis_medium* back)
    110 {
    111   struct sdis_interface_shader shader = SDIS_INTERFACE_SHADER_NULL;
    112   struct sdis_interface* interf = NULL;
    113 
    114   shader.convection_coef = interface_get_convection_coef;
    115   shader.convection_coef_upper_bound = CONVECTION_COEF;
    116   OK(sdis_interface_create(dev, front, back, &shader, NULL, &interf));
    117   return interf;
    118 }
    119 
    120 /*******************************************************************************
    121  * Scene
    122  ******************************************************************************/
    123 static void
    124 get_position(const size_t ivert, double pos[2], void* context)
    125 {
    126   (void)context;
    127   if(ivert < square_nvertices) {
    128     /* Hole */
    129     pos[0] = square_vertices[ivert*2 + 0]*0.5 + 0.25;
    130     pos[1] = square_vertices[ivert*2 + 1]*0.5 + 0.25;
    131   } else {
    132     /* Border */
    133     pos[0] = square_vertices[(ivert-square_nvertices)*2 + 0];
    134     pos[1] = square_vertices[(ivert-square_nvertices)*2 + 1];
    135   }
    136 }
    137 
    138 static void
    139 get_indices(const size_t iseg, size_t ids[2], void* context)
    140 {
    141   (void)context;
    142   if(iseg < square_nsegments) {
    143     /* Hole */
    144     ids[0] = square_indices[iseg*2 + 0];
    145     ids[1] = square_indices[iseg*2 + 1];
    146   } else {
    147     /* Border */
    148     ids[0] = square_indices[(iseg-square_nsegments)*2 + 0] + square_nvertices;
    149     ids[1] = square_indices[(iseg-square_nsegments)*2 + 1] + square_nvertices;
    150   }
    151 }
    152 
    153 static void
    154 get_interface(const size_t iseg, struct sdis_interface** bound, void* context)
    155 {
    156   struct sdis_interface** interfs = context;
    157   (void)context;
    158   if(iseg < square_nsegments) {
    159     *bound = interfs[iseg]; /* Hole */
    160   } else {
    161     *bound = interfs[4]; /* Border */
    162   }
    163 }
    164 
    165 static struct sdis_scene*
    166 create_scene_2d(struct sdis_device* dev)
    167 {
    168   struct sdis_scene_create_args args = SDIS_SCENE_CREATE_ARGS_DEFAULT;
    169   struct sdis_interface* interfaces[5] = {NULL};
    170   struct sdis_medium* fluid[5] = {NULL};
    171   struct sdis_medium* solid = NULL;
    172   struct sdis_scene* scn = NULL;
    173 
    174   fluid[0] = create_fluid(dev, 280);
    175   fluid[1] = create_fluid(dev, 300);
    176   fluid[2] = create_fluid(dev, 320);
    177   fluid[3] = create_fluid(dev, 340);
    178   fluid[4] = create_fluid(dev, Text);
    179   solid = create_solid(dev);
    180 
    181   interfaces[0] = create_interface(dev, fluid[0], solid);
    182   interfaces[1] = create_interface(dev, fluid[1], solid);
    183   interfaces[2] = create_interface(dev, fluid[2], solid);
    184   interfaces[3] = create_interface(dev, fluid[3], solid);
    185   interfaces[4] = create_interface(dev, solid, fluid[4]);
    186 
    187   args.get_indices = get_indices;
    188   args.get_interface = get_interface;
    189   args.get_position = get_position;
    190   args.nprimitives = square_nsegments*2/*border + hole*/;
    191   args.nvertices = square_nvertices*2/*border + hole*/;
    192   args.context = interfaces;
    193   OK(sdis_scene_2d_create(dev, &args, &scn));
    194 
    195   OK(sdis_interface_ref_put(interfaces[0]));
    196   OK(sdis_interface_ref_put(interfaces[1]));
    197   OK(sdis_interface_ref_put(interfaces[2]));
    198   OK(sdis_interface_ref_put(interfaces[3]));
    199   OK(sdis_interface_ref_put(interfaces[4]));
    200   OK(sdis_medium_ref_put(fluid[0]));
    201   OK(sdis_medium_ref_put(fluid[1]));
    202   OK(sdis_medium_ref_put(fluid[2]));
    203   OK(sdis_medium_ref_put(fluid[3]));
    204   OK(sdis_medium_ref_put(fluid[4]));
    205   OK(sdis_medium_ref_put(solid));
    206   return scn;
    207 }
    208 
    209 /*******************************************************************************
    210  * Check
    211  ******************************************************************************/
    212 static void
    213 solve_probe(struct sdis_scene* scn)
    214 {
    215   struct sdis_solve_probe_args args = SDIS_SOLVE_PROBE_ARGS_DEFAULT;
    216   struct sdis_mc T = SDIS_MC_NULL;
    217   struct sdis_estimator* estimator = NULL;
    218 
    219   args.position[0] = 0.5;
    220   args.position[1] = 0.5;
    221   args.position[2] = 0;
    222   args.nrealisations = NREALISATIONS;
    223   CHK(sdis_solve_probe(scn, &args, &estimator) == RES_BAD_OP);
    224 
    225   args.position[0] = 2;
    226   args.position[1] = 0.5;
    227   args.position[2] = 0;
    228   args.nrealisations = NREALISATIONS;
    229   OK(sdis_solve_probe(scn, &args, &estimator));
    230   OK(sdis_estimator_get_temperature(estimator, &T));
    231   OK(sdis_estimator_ref_put(estimator));
    232   CHK(Text == T.E); /* Zero variance */
    233 
    234   args.position[0] = 0.1;
    235   args.position[1] = 0.1;
    236   args.position[2] = 0;
    237   args.nrealisations = NREALISATIONS;
    238   OK(sdis_solve_probe(scn, &args, &estimator));
    239   OK(sdis_estimator_get_temperature(estimator, &T));
    240   OK(sdis_estimator_ref_put(estimator));
    241   printf("T(%g, %g) ~ %g +/- %g\n", SPLIT2(args.position), T.E, T.SE);
    242 }
    243 
    244 /*******************************************************************************
    245  * Test
    246  ******************************************************************************/
    247 int
    248 main(int argc, char** argv)
    249 {
    250   struct sdis_device* dev = NULL;
    251   struct sdis_scene* scn_2d = NULL;
    252   (void)argc, (void)argv;
    253 
    254   OK(sdis_device_create(&SDIS_DEVICE_CREATE_ARGS_DEFAULT, &dev));
    255   scn_2d = create_scene_2d(dev);
    256 
    257   solve_probe(scn_2d);
    258 
    259   OK(sdis_device_ref_put(dev));
    260   OK(sdis_scene_ref_put(scn_2d));
    261 
    262   CHK(mem_allocated_size() == 0);
    263   return 0;
    264 }