NASA Logo
Ocean Color Science Software

ocssw V2022
getglint.c
Go to the documentation of this file.
1 #include "glint.h"
2 
3 #ifndef M_PI
4 #define M_PI 3.1415926
5 #endif
6 const static double degra = M_PI / 180.e0;
7 #define DSIGN(A, B) (B >= 0 ? fabs(A) : -fabs(A))
8 
9 double acoss(double x) {
10  if (x > 1.0)
11  return 0;
12  else if (x < -1.0)
13  return M_PI;
14  else
15  return acos(x);
16 }
17 
18 double asinn(double x) {
19  if (x > 1.0)
20  return M_PI / 2;
21  else if (x < -1.0)
22  return -M_PI / 2;
23  else
24  return asin(x);
25 }
26 
52 void reflec_both(double inc_angle, double *Effective_Refl, double *BiRefl) {
53  const double ref = 4.0e0 / 3.0e0; // water ref index, no wavelength dependencies
54  double refract_angle, Rs, Rp;
55  if (inc_angle < 0.00001) {
56  *Effective_Refl = .0204078;
57  *BiRefl = 0.;
58  } else {
59  refract_angle = asin(sin(inc_angle) / ref); // Snell's law
60  Rs = (sin(inc_angle - refract_angle) / sin(inc_angle + refract_angle));
61  Rs *= Rs;
62  Rp = (tan(inc_angle - refract_angle) / tan(inc_angle + refract_angle));
63  Rp *= Rp;
64  *Effective_Refl = Rs + Rp;
65  *Effective_Refl = *Effective_Refl / 2.;
66  *BiRefl = -Rs + Rp;
67  *BiRefl = *BiRefl / 2.;
68  }
69 }
70 
71 void reflec_(float *inc_angle, float *Effective_Refl) {
72  double BiRefl, effective_Refl, inc_angle_;
73  inc_angle_ = (double)(*inc_angle);
74  reflec_both(inc_angle_, &effective_Refl, &BiRefl);
75  *Effective_Refl = (float)effective_Refl;
76 }
77 
78 void getglint_iqu(float senz, float solz, float raz, float ws, float chi, float *glint_coef,
79  float *glint_coef_q, float *glint_coef_u) {
80  const double deg_cuttof = 1e-7;
81  // from Cox & Munk, 54
82  const double ws_gl = .04964e0;
83  float ws_ = fmax(ws, 0.001f);
84  double senz_ = senz * degra;
85  double solz_ = solz * degra;
86  double raz_ = raz * degra;
87  if (senz_ == 0.0)
88  senz_ = deg_cuttof;
89  if (solz_ == 0.0)
90  solz_ = deg_cuttof;
91  if (raz_ == 0.0)
92  raz_ = deg_cuttof;
93  double argument = cos(senz_) * cos(solz_) -
94  sin(senz_) * sin(solz_) *
95  cos(raz_); // dot product of two vectors, the incident ray and the reflected ray
96  // relaz = senaz - 180 - solaz
97  double omega = acoss(argument) / 2.0e0;
98  if (omega == 0.0)
99  omega = deg_cuttof;
100  argument = (cos(senz_) + cos(solz_)) / (2.0e0 * cos(omega));
101  double beta = acoss(argument);
102  if (beta == 0.0)
103  beta = deg_cuttof;
104  double sigc = ws_gl * sqrt(ws_);
105  double expon = -tan(beta) * tan(beta) / 2. / sigc / sigc;
106  if (expon < -30.)
107  expon = -30.; // ! trap underflow
108  if (expon > 30.)
109  expon = +30.; // ! trap overflow
110  double prob = exp(expon) / (2. * M_PI * sigc * sigc);
111  double BiRefl, effective_refl;
112  reflec_both(omega, &effective_refl, &BiRefl);
113  double cs_beta2 = cos(beta) * cos(beta);
114  double cs_beta4 = cs_beta2 * cs_beta2;
115  *glint_coef = effective_refl * prob / (4.0e0 * cos(senz_) * cs_beta4);
116  double rot_ang;
117  if (omega > 0.0001) {
118  double CR = (cos(solz_) - cos(2. * omega) * cos(senz_)) / (sin(2. * omega) * sin(solz_));
119  double SR = sin(solz_) * sin(M_PI - raz_) / sin(2. * omega);
120  rot_ang = DSIGN(1.0, CR) * asinn(SR);
121  } else {
122  rot_ang = M_PI / 2;
123  }
124  double c2r = cos(2. * rot_ang);
125  double s2r = sin(2. * rot_ang);
126  *glint_coef_q = c2r * BiRefl / effective_refl;
127  *glint_coef_u = -s2r * BiRefl / effective_refl;
128 }
129 
130 void getglint_(float *senz, float *solz, float *raz, float *ws, float *chi, float *glint_coef) {
131  float glint_coef_q, glint_coef_u;
132  getglint_iqu(*senz, *solz, *raz, *ws, *chi, glint_coef, &glint_coef_q, &glint_coef_u);
133 }
134 
135 void getglint_iqu_(float *senz, float *solz, float *raz, float *ws, float *chi, float *glint_coef,
136  float *glint_coef_q, float *glint_coef_u) {
137  getglint_iqu(*senz, *solz, *raz, *ws, *chi, glint_coef, glint_coef_q, glint_coef_u);
138 }
double acoss(double x)
Definition: getglint.c:9
#define DSIGN(A, B)
Definition: getglint.c:7
#define M_PI
Definition: getglint.c:4
void getglint_(float *senz, float *solz, float *raz, float *ws, float *chi, float *glint_coef)
Definition: getglint.c:130
double precision function f(R1)
Definition: tmd.lp.f:1454
data_t omega[NROOTS+1]
Definition: decode_rs.h:77
void reflec_(float *inc_angle, float *Effective_Refl)
Definition: getglint.c:71
integer, parameter double
double beta
double asinn(double x)
Definition: getglint.c:18
void reflec_both(double inc_angle, double *Effective_Refl, double *BiRefl)
C inc_angle Incident angle (radians) C Rs Reflectivity s polarized C Rp Reflectivity p polarized C C ...
Definition: getglint.c:52
void getglint_iqu_(float *senz, float *solz, float *raz, float *ws, float *chi, float *glint_coef, float *glint_coef_q, float *glint_coef_u)
Definition: getglint.c:135
void getglint_iqu(float senz, float solz, float raz, float ws, float chi, float *glint_coef, float *glint_coef_q, float *glint_coef_u)
Get the glint iqu object.
Definition: getglint.c:78