atrstm

Load and structure a combustion gas mixture
git clone git://git.meso-star.fr/atrstm.git
Log | Files | Refs | README | LICENSE

commit 5441ee76ecbdd9721bcc10685f04b94f54087345
parent bfd9f35c045995007128c3ac8fcc627978f05ff7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 27 Jan 2021 12:16:15 +0100

Add auto computation of the grid definition

Diffstat:
Msrc/atrstm.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/atrstm.h | 15+++++++++++++--
Msrc/test_atrstm.c | 34+++++++++++++++++++++++-----------
3 files changed, 129 insertions(+), 32 deletions(-)

diff --git a/src/atrstm.c b/src/atrstm.c @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _POSIX_C_SOURCE 200112L /* snprintf support */ +#define _POSIX_C_SOURCE 200112L /* snprintf & lround support */ #include "atrstm.h" #include "atrstm_c.h" @@ -36,21 +36,88 @@ static int check_args(const struct atrstm_args* args) { - return args - && args->sth_filename - && (args->spectral_type != ATRSTM_SPECTRAL_LW || args->atrck_filename) - && args->atrtp_filename - && args->atrri_filename - && args->name - && (unsigned)args->spectral_type < ATRSTM_SPECTRAL_TYPES_COUNT__ - && args->wlen_range[0] <= args->wlen_range[1] - && args->gyration_radius_prefactor > 0 - && args->fractal_dimension > 0 - && args->grid_max_definition[0] - && args->grid_max_definition[1] - && args->grid_max_definition[2] - && args->optical_thickness >= 0 - && args->nthreads; + if(!args + || !args->sth_filename + || (args->spectral_type == ATRSTM_SPECTRAL_LW && !args->atrck_filename) + || !args->atrtp_filename + || !args->atrri_filename + || !args->name + || (unsigned)args->spectral_type >= ATRSTM_SPECTRAL_TYPES_COUNT__ + || args->wlen_range[0] > args->wlen_range[1] + || args->gyration_radius_prefactor <= 0 + || args->fractal_dimension <= 0 + || args->optical_thickness < 0 + || !args->nthreads) { + return 0; + } + + if(args->auto_grid_definition) { + if(!args->auto_grid_definition_hint) + return 0; + } else { + if(!args->grid_max_definition[0] + || !args->grid_max_definition[1] + || !args->grid_max_definition[2]) + return 0; + } + + return 1; +} + +static void +compute_default_grid_definition + (const struct atrstm* atrstm, + const unsigned definition_hint, + unsigned def[3]) +{ + double low[3]; + double upp[3]; + double sz[3]; + double sz_max; + double vxsz; + int iaxis_max; + int iaxis_remain[2]; + size_t next_pow2[2]; + int i; + ASSERT(atrstm && def); + + SUVM(volume_get_aabb(atrstm->volume, low, upp)); + sz[0] = upp[0] - low[0]; + sz[1] = upp[1] - low[1]; + sz[2] = upp[2] - low[2]; + + /* Define the dimension along which the volume AABB is the greatest */ + sz_max = -DBL_MAX; + FOR_EACH(i, 0, 3) { + if(sz[i] > sz_max) { iaxis_max = i; sz_max = sz[i]; } + } + + /* Define the other axes */ + iaxis_remain[0] = (iaxis_max + 1) % 3; + iaxis_remain[1] = (iaxis_max + 2) % 3; + + /* Fix the definition to along the maximum axis and compute the voxel size + * along this axis */ + def[iaxis_max] = (unsigned)round_up_pow2(definition_hint); + vxsz = sz[iaxis_max] / def[iaxis_max]; + + /* Compute the definition along the 2 remaining axes. First, copute these + * definitions by assuming that the voxels ar cubics [...] */ + def[iaxis_remain[0]] = (unsigned)lround(sz[iaxis_remain[0]]/vxsz); + def[iaxis_remain[1]] = (unsigned)lround(sz[iaxis_remain[1]]/vxsz); + + /* [...] Next compute the power of two directly greatest that the computed + * definition [...] */ + next_pow2[0] = round_up_pow2(def[iaxis_remain[0]]); + next_pow2[1] = round_up_pow2(def[iaxis_remain[1]]); + + /* [...] Finally round the definition to its nearest power of two. */ + def[iaxis_remain[0]] = + next_pow2[0] - def[iaxis_remain[0]] < next_pow2[0]/4 + ? (unsigned)next_pow2[0] : (unsigned)next_pow2[0]/2; + def[iaxis_remain[1]] = + next_pow2[1] - def[iaxis_remain[1]] < next_pow2[1]/4 + ? (unsigned)next_pow2[1] : (unsigned)next_pow2[1]/2; } static void @@ -118,9 +185,6 @@ atrstm_create atrstm->spectral_type = args->spectral_type; atrstm->wlen_range[0] = args->wlen_range[0]; atrstm->wlen_range[1] = args->wlen_range[1]; - atrstm->grid_max_definition[0] = args->grid_max_definition[0]; - atrstm->grid_max_definition[1] = args->grid_max_definition[1]; - atrstm->grid_max_definition[2] = args->grid_max_definition[2]; atrstm->optical_thickness = args->optical_thickness; str_init(allocator, &atrstm->name); @@ -190,6 +254,16 @@ atrstm_create (atrstm, args->precompute_normals, args->sth_filename, &atrstm->volume); if(res != RES_OK) goto error; + /* Define the grid definition */ + if(args->auto_grid_definition) { + compute_default_grid_definition + (atrstm, args->auto_grid_definition_hint, atrstm->grid_max_definition); + } else { + atrstm->grid_max_definition[0] = args->grid_max_definition[0]; + atrstm->grid_max_definition[1] = args->grid_max_definition[1]; + atrstm->grid_max_definition[2] = args->grid_max_definition[2]; + } + /* Load the thermodynamic properties of the volumetric mesh */ res = atrtp_create (atrstm->logger, atrstm->allocator, atrstm->verbose, &atrstm->atrtp); diff --git a/src/atrstm.h b/src/atrstm.h @@ -104,7 +104,10 @@ struct atrstm_args { double gyration_radius_prefactor; double fractal_dimension; - unsigned grid_max_definition[3]; /* Maximum definition of the grid */ + unsigned grid_max_definition[3]; /* Fixed grid definition along the 3 axes */ + unsigned auto_grid_definition_hint; /* Hint on the grid definition to eval */ + int auto_grid_definition; /* Switch between auto and fixed grid definition */ + double optical_thickness; /* Threshold used during octree building */ int precompute_normals; /* Pre-compute the tetrahedra normals */ @@ -120,13 +123,21 @@ struct atrstm_args { NULL, /* AtrRI filename */ \ NULL, /* Cache filename */ \ "semi transparent medium", /* Name */ \ + \ ATRSTM_SPECTRAL_SW, /* Spectral type */ \ {500,500}, /* Spectral integration range */ \ - 1.70, /* Prefactor */ \ + \ + 1.70, /* Gyration radius prefactor */ \ 1.75, /* Fractal dimension */ \ + \ {256, 256, 256}, /* Acceleration grid max definition */ \ + 256, /* Hint on grid Definition in 'auto grid definition' mode */ \ + 1, /* Enable/disable 'auto grid definition' mode */ \ + \ 1, /* Optical thickness */ \ + \ 0, /* Precompute tetrahedra normals */ \ + \ (unsigned)~0, /* #threads */ \ 0 /* Verbosity level */ \ } diff --git a/src/test_atrstm.c b/src/test_atrstm.c @@ -77,7 +77,8 @@ print_help(const char* cmd) " -t NTHREADS hint on the number of threads to use. By default use\n" " as many threads as CPU cores.\n"); printf( -" -V X,Y,Z maximum definition of the acceleration grids\n" +" -V <DEFINITION|X,Y,Z>\n" +" maximum definition of the acceleration grids\n" " along the 3 axis. Its default value is [%u, %u, %u].\n", SPLIT3(ATRSTM_ARGS_DEFAULT.grid_max_definition)); printf( @@ -103,22 +104,33 @@ parse_grid_definition(struct atrstm_args* args, const char* str) ASSERT(args && str); res = cstr_to_list_uint(str, ',', def, &len, 3); - if(res == RES_OK && len != 3) res = RES_BAD_ARG; + if(res == RES_OK && len == 2) res = RES_OK; if(res != RES_OK) { fprintf(stderr, "Invalid grid definition `%s'.\n", str); goto error; } - if(!def[0] || !def[1] || !def[2]) { - fprintf(stderr, - "Invalid null grid definition [%u, %u, %u].\n", SPLIT3(def)); - res = RES_BAD_ARG; - goto error; - } + if(len == 1) { + if(!def[0]) { + fprintf(stderr, "Invalid null grid definition %u.\n", def[0]); + res = RES_BAD_ARG; + goto error; + } + args->auto_grid_definition = 1; + args->auto_grid_definition_hint = def[0]; - args->grid_max_definition[0] = def[0]; - args->grid_max_definition[1] = def[1]; - args->grid_max_definition[2] = def[2]; + } else { + if(!def[0] || !def[1] || !def[2]) { + fprintf(stderr, + "Invalid null grid definition [%u, %u, %u].\n", SPLIT3(def)); + res = RES_BAD_ARG; + goto error; + } + args->auto_grid_definition = 0; + args->grid_max_definition[0] = def[0]; + args->grid_max_definition[1] = def[1]; + args->grid_max_definition[2] = def[2]; + } exit: return res;