commit 1903657bfc8786ea103eb99303b9c6e690bc520d
parent a44d0d7751919deec12c2761e059466417863133
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 23 Sep 2022 10:24:28 +0200
Store the bands overlapped by the input spectral range
Refactor the code to use this list stored in the rnatm data structure
rather than in a local variable. We store this list to speed up the
obtaining of radiative properties, as we need to efficiently retrieve
the band index for which the radiative properties are queried.
Diffstat:
4 files changed, 124 insertions(+), 80 deletions(-)
diff --git a/src/rnatm.c b/src/rnatm.c
@@ -187,6 +187,7 @@ create_rnatm
gas_init(atm->allocator, &atm->gas);
darray_aerosol_init(atm->allocator, &atm->aerosols);
darray_accel_struct_init(atm->allocator, &atm->accel_structs);
+ darray_band_init(atm->allocator, &atm->bands);
/* Setup the number of threads */
nthreads_max = MMAX(omp_get_max_threads(), omp_get_num_procs());
@@ -250,6 +251,7 @@ release_rnatm(ref_T* ref)
if(atm->svx) SVX(device_ref_put(atm->svx));
darray_aerosol_release(&atm->aerosols);
darray_accel_struct_release(&atm->accel_structs);
+ darray_band_release(&atm->bands);
if(atm->svx_allocator_is_init) {
ASSERT(MEM_ALLOCATED_SIZE(&atm->svx_allocator) == 0);
mem_shutdown_regular_allocator(&atm->svx_allocator);
diff --git a/src/rnatm_c.h b/src/rnatm_c.h
@@ -179,12 +179,26 @@ accel_struct_copy_and_release
#include <rsys/dynamic_array.h>
/*******************************************************************************
+ * Spectral band
+ ******************************************************************************/
+struct band {
+ size_t index; /* Index of the spectral band */
+ size_t nquad_pts; /* Number of quadrature points in the band */
+};
+
+/* Define the dynamic array of spectral bands */
+#define DARRAY_NAME band
+#define DARRAY_DATA struct band
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
* Atmosphere
******************************************************************************/
struct rnatm {
struct gas gas;
struct darray_aerosol aerosols;
struct darray_accel_struct accel_structs;
+ struct darray_band bands; /* Spectral bands to be taken into account */
struct str name;
FILE* octrees_storage;
diff --git a/src/rnatm_octree.c b/src/rnatm_octree.c
@@ -249,47 +249,6 @@ error:
goto exit;
}
-static res_T
-find_band_range
- (const struct rnatm* atm,
- const double range[2], /* In nanometers */
- size_t bands[2])
-{
- struct sck_band band_low;
- struct sck_band band_upp;
- size_t nbands_overlaped;
- res_T res = RES_OK;
- ASSERT(atm && range && bands && range[0] <= range[1]);
-
- res = sck_find_bands(atm->gas.ck, range, bands);
- if(res != RES_OK) goto error;
-
- if(bands[0] > bands[1]) {
- log_err(atm,
- "the spectral range [%g, %g] nm does not overlap any bands\n",
- SPLIT2(range));
- res = RES_BAD_ARG;
- goto error;
- }
-
- nbands_overlaped = bands[1] - bands[0] + 1;
-
- SCK(get_band(atm->gas.ck, bands[0], &band_low));
- SCK(get_band(atm->gas.ck, bands[1], &band_upp));
- log_info(atm,
- "the spectral range [%g, %g] nm overlaps %lu band%sin [%g, %g[ nm\n",
- SPLIT2(range),
- (unsigned long)nbands_overlaped,
- nbands_overlaped > 1 ? "s ": " ",
- band_low.lower,
- band_upp.upper);
-
-exit:
- return res;
-error:
- goto exit;
-}
-
static FINLINE unsigned
round_pow2(const unsigned val)
{
@@ -301,40 +260,32 @@ round_pow2(const unsigned val)
}
}
-/* Return the number of quadrature points for the submitted range of bands.
- * Lmits are inclusives */
+/* Return the number of quadrature points for the range of bands overlapped by
+ * the input spectral range */
static INLINE size_t
-compute_nquad_pts(const struct rnatm* atm, const size_t bands[2])
+compute_nquad_pts(const struct rnatm* atm)
{
size_t nquad_pts = 0;
- size_t nbands = 0;
- size_t i = 0;
- ASSERT(atm && bands && bands[0] <= bands[1]);
-
- nbands = bands[1] - bands[0] + 1;
- FOR_EACH(i, 0, nbands) {
- struct sck_band band;
- const size_t iband = bands[0] + i;
- SCK(get_band(atm->gas.ck, iband, &band));
- nquad_pts += band.quad_pts_count;
+ size_t iband = 0;
+ ASSERT(atm);
+
+ FOR_EACH(iband, 0, darray_band_size_get(&atm->bands)) {
+ nquad_pts += darray_band_cdata_get(&atm->bands)[iband].nquad_pts;
}
return nquad_pts;
}
static res_T
-setup_accel_structs
- (struct rnatm* atm,
- const size_t bands[2]) /* Range of bands to handle. Limits are inclusives */
+setup_accel_structs(struct rnatm* atm)
{
struct accel_struct* accel_structs = NULL;
size_t istruct;
size_t naccel_structs;
size_t i;
- size_t nbands;
res_T res = RES_OK;
- ASSERT(atm && bands && bands[0] <= bands[1]);
+ ASSERT(atm);
- naccel_structs = compute_nquad_pts(atm, bands);
+ naccel_structs = compute_nquad_pts(atm);
res = darray_accel_struct_resize(&atm->accel_structs, naccel_structs);
if(res != RES_OK) {
@@ -346,16 +297,13 @@ setup_accel_structs
accel_structs = darray_accel_struct_data_get(&atm->accel_structs);
istruct = 0;
- nbands = bands[1] - bands[0] + 1;
- FOR_EACH(i, 0, nbands) {
- struct sck_band band;
- const size_t iband = bands[0] + i;
+ FOR_EACH(i, 0, darray_band_size_get(&atm->bands)) {
+ const struct band* band = darray_band_cdata_get(&atm->bands)+i;
size_t iquad_pt;
- SCK(get_band(atm->gas.ck, iband, &band));
- FOR_EACH(iquad_pt, 0, band.quad_pts_count) {
+ FOR_EACH(iquad_pt, 0, band->nquad_pts) {
ASSERT(istruct < naccel_structs);
- accel_structs[istruct].iband = iband;
+ accel_structs[istruct].iband = band->index;
accel_structs[istruct].iquad_pt = iquad_pt;
++istruct;
}
@@ -1436,19 +1384,16 @@ error:
}
static res_T
-create_octrees
- (struct rnatm* atm,
- const struct rnatm_create_args* args,
- const size_t bands[2]) /* Limits are inclusive */
+create_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
{
struct build_sync sync = BUILD_SYNC_NULL;
struct pool* pool = NULL;
size_t nbands = 0;
ATOMIC res = RES_OK;
- ASSERT(atm && bands && bands[0] <= bands[1]);
+ ASSERT(atm);
- nbands = bands[1] - bands[0] + 1;
+ nbands = darray_band_size_get(&atm->bands);
res = create_pool(atm, &pool, nbands);
if(res != RES_OK) goto error;
@@ -1522,7 +1467,6 @@ res_T
setup_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
{
char buf[128];
- size_t bands[2];
struct time t0, t1;
size_t sz;
res_T res = RES_OK;
@@ -1537,8 +1481,6 @@ setup_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
if(res != RES_OK) goto error;
/* Setup miscellaneous parameters */
- atm->spectral_range[0] = args->spectral_range[0];
- atm->spectral_range[1] = args->spectral_range[1];
atm->optical_thickness = args->optical_thickness;
res = compute_grid_definition(atm, args);
@@ -1549,16 +1491,14 @@ setup_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
res = init_octrees_storage(atm, args);
if(res != RES_OK) goto error;
- res = find_band_range(atm, atm->spectral_range, bands);
- if(res != RES_OK) goto error;
- res = setup_accel_structs(atm, bands);
+ res = setup_accel_structs(atm);
if(res != RES_OK) goto error;
if(args->load_octrees_from_storage) {
res = load_octrees(atm);
if(res != RES_OK) goto error;
} else {
- res = create_octrees(atm, args, bands);
+ res = create_octrees(atm, args);
if(res != RES_OK) goto error;
}
diff --git a/src/rnatm_properties.c b/src/rnatm_properties.c
@@ -412,6 +412,91 @@ error:
goto exit;
}
+static res_T
+find_band_range
+ (const struct rnatm* atm,
+ const double range[2], /* In nanometers */
+ size_t bands[2])
+{
+ struct sck_band band_low;
+ struct sck_band band_upp;
+ size_t nbands_overlaped;
+ res_T res = RES_OK;
+ ASSERT(atm && range && bands && range[0] <= range[1]);
+
+ res = sck_find_bands(atm->gas.ck, range, bands);
+ if(res != RES_OK) goto error;
+
+ if(bands[0] > bands[1]) {
+ log_err(atm,
+ "the spectral range [%g, %g] nm does not overlap any bands\n",
+ SPLIT2(range));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ nbands_overlaped = bands[1] - bands[0] + 1;
+
+ SCK(get_band(atm->gas.ck, bands[0], &band_low));
+ SCK(get_band(atm->gas.ck, bands[1], &band_upp));
+ log_info(atm,
+ "the spectral range [%g, %g] nm overlaps %lu band%sin [%g, %g[ nm\n",
+ SPLIT2(range),
+ (unsigned long)nbands_overlaped,
+ nbands_overlaped > 1 ? "s ": " ",
+ band_low.lower,
+ band_upp.upper);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+setup_spectral_range(struct rnatm* atm, const struct rnatm_create_args* args)
+{
+ size_t bands[2];
+ size_t iband, nbands;
+ res_T res = RES_OK;
+ ASSERT(atm && args);
+ ASSERT(args->spectral_range[0] <= args->spectral_range[1]);
+
+ atm->spectral_range[0] = args->spectral_range[0];
+ atm->spectral_range[1] = args->spectral_range[1];
+
+ /* Find the bands overlapped by the input spectral range */
+ res = find_band_range(atm, atm->spectral_range, bands);
+ if(res != RES_OK) goto error;
+
+ /* Allocate the list of bands to be taken into account */
+ nbands = bands[1] - bands[0] + 1;
+ res = darray_band_resize(&atm->bands, nbands);
+ if(res != RES_OK) {
+ log_err(atm,
+ "failed to register the bands to be taken into account -- %s\n",
+ res_to_cstr(res));
+ goto error;
+ }
+
+ /* Register the bands */
+ FOR_EACH(iband, bands[0], bands[1]+1) {
+ struct band* band = NULL;
+ struct sck_band sck_band;
+
+ SCK(get_band(atm->gas.ck, iband, &sck_band));
+
+ band = darray_band_data_get(&atm->bands) + iband;
+ band->index = iband;
+ band->nquad_pts = sck_band.quad_pts_count;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -431,6 +516,9 @@ setup_properties(struct rnatm* atm, const struct rnatm_create_args* args)
if(res != RES_OK) goto error;
}
+ res = setup_spectral_range(atm, args);
+ if(res != RES_OK) goto error;
+
exit:
return res;
error: