rnatm

Load and structure data describing an atmosphere
git clone git://git.meso-star.fr/rnatm.git
Log | Files | Refs | README | LICENSE

commit c41c0ba905d0247f8d621eae291403721d8a9d37
parent e72deb14e89f35cf26ae04dbf1f31cae3ebead98
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 24 Aug 2022 18:24:30 +0200

Build the octrees for the user-defined spectral range

The spectral range is an input parameter of the rnatm_create function

Diffstat:
Msrc/rnatm.c | 4++++
Msrc/rnatm.h | 5++++-
Msrc/rnatm_octree.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/rnatm_properties.c | 14++++++++++++++
4 files changed, 91 insertions(+), 8 deletions(-)

diff --git a/src/rnatm.c b/src/rnatm.c @@ -87,6 +87,10 @@ check_rnatm_create_args(const struct rnatm_create_args* args) if(res != RES_OK) return res; } + /* Invalid spectral range */ + if(args->spectral_range[0] > args->spectral_range[1]) + return RES_BAD_ARG; + /* Check miscalleneous arguments */ if(!args->name || args->optical_thickness < 0 diff --git a/src/rnatm.h b/src/rnatm.h @@ -85,6 +85,8 @@ struct rnatm_create_args { size_t naerosols; char* name; /* Name of the atmosphere */ + /* Spectral range to consider (in wavenumbers). Limits are inclusive */ + double spectral_range[2]; double optical_thickness; /* Threshold used during octree building */ unsigned grid_definition_hint; /* Hint on the grid definition */ @@ -102,6 +104,7 @@ struct rnatm_create_args { 0, /* Number of aerosols */ \ "atmosphere", /* Name */ \ \ + {12820.513, 26315.789}, /* Spectral range */ \ 1, /* Optical thickness */ \ \ 512, /* Hint on the grid definition */ \ @@ -122,7 +125,7 @@ struct rnatm; BEGIN_DECLS /******************************************************************************* - * API of the Rad-Net GRounD library + * API of the Rad-Net ATMosphere library ******************************************************************************/ RNATM_API res_T rnatm_create diff --git a/src/rnatm_octree.c b/src/rnatm_octree.c @@ -245,6 +245,60 @@ 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; + size_t nbands_overlaped; + size_t ilow, iupp; + res_T res = RES_OK; + ASSERT(atm && range && bands && range[0] <= range[1]); + + nbands = sck_get_bands_count(atm->gas.ck); + + /* Find the lower bound */ + FOR_EACH(ilow, 0, nbands) { + SCK(get_band(atm->gas.ck, ilow, &band_low)); + if(band_low.upper >= range[0]) break; + } + + /* Find the upper bound */ + FOR_EACH(iupp, ilow, nbands) { + SCK(get_band(atm->gas.ck, iupp, &band_upp)); + if(band_upp.lower > range[1]) break; + } + + bands[0] = ilow; + bands[1] = iupp - 1; /* Make the boundary inclusive */ + + if(bands[0] > bands[1]) { + log_err(atm, + "the spectral range [%g, %g] cm^-1 does not overlap any bands\n", + SPLIT2(range)); + res = RES_BAD_ARG; + goto error; + } + + nbands_overlaped = bands[1] - bands[0] + 1; + log_info(atm, + "the spectral range [%g, %g] cm^-1 overlaps %lu band%sin [%g, %g] cm^-1\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) { @@ -998,8 +1052,8 @@ build_octrees * the voxel, we therefore build `voxel_width' octrees in parallel from a * single voxelization of the atmospheric meshes */ for(istruct = 0; istruct < naccel_structs; istruct += voxel_width) { - const size_t nthreads = MMIN(voxel_width, naccel_structs - istruct); - omp_set_num_threads((int)nthreads); + const size_t batch_size = MMIN(voxel_width, naccel_structs - istruct); + omp_set_num_threads((int)batch_size); /* Note that we are using a parallel block rather than a parallel loop in * order to add an implicit barrier after a batch has been fully consumed. @@ -1104,16 +1158,21 @@ error: } static res_T -create_octrees(struct rnatm* atm, const struct rnatm_create_args* args) +create_octrees + (struct rnatm* atm, + const struct rnatm_create_args* args, + const size_t bands[2]) /* Limits are inclusive */ { struct build_sync sync = BUILD_SYNC_NULL; struct pool* pool = NULL; - const size_t bands[2] = {0,0}; /* TODO handle multiple bands */ + size_t nbands = 0; ATOMIC res = RES_OK; - ASSERT(atm); + ASSERT(atm && bands && bands[0] <= bands[1]); - res = create_pool(atm, &pool, bands[1] - bands[0] + 1); + nbands = bands[1] - bands[0] + 1; + + res = create_pool(atm, &pool, nbands); if(res != RES_OK) goto error; res = setup_accel_structs(atm, bands); if(res != RES_OK) goto error; @@ -1170,6 +1229,7 @@ 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; @@ -1180,7 +1240,9 @@ setup_octrees(struct rnatm* atm, const struct rnatm_create_args* args) res = compute_grid_definition(atm, args); if(res != RES_OK) goto error; - res = create_octrees(atm, args); + res = find_band_range(atm, args->spectral_range, bands); + if(res != RES_OK) goto error; + res = create_octrees(atm, args, bands); if(res != RES_OK) goto error; /* Log elapsed time */ diff --git a/src/rnatm_properties.c b/src/rnatm_properties.c @@ -302,9 +302,12 @@ setup_gas_properties(struct rnatm* atm, const struct rnatm_gas_args* gas_args) { char buf[128]; struct time t0, t1; + struct sck_band band_low = SCK_BAND_NULL; + struct sck_band band_upp = SCK_BAND_NULL; struct sck_create_args sck_args = SCK_CREATE_ARGS_DEFAULT; struct sbuf_create_args sbuf_args = SBUF_CREATE_ARGS_DEFAULT; struct sbuf_desc sbuf_desc = SBUF_DESC_NULL; + size_t nbands; res_T res = RES_OK; ASSERT(atm && gas_args); @@ -346,6 +349,17 @@ setup_gas_properties(struct rnatm* atm, const struct rnatm_gas_args* gas_args) time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); log_info(atm, "gas properties loaded in %s\n", buf); + /* Print gas informations */ + nbands = sck_get_bands_count(atm->gas.ck); + res = sck_get_band(atm->gas.ck, 0, &band_low); + if(res != RES_OK) goto error; + res = sck_get_band(atm->gas.ck, nbands-1, &band_upp); + if(res != RES_OK) goto error; + log_info(atm, "the gas is composed of %lu band%sin [%g, %g] cm^-1\n", + nbands, nbands > 1 ? "s " : " ", + band_low.lower, + band_upp.upper); + exit: return res; error: