star-meteo

Time varying meteorological data
git clone git://git.meso-star.fr/star-meteo.git
Log | Files | Refs | README | LICENSE

test_stardis_smeteo.c (5616B)


      1 /* Copyright (C) 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 dismshbuted 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 #define _POSIX_C_SOURCE 200809L /* strdup */
     17 
     18 #include "smeteo.h"
     19 #include "stardis_smeteo.h"
     20 
     21 #include <rsys/mem_allocator.h>
     22 
     23 /* FIXME required by the UINT_MAX constant used in the stardis-prog-properties
     24  * header. It should by stardis, not by the caller. */
     25 #include <limits.h>
     26 
     27 #include <string.h> /* strdup */
     28 
     29 /*******************************************************************************
     30  * Helper functions
     31  ******************************************************************************/
     32 static void*
     33 check_lib_api(const char* filename)
     34 {
     35   struct stardis_program_context ctx = {0};
     36   char* argv[2] = {NULL};
     37   void* lib = NULL;
     38 
     39   /* Input strings cannot be constants, so they must be duplicated */
     40   CHK(argv[0] = strdup("stardis-plugin")); /* dummy string */
     41   CHK(argv[1] = strdup(filename));
     42 
     43   ctx.name = argv[0];
     44   ctx.verbosity_level = 3;
     45 
     46   /* Invalid function calls */
     47   CHK(stardis_create_library_data(NULL, 2, argv) == NULL);
     48   CHK(stardis_create_library_data(&ctx, 1, argv) == NULL);
     49   CHK(stardis_create_library_data(&ctx, 2, NULL) == NULL);
     50 
     51   /* Valid function call */
     52   CHK((lib = stardis_create_library_data(&ctx, 2, argv)) != NULL);
     53 
     54   /* Verify that, on a valid lib, the legal functions return a valid result */
     55   CHK(get_copyright_notice(lib) != NULL);
     56   CHK(get_license_short(lib) != NULL);
     57   CHK(get_license_text(lib) != NULL);
     58 
     59   CHK(stardis_finalize_library_data(lib) == STARDIS_SUCCESS);
     60 
     61   /* Check for error if file is invalid */
     62   free(argv[1]);
     63   CHK(argv[1] = strdup("invalid_filename.txt"));
     64   CHK(stardis_create_library_data(&ctx, 2, argv) == NULL);
     65 
     66   /* Clean-up allocated memory */
     67   free(argv[0]);
     68   free(argv[1]);
     69 
     70   return lib; /* Return the created library */
     71 }
     72 
     73 static void*
     74 check_data_api(void* lib)
     75 {
     76   struct stardis_description_create_context ctx = {0};
     77   char* argv[2] = {"smeteo", "-hls"};
     78   size_t argc = sizeof(argv)/sizeof(char*);
     79   void* data = NULL;
     80 
     81   /* The input string cannot be constant, so it must be duplicated */
     82   CHK(argv[0] = strdup("boundary-condition")); /* dummy string */
     83   ctx.name = argv[0];
     84 
     85   /* Invalid function calls */
     86   CHK(stardis_create_data(NULL, lib, argc, argv) == NULL);
     87   CHK(stardis_create_data(&ctx, NULL, argc, argv) == NULL);
     88   CHK(stardis_create_data(&ctx, lib, 0, argv) == NULL);
     89   CHK(stardis_create_data(&ctx, lib, argc, NULL) == NULL);
     90 
     91   /* Valid function call */
     92   CHK((data = stardis_create_data(&ctx, lib, argc, argv)) != NULL);
     93 
     94   free(argv[0]);
     95 
     96   return data;
     97 }
     98 
     99 static double /* in [0-1[ */
    100 rand_canonical(void)
    101 {
    102   return rand() / (double)(RAND_MAX-1);
    103 }
    104 
    105 static void
    106 check_getters(void* data, const struct smeteo* smeteo)
    107 {
    108   struct smeteo_desc desc = SMETEO_DESC_NULL;
    109   double interval_duration = 0; /* [s] */
    110 
    111   size_t i = 0;
    112   size_t nqueries = 1000;
    113 
    114   struct stardis_vertex vtx = {0};
    115   struct stardis_interface_fragment frag = {0};
    116 
    117   CHK(smeteo_get_desc(smeteo, &desc) == RES_OK);
    118 
    119   /* Multiplier to convert a time in day_1850 to seconds */
    120   #define M_DAY1850_TO_H (24/*[h]*/ * 3600/*[s]*/)
    121 
    122   /* The dates of the intervals are relative to midnight on January 1, 1850.  In
    123    * addition, their time is defined at the center of the interval. Thus, for
    124    * the first interval, calculate its duration by multiplying its date relative
    125    * to January 1, 1850 by 2 */
    126   interval_duration = desc.entries[0].day_1850 * 2 * M_DAY1850_TO_H;
    127 
    128   FOR_EACH(i, 0, nqueries) {
    129     /* Randomly select a time interval */
    130     const size_t ientry = (size_t)(rand_canonical() * (double)desc.nentries);
    131     const struct smeteo_entry* entry = desc.entries + ientry;
    132 
    133     /* Randomly sample a time [s] in the selected interval */
    134     const double start = entry->day_1850*M_DAY1850_TO_H - interval_duration*0.5;
    135     const double time = start + rand_canonical() * interval_duration;
    136 
    137     vtx.time = frag.time = time;
    138 
    139     /* query data */
    140     CHK(stardis_convection_coefficient(&frag, data) == entry->H);
    141     CHK(stardis_reference_temperature(&frag, data) == entry->Tsrf);
    142     CHK(stardis_boundary_temperature(&frag, data) == entry->Tsrf);
    143     CHK(stardis_medium_temperature(&vtx, data) == entry->Tatm);
    144     CHK(stardis_emissivity(&frag, STARDIS_INTERN_SOURCE_ID, data) == 1.0);
    145   }
    146 
    147   #undef M_DAY1850_TO_H
    148 }
    149 
    150 /*******************************************************************************
    151  * The test
    152  ******************************************************************************/
    153 int
    154 main(void)
    155 {
    156   const char* filename = "samples/star-meteo_input.txt";
    157 
    158   struct smeteo* smeteo = NULL;
    159   void* lib = NULL;
    160   void* data = NULL;
    161 
    162   CHK(smeteo_create(&SMETEO_CREATE_ARGS_DEFAULT, &smeteo) == RES_OK);
    163   CHK(smeteo_load(smeteo, filename) == RES_OK);
    164 
    165   lib = check_lib_api(filename);
    166   data = check_data_api(lib);
    167 
    168   check_getters(data, smeteo);
    169 
    170   stardis_release_library_data(lib);
    171   stardis_release_data(data);
    172 
    173   CHK(smeteo_ref_put(smeteo) == RES_OK);
    174 
    175   CHK(mem_allocated_size() == 0);
    176 
    177   return 0;
    178 }