commit ad62d440bca5da1d1cb77972f42a24df99c91df1
parent 4137c24ab0200e4e4075776d97012409c7336277
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 14 Aug 2025 11:40:31 +0200
The Stardis library data is no longer a smeteo
From now on, it points to a specific stardis_smeteo_lib data structure
that not only references a smeteo variable, but also stores additional
data calculated from it and required by the plugin's accessors, such as
the maximum convection coefficient or the ground temperature range.
This data is calculated once and for all when the library data is
created and stored in the new data structure. Their accessors therefore
only need to return these precalculated values.
Diffstat:
3 files changed, 176 insertions(+), 31 deletions(-)
diff --git a/src/stardis_smeteo.c b/src/stardis_smeteo.c
@@ -17,6 +17,7 @@
#include "smeteo.h"
#include "stardis_smeteo.h"
+#include "stardis_smeteo_library.h"
#include <rsys/algorithm.h>
#include <rsys/mem_allocator.h>
@@ -30,8 +31,8 @@ enum boundary_condition_type {
};
struct boundary_condition {
- struct smeteo* smeteo;
- struct smeteo_desc smeteo_desc;
+ struct stardis_smeteo_lib* lib;
+ struct stardis_smeteo_lib_desc lib_desc;
enum boundary_condition_type type;
};
@@ -91,21 +92,21 @@ get_meteo_entry_id
{
struct smeteo_entry* found = NULL;
double time_1850 = 0;
- ASSERT(bcond && frag);
+ ASSERT(bcond);
/* Define the input time in relation to January 1, 1850, i.e., in terms of the
* number of days that have elapsed since 00:00 on January 1, 1850 */
time_1850 = time/*[s]*/ / (24/*hours*/*3600/*[s]*/);
- /* Limit to 0, i.e. January 1, 1850 */
+ /* Limit to 0, i.e. January 1, 1850, i.e. the initial condition */
time_1850 = time_1850 < 0 ? 0 : time_1850;
/* Search for the time interval whose center date is greater than or equal to
* the input time */
found = search_lower_bound
(&time_1850,
- bcond->smeteo_desc.entries,
- bcond->smeteo_desc.nentries,
+ bcond->lib_desc.smeteo_desc.entries,
+ bcond->lib_desc.smeteo_desc.nentries,
sizeof(struct smeteo_entry),
cmp_day_1850);
@@ -115,7 +116,7 @@ get_meteo_entry_id
* time beyond the available time intervals, amounts to repeating the last
* interval indefinitely. */
if(!found) {
- return bcond->smeteo_desc.nentries -1;
+ return bcond->lib_desc.smeteo_desc.nentries -1;
} else {
double half_interval_duration = 0;
@@ -128,14 +129,13 @@ get_meteo_entry_id
*
* Note that there is no need to check that the interval found is the first
* one and that there is therefore no previous interval, because the input
- * time has already been truncated to 0, i.e. midnight on January 1, 1850.
- * */
- half_interval_duration = bcond->smeteo_desc.entries[0].day_1850;
+ * time has already been truncated to 0, i.e. midnight on January 1, 1850 */
+ half_interval_duration = bcond->lib_desc.smeteo_desc.entries[0].day_1850;
if(found->day_1850 - time_1850 > half_interval_duration) --found;
/* Calculate the index of the selected interval */
- ASSERT((intptr_t)found >= (intptr_t)bcond->smeteo_desc.entries);
- return (size_t)(found - bcond->smeteo_desc.entries);
+ ASSERT((intptr_t)found >= (intptr_t)bcond->lib_desc.smeteo_desc.entries);
+ return (size_t)(found - bcond->lib_desc.smeteo_desc.entries);
}
}
@@ -159,10 +159,9 @@ stardis_create_data
if((res = args_init(&args, (int)argc, argv)) != RES_OK) goto error;
if(!(bcond = mem_calloc(1, sizeof(*bcond)))) goto error;
- bcond->smeteo = lib_data;
- SMETEO(ref_get(bcond->smeteo));
- bcond->type = args.bcond_type;
- SMETEO(get_desc(bcond->smeteo, &bcond->smeteo_desc));
+ bcond->lib = lib_data;
+ stardis_smeteo_lib_ref_get(bcond->lib);
+ stardis_smeteo_lib_get_desc(bcond->lib, &bcond->lib_desc);
exit:
return bcond;
@@ -177,21 +176,21 @@ stardis_release_data(void* data)
struct boundary_condition* bcond = data;
ASSERT(data);
- SMETEO(ref_put(bcond->smeteo));
+ stardis_smeteo_lib_ref_put(bcond->lib);
mem_rm(bcond);
}
-double
+double /* [W/K/m^2] */
stardis_convection_coefficient
(const struct stardis_interface_fragment* frag,
void* data)
{
struct boundary_condition* bcond = data;
- size_t i= 0; /* Index of the meteo entry including fragment time */
+ size_t i = 0; /* Index of the meteo entry including fragment time */
ASSERT(frag && data);
i = get_meteo_entry_id(bcond, frag->time);
- return bcond->smeteo_desc.entries[i].H;
+ return bcond->lib_desc.smeteo_desc.entries[i].H;
}
const char*
diff --git a/src/stardis_smeteo_library.c b/src/stardis_smeteo_library.c
@@ -15,6 +15,22 @@
#include "smeteo.h"
#include "stardis_smeteo.h"
+#include "stardis_smeteo_library.h"
+
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/ref_count.h>
+#include <rsys/str.h>
+
+#include <float.h> /* DBL_MAX */
+
+struct stardis_smeteo_lib {
+ struct smeteo* smeteo;
+ struct str filename; /* Filename of the loaded smeteo file */
+ double max_convection_coef;
+ double surface_temperatue_range[2];
+ ref_T ref;
+};
struct args {
char* filename;
@@ -49,6 +65,61 @@ error:
goto exit;
}
+static res_T
+setup_smeteo
+ (struct stardis_smeteo_lib* lib,
+ const struct stardis_program_context* ctx,
+ const struct args* args)
+{
+ struct smeteo_create_args smeteo_args = SMETEO_CREATE_ARGS_DEFAULT;
+ struct smeteo_desc desc = SMETEO_DESC_NULL;
+
+ double max_H = -DBL_MAX;
+ double t_range[2] = {DBL_MAX, -DBL_MAX};
+ size_t i = 0;
+ res_T res = RES_OK;
+
+ ASSERT(lib && ctx && args);
+
+ /* Create a smeteo instance */
+ smeteo_args.verbose = ctx->verbosity_level;
+ res = smeteo_create(&smeteo_args, &lib->smeteo);
+ if(res != RES_OK) goto error;
+
+ /* Load meteorological data */
+ if((res = smeteo_load(lib->smeteo, args->filename)) != RES_OK) goto error;
+ if((res = smeteo_get_desc(lib->smeteo, &desc)) != RES_OK) goto error;
+
+ /* Retrieve the maximum convection coefficient from meteorological data */
+ FOR_EACH(i, 0, desc.nentries) max_H = MMAX(desc.entries[i].H, max_H);
+ lib->max_convection_coef = max_H;
+
+ /* Retrieve the ground temperature range from meteorological data */
+ FOR_EACH(i, 0, desc.nentries) {
+ t_range[0] = MMIN(desc.entries[i].Tsrf, t_range[0]);
+ t_range[1] = MMAX(desc.entries[i].Tsrf, t_range[1]);
+ }
+ lib->surface_temperatue_range[0] = t_range[0];
+ lib->surface_temperatue_range[1] = t_range[1];
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static void
+release_stardis_smeteo_lib(ref_T* ref)
+{
+ struct stardis_smeteo_lib* lib =
+ CONTAINER_OF(ref, struct stardis_smeteo_lib, ref);
+ ASSERT(ref);
+
+ if(lib->smeteo) SMETEO(ref_put(lib->smeteo));
+ str_release(&lib->filename);
+ mem_rm(lib);
+}
+
/*******************************************************************************
* Exported symbols
******************************************************************************/
@@ -59,33 +130,32 @@ stardis_create_library_data
char* argv[])
{
struct args args = ARGS_DEFAULT;
-
- struct smeteo_create_args smeteo_args = SMETEO_CREATE_ARGS_DEFAULT;
- struct smeteo* smeteo = NULL;
+ struct stardis_smeteo_lib* lib = NULL;
res_T res = RES_OK;
/* Parse library arguments */
if((res = args_init(&args, (int)argc, argv)) != RES_OK) goto error;
- /* Create a smeteo instance */
- smeteo_args.verbose = ctx->verbosity_level;
- if((res = smeteo_create(&smeteo_args, &smeteo)) != RES_OK) goto error;
+ /* Allocate the stardis_smeteo_lib data structure */
+ if(!(lib = mem_calloc(1, sizeof(*lib)))) goto error;
+ ref_init(&lib->ref);
+ str_init(NULL, &lib->filename);
- /* Load meteorological data */
- if((res = smeteo_load(smeteo, args.filename)) != RES_OK) goto error;
+ if((res = setup_smeteo(lib, ctx, &args)) != RES_OK) goto error;
+ if((res = str_set(&lib->filename, args.filename)) != RES_OK) goto error;
exit:
- return smeteo;
+ return lib;
error:
- if(smeteo) { SMETEO(ref_put(smeteo)); smeteo = NULL; }
+ if(lib) { stardis_smeteo_lib_ref_put(lib); lib = NULL; }
goto exit;
}
void
stardis_release_library_data(void* lib_data)
{
- SMETEO(ref_put(lib_data));
+ stardis_smeteo_lib_ref_put(lib_data);
}
enum stardis_return_status
@@ -94,3 +164,33 @@ stardis_finalize_library_data(void* lib_data)
(void)lib_data;
return STARDIS_SUCCESS; /* Nothing to be done */
}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+stardis_smeteo_lib_ref_get(struct stardis_smeteo_lib* lib)
+{
+ ASSERT(lib);
+ ref_get(&lib->ref);
+}
+
+void
+stardis_smeteo_lib_ref_put(struct stardis_smeteo_lib* lib)
+{
+ ASSERT(lib);
+ ref_put(&lib->ref, release_stardis_smeteo_lib);
+}
+
+void
+stardis_smeteo_lib_get_desc
+ (const struct stardis_smeteo_lib* lib,
+ struct stardis_smeteo_lib_desc* desc)
+{
+ ASSERT(lib && desc);
+ SMETEO(get_desc(lib->smeteo, &desc->smeteo_desc));
+ desc->filename = str_cget(&lib->filename);
+ desc->max_convection_coef = lib->max_convection_coef;
+ desc->surface_temperatue_range[0] = lib->surface_temperatue_range[0];
+ desc->surface_temperatue_range[1] = lib->surface_temperatue_range[1];
+}
diff --git a/src/stardis_smeteo_library.h b/src/stardis_smeteo_library.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2025 |Méso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redismshbute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is dismshbuted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef STARDIS_SMETEO_LIBRARY_H
+#define STARDIS_SMETEO_LIBRARY_H
+
+#include <rsys/rsys.h>
+
+struct stardis_smeteo_lib_desc {
+ const char* filename;
+ struct smeteo_desc smeteo_desc;
+ double max_convection_coef;
+ double surface_temperatue_range[2];
+};
+#define STARDIS_SMETEO_LIB_DESC_NULL__ {0}
+static const struct stardis_smeteo_lib_desc STARDIS_SMETEO_LIB_DESC_NULL =
+ STARDIS_SMETEO_LIB_DESC_NULL__;
+
+struct stardis_smeteo_lib;
+
+extern LOCAL_SYM void
+stardis_smeteo_lib_ref_get
+ (struct stardis_smeteo_lib* lib);
+
+extern LOCAL_SYM void
+stardis_smeteo_lib_ref_put
+ (struct stardis_smeteo_lib* lib);
+
+extern LOCAL_SYM void
+stardis_smeteo_lib_get_desc
+ (const struct stardis_smeteo_lib* lib,
+ struct stardis_smeteo_lib_desc* desc);
+
+#endif /* STARDIS_SMETEO_LIBRARY_H */