stardis-test

Test Stardis behaviors
git clone git://git.meso-star.fr/stardis-test.git
Log | Files | Refs | README | LICENSE

sadist_lib_trilinear_profile.c (6433B)


      1 /* Copyright (C) 2024 |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 "sadist.h"
     17 
     18 #include <stardis/stardis-prog-properties.h>
     19 
     20 #include <rsys/cstr.h>
     21 #include <rsys/rsys.h>
     22 #include <rsys/mem_allocator.h>
     23 
     24 #include <stdarg.h> /* va_list */
     25 #include <getopt.h>
     26 
     27 /*******************************************************************************
     28  * Helper functions
     29  ******************************************************************************/
     30 static void
     31 log_err(const char* msg, ...)
     32 {
     33   va_list vargs_list;
     34   ASSERT(msg);
     35 
     36   va_start(vargs_list, msg);
     37   vfprintf(stderr, msg, vargs_list);
     38   va_end(vargs_list);
     39 }
     40 
     41 static void
     42 print_usage(FILE* stream, const char* name)
     43 {
     44   fprintf(stream,
     45 "usage: %s [-h] [-b lower_xyz,upper_xyz]\n"
     46 "   [-t max_Tx,max_Ty,max_Tz]\n",
     47   name);
     48 }
     49 
     50 static res_T
     51 parse_spatial_range(struct sadist_trilinear_profile* profile, const char* str)
     52 {
     53   double range[2] = {0, 0};
     54   size_t len = 0;
     55   res_T res = RES_OK;
     56   ASSERT(profile && str);
     57 
     58   res = cstr_to_list_double(str, ',', range, &len, 2);
     59   if(res == RES_OK && len != 2) res = RES_BAD_ARG;
     60   if(res != RES_OK) {
     61     log_err("%s:%lu: unable to parse spatial range parameter `%s' -- %s\n",
     62       __FILE__, __LINE__, str, res_to_cstr(res));
     63     goto error;
     64   }
     65 
     66   if(range[0] >= range[1]) {
     67     log_err("%s:%lu: invalid spatial range [%g, %g]\n",
     68       __FILE__, __LINE__, range[0], range[1]);
     69     res = RES_BAD_ARG;
     70     goto error;
     71   }
     72 
     73   profile->lower[0] = profile->lower[1] = profile->lower[2] = range[0];
     74   profile->upper[0] = profile->upper[1] = profile->upper[2] = range[1];
     75 
     76 exit:
     77   return res;
     78 error:
     79   goto exit;
     80 }
     81 
     82 static res_T
     83 parse_max_temperatures(struct sadist_trilinear_profile* profile, const char* str)
     84 {
     85   double abc[3] = {0, 0, 0};
     86   size_t len = 0;
     87   res_T res = RES_OK;
     88   ASSERT(profile && str);
     89 
     90   res = cstr_to_list_double(str, ',', abc, &len, 3);
     91   if(res == RES_OK && len != 3) res = RES_BAD_ARG;
     92   if(res != RES_OK) {
     93     log_err("%s:%lu: unable to parse maximum temperatures `%s' -- %s\n",
     94       __FILE__, __LINE__, str, res_to_cstr(res));
     95     goto error;
     96   }
     97 
     98   if(abc[0] < 0 || abc[1] < 0 || abc[2] < 0) {
     99     log_err
    100       ("%s:%lu: invalid maximum temperatures (X = %g K, Y = %g K, Z = %g K)\n",
    101        __FILE__, __LINE__, str, abc[0], abc[1], abc[2]);
    102     res = RES_BAD_ARG;
    103     goto error;
    104   }
    105 
    106   profile->a[1] = abc[0];
    107   profile->b[1] = abc[1];
    108   profile->c[1] = abc[2];
    109 
    110 exit:
    111   return res;
    112 error:
    113   goto exit;
    114 }
    115 
    116 static res_T
    117 parse_args
    118   (const struct stardis_description_create_context* ctx,
    119    struct sadist_trilinear_profile* profile,
    120    int argc,
    121    char* argv[])
    122 {
    123   int opt;
    124   res_T res = RES_OK;
    125   ASSERT(ctx && profile);
    126 
    127   optind = 1;
    128   while((opt = getopt(argc, argv, "b:ht:")) != -1) {
    129     switch(opt) {
    130       case 'b':
    131         res = parse_spatial_range(profile, optarg);
    132         if(res != RES_OK) goto error;
    133         break;
    134       case 'h':
    135         print_usage(stdout, ctx->name);
    136         break;
    137       case 't':
    138         res = parse_max_temperatures(profile, optarg);
    139         if(res != RES_OK) goto error;
    140         break;
    141       default: res = RES_BAD_ARG; break;
    142     }
    143   }
    144 
    145 exit:
    146   return res;
    147 error:
    148   goto exit;
    149 }
    150 
    151 /*******************************************************************************
    152  * Legal notices
    153  ******************************************************************************/
    154 const char*
    155 get_copyright_notice(void* data)
    156 {
    157   (void)data; /* Avoid "unused variable" warnings */
    158   return "Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)";
    159 }
    160 
    161 const char*
    162 get_license_short(void* data)
    163 {
    164   (void)data; /* Avoid "unused variable" warnings */
    165   return "GNU GPL version 3 or later <http://www.gnu.org/licenses/>";
    166 }
    167 
    168 const char*
    169 get_license_text(void* data)
    170 {
    171   (void)data; /* Avoid "unused variable" warnings */
    172   return
    173     "This is free software released under the GPL v3+ license: GNU GPL\n"
    174     "version 3 or later. You are welcome to redistribute it under certain\n"
    175     "conditions; refer to <http://www.gnu.org/licenses/> for details.";
    176 }
    177 
    178 /*******************************************************************************
    179  * Create data
    180  ******************************************************************************/
    181 void*
    182 stardis_create_data
    183   (const struct stardis_description_create_context* ctx,
    184    void* libdata,
    185    size_t argc,
    186    char* argv[])
    187 {
    188   struct sadist_trilinear_profile* profile = NULL;
    189   res_T res = RES_OK;
    190   (void)libdata;
    191 
    192   profile = mem_alloc(sizeof(*profile));
    193   if(!profile) {
    194     log_err("%s:%lu: error allocating the trilinear profile.\n",
    195       __FILE__, __LINE__);
    196     goto error;
    197   }
    198 
    199   *profile = SADIST_TRILINEAR_PROFILE_NULL;
    200 
    201   res = parse_args(ctx, profile, (int)argc, argv);
    202   if(res != RES_OK) goto error;
    203 
    204 exit:
    205   return profile;
    206 error:
    207   if(profile) {
    208     mem_rm(profile);
    209     profile = NULL;
    210   }
    211   goto exit;
    212 }
    213 
    214 void
    215 stardis_release_data(void* data)
    216 {
    217   ASSERT(data);
    218   mem_rm(data);
    219 }
    220 
    221 /*******************************************************************************
    222  * Boundary condition
    223  ******************************************************************************/
    224 double
    225 stardis_boundary_temperature
    226   (const struct stardis_interface_fragment* frag,
    227    void* data)
    228 {
    229   ASSERT(frag && data);
    230   return sadist_trilinear_profile_temperature(data, frag->P);
    231 }
    232 
    233 double*
    234 stardis_t_range(void* data, double range[2])
    235 {
    236   struct sadist_trilinear_profile* profile = data;
    237   ASSERT(data && range);
    238 
    239   range[0] =      MMIN(profile->a[0], profile->a[1]);
    240   range[0] = MMIN(MMIN(profile->b[0], profile->b[1]), range[0]);
    241   range[0] = MMIN(MMIN(profile->c[0], profile->c[1]), range[0]);
    242 
    243   range[1] =      MMAX(profile->a[0], profile->a[1]);
    244   range[1] = MMAX(MMAX(profile->b[0], profile->b[1]), range[1]);
    245   range[1] = MMAX(MMAX(profile->c[0], profile->c[1]), range[1]);
    246 
    247   return range;
    248 }