atrstm

Load and structure a combustion gas mixture
git clone git://git.meso-star.fr/atrstm.git
Log | Files | Refs | README | LICENSE

atrstm_radcoefs_simd4.c (6244B)


      1 /* Copyright (C) 2022, 2023 |Méso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2020, 2021 Centre National de la Recherche Scientifique
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "atrstm_c.h"
     18 #include "atrstm_log.h"
     19 #include "atrstm_radcoefs.h"
     20 #include "atrstm_radcoefs_simd4.h"
     21 
     22 #include <astoria/atrtp.h>
     23 #include <star/suvm.h>
     24 
     25 #include <rsys/cstr.h>
     26 
     27 /*******************************************************************************
     28  * Local functions
     29  ******************************************************************************/
     30 res_T
     31 fetch_radcoefs_simd4
     32   (const struct atrstm* atrstm,
     33    const struct atrstm_fetch_radcoefs_args* args,
     34    atrstm_radcoefs_T radcoefs)
     35 {
     36   struct radcoefs_simd4 prim_radcoefs;
     37   v4f_T bcoords;
     38   res_T res = RES_OK;
     39 
     40   if(!atrstm
     41   || !check_fetch_radcoefs_args(atrstm, args, FUNC_NAME)
     42   || !radcoefs) {
     43     res = RES_BAD_ARG;
     44     goto error;
     45   }
     46   memset(radcoefs, 0, sizeof(double[ATRSTM_RADCOEFS_COUNT__]));
     47 
     48   /* Compute the radiative properties of the primitive nodes */
     49   res = primitive_compute_radcoefs_simd4(atrstm, &atrstm->refract_id,
     50     &args->prim, args->radcoefs_mask, &prim_radcoefs);
     51   if(res != RES_OK) {
     52     log_err(atrstm,
     53       "Error computing the radiative properties for the primitive %lu -- %s.\n",
     54       (unsigned long)args->prim.iprim,
     55       res_to_cstr(res));
     56     goto error;
     57   }
     58 
     59   bcoords = v4f_set
     60     ((float)args->bcoords[0],
     61      (float)args->bcoords[1],
     62      (float)args->bcoords[2],
     63      (float)args->bcoords[3]);
     64 
     65   /* Linearly interpolate the node radiative properties */
     66   if(args->radcoefs_mask & ATRSTM_RADCOEF_FLAG_Ka) {
     67     const float prim_ka_min = v4f_x(v4f_reduce_min(prim_radcoefs.ka));
     68     const float prim_ka_max = v4f_x(v4f_reduce_max(prim_radcoefs.ka));
     69     radcoefs[ATRSTM_RADCOEF_Ka] = v4f_x(v4f_dot(prim_radcoefs.ka, bcoords));
     70     radcoefs[ATRSTM_RADCOEF_Ka] = /* Handle numerical uncertainty */
     71       CLAMP(radcoefs[ATRSTM_RADCOEF_Ka], prim_ka_min, prim_ka_max);
     72     ASSERT(radcoefs[ATRSTM_RADCOEF_Ka] >= args->k_min[ATRSTM_RADCOEF_Ka]);
     73     ASSERT(radcoefs[ATRSTM_RADCOEF_Ka] <= args->k_max[ATRSTM_RADCOEF_Ka]);
     74   }
     75   if(args->radcoefs_mask & ATRSTM_RADCOEF_FLAG_Ks) {
     76     const float prim_ks_min = v4f_x(v4f_reduce_min(prim_radcoefs.ks));
     77     const float prim_ks_max = v4f_x(v4f_reduce_max(prim_radcoefs.ks));
     78     radcoefs[ATRSTM_RADCOEF_Ks] = v4f_x(v4f_dot(prim_radcoefs.ks, bcoords));
     79     radcoefs[ATRSTM_RADCOEF_Ks] = /* Handle numerical uncertainty */
     80       CLAMP(radcoefs[ATRSTM_RADCOEF_Ks], prim_ks_min, prim_ks_max);
     81     ASSERT(radcoefs[ATRSTM_RADCOEF_Ks] >= args->k_min[ATRSTM_RADCOEF_Ks]);
     82     ASSERT(radcoefs[ATRSTM_RADCOEF_Ks] <= args->k_max[ATRSTM_RADCOEF_Ks]);
     83   }
     84   if(args->radcoefs_mask & ATRSTM_RADCOEF_FLAG_Kext) {
     85     const float prim_kext_min = v4f_x(v4f_reduce_min(prim_radcoefs.kext));
     86     const float prim_kext_max = v4f_x(v4f_reduce_max(prim_radcoefs.kext));
     87     radcoefs[ATRSTM_RADCOEF_Kext] = v4f_x(v4f_dot(prim_radcoefs.kext, bcoords));
     88     radcoefs[ATRSTM_RADCOEF_Kext] = /* Handle numerical uncertainty */
     89       CLAMP(radcoefs[ATRSTM_RADCOEF_Kext], prim_kext_min, prim_kext_max);
     90     ASSERT(radcoefs[ATRSTM_RADCOEF_Kext] >= args->k_min[ATRSTM_RADCOEF_Kext]);
     91     ASSERT(radcoefs[ATRSTM_RADCOEF_Kext] <= args->k_max[ATRSTM_RADCOEF_Kext]);
     92   }
     93 
     94 exit:
     95   return res;
     96 error:
     97   goto exit;
     98 }
     99 
    100 res_T
    101 primitive_compute_radcoefs_simd4
    102   (const struct atrstm* atrstm,
    103    const struct atrri_refractive_index* refract_id,
    104    const struct suvm_primitive* prim,
    105    const int radcoefs_mask, /* Combination of atrstm_radcoef_flag */
    106    struct radcoefs_simd4* radcoefs)
    107 {
    108   struct radcoefs_compute_simd4_args args = RADCOEFS_COMPUTE_SIMD4_ARGS_NULL;
    109   struct atrtp_desc desc = ATRTP_DESC_NULL;
    110   const double* node[4];
    111   res_T res = RES_OK;
    112   ASSERT(atrstm && prim && prim->nvertices == 4 && refract_id && radcoefs);
    113 
    114   res = atrtp_get_desc(atrstm->atrtp, &desc);
    115   if(res != RES_OK) goto error;
    116 
    117   /* Setup the constant input arguments of the optical properties computation
    118    * routine */
    119   args.lambda = v4f_set1((float)refract_id->wavelength);
    120   args.n = v4f_set1((float)refract_id->n);
    121   args.kappa = v4f_set1((float)refract_id->kappa);
    122   args.fractal_prefactor = v4f_set1((float)atrstm->fractal_prefactor);
    123   args.fractal_dimension = v4f_set1((float)atrstm->fractal_dimension);
    124   args.radcoefs_mask = radcoefs_mask;
    125 
    126   /* Fetch the thermodynamic properties of the 4 primitive nodes */
    127   node[0] = atrtp_desc_get_node_properties(&desc, prim->indices[0]);
    128   node[1] = atrtp_desc_get_node_properties(&desc, prim->indices[1]);
    129   node[2] = atrtp_desc_get_node_properties(&desc, prim->indices[2]);
    130   node[3] = atrtp_desc_get_node_properties(&desc, prim->indices[3]);
    131 
    132   /* Scatter Soot properties */
    133   args.soot_volumic_fraction = v4f_set
    134     ((float)node[0][ATRTP_SOOT_VOLFRAC],
    135      (float)node[1][ATRTP_SOOT_VOLFRAC],
    136      (float)node[2][ATRTP_SOOT_VOLFRAC],
    137      (float)node[3][ATRTP_SOOT_VOLFRAC]);
    138   args.soot_primary_particles_count = v4f_set
    139     ((float)node[0][ATRTP_SOOT_PRIMARY_PARTICLES_COUNT],
    140      (float)node[1][ATRTP_SOOT_PRIMARY_PARTICLES_COUNT],
    141      (float)node[2][ATRTP_SOOT_PRIMARY_PARTICLES_COUNT],
    142      (float)node[3][ATRTP_SOOT_PRIMARY_PARTICLES_COUNT]);
    143   args.soot_primary_particles_diameter = v4f_set
    144     ((float)node[0][ATRTP_SOOT_PRIMARY_PARTICLES_DIAMETER],
    145      (float)node[1][ATRTP_SOOT_PRIMARY_PARTICLES_DIAMETER],
    146      (float)node[2][ATRTP_SOOT_PRIMARY_PARTICLES_DIAMETER],
    147      (float)node[3][ATRTP_SOOT_PRIMARY_PARTICLES_DIAMETER]);
    148 
    149   /* Compute the per primitive node optical properties */
    150   radcoefs_compute_simd4(radcoefs, &args);
    151 
    152 exit:
    153   return res;
    154 error:
    155   goto exit;
    156 }