stardis

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

commit f4d557983c00c4332ae79248a1f9be55c69f1f88
parent e5c225eee1427bec97be0c02f254a4c79132be90
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sat,  9 May 2020 12:23:53 +0200

Add auto delta solid feature; check user delta validity

Diffstat:
Mdoc/stardis-input.5.txt | 3++-
Msrc/stardis-app.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/stardis-app.h | 6++++++
Msrc/stardis-output.c | 31+++++++------------------------
Msrc/stardis-parsing.c | 51++++++++++++++++++++++++++++++++++++++++++---------
5 files changed, 183 insertions(+), 66 deletions(-)

diff --git a/doc/stardis-input.5.txt b/doc/stardis-input.5.txt @@ -116,7 +116,8 @@ _______ <cp> ::= REAL # in ]0, INF) -<delta> ::= REAL # in ]0, INF) +<delta> ::= "AUTO" # delta is automatically set to V/6S + | REAL # in [0, INF) <initial-temp> ::= REAL # in [0, INF) diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -20,6 +20,8 @@ #include "stardis-fluid.h" #include "stardis-solid.h" +#include<star/senc3d.h> +#include<star/sg3d_sencXd_helper.h> #include <star/sg3d_sdisXd_helper.h> #include <rsys/text_reader.h> @@ -288,6 +290,7 @@ create_holder { res_T res = RES_OK; struct description* description; + struct senc3d_enclosure* enc = NULL; ASSERT(stardis && dummies && idx < darray_descriptions_size_get(&stardis->descriptions)); @@ -378,7 +381,12 @@ create_holder ASSERT(description->d.sf_connect.emissivity >= 0); ASSERT(description->d.sf_connect.hc >= 0); break; - case DESC_MAT_SOLID: + case DESC_MAT_SOLID: { + unsigned e, ecount; + 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++; ERR(create_stardis_solid(stardis, &description->d.solid.name, @@ -392,7 +400,58 @@ create_holder description->d.solid.imposed_temperature, description->d.solid.vpower, &description->d.solid.solid_id)); + /* Check if delta can fit possible multiple enclosures */ + ERR(senc3d_scene_get_enclosure_count_by_medium(stardis->senc3d_scn, + description->d.solid.solid_id, &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, + description->d.solid.solid_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); + 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 was AUTO and need to be computed */ + if(description->d.solid.delta == -1) { + 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]); + } + } + } break; + } case DESC_MAT_FLUID: stardis->counts.fmed_count++; ERR(create_stardis_fluid(stardis, @@ -410,6 +469,7 @@ create_holder } end: + if(enc) ERR(senc3d_enclosure_ref_put(enc)); return res; error: goto end; @@ -436,6 +496,7 @@ stardis_init ASSERT(args && logger && allocator && stardis); + str_init(allocator, &str); /* Init everithing that cannot fail */ stardis->logger = logger; stardis->allocator = allocator; @@ -447,6 +508,7 @@ stardis_init stardis->probe[3] = args->probe[3]; stardis->dev = NULL; stardis->sdis_scn = NULL; + stardis->senc3d_scn = NULL; stardis->mode = args->mode; stardis->counts = COUNTS_NULL; init_camera(&stardis->camera); @@ -490,20 +552,6 @@ stardis_init ERR(sdis_device_create(stardis->logger, stardis->allocator, args->nthreads, args->verbose, &stardis->dev)); - /* Create media and property holders for those found in descriptions */ - str_init(stardis->allocator, &str); - for(i = 0; i < darray_descriptions_size_get(&stardis->descriptions); i++) { - ERR(create_holder(stardis, &dummies, i, - stardis->mode & (MODE_BIN_GREEN | MODE_GREEN))); - str_clear(&str); - str_printf(&str, "Description %d: ", i); - ERR(print_description(&str, - darray_descriptions_cdata_get(&stardis->descriptions) + i)); - ERR(str_printf(&str, "\n")); - logger_print(stardis->logger, LOG_OUTPUT, "%s", str_cget(&str)); - } - str_release(&str); - create_context.geometry = stardis->geometry.sg3d; create_context.app_interface_getter = geometry_get_interface; create_context.app_interface_data = &stardis->geometry.interf_bytrg; @@ -516,25 +564,13 @@ stardis_init stardis->geometry.sg3d, &count)); if(count) { logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), - "Properties conflicts found in the the model (%u triangles).\n", count); + "Properties conflicts found in the model (%u triangles).\n", count); if(is_for_compute) { res = RES_BAD_ARG; goto error; } } - if(is_for_compute) { - for(i = 0; i < tcount; ++i) { - ERR(create_intface(stardis, i, &htable_interfaces)); - } - if(args->paths_filename) { - ERR(str_set(&stardis->paths_filename, args->paths_filename)); - } - if(args->bin_green_filename) { - ERR(str_set(&stardis->bin_green_filename, args->bin_green_filename)); - } - } - /* If computation is on a compute surface, read it */ if(args->mode & SURFACE_COMPUTE_MODES) { unsigned save_count = count; @@ -552,12 +588,40 @@ stardis_init str_cget(&stardis->solve_name)); logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "The file contains %u triangles not in the model.\n", count - save_count); - if(is_for_compute) { + if(is_for_compute) { res = RES_BAD_ARG; goto error; } } } + + /* Create enclosures */ + ERR(init_enclosures(stardis)); + + /* Create media and property holders for those found in descriptions */ + for (i = 0; i < darray_descriptions_size_get(&stardis->descriptions); i++) { + ERR(create_holder(stardis, &dummies, i, + stardis->mode & (MODE_BIN_GREEN | MODE_GREEN))); + str_clear(&str); + str_printf(&str, "Description %d: ", i); + ERR(print_description(&str, + darray_descriptions_cdata_get(&stardis->descriptions) + i)); + ERR(str_printf(&str, "\n")); + logger_print(stardis->logger, LOG_OUTPUT, "%s", str_cget(&str)); + } + + if(is_for_compute) { + for(i = 0; i < tcount; ++i) { + ERR(create_intface(stardis, i, &htable_interfaces)); + } + if(args->paths_filename) { + ERR(str_set(&stardis->paths_filename, args->paths_filename)); + } + if(args->bin_green_filename) { + ERR(str_set(&stardis->bin_green_filename, args->bin_green_filename)); + } + } + /* If computation is on a volume, check medium is known */ if(args->mode & MODE_MEDIUM_COMPUTE) { if(!find_medium_by_name(stardis, &stardis->solve_name, NULL)) { @@ -583,6 +647,9 @@ stardis_init if(is_for_compute) { ASSERT(darray_interface_ptrs_size_get(&stardis->geometry.interf_bytrg) == tcount); + /* Can release enclosures as they are no longer needed if compute */ + SENC3D(scene_ref_put(stardis->senc3d_scn)); + stardis->senc3d_scn = NULL; res = sdis_scene_create(stardis->dev, tcount, sg3d_sdisXd_geometry_get_indices, sg3d_sdisXd_geometry_get_interface, @@ -596,6 +663,7 @@ stardis_init } exit: + str_release(&str); htable_intface_release(&htable_interfaces); return res; error: @@ -604,7 +672,8 @@ error: } void -stardis_release(struct stardis* stardis) +stardis_release + (struct stardis* stardis) { size_t i; @@ -612,6 +681,7 @@ stardis_release(struct stardis* stardis) if(stardis->dev) SDIS(device_ref_put(stardis->dev)); if(stardis->sdis_scn) SDIS(scene_ref_put(stardis->sdis_scn)); + if(stardis->senc3d_scn) SENC3D(scene_ref_put(stardis->senc3d_scn)); str_release(&stardis->solve_name); str_release(&stardis->paths_filename); str_release(&stardis->bin_green_filename); @@ -625,6 +695,30 @@ stardis_release(struct stardis* stardis) darray_media_ptr_release(&stardis->media); } +res_T +init_enclosures + (struct stardis* stardis) +{ + res_T res = RES_OK; + unsigned tsz, vsz; + struct senc3d_device* senc_dev = NULL; + + ERR(sg3d_geometry_get_unique_triangles_count(stardis->geometry.sg3d, &tsz)); + ERR(sg3d_geometry_get_unique_vertices_count(stardis->geometry.sg3d, &vsz)); + ERR(senc3d_device_create(stardis->logger, stardis->allocator, + SENC3D_NTHREADS_DEFAULT, stardis->verbose, &senc_dev)); + 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, + vsz, sg3d_sencXd_geometry_get_position, stardis->geometry.sg3d, + &stardis->senc3d_scn)); +exit: + if(senc_dev) senc3d_device_ref_put(senc_dev); + return res; +error: + goto exit; +} + /******************************************************************************* * rsys/str additions ******************************************************************************/ @@ -663,8 +757,8 @@ ensure_allocated(struct str* str, const size_t len, const char keep_old) res_T str_printf -(struct str* str, - const char* fmt, ...) + (struct str* str, + const char* fmt, ...) { res_T res = RES_OK; size_t initial_len, left; diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -754,6 +754,7 @@ struct stardis { struct sdis_scene* sdis_scn; /* The solver scene */ struct darray_descriptions descriptions; /* Materials and boundaries */ struct darray_media_ptr media; + struct senc3d_scene* senc3d_scn; struct counts counts; double probe[4]; /* x,y,z,t of probe when mode is PROBE_COMPUTE */ @@ -789,4 +790,9 @@ extern LOCAL_SYM void stardis_release (struct stardis* stardis); + +extern LOCAL_SYM res_T +init_enclosures + (struct stardis* stardis); + #endif /*STARDIS-APP_H*/ diff --git a/src/stardis-output.c b/src/stardis-output.c @@ -23,7 +23,6 @@ #include <sdis.h> #include<star/senc3d.h> -#include<star/sg3d_sencXd_helper.h> #include <rsys/math.h> #include <rsys/mem_allocator.h> @@ -819,40 +818,26 @@ dump_enclosure_related_stuff_at_the_end_of_vtk { res_T res = RES_OK; unsigned* trgs = NULL; - struct senc3d_scene* senc3d_scn = NULL; - struct senc3d_device* senc_dev = NULL; struct senc3d_enclosure* enc = NULL; - unsigned tsz, vsz, e, s, t, scount, ecount; + unsigned tsz, e, s, t, scount, ecount; int* enc_status = NULL; int invalid_enclosures_count = 0; ASSERT(stardis && stream); ERR(sg3d_geometry_get_unique_triangles_count(stardis->geometry.sg3d, &tsz)); - ERR(sg3d_geometry_get_unique_vertices_count(stardis->geometry.sg3d, &vsz)); trgs = MEM_CALLOC(stardis->allocator, tsz, sizeof(*trgs)); if(!trgs) { res = RES_MEM_ERR; goto error; } - /* Create enclosures - * For dump results to be reproducible, we setup star-enclosures with a - * single thread */ - ERR(senc3d_device_create(stardis->logger, stardis->allocator, - SENC3D_NTHREADS_DEFAULT, stardis->verbose, &senc_dev)); - 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, - vsz, sg3d_sencXd_geometry_get_position, stardis->geometry.sg3d, - &senc3d_scn)); - /* Keep the segments involved in holes (not the vertices) */ - ERR(senc3d_scene_get_frontier_segments_count(senc3d_scn, &scount)); + ERR(senc3d_scene_get_frontier_segments_count(stardis->senc3d_scn, &scount)); if(scount) { /* Room to store frontier triangles */ FOR_EACH(s, 0, scount) { unsigned vrtc[2], trid; - ERR(senc3d_scene_get_frontier_segment(senc3d_scn, s, vrtc, &trid)); + ERR(senc3d_scene_get_frontier_segment(stardis->senc3d_scn, s, vrtc, &trid)); trgs[trid] = 1; } logger_print(stardis->logger, LOG_WARNING, "Model contains hole(s).\n"); @@ -862,7 +847,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk } /* Dump enclosure information */ - ERR(senc3d_scene_get_enclosure_count(senc3d_scn, &ecount)); + ERR(senc3d_scene_get_enclosure_count(stardis->senc3d_scn, &ecount)); enc_status = MEM_CALLOC(stardis->allocator, ecount, sizeof(*enc_status)); if(!enc_status) { res = RES_MEM_ERR; @@ -872,7 +857,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk struct senc3d_enclosure_header header; enc_status[e] = NO_ENCLOSURE_ERROR; - ERR(senc3d_scene_get_enclosure(senc3d_scn, e, &enc)); + ERR(senc3d_scene_get_enclosure(stardis->senc3d_scn, e, &enc)); ERR(senc3d_enclosure_get_header(enc, &header)); /* Check if anclosure is invalid regarding stardis solver requirements */ if(!header.is_infinite) { @@ -896,7 +881,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk fprintf(stream, "Enclosure_ID %d %d unsigned_char\n", ecount, tsz); FOR_EACH(t, 0, tsz) { unsigned encs[2]; - ERR(senc3d_scene_get_triangle_enclosures(senc3d_scn, t, encs)); + ERR(senc3d_scene_get_triangle_enclosures(stardis->senc3d_scn, t, encs)); FOR_EACH(e, 0, ecount) { if(e == encs[SENC3D_FRONT] || e == encs[SENC3D_BACK]) fprintf(stream, "%d ", (char)enc_status[e]); @@ -908,9 +893,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk exit: MEM_RM(stardis->allocator, trgs); - MEM_RM(stardis->allocator, enc_status); - if(senc3d_scn) senc3d_scene_ref_put(senc3d_scn); - if(senc_dev) senc3d_device_ref_put(senc_dev); + MEM_RM(stardis->allocator, enc_status); return res; error: goto exit; diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -1287,6 +1287,7 @@ read_imposed_temperature char* tk = NULL; struct str keep; res_T res = RES_OK; + ASSERT(stardis && imposed_temperature && tok_ctx); str_init(stardis->allocator, &keep); CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "imposed temperature"); @@ -1317,6 +1318,46 @@ error: goto end; } +static res_T +read_delta + (struct stardis* stardis, + double* delta, + char** tok_ctx) +{ + char* tk = NULL; + struct str keep; + res_T res = RES_OK; + ASSERT(stardis && delta && tok_ctx); + + str_init(stardis->allocator, &keep); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "delta"); + ERR(str_set(&keep, tk)); + if(RES_OK == cstr_to_double(tk, delta)) { + /* Was a number */ + if(delta <= 0) { + res = RES_BAD_ARG; + goto error; + } + } else { + /* Could be 'auto' */ + _strupr(tk); + if(0 == strcmp(tk, "AUTO")) { + /* Set to -1 until actual value is substituted */ + *delta = -1; + } else { + res = RES_BAD_ARG; + goto error; + } + } +end: + str_release(&keep); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, "Invalid delta: %s\n", + str_cget(&keep)); + goto end; +} + /* SOLID Name lambda rho cp delta Tinit Timposed volumic_power STL_filenames */ static res_T process_solid @@ -1377,15 +1418,7 @@ process_solid if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "delta"); - res = cstr_to_double(tk, &desc->d.solid.delta); - if(res != RES_OK - || desc->d.solid.delta <= 0) - { - logger_print(stardis->logger, LOG_ERROR, "Invalid delta: %s\n", tk); - if(res == RES_OK) res = RES_BAD_ARG; - goto end; - } + ERR(read_delta(stardis, &desc->d.solid.delta, tok_ctx)); CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Tinit"); res = cstr_to_double(tk, &desc->d.solid.tinit); if(res != RES_OK