@@ -87,104 +87,62 @@ namespace Raytracer_functions
8787 }
8888
8989 __device__
90- inline Float mie_sample_angle (const Float * mie_cdf, const Float* mie_lut , const Float random_number, const Float r_eff, const int n_mie )
90+ inline int find_index (const float * mie_cdf, const int size , const float random_number)
9191 {
92- // interpolation over effective radius. Currently, r_eff should range between 2.5 and 21.5 (similar to RRTMGP) OR
93- // be exactly 100 micrometer for optical effects such as rainbows
94- const int r_idx = (r_eff == Float (100 .)) ? 20 : min (max (int (r_eff-2.5 ), 0 ), 18 );
95- const Float r_rest = fmod (r_eff-Float (2.5 ),Float (1 .));
92+ int left = 0 ;
93+ int right = size - 1 ;
9694
97- int i = 0 ;
98- while (random_number < mie_cdf[i])
99- {
100- ++i;
101- }
95+ while (left < right) {
96+ int mid = left + (right - left) / 2 ;
10297
103- // sampled scattering angle
104- Float ang;
105- if (r_idx < 20 )
106- {
107- if (i==0 )
108- {
109- const Float ang_lwr = mie_lut[r_idx*n_mie]*(1 -r_rest);
110- const Float ang_upr = mie_lut[(r_idx+1 )*n_mie]*r_rest;
111- ang = ang_lwr + ang_upr;
112- }
113- else
114- {
115- const int midx_lwr = r_idx*n_mie;
116- const int midx_upr = (r_idx+1 )*n_mie;
117- const Float dr = abs (mie_cdf[i] - mie_cdf[i-1 ]);
118-
119- const Float ang_lwr = (abs (random_number - mie_cdf[i])*mie_lut[(i-1 )+midx_lwr] + abs (mie_cdf[i-1 ]-random_number)*mie_lut[i+midx_lwr]) / dr;
120- const Float ang_upr = (abs (random_number - mie_cdf[i])*mie_lut[(i-1 )+midx_upr] + abs (mie_cdf[i-1 ]-random_number)*mie_lut[i+midx_upr]) / dr;
121- ang = ang_lwr * (1 -r_rest) + ang_upr * r_rest;
98+ if (random_number >= mie_cdf[mid]) {
99+ right = mid;
100+ } else {
101+ left = mid + 1 ;
122102 }
123103 }
124- else
125- {
126- if (i==0 )
127- {
128- ang = mie_lut[r_idx*n_mie];
129- }
130- else
131- {
132- const int midx = r_idx*n_mie;
133- const Float dr = abs (mie_cdf[i] - mie_cdf[i-1 ]);
134104
135- ang = (abs (random_number - mie_cdf[i])*mie_lut[(i-1 )+midx] + abs (mie_cdf[i-1 ]-random_number)*mie_lut[i+midx]) / dr;
136- }
137- }
105+ return left - 1 ;
106+ }
107+
108+ __device__
109+ inline Float mie_sample_angle (const Float* mie_cdf, const Float* mie_lut, const Float random_number, const Float r_eff, const int n_mie)
110+ {
111+ // interpolation over effective radius. Currently, r_eff should range between 2.5 and 21.5 (similar to RRTMGP)
112+ const int r_idx = min (max (int (r_eff-2.5 ), 0 ), 18 );
113+ const Float r_rest = fmod (r_eff-Float (2.5 ),Float (1 .));
114+
115+ const int i = min (max (0 , find_index (mie_cdf, n_mie, random_number)), n_mie - 2 );
116+
117+ const int midx_lwr = r_idx*n_mie;
118+ const int midx_upr = (r_idx+1 )*n_mie;
119+ const Float dr = abs (mie_cdf[i+1 ] - mie_cdf[i]);
120+
121+ const Float ang_lwr = (abs (random_number - mie_cdf[i+1 ])*mie_lut[(i)+midx_lwr] + abs (mie_cdf[i]-random_number)*mie_lut[i+midx_lwr+1 ]) / dr;
122+ const Float ang_upr = (abs (random_number - mie_cdf[i+1 ])*mie_lut[(i)+midx_upr] + abs (mie_cdf[i]-random_number)*mie_lut[i+midx_upr+1 ]) / dr;
123+ const Float ang = ang_lwr * (1 -r_rest) + ang_upr * r_rest;
138124 return ang;
139125 }
140126
141127 __device__
142128 inline Float mie_interpolate_phase_table (const Float* mie_phase, const Float* mie_lut, const Float scat_ang, const Float r_eff, const int n_mie)
143129 {
144- // interpolation over effective radius. Currently, r_eff should range between 2.5 and 21.5 (similar to RRTMGP) OR
145- // be exactly 100 micrometer for optical effects such as rainbows
146- const int r_idx = (r_eff == Float (100 .)) ? 20 : min (max (int (r_eff-2.5 ), 0 ), 18 );
130+ // interpolation over effective radius. Currently, r_eff should range between 2.5 and 21.5 (similar to RRTMGP)
131+ const int r_idx = min (max (int (r_eff-2.5 ), 0 ), 18 );
147132 const Float r_rest = fmod (r_eff-Float (2.5 ),Float (1 .));
148133
149134 // interpolation between 1800 equally spaced scattering angles between 0 and PI (both inclusive).
150- const Float d_pi = Float (1.74629942e-03 );
151- const int i = min (max (0 , int (1800 -( scat_ang/d_pi+ 1 ) )), 1798 );
135+ constexpr Float d_pi = Float (1.74629942e-03 );
136+ const int i = min (max (0 , int (scat_ang/d_pi)), 1798 );
152137
153- // probability (of scattering at angle scat_ang)
154- Float prob;
155- if (r_idx < 20 )
156- {
157- if (i==0 )
158- {
159- const Float prob_lwr = mie_lut[r_idx*n_mie]*(1 -r_rest);
160- const Float prob_upr = mie_lut[(r_idx+1 )*n_mie]*r_rest;
161- prob = prob_lwr + prob_upr;
162- }
163- else
164- {
165- const int midx_lwr = r_idx*n_mie;
166- const int midx_upr = (r_idx+1 )*n_mie;
167- const Float dr = abs (mie_phase[i] - mie_phase[i-1 ]);
168-
169- const Float prob_lwr = (abs (scat_ang - mie_phase[i])*mie_lut[(i-1 )+midx_lwr] + abs (mie_phase[i-1 ]-scat_ang)*mie_lut[i+midx_lwr]) / dr;
170- const Float prob_upr = (abs (scat_ang - mie_phase[i])*mie_lut[(i-1 )+midx_upr] + abs (mie_phase[i-1 ]-scat_ang)*mie_lut[i+midx_upr]) / dr;
171- prob = prob_lwr * (1 -r_rest) + prob_upr * r_rest;
172- }
173- }
174- else
175- {
176- if (i==0 )
177- {
178- prob = mie_lut[r_idx*n_mie];
179- }
180- else
181- {
182- const int midx = r_idx*n_mie;
183- const Float dr = abs (mie_phase[i] - mie_phase[i-1 ]);
138+ const int midx_lwr = r_idx*n_mie;
139+ const int midx_upr = (r_idx+1 )*n_mie;
140+ const Float dr = abs (mie_phase[i+1 ] - mie_phase[i]);
141+
142+ const Float prob_lwr = (abs (scat_ang - mie_phase[i+1 ])*mie_lut[(i)+midx_lwr] + abs (mie_phase[i]-scat_ang)*mie_lut[i+1 +midx_lwr]) / dr;
143+ const Float prob_upr = (abs (scat_ang - mie_phase[i+1 ])*mie_lut[(i)+midx_upr] + abs (mie_phase[i]-scat_ang)*mie_lut[i+1 +midx_upr]) / dr;
144+ const Float prob = prob_lwr * (1 -r_rest) + prob_upr * r_rest;
184145
185- prob = (abs (scat_ang - mie_phase[i])*mie_lut[(i-1 )+midx] + abs (mie_phase[i-1 ]-scat_ang)*mie_lut[i+midx]) / dr;
186- }
187- }
188146 return prob;
189147 }
190148
0 commit comments