commit 59cbec3ab09527de64d846618a03cbdef2a5d5c6
parent dc631bf460ff0158dc2aacb09ca2a7dc833a5990
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 15 Oct 2021 12:44:35 +0200
Set the required version of StarSP to 0.12
Older versions do not compile with gcc 11. This commits handle API
breaks introduced by StarSP 0.12 and remove useless code in the green
function [de]serialization process that previously had to define an
unique enum from the RNG type.
Diffstat:
16 files changed, 282 insertions(+), 62 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -31,7 +31,7 @@ CMAKE_DEPENDENT_OPTION(ALL_TESTS
find_package(RCMake 0.4 REQUIRED)
find_package(Star2D 0.5 REQUIRED)
find_package(Star3D 0.8 REQUIRED)
-find_package(StarSP 0.8 REQUIRED)
+find_package(StarSP 0.12 REQUIRED)
find_package(StarEnc2D 0.5 REQUIRED)
find_package(StarEnc3D 0.5 REQUIRED)
find_package(RSys 0.12 REQUIRED)
diff --git a/src/sdis_device.c b/src/sdis_device.c
@@ -148,7 +148,7 @@ create_rng_from_rng_proxy
const struct ssp_rng_proxy* proxy,
struct ssp_rng** out_rng)
{
- struct ssp_rng_type rng_type;
+ enum ssp_rng_type rng_type;
struct ssp_rng* rng = NULL;
FILE* stream = NULL;
res_T res = RES_OK;
@@ -163,7 +163,7 @@ create_rng_from_rng_proxy
}
SSP(rng_proxy_get_type(proxy, &rng_type));
- res = ssp_rng_create(dev->allocator, &rng_type, &rng);
+ res = ssp_rng_create(dev->allocator, rng_type, &rng);
if(res != RES_OK) {
log_err(dev, "Could not create the RNG -- %s\n", res_to_cstr(res));
goto error;
diff --git a/src/sdis_green.c b/src/sdis_green.c
@@ -303,7 +303,7 @@ struct sdis_green_function {
struct accum realisation_time; /* Time per realisation */
- struct ssp_rng_type rng_type;
+ enum ssp_rng_type rng_type;
FILE* rng_state;
ref_T ref;
@@ -313,38 +313,6 @@ struct sdis_green_function {
/*******************************************************************************
* Helper functions
******************************************************************************/
-enum rng_type {
- RNG_KISS,
- RNG_MT_19937_64,
- RNG_RANLUX48,
- RNG_THREEFRY,
- RNG_UNKNOWN
-};
-
-static INLINE enum rng_type
-get_rng_type_enum(const struct ssp_rng_type* type)
-{
- ASSERT(type);
- if(ssp_rng_type_eq(type, &ssp_rng_kiss)) return RNG_KISS;
- if(ssp_rng_type_eq(type, &ssp_rng_mt19937_64)) return RNG_MT_19937_64;
- if(ssp_rng_type_eq(type, &ssp_rng_ranlux48)) return RNG_RANLUX48;
- if(ssp_rng_type_eq(type, &ssp_rng_threefry)) return RNG_THREEFRY;
- return RNG_UNKNOWN;
-}
-
-static INLINE void
-get_rng_type_ssp(const enum rng_type type, struct ssp_rng_type* ssp_type)
-{
- switch(type) {
- case RNG_KISS: *ssp_type = ssp_rng_kiss; break;
- case RNG_MT_19937_64: *ssp_type = ssp_rng_mt19937_64; break;
- case RNG_RANLUX48: *ssp_type = ssp_rng_ranlux48; break;
- case RNG_THREEFRY: *ssp_type = ssp_rng_threefry; break;
- case RNG_UNKNOWN: memset(ssp_type, 0, sizeof(*ssp_type)); break;
- default: FATAL("Unreachable code.\n"); break;
- }
-}
-
static res_T
ensure_medium_registration
(struct sdis_green_function* green,
@@ -894,7 +862,6 @@ res_T
sdis_green_function_write(struct sdis_green_function* green, FILE* stream)
{
struct ssp_rng* rng = NULL;
- enum rng_type rng_type = RNG_UNKNOWN;
hash256_T hash;
res_T res = RES_OK;
@@ -910,10 +877,9 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream)
} \
} (void)0
- rng_type = get_rng_type_enum(&green->rng_type);
- if(rng_type == RNG_UNKNOWN) {
+ if(green->rng_type == SSP_RNG_TYPE_NULL) {
log_err(green->scn->dev,
- "%s: could not function a green function with an unknown RNG type.\n",
+ "%s: could not write a green function with an unknown RNG type.\n",
FUNC_NAME);
res = RES_BAD_ARG;
goto error;
@@ -935,11 +901,11 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream)
WRITE(&green->npaths_valid, 1);
WRITE(&green->npaths_invalid, 1);
WRITE(&green->realisation_time, 1);
- WRITE(&rng_type, 1);
+ WRITE(&green->rng_type, 1);
#undef WRITE
/* Create a temporary RNG used to serialise the RNG state */
- res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng);
+ res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng);
if(res != RES_OK) goto error;
rewind(green->rng_state);
res = ssp_rng_read(rng, green->rng_state);
@@ -963,7 +929,6 @@ sdis_green_function_create_from_stream
hash256_T hash0, hash1;
struct sdis_green_function* green = NULL;
struct ssp_rng* rng = NULL;
- enum rng_type rng_type = RNG_UNKNOWN;
int version = 0;
res_T res = RES_OK;
@@ -1020,13 +985,11 @@ sdis_green_function_create_from_stream
READ(&green->npaths_valid, 1);
READ(&green->npaths_invalid, 1);
READ(&green->realisation_time, 1);
- READ(&rng_type, 1);
+ READ(&green->rng_type, 1);
#undef READ
- get_rng_type_ssp(rng_type, &green->rng_type);
-
/* Create a temporary RNG used to deserialise the RNG state */
- res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng);
+ res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng);
if(res != RES_OK) goto error;
res = ssp_rng_read(rng, stream);
if(res != RES_OK) goto error;
diff --git a/src/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h b/src/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h
@@ -0,0 +1,257 @@
+/* Copyright (C) 2016-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_green.h"
+#include "sdis_heat_path_boundary_c.h"
+#include "sdis_interface_c.h"
+#include "sdis_medium_c.h"
+#include "sdis_misc.h"
+#include "sdis_scene_c.h"
+
+#include <star/ssp.h>
+
+#include "sdis_Xd_begin.h"
+
+/*******************************************************************************
+ * Boundary path between a solid and a fluid
+ ******************************************************************************/
+res_T
+XD(solid_fluid_boundary_picard1_path)
+ (const struct sdis_scene* scn,
+ const struct rwalk_context* ctx,
+ const struct sdis_interface_fragment* frag,
+ struct XD(rwalk)* rwalk,
+ struct ssp_rng* rng,
+ struct XD(temperature)* T)
+{
+ struct sdis_interface* interf = NULL;
+ struct sdis_medium* mdm_front = NULL;
+ struct sdis_medium* mdm_back = NULL;
+ struct sdis_medium* solid = NULL;
+ struct sdis_medium* fluid = NULL;
+ struct XD(rwalk) rwalk_saved;
+ struct sXd(hit) hit = SXD_HIT_NULL;
+ struct sdis_interface_fragment frag_fluid;
+ double hc;
+ double hr;
+ double epsilon; /* Interface emissivity */
+ double lambda;
+ double fluid_proba;
+ double radia_proba;
+ double delta;
+ double delta_boundary;
+ double r;
+ double tmp;
+ float dir0[DIM], dir1[DIM];
+ float reinject_dst;
+ /* In 2D it is useless to try to resample a reinjection direction since there
+ * is only one possible direction */
+ const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10;
+ int iattempt;
+ int reinjection_is_valid = 0;
+ res_T res = RES_OK;
+ ASSERT(scn && rwalk && rng && T && ctx);
+ ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag));
+
+ /* Retrieve the solid and the fluid split by the boundary */
+ interf = scene_get_interface(scn, rwalk->hit.prim.prim_id);
+ mdm_front = interface_get_medium(interf, SDIS_FRONT);
+ mdm_back = interface_get_medium(interf, SDIS_BACK);
+ ASSERT(mdm_front->type != mdm_back->type);
+
+ /* Setup the fluid side fragment */
+ frag_fluid = *frag;
+ if(mdm_front->type == SDIS_SOLID) {
+ solid = mdm_front;
+ fluid = mdm_back;
+ frag_fluid.side = SDIS_BACK;
+ } else {
+ solid = mdm_back;
+ fluid = mdm_front;
+ frag_fluid.side = SDIS_FRONT;
+ }
+
+ /* Fetch the boundary properties */
+ epsilon = interface_side_get_emissivity(interf, &frag_fluid);
+ Tref = interface_side_get_reference_temperature(interf, &frag_fluid);
+
+ /* Fetch the solid properties */
+ lambda = solid_get_thermal_conductivity(solid, &rwalk->vtx);
+ delta = solid_get_delta(solid, &rwalk->vtx);
+
+ /* Note that the reinjection distance is *FIXED*. It MUST ensure that the
+ * orthogonal distance from the boundary to the point to chalenge is equal to
+ * delta. */
+ delta_boundary = sqrt(DIM) * delta;
+
+ rwalk_saved = *rwalk;
+ reinjection_is_valid = 0;
+ iattempt = 0;
+ do {
+ if(iattempt != 0) *rwalk = rwalk_saved;
+
+ /* Sample a reinjection direction */
+ XD(sample_reinjection_dir)(rwalk, rng, dir0);
+
+ /* Reflect the sampled direction around the normal */
+ XD(reflect)(dir1, dir0, rwalk->hit.normal);
+
+ if(solid == mdm_back) {
+ fX(minus)(dir0, dir0);
+ fX(minus)(dir1, dir1);
+ }
+
+ /* Select the solid reinjection direction and distance */
+ res = XD(select_reinjection_dir_and_check_validity)(scn, solid, rwalk,
+ dir0, dir1, delta_boundary, dir0, &reinject_dst, 1, NULL,
+ &reinjection_is_valid, &hit);
+ if(res != RES_OK) goto error;
+
+ } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS);
+
+ /* Could not find a valid reinjecton */
+ if(iattempt >= MAX_ATTEMPTS) {
+ *rwalk = rwalk_saved;
+ log_warn(scn->dev,
+ "%s: could not find a valid solid/fluid reinjection at {%g, %g %g}.\n",
+ FUNC_NAME, SPLIT3(rwalk->vtx.P));
+ res = RES_BAD_OP_IRRECOVERABLE;
+ goto error;
+ }
+
+ /* Define the orthogonal dst from the reinjection pos to the interface */
+ delta = reinject_dst / sqrt(DIM);
+
+ /* Compute the convective, conductive and the upper bound radiative coef */
+ h_conv = interface_get_convection_coef(interf, frag);
+ h_cond = lambda / (delta * scn->fp_to_meter);
+ h_rad_hat = 4.0 * BOLTZMANN_CONSTANT * ctx->That3 * epsilon;
+
+ /* Compute a global upper bound coefficient */
+ h_hat = h_conv + h_cond + h_rad_hat;
+
+ /* Compute the probas to switch in solid, fluid or radiative random walk */
+ p_conv = h_conv / h_hat;
+ p_cond = h_cond / h_hat;
+
+ /* Null collision */
+ for(;;) {
+ r = ssp_rng_canonical(rng);
+
+ /* Switch in convective path */
+ if(r < p_conv) {
+ T->func = XD(convective_path);
+ rwalk->mdm = fluid;
+ rwalk->hit_side = rwalk->mdm == mdm_front ? SDIS_FRONT : SDIS_BACK;
+ break;
+ }
+
+ /* Switch in conductive path */
+ if(r < p_conv + p_cond) {
+ /* Handle the volumic power */
+ const double power = solid_get_volumic_power(solid, &rwalk->vtx);
+ if(power != SDIS_VOLUMIC_POWER_NONE) {
+ const double delta_in_meter = reinject_dst * scn->fp_to_meter;
+ tmp = delta_in_meter * delta_in_meter / (2.0 * DIM * lambda);
+ T->value += power * tmp;
+
+ if(ctx->green_path) {
+ res = green_path_add_power_term(ctx->green_path, solid, &rwalk->vtx, tmp);
+ if(res != RES_OK) goto error;
+ }
+ }
+
+ /* Time rewind */
+ res = XD(time_rewind)(solid, rng, reinject_dst * scn->fp_to_meter, ctx, rwalk, T);
+ if(res != RES_OK) goto error;
+ if(T->done) goto exit; /* Limit condition was reached */
+
+ /* Perform solid reinjection */
+ XD(move_pos)(rwalk->vtx.P, dir0, reinject_dst);
+ if(hit.distance == reinject_dst) {
+ T->func = XD(boundary_path);
+ rwalk->mdm = NULL;
+ rwalk->hit = hit;
+ rwalk->hit_side = fX(dot)(hit.normal, dir0) < 0 ? SDIS_FRONT : SDIS_BACK;
+ } else {
+ T->func = XD(conductive_path);
+ rwalk->mdm = solid;
+ rwalk->hit = SXD_HIT_NULL;
+ rwalk->hit_side = SDIS_SIDE_NULL__;
+ }
+
+ /* Register the new vertex against the heat path */
+ res = register_heat_vertex
+ (ctx->heat_path, &rwalk->vtx, T->value, SDIS_HEAT_VERTEX_CONDUCTION);
+ if(res != RES_OK) goto error;
+ break;
+ }
+
+ /* From there, we know the path is either a radiative path or a
+ * null-collision */
+
+ /* Trace a candidate radiative path and get the Tref at its end.
+ * TODO handle the registration of the path geometry */
+ T_candidate = *T;
+ rwalk_candidate = *rwalk;
+ res = XD(radiative_path)(scn, ctx, &rwalk_candidate, rng, T_candidate);
+ if(res != RES_OK) goto error;
+
+ /* Get the Tref at the end of the candidate radiative path */
+ if(T_candidate->done) {
+ Tref_candidate = T_candidate->value;
+ } else {
+ ASSERT(!SXD_HIT_NONE(rwalk_candidate->hit));
+ XD(setup_interface_fragment)
+ (&frag_candidate, &rwalk_candidate->vtx, &rwalk_candidate->hit,
+ rwalk_candidate->hit_side);
+ interf_candidate = scene_get_interface
+ (scn, rwalk_candidate->hit.prim.prim_id);
+
+ Tref_candidate = interface_side_get_reference_temperature(interf, f&rag);
+ }
+
+ if(Tref_candidate < 0) {
+ log_err(scn->dev,
+ "%s: invalid reference temperature `%gK' at the position `%g %g %g'.\n",
+ FUNC_NAME, Tref_candidate, SPLIT3(rwalk_candidate->vtx.P));
+ res = RES_BAD_OP_IRRECOVERABLE;
+ goto error;
+ }
+
+ h_rad = BOLTZMANN_CONSTANT
+ * epsilon
+ * ( Tref*Tref*Tref
+ + Tref*Tref * Tref_candidate
+ + Tref* Tref_candidate*Tref_candidate
+ + Tref_candidate*Tref_candidate*Tref_candidate);
+
+ p_rad = h_rad / h_hat;
+ if(r < p_conv + p_cond + p_rad) { /* Radiative path */
+ *rwalk = *rwalk_candidate;
+ *T = *T_candidate;
+ break;
+ }
+
+ /* Null-collision, looping at the beginning */
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+#include "sdis_Xd_end.h"
diff --git a/src/sdis_solve.c b/src/sdis_solve.c
@@ -384,7 +384,7 @@ sdis_solve_camera
}
/* Create the proxy RNG */
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h
@@ -187,7 +187,7 @@ XD(solve_boundary)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
@@ -524,7 +524,7 @@ XD(solve_boundary_flux)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h
@@ -252,7 +252,7 @@ XD(solve_medium)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
@@ -520,7 +520,7 @@ XD(compute_power)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h
@@ -83,7 +83,7 @@ XD(solve_probe)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h
@@ -123,7 +123,7 @@ XD(solve_probe_boundary)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
@@ -427,7 +427,7 @@ XD(solve_probe_boundary_flux)
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
} else {
- res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64,
+ res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64,
scn->dev->nthreads, &rng_proxy);
if(res != RES_OK) goto error;
}
diff --git a/src/test_sdis_conducto_radiative.c b/src/test_sdis_conducto_radiative.c
@@ -407,7 +407,7 @@ main(int argc, char** argv)
/* Run the simulations */
p_intface
= (struct interfac*)sdis_data_get(sdis_interface_get_data(interfaces[4]));
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
FOR_EACH(isimul, 0, nsimuls) {
struct sdis_mc T = SDIS_MC_NULL;
struct sdis_mc time = SDIS_MC_NULL;
diff --git a/src/test_sdis_conducto_radiative_2d.c b/src/test_sdis_conducto_radiative_2d.c
@@ -394,7 +394,7 @@ main(int argc, char** argv)
Ts1 = T1 - tmp;
/* Run the simulations */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
FOR_EACH(isimul, 0, nsimuls) {
struct sdis_mc T = SDIS_MC_NULL;
struct sdis_mc time = SDIS_MC_NULL;
diff --git a/src/test_sdis_contact_resistance.c b/src/test_sdis_contact_resistance.c
@@ -425,7 +425,7 @@ main(int argc, char** argv)
OK(sdis_interface_ref_put(interf_R));
/* Solve */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
printf(">> Box scene\n");
solve(box_scn, interf_props, rng);
printf("\n>> Square scene\n");
diff --git a/src/test_sdis_contact_resistance_2.c b/src/test_sdis_contact_resistance_2.c
@@ -519,7 +519,7 @@ main(int argc, char** argv)
OK(sdis_interface_ref_put(interf_R));
/* Solve */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
printf(">> Box scene\n");
solve_probe(box_scn, interf_props, rng);
solve(box_scn, interf_props, rng);
diff --git a/src/test_sdis_flux.c b/src/test_sdis_flux.c
@@ -449,7 +449,7 @@ main(int argc, char** argv)
OK(sdis_interface_ref_put(interf_phi));
/* Solve */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
printf(">> Box scene\n");
solve(box_scn, rng, interf_props);
printf(">> Square Scene\n");
diff --git a/src/test_sdis_unstationary_atm.c b/src/test_sdis_unstationary_atm.c
@@ -858,7 +858,7 @@ main(int argc, char** argv)
OK(sdis_interface_ref_put(interf_TA));
/* Solve */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
printf(">> Box scene\n");
solve_tfluid(box_scn);
solve_tbound1(box_scn, rng);
diff --git a/src/test_sdis_volumic_power.c b/src/test_sdis_volumic_power.c
@@ -487,7 +487,7 @@ main(int argc, char** argv)
OK(sdis_interface_ref_put(interf_T0));
/* Solve */
- OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng));
+ OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng));
printf(">> Box scene\n");
solve(box_scn, rng, solid_props);
printf(">> Square scene\n");