3030#include " Raytracer_bw.h"
3131#include " raytracer_kernels_bw.h"
3232#include " types.h"
33+ #include " rte_solver_kernels_cuda_rt.h"
34+ #include " Rte_sw_rt.h"
3335#include " tools_gpu.h"
3436
3537
@@ -129,20 +131,22 @@ void solve_radiation(int argc, char** argv)
129131 // Parse the command line options.
130132 std::map<std::string, std::pair<bool , std::string>> command_line_switches {
131133 {" raytracing" , { true , " Use forward raytracer for irradiances. '--raytracing 256': use 256 rays per pixel" }},
132- {" bw_raytracing" , { true , " Use backward raytracer radiances. '--raytracing 256': use 256 rays per pixel" }},
134+ {" bw-raytracing" , { true , " Use backward raytracer radiances. '--raytracing 256': use 256 rays per pixel" }},
135+ {" two-stream" , { true , " Perform two-stream computations" }},
133136 {" cloud-mie" , { false , " Use Mie tables for cloud scattering in ray tracer" }},
134137 {" independent-column" , { false , " run raytracer in independent column mode" }},
135138 {" profiling" , { false , " Perform additional profiling run." }} };
136139
137140 std::map<std::string, std::pair<int , std::string>> command_line_ints {
138141 {" raytracing" , {32 , " Number of rays initialised at TOD per pixel." }},
139- {" bw_raytracing " , {32 , " Number of rays initialised at per camera pixel." }}} ;
142+ {" bw-raytracing " , {32 , " Number of rays initialised at per camera pixel." }}} ;
140143
141144 if (parse_command_line_options (command_line_switches, command_line_ints, argc, argv))
142145 return ;
143146
144147 const bool switch_raytracing = command_line_switches.at (" raytracing" ).first ;
145- const bool switch_bw_raytracing = command_line_switches.at (" bw_raytracing" ).first ;
148+ const bool switch_bw_raytracing = command_line_switches.at (" bw-raytracing" ).first ;
149+ const bool switch_two_stream = command_line_switches.at (" two-stream" ).first ;
146150 const bool switch_cloud_mie = command_line_switches.at (" cloud-mie" ).first ;
147151 const bool switch_independent_column = command_line_switches.at (" independent-column" ).first ;
148152 const bool switch_profiling = command_line_switches.at (" profiling" ).first ;
@@ -207,6 +211,7 @@ void solve_radiation(int argc, char** argv)
207211 // Read the atmospheric fields.
208212 const Array<Float,2 > tot_tau (input_nc.get_variable <Float>(" tot_tau" , {n_lay, ny, nx}), {ncol, n_lay});
209213 const Array<Float,2 > tot_ssa (input_nc.get_variable <Float>(" tot_ssa" , {n_lay, ny, nx}), {ncol, n_lay});
214+ const Array<Float,2 > tot_asy (input_nc.get_variable <Float>(" tot_asy" , {n_lay, ny, nx}), {ncol, n_lay});
210215
211216 Array<Float,2 > cld_tau ({ncol, n_lay});
212217 Array<Float,2 > cld_ssa ({ncol, n_lay});
@@ -225,13 +230,16 @@ void solve_radiation(int argc, char** argv)
225230 aer_asy = std::move (input_nc.get_variable <Float>(" aer_asy" , {n_lay, ny, nx}));
226231
227232 // read albedo, solar angles, and top-of-domain fluxes
228- Array<Float,2 > sfc_albedo ({1 ,ncol});
229- sfc_albedo.fill (input_nc.get_variable <Float>(" albedo" ));
233+ Array<Float,2 > sfc_albedo ({ncol, 1 });
234+ sfc_albedo = std::move (input_nc.get_variable <Float>(" albedo" , {ny, nx}));
235+
230236 const Float zenith_angle = input_nc.get_variable <Float>(" sza" );
231237 const Float azimuth_angle = input_nc.get_variable <Float>(" azi" );
232238 const Float tod_dir = input_nc.get_variable <Float>(" tod_direct" );
233239
234-
240+ Array<Float,1 > mu0 ({ncol});
241+ mu0.fill (cos (zenith_angle));
242+
235243 Camera camera;
236244 if (switch_bw_raytracing)
237245 {
@@ -267,6 +275,10 @@ void solve_radiation(int argc, char** argv)
267275 Array_gpu<Float,3 > flux_abs_dif ({nx, ny, nz});
268276 Array_gpu<Float,2 > radiance ({camera.nx , camera.ny });
269277
278+ Array_gpu<Float,2 > flux_dn_2stream;
279+ Array_gpu<Float,2 > flux_up_2stream;
280+ Array_gpu<Float,2 > flux_dn_dir_2stream;
281+
270282 // empty arrays (mie scattering not (yet) supported in lite version)
271283 Array<Float,2 > mie_cdfs_c;
272284 Array<Float,3 > mie_angs_c;
@@ -317,34 +329,69 @@ void solve_radiation(int argc, char** argv)
317329 lum_c.fill (Float (0 .));
318330 Array_gpu<Float,1 > land_use_map (lum_c);
319331
320-
332+ // // GPU arrays
333+ Array_gpu<Float,2 > tot_tau_g (tot_tau);
334+ Array_gpu<Float,2 > tot_ssa_g (tot_ssa);
335+ Array_gpu<Float,2 > tot_asy_g (tot_asy);
336+ Array_gpu<Float,2 > cld_tau_g (cld_tau);
337+ Array_gpu<Float,2 > cld_ssa_g (cld_ssa);
338+ Array_gpu<Float,2 > cld_asy_g (cld_asy);
339+ Array_gpu<Float,2 > aer_tau_g (aer_tau);
340+ Array_gpu<Float,2 > aer_ssa_g (aer_ssa);
341+ Array_gpu<Float,2 > aer_asy_g (aer_asy);
342+ Array_gpu<Float,2 > sfc_albedo_g (sfc_albedo);
343+ Array_gpu<Float,1 > mu0_g (mu0);
344+
321345 // //// CREATE THE OUTPUT FILE //////
322346 // Create the general dimensions and arrays.
323347 Status::print_message (" Preparing NetCDF output file." );
324348
325349 Netcdf_file output_nc (" rt_lite_output.nc" , Netcdf_mode::Create);
326- if (switch_raytracing)
350+ if (switch_raytracing || switch_two_stream )
327351 {
328352 output_nc.add_dimension (" x" , nx);
329353 output_nc.add_dimension (" y" , ny);
330- output_nc.add_dimension (" z" , n_z_in);
354+ output_nc.add_dimension (" z" , nz);
355+ output_nc.add_dimension (" lev" , n_lay+1 );
331356 }
332357 if (switch_bw_raytracing)
333358 {
334359 output_nc.add_dimension (" nx" , camera.nx );
335360 output_nc.add_dimension (" ny" , camera.ny );
336361 }
337362
338- // // GPU arrays
339- Array_gpu<Float,2 > tot_tau_g (tot_tau);
340- Array_gpu<Float,2 > tot_ssa_g (tot_ssa);
341- Array_gpu<Float,2 > cld_tau_g (cld_tau);
342- Array_gpu<Float,2 > cld_ssa_g (cld_ssa);
343- Array_gpu<Float,2 > cld_asy_g (cld_asy);
344- Array_gpu<Float,2 > aer_tau_g (aer_tau);
345- Array_gpu<Float,2 > aer_ssa_g (aer_ssa);
346- Array_gpu<Float,2 > aer_asy_g (aer_asy);
347- Array_gpu<Float,2 > sfc_albedo_g (sfc_albedo);
363+
364+ if (switch_two_stream)
365+ {
366+ flux_up_2stream.set_dims ({ncol, n_lay+1 });
367+ flux_dn_2stream.set_dims ({ncol, n_lay+1 });
368+ flux_dn_dir_2stream.set_dims ({ncol, n_lay+1 });
369+
370+ Rte_sw_rt rte_sw;
371+ Rte_solver_kernels_cuda_rt::apply_BC (ncol, n_lay, 1 , 0 , tod_dir * cos (zenith_angle), flux_dn_dir_2stream.ptr ());
372+ Rte_solver_kernels_cuda_rt::apply_BC (ncol, n_lay, 1 , 0 , flux_dn_2stream.ptr ());
373+
374+ Rte_solver_kernels_cuda_rt::sw_solver_2stream (
375+ ncol, n_lay, 1 , 0 ,
376+ tot_tau_g.ptr (),
377+ tot_ssa_g.ptr (),
378+ tot_asy_g.ptr (),
379+ mu0_g.ptr (),
380+ sfc_albedo_g.ptr (), sfc_albedo_g.ptr (),
381+ flux_up_2stream.ptr (), flux_dn_2stream.ptr (), flux_dn_dir_2stream.ptr ());
382+
383+ Array<Float,2 > flux_up_2stream_c (flux_up_2stream);
384+ Array<Float,2 > flux_dn_2stream_c (flux_dn_2stream);
385+ Array<Float,2 > flux_dn_dir_2stream_c (flux_dn_dir_2stream);
386+
387+ auto nc_up_2stream = output_nc.add_variable <Float>(" flux_up_2stream" , {" lev" , " y" , " x" });
388+ auto nc_dn_2stream = output_nc.add_variable <Float>(" flux_dn_2stream" , {" lev" , " y" , " x" });
389+ auto nc_dn_dir_2stream = output_nc.add_variable <Float>(" flux_dn_dir_2stream" , {" lev" , " y" , " x" });
390+
391+ nc_up_2stream.insert (flux_up_2stream_c .v (), {0 , 0 , 0 });
392+ nc_dn_2stream.insert (flux_dn_2stream_c .v (), {0 , 0 , 0 });
393+ nc_dn_dir_2stream.insert (flux_dn_dir_2stream_c .v (), {0 , 0 , 0 });
394+ }
348395
349396 if (switch_raytracing)
350397 {
0 commit comments