stardis-solver

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

sdis_misc.h (5004B)


      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 #ifndef SDIS_MISC_H
     17 #define SDIS_MISC_H
     18 
     19 #include "sdis_heat_path.h"
     20 
     21 #include <rsys/float2.h>
     22 #include <rsys/float3.h>
     23 #include <star/ssp.h>
     24 
     25 struct bound_flux_result {
     26   double Tradiative;
     27   double Tboundary;
     28   double Tfluid;
     29 };
     30 #define BOUND_FLUX_RESULT_NULL__ {0,0,0}
     31 static const struct bound_flux_result
     32 BOUND_FLUX_RESULT_NULL = BOUND_FLUX_RESULT_NULL__;
     33 
     34 struct accum {
     35   double sum; /* Sum of MC weights */
     36   double sum2; /* Sum of square MC weights */
     37   size_t count; /* #accumulated MC weights */
     38 };
     39 #define ACCUM_NULL__ {0,0,0}
     40 static const struct accum ACCUM_NULL = ACCUM_NULL__;
     41 
     42 /* Empirical scale factor to apply to the upper bound of the ray range in order
     43  * to handle numerical imprecisions */
     44 #define RAY_RANGE_MAX_SCALE 1.001f
     45 
     46 /* Define a new result code from RES_BAD_OP saying that the bad operation is
     47  * definitive, i.e. in the current state, the realisation will inevitably fail.
     48  * It is thus unecessary to retry a specific section of the random walk */
     49 #define RES_BAD_OP_IRRECOVERABLE (-RES_BAD_OP)
     50 
     51 #define BOLTZMANN_CONSTANT 5.6696e-8 /* W/m^2/K^4 */
     52 
     53 static INLINE void
     54 sum_accums
     55   (const struct accum accums[],
     56    const size_t naccums,
     57    struct accum* accum)
     58 {
     59   struct accum acc = ACCUM_NULL;
     60   size_t i;
     61   ASSERT(accums && naccums && accum);
     62 
     63   FOR_EACH(i, 0, naccums) {
     64     acc.sum += accums[i].sum;
     65     acc.sum2 += accums[i].sum2;
     66     acc.count += accums[i].count;
     67   }
     68   *accum = acc;
     69 }
     70 
     71 /* Reflect the V wrt the normal N. By convention V points outward the surface */
     72 static FINLINE float*
     73 reflect_2d(float res[2], const float V[2], const float N[2])
     74 {
     75   float tmp[2];
     76   float cos_V_N;
     77   ASSERT(res && V && N);
     78   ASSERT(f2_is_normalized(V) && f2_is_normalized(N));
     79   cos_V_N = f2_dot(V, N);
     80   f2_mulf(tmp, N, 2*cos_V_N);
     81   f2_sub(res, tmp, V);
     82   return res;
     83 }
     84 
     85 /* Reflect the V wrt the normal N. By convention V points outward the surface */
     86 static FINLINE float*
     87 reflect_3d(float res[3], const float V[3], const float N[3])
     88 {
     89   float tmp[3];
     90   float cos_V_N;
     91   ASSERT(res && V && N);
     92   ASSERT(f3_is_normalized(V) && f3_is_normalized(N));
     93   cos_V_N = f3_dot(V, N);
     94   f3_mulf(tmp, N, 2*cos_V_N);
     95   f3_sub(res, tmp, V);
     96   f3_normalize(res, res); /* Handle numerical issue */
     97   return res;
     98 }
     99 
    100 static FINLINE double*
    101 move_pos_2d(double pos[2], const float dir[2], const float delta)
    102 {
    103   ASSERT(pos && dir);
    104   pos[0] += dir[0] * delta;
    105   pos[1] += dir[1] * delta;
    106   return pos;
    107 }
    108 
    109 static FINLINE double*
    110 move_pos_3d(double pos[3], const float dir[3], const float delta)
    111 {
    112   ASSERT(pos && dir);
    113   pos[0] += dir[0] * delta;
    114   pos[1] += dir[1] * delta;
    115   pos[2] += dir[2] * delta;
    116   return pos;
    117 }
    118 
    119 static INLINE double
    120 sample_time(struct ssp_rng* rng, const double time_range[2])
    121 {
    122   ASSERT(time_range && time_range[0] >= 0 && time_range[1] >= time_range[0]);
    123   ASSERT(rng);
    124   if(time_range[0] == time_range[1]) return time_range[0];
    125   return ssp_rng_uniform_double(rng, time_range[0], time_range[1]);
    126 }
    127 
    128 static INLINE res_T
    129 register_heat_vertex
    130   (struct sdis_heat_path* path,
    131    const struct sdis_rwalk_vertex* vtx,
    132    const double weight,
    133    const enum sdis_heat_vertex_type type,
    134    const int branch_id)
    135 {
    136   struct sdis_heat_vertex heat_vtx = SDIS_HEAT_VERTEX_NULL;
    137   ASSERT(vtx && branch_id >= 0);
    138 
    139   if(!path) return RES_OK;
    140 
    141   heat_vtx.P[0] = vtx->P[0];
    142   heat_vtx.P[1] = vtx->P[1];
    143   heat_vtx.P[2] = vtx->P[2];
    144   heat_vtx.time = vtx->time;
    145   heat_vtx.weight = weight;
    146   heat_vtx.type = type;
    147   heat_vtx.branch_id = branch_id;
    148   return heat_path_add_vertex(path, &heat_vtx);
    149 }
    150 
    151 extern LOCAL_SYM res_T
    152 time_rewind
    153   (struct sdis_scene* scn,
    154    const double mu,
    155    const double t0, /* Initial time */
    156    struct ssp_rng* rng,
    157    struct rwalk* rwalk,
    158    const struct rwalk_context* ctx,
    159    struct temperature* T);
    160 
    161 /* Check the validity of the parametric coordinate onto a 2D primitive. If it
    162  * is invalid, the function prints an error message and return RES_BAD_ARG. */
    163 extern LOCAL_SYM res_T
    164 check_primitive_uv_2d
    165   (struct sdis_device* dev,
    166    const double u[]);
    167 
    168 /* Check the validity of the parametric coordinates onto a 3D primitive. If
    169  * they are invalid, the function prints an error message and return
    170  * RES_BAD_ARG.  */
    171 extern LOCAL_SYM res_T
    172 check_primitive_uv_3d
    173   (struct sdis_device* dev,
    174    const double uv[]);
    175 
    176 #endif /* SDIS_MISC_H */