stardis-solver

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

sdis_misc.c (3731B)


      1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "sdis.h"
     17 #include "sdis_heat_path.h"
     18 #include "sdis_log.h"
     19 #include "sdis_medium_c.h"
     20 #include "sdis_misc.h"
     21 #include "sdis_green.h"
     22 
     23 #include <star/ssp.h>
     24 
     25 res_T
     26 time_rewind
     27   (struct sdis_scene* scn,
     28    const double mu,
     29    const double t0,
     30    struct ssp_rng* rng,
     31    struct rwalk* rwalk,
     32    const struct rwalk_context* ctx,
     33    struct temperature* T)
     34 {
     35   const struct enclosure* enc = NULL;
     36   struct sdis_medium* mdm = NULL;
     37   double temperature;
     38   double tau;
     39   res_T res = RES_OK;
     40   ASSERT(scn && rwalk && ctx && rng && T);
     41 
     42   /* Get the current medium */
     43   enc = scene_get_enclosure(scn, rwalk->enc_id);
     44   res = scene_get_enclosure_medium(scn, enc, &mdm);
     45   if(res != RES_OK) goto error;
     46 
     47   /* Sample the time using the upper bound. */
     48   tau = ssp_ran_exp(rng, mu);
     49 
     50   /* Increment the elapsed time */
     51   ASSERT(rwalk->vtx.time >= t0);
     52   rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0);
     53 
     54   if(IS_INF(rwalk->vtx.time)) goto exit; /* Steady computation */
     55 
     56   /* Time rewind */
     57   rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); /* Time rewind */
     58 
     59   /* The path does not reach the limit condition */
     60   if(rwalk->vtx.time > t0) goto exit;
     61 
     62   /* Fetch the initial temperature */
     63   temperature = medium_get_temperature(mdm, &rwalk->vtx);
     64   if(SDIS_TEMPERATURE_IS_UNKNOWN(temperature)) {
     65     log_err(mdm->dev, "the path reaches the limit condition but the "
     66       "%s temperature remains unknown -- position=%g, %g, %g\n",
     67       medium_type_to_string(sdis_medium_get_type(mdm)),
     68       SPLIT3(rwalk->vtx.P));
     69     res = RES_BAD_ARG;
     70     goto error;
     71   }
     72 
     73   /* Update temperature */
     74   T->value += temperature;
     75   T->done = 1;
     76 
     77   if(ctx->heat_path) {
     78     /* Update the registered vertex data */
     79     struct sdis_heat_vertex* vtx;
     80     vtx = heat_path_get_last_vertex(ctx->heat_path);
     81     vtx->time = rwalk->vtx.time;
     82     vtx->weight = T->value;
     83   }
     84 
     85   if(ctx->green_path) {
     86     res = green_path_set_limit_vertex
     87       (ctx->green_path, mdm, &rwalk->vtx, rwalk->elapsed_time);
     88     if(res != RES_OK) goto error;
     89   }
     90 
     91 exit:
     92   return res;
     93 error:
     94   goto exit;
     95 }
     96 
     97 res_T
     98 check_primitive_uv_2d(struct sdis_device* dev, const double param_coord[])
     99 {
    100   double u;
    101   res_T res = RES_OK;
    102   ASSERT(dev && param_coord);
    103 
    104   u = param_coord[0];
    105 
    106   if(u < 0 || 1 < u) {
    107     log_err(dev,
    108       "%s: invalid parametric coordinates u=%g; it must be in [0, 1].\n",
    109       FUNC_NAME, u);
    110     res = RES_BAD_ARG;
    111     goto error;
    112   }
    113 
    114 exit:
    115   return res;
    116 error:
    117   goto exit;
    118 }
    119 
    120 res_T
    121 check_primitive_uv_3d(struct sdis_device* dev, const double param_coords[])
    122 {
    123   double u, v, w;
    124   res_T res = RES_OK;
    125   ASSERT(dev && param_coords);
    126 
    127   u = param_coords[0];
    128   v = param_coords[1];
    129   w = CLAMP(1 - u - v, 0, 1);
    130 
    131   if(u < 0 || 1 < u || v < 0 || 1 < v || !eq_eps(u + v + w, 1, 1.e-6)) {
    132     log_err(dev,
    133       "%s: invalid parametric coordinates u=%g; v=%g. "
    134       "u + v + (1-u-v) must be equal to 1 with u and v in [0, 1].\n",
    135       FUNC_NAME, u, v);
    136     res = RES_BAD_ARG;
    137     goto error;
    138   }
    139 
    140 exit:
    141   return res;
    142 error:
    143   goto exit;
    144 }