stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit ae1c884e299b19c401830dc8c5c7512e5c08faab
parent 935b2e1aa58040448edd97b0bf0f2123e989561f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 14 Mar 2024 16:39:23 +0100

WoS algorithm now supports unsteady systems

We rely on the Star-WoS-Function library to sample the first-passage
time of a sphere or circle, depending on whether the configuration is 2D
or 3D, respectively.

Diffstat:
MMakefile | 2++
Mconfig.mk | 6++++++
Msrc/sdis_device.c | 36++++++++++++++++++++++++++++++++++++
Msrc/sdis_device_c.h | 4++++
Msrc/sdis_heat_path_conductive_wos_Xd.h | 87++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 132 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile @@ -90,6 +90,8 @@ libsdis.o: $(OBJ) echo "senc3d $(SENC3D_VERSION) not found" >&2; exit 1; fi @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SWF_VERSION) swf; then \ + echo "swf $(SWF_VERSION) not found" >&2; exit 1; fi @echo "config done" > $@ .SUFFIXES: .c .d .o diff --git a/config.mk b/config.mk @@ -63,6 +63,10 @@ SSP_VERSION = 0.14 SSP_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags star-sp) SSP_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs star-sp) +SWF_VERSION = 0.0 +SWF_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags swf) +SWF_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs swf) + # For tests only S3DUT_VERSION = 0.4 S3DUT_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags s3dut) @@ -75,6 +79,7 @@ DPDC_CFLAGS =\ $(SENC2D_CFLAGS)\ $(SENC3D_CFLAGS)\ $(SSP_CFLAGS)\ + $(SWF_CFLAGS)\ $($(DISTRIB_PARALLELISM)_CFLAGS)\ -fopenmp DPDC_LIBS =\ @@ -84,6 +89,7 @@ DPDC_LIBS =\ $(SENC2D_LIBS)\ $(SENC3D_LIBS)\ $(SSP_LIBS)\ + $(SWF_LIBS)\ $($(DISTRIB_PARALLELISM)_LIBS)\ -lm\ -fopenmp diff --git a/src/sdis_device.c b/src/sdis_device.c @@ -25,6 +25,7 @@ #include <star/s2d.h> #include <star/s3d.h> #include <star/ssp.h> +#include <star/swf.h> #include <omp.h> @@ -251,6 +252,37 @@ error: } static INLINE res_T +setup_starwf(struct sdis_device* dev) +{ + struct swf_H_tabulate_args H2d_args = SWF_H2D_TABULATE_ARGS_DEFAULT; + struct swf_H_tabulate_args H3d_args = SWF_H3D_TABULATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(dev); + + H2d_args.allocator = dev->allocator; + H3d_args.allocator = dev->allocator; + + res = swf_H2d_tabulate(&H2d_args, &dev->H_2d); + if(res != RES_OK) { + log_err(dev, "Unable to tabulate H2d function -- %s.\n", + res_to_cstr(res)); + goto error; + } + + res = swf_H3d_tabulate(&H3d_args, &dev->H_3d); + if(res != RES_OK) { + log_err(dev, "Unable to tabulate H3d function -- %s.\n", + res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static INLINE res_T setup_mpi(struct sdis_device* dev, const struct sdis_device_create_args* args) { ASSERT(dev && args); @@ -279,6 +311,8 @@ device_release(ref_T* ref) dev = CONTAINER_OF(ref, struct sdis_device, ref); if(dev->s2d_dev) S2D(device_ref_put(dev->s2d_dev)); if(dev->s3d_dev) S3D(device_ref_put(dev->s3d_dev)); + if(dev->H_2d) SWF(tabulation_ref_put(dev->H_2d)); + if(dev->H_3d) SWF(tabulation_ref_put(dev->H_3d)); if(dev->logger == &dev->logger__) logger_release(&dev->logger__); ASSERT(flist_name_is_empty(&dev->interfaces_names)); ASSERT(flist_name_is_empty(&dev->media_names)); @@ -342,6 +376,8 @@ sdis_device_create if(res != RES_OK) goto error; res = setup_star3d(dev); if(res != RES_OK) goto error; + res = setup_starwf(dev); + if(res != RES_OK) goto error; res = setup_mpi(dev, args); if(res != RES_OK) goto error; diff --git a/src/sdis_device_c.h b/src/sdis_device_c.h @@ -36,6 +36,7 @@ struct mutex; struct ssp_rng; struct ssp_rng_proxy; +struct swf_tabulation; struct name { FITEM; void* mem; }; #define FITEM_TYPE name @@ -64,6 +65,9 @@ struct sdis_device { struct s2d_device* s2d_dev; struct s3d_device* s3d_dev; + struct swf_tabulation* H_2d; + struct swf_tabulation* H_3d; + ref_T ref; }; diff --git a/src/sdis_heat_path_conductive_wos_Xd.h b/src/sdis_heat_path_conductive_wos_Xd.h @@ -13,10 +13,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "sdis_device_c.h" #include "sdis_heat_path_conductive_c.h" #include "sdis_medium_c.h" #include "sdis_scene_c.h" +#include <star/swf.h> + #include "sdis_Xd_begin.h" /******************************************************************************* @@ -49,6 +52,69 @@ error: goto exit; } +static res_T +XD(time_travel) + (struct sdis_scene* scn, + struct XD(rwalk)* rwalk, + struct ssp_rng* rng, + const double alpha, /* Diffusivity, i.e. lambda/(rho*cp) */ + const double t0, /* Initial time [s] */ + const double distance, /* Displacement. Must be multipled by fp_to_meter */ + struct XD(temperature)* T) +{ + double dst = 0; /* Distance [m] */ + double tau = 0; /* Time [s] */ + double x = 0; + double r = 0; + double temperature = 0; /* [k] */ + res_T res = RES_OK; + ASSERT(scn && rwalk && rng && alpha && T); + + /* No displacement => no time travel */ + if(distance == 0) goto exit; + + /* Sample x = tau*alpha/distance^2 */ + r = ssp_rng_canonical(rng); + x = swf_tabulation_inverse(XD(scn->dev->H), SWF_QUADRATIC, r); + + /* Retrieve the time to travel */ + dst = distance * scn->fp_to_meter; + tau = x / alpha * dst * dst; + + /* Increment the elapsed time */ + rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0); + + if(IS_INF(rwalk->vtx.time)) goto exit; /* Steady computation */ + + /* Let's take a trip back in time */ + rwalk->vtx.time -= MMAX(t0, rwalk->vtx.time - tau); + + /* Thepath does not reach the initial condition */ + if(rwalk->vtx.time > t0) goto exit; + + /* Fethc the initial temperature */ + temperature = medium_get_temperature(rwalk->mdm, &rwalk->vtx); + if(temperature < 0) { + log_err(scn->dev, + "%s:%s: the path reaches the initial condition but the " + "%s temperature remains unknown -- position=%g, %g, %g\n", + __FILE__, FUNC_NAME, + medium_type_to_string(sdis_medium_get_type(rwalk->mdm)), + SPLIT3(rwalk->vtx.P)); + res = RES_BAD_ARG; + goto error; + } + + /* Update the temperature */ + T->value += temperature; + T->done = 1; + +exit: + return res; +error: + goto exit; +} + #if DIM == 2 static INLINE enum sdis_side compute_hit_side_2d @@ -276,7 +342,8 @@ static res_T XD(sample_next_position) (struct sdis_scene* scn, struct XD(rwalk)* rwalk, - struct ssp_rng* rng) + struct ssp_rng* rng, + double* distance) /* Displacement distance */ { /* Intersection */ struct sXd(hit) hit = SXD_HIT_NULL; @@ -289,7 +356,7 @@ XD(sample_next_position) /* Miscellaneous */ res_T res = RES_OK; - ASSERT(rwalk && rng); + ASSERT(rwalk && rng && distance); /* Find the closest distance from the current position to the geometry */ wos_radius = (float)INF; @@ -374,6 +441,7 @@ XD(sample_next_position) } exit: + *distance = hit.distance; return res; error: goto exit; @@ -393,6 +461,7 @@ XD(conductive_path_wos) /* Properties */ struct solid_props props_ref = SOLID_PROPS_NULL; struct solid_props props = SOLID_PROPS_NULL; + double alpha = 0; /* diffusivity, i.e. lambda/(rho*cp) */ /* Miscellaneous */ size_t ndiffusion_steps = 0; /* For debug */ @@ -418,13 +487,25 @@ XD(conductive_path_wos) * with respect to the properties of the reinjected position. */ solid_get_properties(rwalk->mdm, &rwalk->vtx, &props_ref); + /* The algorithm assumes that lambda, rho and cp are constants. The + * diffusivity of the material (alpha) can therefore be calculated once */ + alpha = props_ref.lambda / (props_ref.rho * props_ref.cp); + /* Sample a diffusive path */ for(;;) { + double distance = 0; /* Find the next position of the conductive path */ - res = XD(sample_next_position)(scn, rwalk, rng); + res = XD(sample_next_position)(scn, rwalk, rng, &distance); + if(res != RES_OK) goto error; + + /* Going back in time */ + res = XD(time_travel)(scn, rwalk, rng, alpha, props_ref.t0, distance, T); if(res != RES_OK) goto error; + /* The path reaches the initial condition */ + if(T->done) break; + /* The path reaches a boundary */ if(!SXD_HIT_NONE(&rwalk->hit)) break;