stardis

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

commit aa5fb217a7a0ec260ca27699fafddcf35def0423
parent 4acde1d9c3798aa01d9acf822e7f4f0bc2996b5c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sat, 12 Sep 2020 14:08:56 +0200

Fix description/medium mismatch in green output

Diffstat:
Msrc/stardis-app.c | 308+++++++++++++++++++++----------------------------------------------------------
Msrc/stardis-app.h | 244++++++++++++++++++-------------------------------------------------------------
Msrc/stardis-fluid.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/stardis-fluid.h | 37+++++++++++++++++++++----------------
Msrc/stardis-intface.c | 4++--
Msrc/stardis-intface.h | 3++-
Msrc/stardis-output.c | 57+++++++++++++++++++++++++++------------------------------
Msrc/stardis-parsing.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/stardis-parsing.h | 10++++++++++
Msrc/stardis-solid.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/stardis-solid.h | 38++++++++++++++++++++------------------
11 files changed, 459 insertions(+), 575 deletions(-)

diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -49,7 +49,7 @@ read_model FILE* f = NULL; struct txtrdr* txtrdr = NULL; - ASSERT(model_files && stardis); + ASSERT(model_files && stardis && dummies); files = darray_str_cdata_get(model_files); FOR_EACH(i, 0, darray_str_size_get(model_files)) { const char* name = str_cget(files + i); @@ -99,208 +99,79 @@ geometry_get_interface } static res_T -create_holder +check_delta_and_create_solid (struct stardis* stardis, - struct dummies* dummies, - const unsigned idx, - const int is_green) + struct description* description) { res_T res = RES_OK; - struct description* description; struct senc3d_enclosure* enc = NULL; - - ASSERT(stardis && dummies - && idx < darray_descriptions_size_get(&stardis->descriptions)); - - description = darray_descriptions_data_get(&stardis->descriptions) + idx; - switch (description->type) { - case DESC_BOUND_H_FOR_SOLID: - stardis->counts.hbound_count++; - /* Create an external fluid with imposed temperature */ - ASSERT(description->d.h_boundary.mat_id != UINT_MAX); - ERR(create_stardis_fluid(stardis, NULL, 1, 1, is_green, 1, -1, - description->d.h_boundary.imposed_temperature, - description->d.h_boundary.mat_id)); - logger_print(stardis->logger, LOG_OUTPUT, - "External fluid: rho=1 cp=1 T=%g (it is medium %u)\n", - description->d.h_boundary.imposed_temperature, - description->d.h_boundary.mat_id); - break; - case DESC_BOUND_H_FOR_FLUID: - stardis->counts.hbound_count++; - ASSERT(dummies->dummy_solid_id != UINT_MAX); - if(dummies->dummy_solid) { - /* Reuse external dummy solid */ - description->d.h_boundary.mat_id = dummies->dummy_solid_id; - } else { - /* Create dummy solid */ - description->d.h_boundary.mat_id = dummies->dummy_solid_id; - ERR(create_stardis_solid(stardis, NULL, 1, 1, 1, 1, is_green, 1, -1, - -1, 0, description->d.h_boundary.mat_id)); - dummies->dummy_solid - = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_solid_id]; - logger_print(stardis->logger, LOG_OUTPUT, - "Dummy solid: lambda=1 rho=1 cp=1 (it is medium %u)\n", - dummies->dummy_solid_id); - } - break; - case DESC_BOUND_T_FOR_SOLID: - stardis->counts.tbound_count++; - ASSERT(dummies->dummy_fluid_id != UINT_MAX); - if(dummies->dummy_fluid) { - /* Reuse external dummy fluid */ - description->d.t_boundary.mat_id = dummies->dummy_fluid_id; - } else { - /* Create dummy fluid */ - description->d.t_boundary.mat_id = dummies->dummy_fluid_id; - ERR(create_stardis_fluid(stardis, NULL, 1, 1, is_green, 1, -1, - -1, description->d.t_boundary.mat_id)); - dummies->dummy_fluid - = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_fluid_id]; - logger_print(stardis->logger, LOG_OUTPUT, - "Dummy fluid: rho=1 cp=1 (it is medium %u)\n", - dummies->dummy_fluid_id); - } - break; - case DESC_BOUND_T_FOR_FLUID: - stardis->counts.tbound_count++; - ASSERT(dummies->dummy_solid_id != UINT_MAX); - if(dummies->dummy_solid) { - /* Reuse external dummy solid */ - description->d.t_boundary.mat_id = dummies->dummy_solid_id; - } else { - /* Create dummy solid */ - description->d.t_boundary.mat_id = dummies->dummy_solid_id; - ERR(create_stardis_solid(stardis, NULL, 1, 1, 1, 1, is_green, 1, -1, - -1, 0, description->d.t_boundary.mat_id)); - dummies->dummy_solid - = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_solid_id]; - logger_print(stardis->logger, LOG_OUTPUT, - "Dummy solid: lambda=1 rho=1 cp=1 (it is medium %u)\n", - dummies->dummy_solid_id); - } - break; - case DESC_BOUND_F_FOR_SOLID: - stardis->counts.fbound_count++; - ASSERT(dummies->dummy_fluid_id != UINT_MAX); - if(dummies->dummy_fluid) { - /* Reuse external dummy fluid */ - description->d.f_boundary.mat_id = dummies->dummy_fluid_id; - } else { - /* Create dummy fluid */ - description->d.f_boundary.mat_id = dummies->dummy_fluid_id; - ERR(create_stardis_fluid(stardis, NULL, 1, 1, is_green, 1, -1, -1, - description->d.f_boundary.mat_id)); - dummies->dummy_fluid - = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_fluid_id]; - logger_print(stardis->logger, LOG_OUTPUT, - "Dummy fluid: rho=1 cp=1 (it is medium %u)\n", dummies->dummy_fluid_id); + double ratio, delta_range[2] = { DBL_MAX, -DBL_MAX }; + const double acceptance_ratio = 3; + struct senc3d_enclosure_header header; + + ASSERT(stardis && description && description->type == DESC_MAT_SOLID); + + /* Create solid to have ID informed */ + /* Check if delta can fit possible multiple enclosures */ + if(stardis->senc3d_scn) { + /* Due to previous errors, senc3d_scn can be unavailable */ + unsigned e, ecount = 0; + const unsigned desc_id = description->d.solid.desc_id; + + /* The enclosures where created using description ids */ + ERR(senc3d_scene_get_enclosure_count_by_medium(stardis->senc3d_scn, + desc_id, &ecount)); + CHK(ecount != 0); /* This solid cannot be unused */ + /* Can be unused if conflicts; in this case, avoid delta warnings */ + int external = 0; + FOR_EACH(e, 0, ecount) { + ERR(senc3d_scene_get_enclosure_by_medium(stardis->senc3d_scn, desc_id, + e, &enc)); + ERR(senc3d_enclosure_get_header(enc, &header)); + if(header.is_infinite) { + /* External solid, volume is negative and no delta walk expected */ + external = 1; + } else { + double d = header.volume / (header.area * 6); + ASSERT(d >= 0); + delta_range[0] = MMIN(delta_range[0], d); + delta_range[1] = MMAX(delta_range[1], d); + } + ERR(senc3d_enclosure_ref_put(enc)); + enc = NULL; } - break; - case DESC_SOLID_FLUID_CONNECT: - stardis->counts.sfconnect_count++; - ASSERT(description->d.sf_connect.connection_id != UINT_MAX); - ASSERT(description->d.sf_connect.specular_fraction >= 0 - && description->d.sf_connect.specular_fraction <= 1); - ASSERT(description->d.sf_connect.emissivity >= 0); - ASSERT(description->d.sf_connect.hc >= 0); - break; - case DESC_MAT_SOLID: { - double ratio, delta_range[2] = { DBL_MAX, -DBL_MAX }; - const double acceptance_ratio = 3; - struct senc3d_enclosure_header header; - /* Create solid to have ID informed */ - stardis->counts.smed_count++; - ASSERT(description->d.solid.solid_id != UINT_MAX); - /* Check if delta can fit possible multiple enclosures */ - if(stardis->senc3d_scn) { - /* Due to previous errors, senc3d_scn can be unavailable */ - unsigned e, ecount = 0; - - /* At this stage we use a geometry that was created using description ids - * as media ids. As a consequence we thereafter use description ids in - * APIs calls requiring a medium id */ - ERR(senc3d_scene_get_enclosure_count_by_medium(stardis->senc3d_scn, idx, - &ecount)); - if(ecount != 0) { - /* Can be unused if conflicts; in this case, avoid delta warnings */ - int external = 0; - FOR_EACH(e, 0, ecount) { - ERR(senc3d_scene_get_enclosure_by_medium(stardis->senc3d_scn, idx, e, - &enc)); - ERR(senc3d_enclosure_get_header(enc, &header)); - if(header.is_infinite) { - /* External solid, volume is negative and no delta walk expected */ - external = 1; - } else { - double d = header.volume / (header.area * 6); - ASSERT(d >= 0); - delta_range[0] = MMIN(delta_range[0], d); - delta_range[1] = MMAX(delta_range[1], d); - } - ERR(senc3d_enclosure_ref_put(enc)); - enc = NULL; - } - if(ecount > 1 || !external) { - ASSERT(0 < delta_range[0] && delta_range[0] <= delta_range[1]); - ratio = delta_range[1] / delta_range[0]; - if(ratio > acceptance_ratio) - logger_print(stardis->logger, LOG_WARNING, - "Solid %s is used in %u different enclosures that have different " - "delta requirements.\n", - str_cget(&description->d.solid.name), ecount); - /* Delta needs to be substituted with actual value */ - if(description->d.solid.delta == DELTA_AUTO) { - description->d.solid.delta = delta_range[0]; - logger_print(stardis->logger, LOG_OUTPUT, - "Auto delta for solid %s set to %g\n", - str_cget(&description->d.solid.name), description->d.solid.delta); - } else { - int too_small - = (delta_range[0] > description->d.solid.delta * acceptance_ratio); - int too_big - = (delta_range[0] * acceptance_ratio < description->d.solid.delta); - /* Check if user delta is OK */ - if(too_small || too_big) - logger_print(stardis->logger, LOG_WARNING, - "User delta for solid %s seems too %s: %g; " - "auto delta would have set it to %g.\n", - str_cget(&description->d.solid.name), (too_big ? "big" : "small"), - description->d.solid.delta, delta_range[0]); - } + if(ecount > 1 || !external) { + ASSERT(0 < delta_range[0] && delta_range[0] <= delta_range[1]); + ratio = delta_range[1] / delta_range[0]; + if(ratio > acceptance_ratio) + logger_print(stardis->logger, LOG_WARNING, + "Solid %s is used in %u different enclosures that have different " + "delta requirements.\n", + str_cget(&description->d.solid.name), ecount); + /* Delta needs to be substituted with actual value */ + if(description->d.solid.delta == DELTA_AUTO) { + description->d.solid.delta = delta_range[0]; + logger_print(stardis->logger, LOG_OUTPUT, + "Auto delta for solid %s set to %g\n", + str_cget(&description->d.solid.name), description->d.solid.delta); + } else { + int too_small + = (delta_range[0] > description->d.solid.delta * acceptance_ratio); + int too_big + = (delta_range[0] * acceptance_ratio < description->d.solid.delta); + /* Check if user delta is OK */ + if(too_small || too_big) { + logger_print(stardis->logger, LOG_WARNING, + "User delta for solid %s seems too %s: %g; " + "auto delta would have set it to %g.\n", + str_cget(&description->d.solid.name), (too_big ? "big" : "small"), + description->d.solid.delta, delta_range[0]); } } } - ERR(create_stardis_solid(stardis, - &description->d.solid.name, - description->d.solid.lambda, - description->d.solid.rho, - description->d.solid.cp, - description->d.solid.delta, - is_green, - 0, - description->d.solid.tinit, - description->d.solid.imposed_temperature, - description->d.solid.vpower, - description->d.solid.solid_id)); - break; - } - case DESC_MAT_FLUID: - stardis->counts.fmed_count++; - ASSERT(description->d.fluid.fluid_id != UINT_MAX); - ERR(create_stardis_fluid(stardis, - &description->d.fluid.name, - description->d.fluid.rho, - description->d.fluid.cp, - is_green, - 0, - description->d.fluid.tinit, - description->d.fluid.imposed_temperature, - description->d.fluid.fluid_id)); - break; - default: - FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); + } + ERR(create_solver_solid(stardis, &description->d.solid)); end: if(enc) SENC3D(enclosure_ref_put(enc)); @@ -372,6 +243,9 @@ stardis_init is_for_compute = (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_VTK); + ERR(sdis_device_create(stardis->logger, stardis->allocator, stardis->nthreads, + args->verbose, &stardis->dev)); + ERR(init_geometry(stardis->logger, stardis->allocator, stardis->verbose, &stardis->geometry)); @@ -389,9 +263,6 @@ stardis_init } ERR(read_model(&args->model_files, stardis, &dummies)); - ERR(sdis_device_create(stardis->logger, stardis->allocator, stardis->nthreads, - args->verbose, &stardis->dev)); - create_context.geometry = stardis->geometry.sg3d; create_context.app_interface_getter = geometry_get_interface; create_context.app_interface_data = &stardis->geometry.interf_bytrg; @@ -452,16 +323,18 @@ stardis_init } } - /* Create media and property holders for those found in descriptions */ + /* Create solids and log model information */ for(i = 0; i < darray_descriptions_size_get(&stardis->descriptions); i++) { - tmp_res = create_holder(stardis, &dummies, i, - stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)); - if(tmp_res != RES_OK && is_for_compute) { - res = tmp_res; - goto error; + struct description* desc = + darray_descriptions_data_get(&stardis->descriptions) + i; + if(desc->type == DESC_MAT_SOLID) { + tmp_res = check_delta_and_create_solid(stardis, desc); + if(tmp_res != RES_OK && is_for_compute) { + res = tmp_res; + goto error; + } } - ERR(str_print_description(&str, i, - darray_descriptions_cdata_get(&stardis->descriptions) + i)); + ERR(str_print_description(&str, i, desc)); logger_print(stardis->logger, LOG_OUTPUT, "%s\n", str_cget(&str)); } @@ -553,8 +426,8 @@ init_enclosures ERR(sg3d_geometry_get_unique_vertices_count(stardis->geometry.sg3d, &vsz)); ERR(senc3d_device_create(stardis->logger, stardis->allocator, stardis->nthreads, stardis->verbose, &senc_dev)); - allocate_stardis_medium_id(stardis, - &stardis->undefined_medium_behind_boundary_id); + stardis->undefined_medium_behind_boundary_id + = allocate_stardis_medium_id(stardis); ERR(senc3d_scene_create(senc_dev, SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE, tsz, sg3d_sencXd_geometry_get_indices, sg3d_sencXd_geometry_get_media, @@ -717,25 +590,4 @@ end: return res; } -res_T -str_append_printf - (struct str* accum, const char* fmt, ...) -{ - struct str tmp; - va_list ap; - res_T res = RES_OK; - ASSERT(accum && fmt); - str_init(accum->allocator, &tmp); - va_start(ap, fmt); - ERR(str_printf(&tmp, fmt, ap)); - va_end(ap); - ERR(str_append(accum, str_cget(&tmp))); - -end: - str_release(&tmp); - return res; -error: - goto end; -} - #undef COUNT_SIDE diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -18,6 +18,8 @@ #include "stardis-parsing.h" #include "stardis-default.h" +#include "stardis-solid.h" +#include "stardis-fluid.h" #include <star/sstl.h> #include <star/sg3d.h> @@ -42,6 +44,16 @@ struct sdis_medium; /* Utility macros */ #define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0 +#define STR_APPEND_PRINTF(accum, fmt, ...) \ +{ \ + struct str tmp; \ + str_init((accum)->allocator, &tmp); \ + res = str_printf(&tmp, (fmt), ##__VA_ARGS__);\ + if(res == RES_OK) res = str_append((accum), str_cget(&tmp)); \ + str_release(&tmp); \ + if(res != RES_OK) goto error; \ +} (void)0 + #define DELTA_AUTO INF /* Placeholder until actual value is substituted */ #define UNKNOWN_MEDIUM_TEMPERATURE -1 /* Unknown for stadis solver is -1 */ @@ -172,165 +184,26 @@ error: goto exit; } -extern LOCAL_SYM res_T -str_append_printf -(struct str* accum, const char* fmt, ...); - /******************************************************************************/ -struct mat_fluid { - struct str name; - unsigned fluid_id; - double rho; - double cp; - double tinit; - double imposed_temperature; -}; - -static FINLINE res_T -init_fluid(struct mem_allocator* allocator, struct mat_fluid* dst) -{ - str_init(allocator, &dst->name); - dst->fluid_id = UINT_MAX; - dst->rho = 0; - dst->cp = 0; - dst->tinit = 0; - dst->imposed_temperature = -1; - return RES_OK; -} - -static FINLINE void -release_fluid(struct mat_fluid* fluid) -{ - str_release(&fluid->name); -} - -static res_T -str_print_fluid - (struct str* str, - const struct mat_fluid* f) -{ - res_T res = RES_OK; - ASSERT(str && f); - ERR(str_append_printf(str, "Fluid '%s': rho=%g cp=%g", - str_cget(&f->name), f->rho, f->cp)); - if(f->tinit >= 0) { - ERR(str_append_printf(str, " Tinit=%g", f->tinit)); - } - if(f->imposed_temperature >= 0) { - ERR(str_append_printf(str, " Temp=%g", f->imposed_temperature)); - } - ERR(str_append_printf(str, " (it is medium %u)", f->fluid_id)); -end: - return res; -error: - goto end; -} - -static FINLINE res_T -cp_fluid(struct mat_fluid* dst, const struct mat_fluid* src) -{ - str_copy(&dst->name, &src->name); - dst->fluid_id = src->fluid_id; - dst->rho = src->rho; - dst->cp = src->cp; - dst->tinit = src->tinit; - dst->imposed_temperature = src->imposed_temperature; - return RES_OK; -} - -struct mat_solid { - struct str name; - unsigned solid_id; - double lambda; - double rho; - double cp; - double delta; - double tinit; - double imposed_temperature; - double vpower; -}; - -static FINLINE res_T -init_solid(struct mem_allocator* allocator, struct mat_solid* dst) -{ - str_init(allocator, &dst->name); - dst->solid_id = UINT_MAX; - dst->lambda = 0; - dst->rho = 0; - dst->cp = 0; - dst->delta = 0; - dst->tinit = -1; - dst->imposed_temperature = -1; - dst->vpower = 0; - return RES_OK; -} - -static FINLINE void -release_solid(struct mat_solid* solid) -{ - str_release(&solid->name); -} - -static res_T -str_print_solid - (struct str* str, - const struct mat_solid* s) -{ - res_T res = RES_OK; - ASSERT(str && s); - ERR(str_append_printf(str, "Solid '%s': lambda=%g rho=%g cp=%g delta=%g", - str_cget(&s->name), s->lambda, s->rho, s->cp, s->delta)); - if(s->vpower != 0) { - ERR(str_append_printf(str, " VPower=%g", s->vpower)); - } - if(s->tinit >= 0) { - ERR(str_append_printf(str, " Tinit=%g", s->tinit)); - } - if(s->imposed_temperature >= 0) { - ERR(str_append_printf(str, " Temp=%g", s->imposed_temperature)); - } - ERR(str_append_printf(str, " (it is medium %u)", s->solid_id)); -end: - return res; -error: - goto end; -} - -static FINLINE res_T -cp_solid(struct mat_solid* dst, const struct mat_solid* src) -{ - str_copy(&dst->name, &src->name); - dst->solid_id = src->solid_id; - dst->lambda = src->lambda; - dst->rho = src->rho; - dst->cp = src->cp; - dst->delta = src->delta; - dst->tinit = src->tinit; - dst->imposed_temperature = src->imposed_temperature; - dst->vpower = src->vpower; - return RES_OK; -} - struct h_boundary { struct str name; - unsigned mat_id; double emissivity; double specular_fraction; double hc; double imposed_temperature; + unsigned mat_id; }; -static FINLINE res_T +static FINLINE void init_h(struct mem_allocator* allocator, struct h_boundary* dst) { str_init(allocator, &dst->name); - dst->mat_id = UINT_MAX; dst->emissivity = 0; dst->specular_fraction = 0; dst->hc = 0; dst->imposed_temperature = -1; - return RES_OK; + dst->mat_id = UINT_MAX; } static FINLINE void @@ -347,11 +220,11 @@ str_print_h_boundary { res_T res = RES_OK; ASSERT(str && b && DESC_IS_H(type)); - ERR(str_append_printf(str, + STR_APPEND_PRINTF(str, "H boundary for %s '%s': emissivity=%g specular_fraction=%g hc=%g T=%g " "(using medium %u as external medium)", (type == DESC_BOUND_H_FOR_SOLID ? "solid" : "fluid"), str_cget(&b->name), - b->emissivity, b->specular_fraction, b->hc, b->imposed_temperature, b->mat_id)); + b->emissivity, b->specular_fraction, b->hc, b->imposed_temperature, b->mat_id); end: return res; error: @@ -361,34 +234,32 @@ error: static FINLINE res_T cp_h_boundary(struct h_boundary* dst, const struct h_boundary* src) { - str_copy(&dst->name, &src->name); - dst->mat_id = src->mat_id; dst->specular_fraction = src->specular_fraction; dst->imposed_temperature = src->imposed_temperature; dst->emissivity = src->emissivity; dst->hc = src->hc; - return RES_OK; + dst->mat_id = src->mat_id; + return str_copy(&dst->name, &src->name); } struct t_boundary { struct str name; - unsigned mat_id; double emissivity; double specular_fraction; double hc; double imposed_temperature; + unsigned mat_id; }; -static FINLINE res_T +static FINLINE void init_t(struct mem_allocator* allocator, struct t_boundary* dst) { str_init(allocator, &dst->name); - dst->mat_id = UINT_MAX; dst->emissivity = 0; dst->specular_fraction = 0; dst->hc = 0; dst->imposed_temperature = -1; - return RES_OK; + dst->mat_id = UINT_MAX; } static FINLINE void @@ -405,15 +276,15 @@ str_print_t_boundary { res_T res = RES_OK; ASSERT(str && b && DESC_IS_T(type)); - ERR(str_append_printf(str, "T boundary for %s' %s': T=%g ", + STR_APPEND_PRINTF(str, "T boundary for %s' %s': T=%g ", (type == DESC_BOUND_T_FOR_SOLID ? "solid" : "fluid"), - str_cget(&b->name), b->imposed_temperature)); + str_cget(&b->name), b->imposed_temperature); if(type == DESC_BOUND_T_FOR_FLUID) { - ERR(str_append_printf(str, "emissivity=%g, specular_fraction=%g hc=%g ", - b->emissivity, b->specular_fraction, b->hc)); + STR_APPEND_PRINTF(str, "emissivity=%g, specular_fraction=%g hc=%g ", + b->emissivity, b->specular_fraction, b->hc); } - ERR(str_append_printf(str, "(using medium %u as external medium)", b->mat_id)); + STR_APPEND_PRINTF(str, "(using medium %u as external medium)", b->mat_id); end: return res; error: @@ -423,28 +294,26 @@ error: static FINLINE res_T cp_t_boundary(struct t_boundary* dst, const struct t_boundary* src) { - str_copy(&dst->name, &src->name); - dst->mat_id = src->mat_id; dst->emissivity = src->emissivity; dst->specular_fraction = src->specular_fraction; dst->hc = src->hc; dst->imposed_temperature = src->imposed_temperature; - return RES_OK; + dst->mat_id = src->mat_id; + return str_copy(&dst->name, &src->name); } struct f_boundary { struct str name; - unsigned mat_id; double imposed_flux; + unsigned mat_id; }; -static FINLINE res_T +static FINLINE void init_f(struct mem_allocator* allocator, struct f_boundary* dst) { str_init(allocator, &dst->name); dst->mat_id = UINT_MAX; dst->imposed_flux = -1; - return RES_OK; } static FINLINE void @@ -460,9 +329,9 @@ str_print_f_boundary { res_T res = RES_OK; ASSERT(str && b); - ERR(str_append_printf(str, + STR_APPEND_PRINTF(str, "F boundary for SOLID '%s': flux=%g (using medium %u as external medium)", - str_cget(&b->name), b->imposed_flux, b->mat_id)); + str_cget(&b->name), b->imposed_flux, b->mat_id); end: return res; error: @@ -472,18 +341,17 @@ error: static FINLINE res_T cp_f_boundary(struct f_boundary* dst, const struct f_boundary* src) { - str_copy(&dst->name, &src->name); - dst->mat_id = src->mat_id; dst->imposed_flux = src->imposed_flux; - return RES_OK; + dst->mat_id = src->mat_id; + return str_copy(&dst->name, &src->name); } struct solid_fluid_connect { struct str name; - unsigned connection_id; double emissivity; double specular_fraction; double hc; + unsigned connection_id; }; static FINLINE void @@ -492,15 +360,14 @@ release_sf_connect(struct solid_fluid_connect* connect) str_release(&connect->name); } -static FINLINE res_T +static FINLINE void init_sf(struct mem_allocator* allocator, struct solid_fluid_connect* dst) { str_init(allocator, &dst->name); - dst->connection_id = UINT_MAX; dst->emissivity = 0; dst->specular_fraction = 0; dst->hc = 0; - return RES_OK; + dst->connection_id = UINT_MAX; } static res_T @@ -510,9 +377,9 @@ str_print_sf_connect { res_T res = RES_OK; ASSERT(str && c); - ERR(str_append_printf(str, "Solid-Fluid connection '%s':", str_cget(&c->name))); - ERR(str_append_printf(str, " emissivity=%g, specular_fraction=%g hc=%g", - c->emissivity, c->specular_fraction, c->hc)); + STR_APPEND_PRINTF(str, "Solid-Fluid connection '%s':", str_cget(&c->name)); + STR_APPEND_PRINTF(str, " emissivity=%g, specular_fraction=%g hc=%g", + c->emissivity, c->specular_fraction, c->hc); end: return res; error: @@ -523,12 +390,11 @@ static FINLINE res_T cp_sf_connect (struct solid_fluid_connect* dst, const struct solid_fluid_connect* src) { - str_copy(&dst->name, &src->name); dst->connection_id = src->connection_id; dst->specular_fraction = src->specular_fraction; dst->emissivity = src->emissivity; dst->hc = src->hc; - return RES_OK; + return str_copy(&dst->name, &src->name); } static FINLINE res_T @@ -541,8 +407,8 @@ cp_release_sf_connect struct description { enum description_type type; union { - struct mat_fluid fluid; - struct mat_solid solid; + struct fluid fluid; + struct solid solid; struct t_boundary t_boundary; struct f_boundary f_boundary; struct h_boundary h_boundary; @@ -664,14 +530,14 @@ cp_description case DESC_MAT_SOLID: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_solid(src->d.solid.name.allocator, &dst->d.solid)); + init_solid(src->d.solid.name.allocator, &dst->d.solid); } ERR(cp_solid(&dst->d.solid, &src->d.solid)); break; case DESC_MAT_FLUID: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_fluid(src->d.fluid.name.allocator, &dst->d.fluid)); + init_fluid(src->d.fluid.name.allocator, &dst->d.fluid); } ERR(cp_fluid(&dst->d.fluid, &src->d.fluid)); break; @@ -679,7 +545,7 @@ cp_description case DESC_BOUND_H_FOR_FLUID: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_h(src->d.h_boundary.name.allocator, &dst->d.h_boundary)); + init_h(src->d.h_boundary.name.allocator, &dst->d.h_boundary); } ERR(cp_h_boundary(&dst->d.h_boundary, &src->d.h_boundary)); break; @@ -687,21 +553,21 @@ cp_description case DESC_BOUND_T_FOR_FLUID: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_t(src->d.t_boundary.name.allocator, &dst->d.t_boundary)); + init_t(src->d.t_boundary.name.allocator, &dst->d.t_boundary); } ERR(cp_t_boundary(&dst->d.t_boundary, &src->d.t_boundary)); break; case DESC_BOUND_F_FOR_SOLID: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_f(src->d.f_boundary.name.allocator, &dst->d.f_boundary)); + init_f(src->d.f_boundary.name.allocator, &dst->d.f_boundary); } ERR(cp_f_boundary(&dst->d.f_boundary, &src->d.f_boundary)); break; case DESC_SOLID_FLUID_CONNECT: if(dst->type == DESCRIPTION_TYPE_COUNT__) { dst->type = src->type; - ERR(init_sf(src->d.sf_connect.name.allocator, &dst->d.sf_connect)); + init_sf(src->d.sf_connect.name.allocator, &dst->d.sf_connect); } ERR(cp_sf_connect(&dst->d.sf_connect, &src->d.sf_connect)); break; @@ -863,13 +729,11 @@ struct stardis { int verbose; }; -static INLINE void -allocate_stardis_medium_id - (struct stardis* stardis, - unsigned* id) +static INLINE unsigned +allocate_stardis_medium_id(struct stardis* stardis) { - ASSERT(stardis && id); - *id = stardis->next_medium_id++; + ASSERT(stardis); + return stardis->next_medium_id++; } extern LOCAL_SYM res_T diff --git a/src/stardis-fluid.c b/src/stardis-fluid.c @@ -74,44 +74,31 @@ fluid_get_temperature ******************************************************************************/ res_T -create_stardis_fluid +create_solver_fluid (struct stardis* stardis, - const struct str* name, /* Can be NULL */ - const double rho, - const double cp, - const int is_green, - const int is_outside, - const double tinit, - const double imposed_temperature, - const unsigned id) + const struct fluid* fluid_props) { res_T res = RES_OK; struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL; struct sdis_data* data = NULL; - struct fluid* fluid_props; + struct fluid* props; - ASSERT(stardis && rho >= 0 && cp >= 0); + ASSERT(stardis && fluid_props); fluid_shader.calorific_capacity = fluid_get_calorific_capacity; fluid_shader.volumic_mass = fluid_get_volumic_mass; fluid_shader.temperature = fluid_get_temperature; ERR(sdis_data_create(stardis->dev, sizeof(struct fluid), ALIGNOF(struct fluid), NULL, &data)); - fluid_props = sdis_data_get(data); /* Fetch the allocated memory space */ - str_init(stardis->allocator, &fluid_props->name); - if(name) str_copy(&fluid_props->name, name); - fluid_props->t0 = 0; - fluid_props->cp = cp; - fluid_props->rho = rho; - fluid_props->tinit = tinit; - fluid_props->imposed_temperature = imposed_temperature; - fluid_props->is_green = is_green; - fluid_props->is_outside = is_outside; - fluid_props->id = id; - ASSERT(id >= darray_media_ptr_size_get(&stardis->media)); - ERR(darray_media_ptr_resize(&stardis->media, id + 1)); + props = sdis_data_get(data); /* Fetch the allocated memory space */ + init_fluid(stardis->allocator, props); + cp_fluid(props, fluid_props); + if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) { + ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1)); + } + ASSERT(darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id] == NULL); ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data, - darray_media_ptr_data_get(&stardis->media) + id)); + darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id)); end: if(data) SDIS(data_ref_put(data)); @@ -119,3 +106,59 @@ end: error: goto end; } + +void +init_fluid(struct mem_allocator* allocator, struct fluid* dst) +{ + str_init(allocator, &dst->name); + dst->rho = 1; + dst->cp = 1; + dst->tinit = -1; + dst->imposed_temperature = -1; + dst->t0 = 0; + dst->is_outside = 0; + dst->is_green = 0; + dst->desc_id = UINT_MAX; + dst->fluid_id = UINT_MAX; +} + +void +release_fluid(struct fluid* fluid) +{ + str_release(&fluid->name); +} + +res_T +str_print_fluid(struct str* str, const struct fluid* f) +{ + res_T res = RES_OK; + ASSERT(str && f); + STR_APPEND_PRINTF(str, "Fluid '%s': rho=%g cp=%g", + str_cget(&f->name), f->rho, f->cp); + if(f->tinit >= 0) { + STR_APPEND_PRINTF(str, " Tinit=%g", f->tinit); + } + if(f->imposed_temperature >= 0) { + STR_APPEND_PRINTF(str, " Temp=%g", f->imposed_temperature); + } + STR_APPEND_PRINTF(str, " (it is medium %u)", f->fluid_id); +end: + return res; +error: + goto end; +} + +res_T +cp_fluid(struct fluid* dst, const struct fluid* src) +{ + dst->rho = src->rho; + dst->cp = src->cp; + dst->tinit = src->tinit; + dst->imposed_temperature = src->imposed_temperature; + dst->t0 = src->t0; + dst->is_outside = src->is_outside; + dst->is_green = src->is_green; + dst->desc_id = src->desc_id; + dst->fluid_id = src->fluid_id; + return str_copy(&dst->name, &src->name); +} diff --git a/src/stardis-fluid.h b/src/stardis-fluid.h @@ -28,27 +28,32 @@ struct stardis; ******************************************************************************/ struct fluid { struct str name; - double cp; /* Calorific capacity */ double rho; /* Volumic mass */ - /* Compute mode */ - int is_green, is_outside; - double t0; /* End time of tinit */ + double cp; /* Calorific capacity */ double tinit; double imposed_temperature; - /* ID */ - unsigned id; + double t0; /* End time of tinit */ + int is_outside; /* the fluid is used for a boundary */ + int is_green; /* green computation (nothing to do with fluid itself) */ + unsigned desc_id; /* id of the boundary; meaningful if is_outside */ + unsigned fluid_id; }; -extern res_T -create_stardis_fluid +res_T +create_solver_fluid (struct stardis* stardis, - const struct str* name, - const double rho, - const double cp, - const int is_green, - const int is_outside, - const double tinit, - const double imposed_temperature, - const unsigned out_id); + const struct fluid* fluid_props); + +LOCAL_SYM void +init_fluid(struct mem_allocator* allocator, struct fluid* dst); + +LOCAL_SYM void +release_fluid(struct fluid* fluid); + +LOCAL_SYM res_T +str_print_fluid(struct str* str, const struct fluid* s); + +LOCAL_SYM res_T +cp_fluid(struct fluid* dst, const struct fluid* src); #endif diff --git a/src/stardis-intface.c b/src/stardis-intface.c @@ -133,7 +133,7 @@ create_intface interface_props->imposed_flux = SDIS_FLUX_NONE; interface_props->front_medium_id = UINT_MAX; interface_props->back_medium_id = UINT_MAX; - interface_props->connect_id = UINT_MAX; + interface_props->desc_id = UINT_MAX; if(front_defined) { switch (descriptions[fd].type) { @@ -201,7 +201,7 @@ create_intface fluid_side_shader = (descriptions[bd].type == DESC_MAT_FLUID) ? &interface_shader.back : &interface_shader.front; } - interface_props->connect_id = cd; + interface_props->desc_id = cd; switch(connect->type) { case DESC_BOUND_H_FOR_FLUID: if(sdis_medium_get_type(def_medium) != SDIS_FLUID) { diff --git a/src/stardis-intface.h b/src/stardis-intface.h @@ -34,7 +34,8 @@ struct intface { double imposed_temperature; double imposed_flux; /* IDs */ - unsigned front_medium_id, back_medium_id, connect_id; + unsigned front_medium_id, back_medium_id; + unsigned desc_id; /* The description this interfaces comes from */ }; /* Declare the hash table that map an interface to its descriptor */ diff --git a/src/stardis-output.c b/src/stardis-output.c @@ -73,7 +73,7 @@ merge_flux_terms res_T res = RES_OK; struct sdis_data* data = NULL; struct intface* d__; - unsigned cid; + unsigned desc_id; struct w_ctx* w_ctx = ctx; const struct description* descs; @@ -82,10 +82,10 @@ merge_flux_terms data = sdis_interface_get_data(interf); d__ = sdis_data_get(data); - cid = d__->connect_id; + desc_id = d__->desc_id; descs = darray_descriptions_cdata_get(w_ctx->desc); - switch (descs[cid].type) { + switch (descs[desc_id].type) { case DESC_BOUND_T_FOR_SOLID: case DESC_BOUND_T_FOR_FLUID: case DESC_BOUND_H_FOR_SOLID: @@ -93,9 +93,9 @@ merge_flux_terms FATAL("Cannot have a flux term here.\n"); break; case DESC_BOUND_F_FOR_SOLID: { double* w; - w = htable_weigth_find(&w_ctx->flux, &cid); + w = htable_weigth_find(&w_ctx->flux, &desc_id); if(w) *w += flux_term; - else ERR(htable_weigth_set(&w_ctx->flux, &cid, &flux_term)); + else ERR(htable_weigth_set(&w_ctx->flux, &desc_id, &flux_term)); break; } default: FATAL("Unreachable code.\n"); break; @@ -130,7 +130,7 @@ merge_power_terms case SDIS_SOLID: { struct solid* d__ = sdis_data_get(data); double* w; - unsigned mid = d__->id; + unsigned mid = d__->solid_id; w = htable_weigth_find(&w_ctx->pw, &mid); if(w) *w += power_term; else ERR(htable_weigth_set(&w_ctx->pw, &mid, &power_term)); @@ -384,12 +384,12 @@ dump_sample switch (pt.type) { case SDIS_FRAGMENT: { struct intface* d__; - unsigned cid; + unsigned desc_id; data = sdis_interface_get_data(pt.data.itfrag.intface); d__ = sdis_data_get(data); - cid = d__->connect_id; - CHK(DESC_IS_T(descs[cid].type) || DESC_IS_H(descs[cid].type)); - header.id = cid; + desc_id = d__->desc_id; + CHK(DESC_IS_T(descs[desc_id].type) || DESC_IS_H(descs[desc_id].type)); + header.id = desc_id; break; } case SDIS_VERTEX: @@ -403,12 +403,12 @@ dump_sample } else if(type == SDIS_FLUID) { struct fluid* d__ = sdis_data_get(data); - header.id = d__->id; + header.id = d__->desc_id; } else { struct solid* d__ = sdis_data_get(data); ASSERT(type == SDIS_SOLID); ASSERT(!d__->is_outside); /* FIXME: what if in external solid? */ - header.id = d__->id; + header.id = d__->desc_id; } break; default: FATAL("Unreachable code.\n"); break; @@ -524,7 +524,7 @@ dump_green_bin pool_ptr += len + 1; } ASSERT(pool_ptr == name_pool + name_pool_sz); - /*Write Green string */ + /* Write Green string */ FW(green_string, sizeof(green_string)); /* Write counts */ @@ -573,7 +573,7 @@ print_sample struct sdis_data* data = NULL; enum sdis_medium_type type; struct htable_weigth_iterator it, end; - unsigned mid, cid; + unsigned desc_id; size_t pcount, fcount; struct w_ctx* w_ctx = ctx; const struct description* descs; @@ -595,18 +595,15 @@ print_sample struct intface* d__; data = sdis_interface_get_data(pt.data.itfrag.intface); d__ = sdis_data_get(data); - mid = (pt.data.itfrag.fragment.side == SDIS_FRONT) - ? d__->front_medium_id : d__->back_medium_id; - cid = d__->connect_id; - ASSERT(mid != UINT_MAX); - switch (descs[cid].type) { + desc_id = d__->desc_id; + switch (descs[desc_id].type) { case DESC_BOUND_T_FOR_SOLID: case DESC_BOUND_T_FOR_FLUID: - fprintf(w_ctx->stream, "T\t%u", cid); + fprintf(w_ctx->stream, "T\t%u", desc_id); break; case DESC_BOUND_H_FOR_SOLID: case DESC_BOUND_H_FOR_FLUID: - fprintf(w_ctx->stream, "H\t%u", cid); + fprintf(w_ctx->stream, "H\t%u", desc_id); break; case DESC_BOUND_F_FOR_SOLID: FATAL("Heat path cannot end at a flux boundary.\n"); break; @@ -626,19 +623,19 @@ print_sample } else if(type == SDIS_FLUID) { struct fluid* d__ = sdis_data_get(data); - mid = d__->id; + desc_id = d__->desc_id; if(d__->is_outside) /* If outside the model and in a fluid with known temperature, * its a fluid attached to a H boundary */ - fprintf(w_ctx->stream, "H\t%u", mid); + fprintf(w_ctx->stream, "H\t%u", desc_id); /* In a standard fluid with known temperature */ - else fprintf(w_ctx->stream, "F\t%u", mid); + else fprintf(w_ctx->stream, "F\t%u", desc_id); } else { struct solid* d__ = sdis_data_get(data); ASSERT(type == SDIS_SOLID); - mid = d__->id; ASSERT(!d__->is_outside); /* FIXME: what if in external solid? */ - fprintf(w_ctx->stream, "S\t%u", mid); + desc_id = d__->desc_id; + fprintf(w_ctx->stream, "S\t%u", desc_id); } break; default: FATAL("Unreachable code.\n"); break; @@ -718,10 +715,10 @@ dump_green_ascii /* List Media */ if(stardis->counts.smed_count) { fprintf(stream, "# Solids\n"); - fprintf(stream, "# ID Name lambda rho cp power\n"); + fprintf(stream, "# ID Name lambda rho cp power Temp\n"); FOR_EACH(i, 0, szd) { const struct description* desc = descs + i; - const struct mat_solid* sl; + const struct solid* sl; if(desc->type != DESC_MAT_SOLID) continue; sl = &desc->d.solid; fprintf(stream, "%u\t%s\t%g\t%g\t%g\t%g\n", @@ -730,10 +727,10 @@ dump_green_ascii } if(stardis->counts.fmed_count) { fprintf(stream, "# Fluids\n"); - fprintf(stream, "# ID Name rho cp\n"); + fprintf(stream, "# ID Name rho cp Temp\n"); FOR_EACH(i, 0, szd) { const struct description* desc = descs + i; - const struct mat_fluid* fl; + const struct fluid* fl; if(desc->type != DESC_MAT_FLUID) continue; fl = &desc->d.fluid; fprintf(stream, "%u\t%s\t%g\t%g\n", diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -281,7 +281,7 @@ read_sides_and_files logger_print(stardis->logger, LOG_WARNING, "File '%s' included %zu degenerated triangles (removed)\n", tk, c); ERR(str_printf(&str, "Degenerated triangles IDs: %u", ids[0])); - FOR_EACH(n, 1, c) ERR(str_append_printf(&str, ", %u", ids[n])); + FOR_EACH(n, 1, c) { STR_APPEND_PRINTF(&str, ", %u", ids[n]); } logger_print(stardis->logger, LOG_OUTPUT, "%s\n", str_cget(&str)); darray_uint_clear(&degenerated); } @@ -1051,22 +1051,13 @@ process_h ASSERT(stardis && tok_ctx); + stardis->counts.hbound_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz+1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; init_h(stardis->allocator, &desc->d.h_boundary); - if(type == DESC_BOUND_H_FOR_SOLID) { - /* Need a dedicated fluid */ - allocate_stardis_medium_id(stardis, &desc->d.h_boundary.mat_id); - } else { - /* Can use dummy solid */ - if(dummies->dummy_solid_id == UINT_MAX) { - /* Allocate an ID for dummy solid */ - allocate_stardis_medium_id(stardis, &dummies->dummy_solid_id); - } - desc->d.h_boundary.mat_id = dummies->dummy_solid_id; - } desc->type = type; CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "h boundary name"); @@ -1120,6 +1111,26 @@ process_h goto end; } + if(type == DESC_BOUND_H_FOR_FLUID) + desc->d.h_boundary.mat_id = get_dummy_solid_id(stardis, dummies); + else { + struct fluid fluid_props; + init_fluid(stardis->allocator, &fluid_props); + fluid_props.fluid_id = allocate_stardis_medium_id(stardis); + desc->d.h_boundary.mat_id = fluid_props.fluid_id; + ASSERT(sz <= UINT_MAX); + fluid_props.desc_id = (unsigned)sz; + fluid_props.imposed_temperature + = desc->d.h_boundary.imposed_temperature; + fluid_props.is_outside = 1; + fluid_props.is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + ERR(create_solver_fluid(stardis, &fluid_props)); + logger_print(stardis->logger, LOG_OUTPUT, + "External fluid created: T=%g (it is medium %u)\n", + fluid_props.imposed_temperature, + fluid_props.fluid_id); + } + ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); @@ -1145,12 +1156,16 @@ process_t ASSERT(stardis && tok_ctx); + stardis->counts.tbound_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; init_t(stardis->allocator, &desc->d.t_boundary); desc->type = type; + desc->d.t_boundary.mat_id = (type == DESC_BOUND_T_FOR_FLUID) + ? get_dummy_solid_id(stardis, dummies) : get_dummy_fluid_id(stardis, dummies); CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "temperature boundary name"); ERR(str_set(&desc->d.t_boundary.name, tk)); @@ -1173,11 +1188,6 @@ process_t goto end; } if(type == DESC_BOUND_T_FOR_FLUID) { - if(dummies->dummy_solid_id == UINT_MAX) { - /* Allocate an ID for dummy solid */ - allocate_stardis_medium_id(stardis, &dummies->dummy_solid_id); - } - desc->d.t_boundary.mat_id = dummies->dummy_solid_id; CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "emissivity"); res = cstr_to_double(tk, &desc->d.t_boundary.emissivity); if(res != RES_OK @@ -1208,12 +1218,6 @@ process_t if(res == RES_OK) res = RES_BAD_ARG; goto end; } - } else { - if(dummies->dummy_fluid_id == UINT_MAX) { - /* Allocate an ID for dummy fluid */ - allocate_stardis_medium_id(stardis, &dummies->dummy_fluid_id); - } - desc->d.t_boundary.mat_id = dummies->dummy_fluid_id; } ASSERT(sz <= UINT_MAX); @@ -1239,17 +1243,15 @@ process_flx ASSERT(stardis && tok_ctx); + stardis->counts.fbound_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; init_f(stardis->allocator, &desc->d.f_boundary); - if(dummies->dummy_fluid_id == UINT_MAX) { - /* Allocate an ID for dummy fluid */ - allocate_stardis_medium_id(stardis, &dummies->dummy_fluid_id); - } - desc->d.f_boundary.mat_id = dummies->dummy_fluid_id; desc->type = DESC_BOUND_F_FOR_SOLID; + desc->d.f_boundary.mat_id = get_dummy_fluid_id(stardis, dummies); CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "flux boundary name"); ERR(str_set(&desc->d.f_boundary.name, tk)); @@ -1294,6 +1296,8 @@ process_sfc ASSERT(stardis && tok_ctx); + stardis->counts.sfconnect_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1302,8 +1306,8 @@ process_sfc /* Use a medium ID even if there is no medium here * As other cases use media IDs as unique IDs for read_sides_and_files calls * we continue the trend to ensure connection ID is OK */ - allocate_stardis_medium_id(stardis, &desc->d.sf_connect.connection_id); desc->type = DESC_SOLID_FLUID_CONNECT; + desc->d.sf_connect.connection_id = allocate_stardis_medium_id(stardis); CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid fluid connection name"); ERR(str_set(&desc->d.sf_connect.name, tk)); @@ -1448,13 +1452,19 @@ process_solid ASSERT(stardis && tok_ctx); + stardis->counts.smed_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; init_solid(stardis->allocator, &desc->d.solid); - allocate_stardis_medium_id(stardis, &desc->d.solid.solid_id); desc->type = DESC_MAT_SOLID; + desc->d.solid.solid_id = allocate_stardis_medium_id(stardis); + desc->d.solid.is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + desc->d.solid.is_outside = 0; + ASSERT(sz <= UINT_MAX); + desc->d.solid.desc_id = (unsigned)sz; CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid name"); ERR(str_set(&desc->d.solid.name, tk)); @@ -1514,6 +1524,9 @@ process_solid goto end; } + /* Actual solid creation is defered until geometry is read to allow + * enclosure shape VS delta analysis (and auto delta computation) */ + ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); @@ -1536,13 +1549,19 @@ process_fluid ASSERT(stardis && tok_ctx); + stardis->counts.fmed_count++; + sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; init_fluid(stardis->allocator, &desc->d.fluid); - allocate_stardis_medium_id(stardis, &desc->d.fluid.fluid_id); desc->type = DESC_MAT_FLUID; + desc->d.fluid.fluid_id = allocate_stardis_medium_id(stardis); + desc->d.fluid.is_outside = 0; + desc->d.fluid.is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + ASSERT(sz <= UINT_MAX); + desc->d.fluid.desc_id = (unsigned)sz; CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "fluid name"); ERR(str_set(&desc->d.fluid.name, tk)); @@ -1586,6 +1605,8 @@ process_fluid ERR(read_imposed_temperature(stardis, &desc->d.fluid.imposed_temperature, tok_ctx)); + ERR(create_solver_fluid(stardis, &desc->d.fluid)); + ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); @@ -1693,4 +1714,48 @@ error: "Invalid description line in model file '%s':\n", file_name); logger_print(stardis->logger, LOG_ERROR, "%s\n", str_cget(&keep)); goto end; -} -\ No newline at end of file +} + +unsigned +get_dummy_solid_id + (struct stardis* stardis, + struct dummies* dummies) +{ + struct solid dummy; + if(dummies->dummy_solid) + return dummies->dummy_solid_id; + dummies->dummy_solid_id = allocate_stardis_medium_id(stardis); + init_solid(stardis->allocator, &dummy); + dummy.solid_id = dummies->dummy_solid_id; + dummy.is_outside = 1; + dummy.is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + create_solver_solid(stardis, &dummy); + dummies->dummy_solid + = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_solid_id]; + logger_print(stardis->logger, LOG_OUTPUT, + "Dummy solid created: (it is medium %u)\n", + dummies->dummy_solid_id); + return dummies->dummy_solid_id; +} + +unsigned +get_dummy_fluid_id + (struct stardis* stardis, + struct dummies* dummies) +{ + struct fluid dummy; + if(dummies->dummy_fluid) + return dummies->dummy_fluid_id; + dummies->dummy_fluid_id = allocate_stardis_medium_id(stardis); + init_fluid(stardis->allocator, &dummy); + dummy.fluid_id = dummies->dummy_fluid_id; + dummy.is_outside = 1; + dummy.is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + create_solver_fluid(stardis, &dummy); + dummies->dummy_fluid + = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_fluid_id]; + logger_print(stardis->logger, LOG_OUTPUT, + "Dummy fluid created: (it is medium %u)\n", + dummies->dummy_fluid_id); + return dummies->dummy_fluid_id; +} diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -188,4 +188,14 @@ process_model_line struct stardis* stardis, struct dummies* dummies); +extern LOCAL_SYM unsigned +get_dummy_solid_id + (struct stardis* stardis, + struct dummies* dummies); + +extern LOCAL_SYM unsigned +get_dummy_fluid_id + (struct stardis* stardis, + struct dummies* dummies); + #endif /*ARGS_H*/ diff --git a/src/stardis-solid.c b/src/stardis-solid.c @@ -117,27 +117,17 @@ solid_get_power ******************************************************************************/ res_T -create_stardis_solid +create_solver_solid (struct stardis* stardis, - const struct str* name, /* Can be NULL */ - const double lambda, - const double rho, - const double cp, - const double delta, - const int is_green, - const int is_outside, - const double tinit, - const double imposed_temperature, - const double vpower, - const unsigned id) + const struct solid* solid_props) { res_T res = RES_OK; struct sdis_solid_shader solid_shader = SDIS_SOLID_SHADER_NULL; struct sdis_data* data = NULL; - struct solid* solid_props; + struct solid* props; /* Could be less restrictive if green output included positions/dates */ - ASSERT(stardis && lambda > 0 && rho > 0 && cp > 0 && delta > 0); + ASSERT(stardis && solid_props); solid_shader.calorific_capacity = solid_get_calorific_capacity; solid_shader.thermal_conductivity = solid_get_thermal_conductivity; solid_shader.volumic_mass = solid_get_volumic_mass; @@ -149,25 +139,16 @@ create_stardis_solid ERR(sdis_data_create(stardis->dev, sizeof(struct solid), ALIGNOF(struct solid), NULL, &data)); - solid_props = sdis_data_get(data); /* Fetch the allocated memory space */ - str_init(stardis->allocator, &solid_props->name); - if(name) str_copy(&solid_props->name, name); - solid_props->t0 = 0; - solid_props->lambda = lambda; - solid_props->rho = rho; - solid_props->cp = cp; - solid_props->delta = delta; - solid_props->tinit = tinit; - solid_props->imposed_temperature = imposed_temperature; - solid_props->vpower = vpower; - solid_props->is_green = is_green; - solid_props->is_outside = is_outside; - solid_props->id = id; - if(vpower != 0) solid_shader.volumic_power = solid_get_power; - ASSERT(id >= darray_media_ptr_size_get(&stardis->media)); - ERR(darray_media_ptr_resize(&stardis->media, id + 1)); + props = sdis_data_get(data); /* Fetch the allocated memory space */ + init_solid(stardis->allocator, props); + cp_solid(props, solid_props); + if(solid_props->vpower != 0) solid_shader.volumic_power = solid_get_power; + if(solid_props->solid_id >= darray_media_ptr_size_get(&stardis->media)) { + ERR(darray_media_ptr_resize(&stardis->media, solid_props->solid_id + 1)); + } + ASSERT(darray_media_ptr_data_get(&stardis->media)[solid_props->solid_id] == NULL); ERR(sdis_solid_create(stardis->dev, &solid_shader, data, - darray_media_ptr_data_get(&stardis->media) + id)); + darray_media_ptr_data_get(&stardis->media) + solid_props->solid_id)); end: if(data) SDIS(data_ref_put(data)); @@ -175,3 +156,68 @@ end: error: goto end; } + +void +init_solid(struct mem_allocator* allocator, struct solid* dst) +{ + str_init(allocator, &dst->name); + dst->lambda = 1; + dst->rho = 1; + dst->cp = 1; + dst->delta = 1; + dst->tinit = -1; + dst->imposed_temperature = -1; + dst->vpower = 0; + dst->t0 = 0; + dst->is_outside = 0; + dst->is_green = 0; + dst->desc_id = UINT_MAX; + dst->solid_id = UINT_MAX; +} + +void +release_solid(struct solid* solid) +{ + str_release(&solid->name); +} + +res_T +str_print_solid(struct str* str, const struct solid* s) +{ + res_T res = RES_OK; + ASSERT(str && s); + STR_APPEND_PRINTF(str, "Solid '%s': lambda=%g rho=%g cp=%g delta=%g", + str_cget(&s->name), s->lambda, s->rho, s->cp, s->delta); + if(s->vpower != 0) { + STR_APPEND_PRINTF(str, " VPower=%g", s->vpower); + } + if(s->tinit >= 0) { + STR_APPEND_PRINTF(str, " Tinit=%g", s->tinit); + } + if(s->imposed_temperature >= 0) { + STR_APPEND_PRINTF(str, " Temp=%g", s->imposed_temperature); + } + STR_APPEND_PRINTF(str, " (it is medium %u)", s->solid_id); +end: + return res; +error: + goto end; +} + +res_T +cp_solid(struct solid* dst, const struct solid* src) +{ + dst->lambda = src->lambda; + dst->rho = src->rho; + dst->cp = src->cp; + dst->delta = src->delta; + dst->tinit = src->tinit; + dst->imposed_temperature = src->imposed_temperature; + dst->vpower = src->vpower; + dst->t0 = src->t0; + dst->is_outside = src->is_outside; + dst->is_green = src->is_green; + dst->desc_id = src->desc_id; + dst->solid_id = src->solid_id; + return str_copy(&dst->name, &src->name); +} diff --git a/src/stardis-solid.h b/src/stardis-solid.h @@ -26,33 +26,35 @@ struct stardis; ******************************************************************************/ struct solid { struct str name; - double cp; /* Calorific capacity */ double lambda; /* Conductivity */ double rho; /* Volumic mass */ + double cp; /* Calorific capacity */ double delta; /* Numerical parameter */ double tinit; /* Initial temperature */ double imposed_temperature; /* allow to impose a T; -1 if unset */ double vpower; - /* Compute mode */ - int is_green, is_outside; double t0; /* End time of tinit */ - /* ID */ - unsigned id; + int is_outside; /* the solid is used for a boundary */ + int is_green; /* green computation (nothing to do with solid itself) */ + unsigned desc_id; /* id of the boundary; meaningful if is_outside */ + unsigned solid_id; }; -extern res_T -create_stardis_solid +LOCAL_SYM void +init_solid(struct mem_allocator* allocator, struct solid* dst); + +LOCAL_SYM void +release_solid(struct solid* solid); + +LOCAL_SYM res_T +str_print_solid(struct str* str, const struct solid* s); + +LOCAL_SYM res_T +cp_solid(struct solid* dst, const struct solid* src); + +LOCAL_SYM res_T +create_solver_solid (struct stardis* stardis, - const struct str* name, - const double lambda, - const double rho, - const double cp, - const double delta, - const int is_green, - const int is_outside, - const double tinit, - const double imposed_temperature, - const double vpower, - const unsigned id); + const struct solid* solid_props); #endif