htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

htrdr_atmosphere_sun.c (4674B)


      1 /* Copyright (C) 2018-2019, 2022-2025 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux
      3  * Copyright (C) 2022-2025 Institut Pierre-Simon Laplace
      4  * Copyright (C) 2022-2025 Institut de Physique du Globe de Paris
      5  * Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com)
      6  * Copyright (C) 2022-2025 Observatoire de Paris
      7  * Copyright (C) 2022-2025 Université de Reims Champagne-Ardenne
      8  * Copyright (C) 2022-2025 Université de Versaille Saint-Quentin
      9  * Copyright (C) 2018-2019, 2022-2025 Université Paul Sabatier
     10  *
     11  * This program is free software: you can redistribute it and/or modify
     12  * it under the terms of the GNU General Public License as published by
     13  * the Free Software Foundation, either version 3 of the License, or
     14  * (at your option) any later version.
     15  *
     16  * This program is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     19  * GNU General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU General Public License
     22  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     23 
     24 #include "atmosphere/htrdr_atmosphere_c.h"
     25 #include "atmosphere/htrdr_atmosphere_sun.h"
     26 
     27 #include "core/htrdr.h"
     28 #include "core/htrdr_log.h"
     29 
     30 #include <rsys/algorithm.h>
     31 #include <rsys/double33.h>
     32 #include <rsys/ref_count.h>
     33 #include <rsys/math.h>
     34 
     35 #include <star/ssp.h>
     36 
     37 struct htrdr_atmosphere_sun {
     38   double half_angle; /* In radian */
     39   double cos_half_angle;
     40   double solid_angle; /* In sr; solid_angle = 2*PI*(1 - cos(half_angle)) */
     41   double frame[9];
     42   double temperature; /* In K */
     43 
     44   ref_T ref;
     45   struct htrdr* htrdr;
     46 };
     47 
     48 /*******************************************************************************
     49  * Helper functions
     50  ******************************************************************************/
     51 static void
     52 release_sun(ref_T* ref)
     53 {
     54   struct htrdr_atmosphere_sun* sun;
     55   struct htrdr* htrdr;
     56   ASSERT(ref);
     57   sun = CONTAINER_OF(ref, struct htrdr_atmosphere_sun, ref);
     58   htrdr = sun->htrdr;
     59   MEM_RM(htrdr_get_allocator(htrdr), sun);
     60   htrdr_ref_put(htrdr);
     61 }
     62 
     63 /*******************************************************************************
     64  * Local functions
     65  ******************************************************************************/
     66 res_T
     67 htrdr_atmosphere_sun_create
     68   (struct htrdr* htrdr,
     69    struct htrdr_atmosphere_sun** out_sun)
     70 {
     71   const double main_dir[3] = {0, 0, 1}; /* Default main sun direction */
     72   struct htrdr_atmosphere_sun* sun = NULL;
     73   res_T res = RES_OK;
     74   ASSERT(htrdr && out_sun);
     75 
     76   sun = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*sun));
     77   if(!sun) {
     78     htrdr_log_err(htrdr, "could not allocate the sun data structure.\n");
     79     res = RES_MEM_ERR;
     80     goto error;
     81   }
     82   ref_init(&sun->ref);
     83 
     84   sun->half_angle = 4.6524e-3;
     85   sun->temperature = 5778;
     86   sun->cos_half_angle = cos(sun->half_angle);
     87   sun->solid_angle = 2*PI*(1-sun->cos_half_angle);
     88   d33_basis(sun->frame, main_dir);
     89   htrdr_ref_get(htrdr);
     90   sun->htrdr = htrdr;
     91 
     92 exit:
     93   *out_sun = sun;
     94   return res;
     95 error:
     96   if(sun) {
     97     htrdr_atmosphere_sun_ref_put(sun);
     98     sun = NULL;
     99   }
    100   goto exit;
    101 }
    102 
    103 void
    104 htrdr_atmosphere_sun_ref_get(struct htrdr_atmosphere_sun* sun)
    105 {
    106   ASSERT(sun);
    107   ref_get(&sun->ref);
    108 }
    109 
    110 void
    111 htrdr_atmosphere_sun_ref_put(struct htrdr_atmosphere_sun* sun)
    112 {
    113   ASSERT(sun);
    114   ref_put(&sun->ref, release_sun);
    115 }
    116 
    117 void
    118 htrdr_atmosphere_sun_set_direction
    119   (struct htrdr_atmosphere_sun* sun,
    120    const double dir[3])
    121 {
    122   ASSERT(sun && dir && d3_is_normalized(dir));
    123   d33_basis(sun->frame, dir);
    124 }
    125 
    126 double
    127 htrdr_atmosphere_sun_sample_direction
    128   (struct htrdr_atmosphere_sun* sun,
    129    struct ssp_rng* rng,
    130    double dir[3])
    131 {
    132   ASSERT(sun && rng && dir);
    133   ssp_ran_sphere_cap_uniform_local(rng, sun->cos_half_angle, dir, NULL);
    134   d33_muld3(dir, sun->frame, dir);
    135   return 1.0 / htrdr_atmosphere_sun_get_solid_angle(sun);
    136 }
    137 
    138 double
    139 htrdr_atmosphere_sun_get_solid_angle(const struct htrdr_atmosphere_sun* sun)
    140 {
    141   ASSERT(sun);
    142   return sun->solid_angle;
    143 }
    144 
    145 double
    146 htrdr_atmosphere_sun_get_radiance
    147   (const struct htrdr_atmosphere_sun* sun,
    148    const double wlen/*In nm*/)
    149 {
    150   return htrdr_planck_monochromatic
    151     (wlen*1.e-9/*From nm to m*/, sun->temperature);
    152 }
    153 
    154 int
    155 htrdr_atmosphere_sun_is_dir_in_solar_cone
    156   (const struct htrdr_atmosphere_sun* sun,
    157    const double dir[3])
    158 {
    159   const double* main_dir;
    160   double dot;
    161   ASSERT(sun && dir && d3_is_normalized(dir));
    162   ASSERT(d3_is_normalized(sun->frame + 6));
    163   main_dir = sun->frame + 6;
    164   dot = d3_dot(dir, main_dir);
    165   return dot >= sun->cos_half_angle;
    166 }
    167