stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

commit 9d1152d78345c0db8905fa2c1bf6ecee66f106f0
parent 1ad54ad0656369b371f26136e4f40423149597d5
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  3 Dec 2021 11:43:08 +0100

Merge branch 'feature_non_linear' into develop

Diffstat:
Mcmake/CMakeLists.txt | 1+
Mdoc/stardis.1.txt.in | 46+++++++++++++++++++++++++++++++++-------------
Msrc/stardis-app.c | 5++++-
Msrc/stardis-app.h | 13+++++++------
Msrc/stardis-args.c | 44++++++++++++++++++++++++++++++++++++++------
Msrc/stardis-args.h | 5+++--
Msrc/stardis-compute.c | 7+++++++
Msrc/stardis-default.h.in | 1+
Msrc/stardis-parsing.c | 16++++++++++++++++
9 files changed, 110 insertions(+), 28 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -38,6 +38,7 @@ set_property(CACHE STARDIS_DOC PROPERTY STRINGS set(STARDIS_ARGS_DEFAULT_TRAD "300") set(STARDIS_ARGS_DEFAULT_TRAD_REFERENCE "300") set(STARDIS_ARGS_DEFAULT_COMPUTE_TIME "INF") +set(STARDIS_ARGS_DEFAULT_PICARD_ORDER "1") set(STARDIS_ARGS_DEFAULT_RENDERING_FOV "70") # degrees set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT "480") set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH "640") diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in @@ -29,12 +29,14 @@ SYNOPSIS *stardis* *-M* <__file__> [_option_] DESCRIPTION ------------ -*stardis* solves coupled thermal systems under the linear assumption. Here -coupled refers to conductive, convective and radiative transfers, and linear -means that each phenomena is represented using a model that is linear -with temperature. *stardis* can deal with complex geometries as well as -high-frequency external solicitations over a very long period of time, +*stardis* solves coupled thermal systems: conductive, convective and +radiative transfers are solved together. The physical model used for +conduction is the local unstationary heat conduction equation. +Convection fluxes are assumed to be linear with temperature, and radiation +is assumed to be integrated over the whole thermal spectral range, +therefore radiative heat fluxes are proportionnal to a difference of +temperatures to the power 4. *stardis* can deal with complex geometries as +well as high-frequency external solicitations over a very long period of time, relative to the characteristic time of the system. The provided system description should comply with the *stardis-input*(5) format. @@ -62,13 +64,23 @@ computer graphics technology which has already been a game changer in the cinema industry (FX and animated movies), this theoretical framework can now be practically used on the most geometrically complex systems. -Everytime the linear assumption is relevant, this theoretical framework allows -to encompass all the heat transfer mechanisms (conductive-convective-radiative) -in an unified statistical model. Such systems can be solved by a Monte-Carlo -approach just by sampling heat paths. This can be seen as an extension of -Monte-Carlo algorithms that solve radiative transfer by sampling optical paths. -A main property of this approach is that the resulting algorithms does not rely -on a volume mesh of the system. +Monte-Carlo algorithms associated with convective and conductive processes +consist in sampling heat paths: this can be seen as an extension of +Monte-Carlo algorithms that solve monochromatic radiative transfer. +The radiative transfer algorithm, based on the Picard method, is also based +on sampling radiative paths. However, since stardis solves the spectrally +integrated radiative transfer, the process can be recursive: secondary heat +paths (convective, conductive and radiative) may be necessary along the +sampling of an initial radiative path. + +The solution may not be sufficiently converged with a Picard order equal +to 1 in the presence of high temperature gradients. +Increasing the Picard order may be necessary in this case, until the +required convergence is reached. + +A main property of this approach is that the resulting algorithms do +not rely on a volumic mesh of the system: only the representation +of interfaces is necessary. [1] Delatorre et al., Monte Carlo advances and concentrated solar applications, Solar Energy, 2014 @@ -238,6 +250,14 @@ different temperature, flux or volumic power values. Number of Monte-Carlo samples. By default *samples-count* is set to @STARDIS_ARGS_DEFAULT_SAMPLES_COUNT@. +*-o* _Picard_order_:: + Determine the iteration level used with the Picard method to deal with + non-linear radiative transfer accross the model. + By default *Picard_order* is set to @STARDIS_ARGS_DEFAULT_PICARD_ORDER@. + Note that a Picard order greater than 1 is incompatible both with Green + computations and models including volumic power sources or non zero flux + at a boundary. + *-t* _threads-count_:: Hint on the number of threads to use. By default use as many threads as CPU cores. diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -83,7 +83,9 @@ read_model stardis->t_range[0] = MMIN(stardis->t_range[0], stardis->trad_ref); stardis->t_range[1] = MMAX(stardis->t_range[1], stardis->trad_ref); logger_print(stardis->logger, LOG_OUTPUT, - "System Tref range is [%g %g]\n", SPLIT2(stardis->t_range)); + "System T range is [%g %g]\n", SPLIT2(stardis->t_range)); + logger_print(stardis->logger, LOG_OUTPUT, + "Picard order is %u\n", stardis->picard_order); ASSERT(!f && !txtrdr); exit: @@ -239,6 +241,7 @@ stardis_init stardis->compute_surface.area = 0; stardis->samples = args->samples; stardis->nthreads = args->nthreads; + stardis->picard_order = args->picard_order; stardis->scale_factor = -1; /* invalid value */ stardis->trad = STARDIS_DEFAULT_TRAD; stardis->trad_ref = STARDIS_DEFAULT_TRAD_REFERENCE; diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -793,16 +793,17 @@ struct stardis { struct str rndgen_state_in_filename; struct str rndgen_state_out_filename; struct str chunks_prefix; - int mode; - int trad_def; + struct mem_allocator* allocator; + struct logger* logger; + struct sdis_device* dev; size_t samples; - unsigned nthreads; double scale_factor; double trad, trad_ref; double t_range[2]; - struct mem_allocator* allocator; - struct logger* logger; - struct sdis_device* dev; + int mode; + int trad_def; + unsigned nthreads; + unsigned picard_order; unsigned next_medium_id; unsigned undefined_medium_behind_boundary_id; int dump_paths; diff --git a/src/stardis-args.c b/src/stardis-args.c @@ -181,9 +181,10 @@ init_args args->logger = logger; args->allocator = allocator; darray_str_init(allocator, &args->model_files); - /* Set default values */ + /* Set non-zero default values */ args->samples = STARDIS_DEFAULT_SAMPLES_COUNT; args->nthreads = SDIS_NTHREADS_DEFAULT; + args->picard_order = STARDIS_DEFAULT_PICARD_ORDER; d2(args->pos_and_time+3, STARDIS_DEFAULT_COMPUTE_TIME, STARDIS_DEFAULT_COMPUTE_TIME); args->verbose = STARDIS_DEFAULT_VERBOSE_LEVEL; @@ -228,13 +229,13 @@ short_help print_version(stream); fprintf(stream, "\nMandatory options\n"); - fprintf(stream, "-------------------\n"); + fprintf(stream, "-----------------\n"); fprintf(stream, "\n -M <FILE>\n"); fprintf(stream, " Read a text file that contains (partial) description of the model.\n"); fprintf(stream, "\nExclusive options\n"); - fprintf(stream, "-------------------\n"); + fprintf(stream, "-----------------\n"); fprintf(stream, "\n -F STL_FILE[,TIME-RANGE]\n"); fprintf(stream, " Compute the mean flux on a given 2D region at a given time.\n"); @@ -258,7 +259,7 @@ short_help fprintf(stream, " Compute the by-triangle mean temperature on a given 2D region.\n"); fprintf(stream, "\nOther options\n"); - fprintf(stream, "-------------------\n"); + fprintf(stream, "-------------\n"); fprintf(stream, "\n -c NAMES_PREFIX\n"); fprintf(stream, " Dump the geometry and property ids to stdout as C chunks.\n"); @@ -284,6 +285,9 @@ short_help fprintf(stream, "\n -n SAMPLE_COUNT\n"); fprintf(stream, " Set the number of Monte-Carlo samples.\n"); + fprintf(stream, "\n -o\n"); + fprintf(stream, " Set the order for the Picard linearization of radiative transfer.\n"); + fprintf(stream, "\n -t NUM_OF_THREADS\n"); fprintf(stream, " Hint on the number of threads.\n"); @@ -359,9 +363,9 @@ parse_args struct args* args, struct mem_allocator* allocator) { - int opt = 0, n_used = 0; + int opt = 0, n_used = 0, o_used = 0; size_t len = 0; - const char option_list[] = "c:dD:eF:gG:hm:M:n:p:P:R:s:S:t:vV:x:X:"; + const char option_list[] = "c:dD:eF:gG:hm:M:n:o:p:P:R:s:S:t:vV:x:X:"; char buf[128]; struct str keep; char** line = NULL; @@ -536,6 +540,23 @@ parse_args break; } + case 'o': { + int order; + res = cstr_to_int(optarg, &order); + if(res != RES_OK + || order <= 0) + { + if(res == RES_OK) res = RES_BAD_ARG; + logger_print(args->logger, LOG_ERROR, + "Invalid argument for option -%c: %s\n", + opt, optarg); + goto error; + } + args->picard_order = (unsigned)order; + o_used = 1; + break; + } + case 'p': if(args->mode & EXCLUSIVE_MODES) { res = RES_BAD_ARG; @@ -728,6 +749,17 @@ parse_args goto error; } + if(args->mode & (MODE_BIN_GREEN | MODE_GREEN) + && o_used && args->picard_order > 1) + { + logger_print(args->logger, LOG_ERROR, + "Option -%c cannot be used if Picard order is not 1 (here order is %u)\n", + mode_option(args->mode & (MODE_BIN_GREEN | MODE_GREEN)), + args->picard_order); + res = RES_BAD_ARG; + goto error; + } + if(args->mode & MODE_IR_COMPUTE && n_used) { logger_print(args->logger, LOG_ERROR, "The -n option has no effect in rendering mode;" diff --git a/src/stardis-args.h b/src/stardis-args.h @@ -96,11 +96,12 @@ struct args { char* rndgen_state_in_filename; char* rndgen_state_out_filename; char* chunks_prefix; + char* camera; size_t samples; - unsigned nthreads; double pos_and_time[5]; + unsigned nthreads; + unsigned picard_order; enum stardis_mode mode; - char* camera; enum dump_path_type dump_paths; int verbose; }; diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -469,6 +469,7 @@ compute_probe(struct stardis* stardis, struct time* start) } } else { args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; time_current(&compute_start); ERR(sdis_solve_probe(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); @@ -703,6 +704,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start) } } else { args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; time_current(&compute_start); ERR(sdis_solve_probe_boundary(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); @@ -851,6 +853,7 @@ compute_camera(struct stardis* stardis, struct time* start) args.image_resolution[1] = height; args.spp = (size_t)stardis->camera.spp; args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; /* Launch the simulation */ time_current(&compute_start); @@ -963,6 +966,7 @@ compute_medium(struct stardis* stardis, struct time* start) } } else { args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; time_current(&compute_start); ERR(sdis_solve_medium(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); @@ -1094,6 +1098,7 @@ compute_boundary(struct stardis* stardis, struct time* start) } } else { args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; time_current(&compute_start); ERR(sdis_solve_boundary(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); @@ -1138,6 +1143,7 @@ compute_flux_boundary(struct stardis* stardis, struct time* start) = darray_size_t_cdata_get(&stardis->compute_surface.primitives); args.nprimitives = darray_size_t_size_get(&stardis->compute_surface.primitives); + args.picard_order = stardis->picard_order; d2_set(args.time_range, stardis->time_range); /* Input random state? */ @@ -1199,6 +1205,7 @@ compute_map(struct stardis* stardis, struct time* start) = darray_size_t_size_get(&stardis->compute_surface.primitives); d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; + args.picard_order = stardis->picard_order; ERR(sdis_solve_boundary(stardis->sdis_scn, &args, darray_estimators_data_get(&estimators) + p)); diff --git a/src/stardis-default.h.in b/src/stardis-default.h.in @@ -20,6 +20,7 @@ #define STARDIS_DEFAULT_TRAD @STARDIS_ARGS_DEFAULT_TRAD@ #define STARDIS_DEFAULT_TRAD_REFERENCE @STARDIS_ARGS_DEFAULT_TRAD_REFERENCE@ #define STARDIS_DEFAULT_COMPUTE_TIME @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@ +#define STARDIS_DEFAULT_PICARD_ORDER @STARDIS_ARGS_DEFAULT_PICARD_ORDER@ #define STARDIS_DEFAULT_RENDERING_FOV @STARDIS_ARGS_DEFAULT_RENDERING_FOV@ #define STARDIS_DEFAULT_RENDERING_IMG_HEIGHT @STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT@ #define STARDIS_DEFAULT_RENDERING_IMG_WIDTH @STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH@ diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -523,6 +523,14 @@ process_flx logger_print(stardis->logger, LOG_ERROR, "Invalid flux: %s\n", tk); goto end; } + if(f_boundary->imposed_flux != 0 && stardis->picard_order > 1) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot have a flux defined at a boundary (here %f) if Picard order " + "is not 1 (here order is %u)\n", + f_boundary->imposed_flux, stardis->picard_order); + res = RES_BAD_ARG; + goto end; + } ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); @@ -859,6 +867,14 @@ process_solid logger_print(stardis->logger, LOG_ERROR, "Invalid volumic power: %s\n", tk); goto end; } + if(solid->vpower != 0 && stardis->picard_order > 1) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot have volumic power (here %f) if Picard order is not 1 " + "(here order is %u)\n", + solid->vpower, stardis->picard_order); + res = RES_BAD_ARG; + goto end; + } /* Actual solid creation is defered until geometry is read to allow * enclosure shape VS delta analysis (and auto delta computation) */