Skip to content

Commit 812e32c

Browse files
authored
Merge pull request #60 from MennoVeerman/main
Fix bugs in tilting aerosols concentrations in tica mode.
2 parents d12778a + c3cd9fa commit 812e32c

File tree

10 files changed

+368
-298
lines changed

10 files changed

+368
-298
lines changed

include_rt_kernels/raytracer_kernels_bw.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ constexpr int bw_kernel_grid = 256;
2727
// sun has a half angle of .266 degrees
2828
constexpr Float cos_half_angle = Float(0.9999891776066407); // cos(half_angle);
2929
constexpr Float sun_solid_angle = Float(6.799910294339209e-05); // 2.*M_PI*(1-cos_half_angle);
30-
constexpr Float sun_solid_angle_reciprocal = Float(14706.07635563193);
30+
constexpr Float sun_solid_angle_reciprocal = Float(14706.07635563193);
3131

3232

3333
struct Grid_knull
@@ -40,7 +40,7 @@ struct Grid_knull
4040
struct Camera
4141
{
4242
Vector<Float> position;
43-
bool fisheye = true;
43+
int cam_type; // (0: fisheye, 1: rectangular, 2: top-of-atmosphere radiances)
4444

4545
// rotation matrix for fisheye version - we need to do implement this in a nice way at some point
4646
Vector<Float> mx;
@@ -66,17 +66,17 @@ struct Camera
6666

6767
void setup_normal_camera(const Camera camera)
6868
{
69-
if (!fisheye)
69+
if (camera.cam_type != 0)
7070
{
7171
const Vector<Float> dir_tmp = {1, 0, 0};
72+
const Vector<Float> dir_up = {0, 0, 1};
73+
7274
const Vector<Float> dir_cam = normalize(Vector<Float>({dot(camera.mx,dir_tmp), dot(camera.my,dir_tmp), dot(camera.mz,dir_tmp)}));
73-
const Vector<Float> dir_up_tmp = {0, 0, 1};
74-
const Vector<Float> dir_up = normalize(Vector<Float>({dot(camera.mx,dir_up_tmp), dot(camera.my,dir_up_tmp), dot(camera.mz,dir_up_tmp)}));
7575

76+
cam_height = normalize(Vector<Float>({dot(camera.mx, dir_up), dot(camera.my,dir_up), dot(camera.mz,dir_up)}));
7677
cam_width = Float(-1) * normalize(cross(dir_cam, dir_up));
77-
cam_height = normalize(cross(dir_cam, cam_width));
7878
cam_depth = dir_cam / tan(fov/Float(180)*M_PI/Float(2.));
79-
79+
8080
if (camera.nx > camera.ny)
8181
cam_height = cam_height * Float(camera.ny)/Float(camera.nx);
8282
else if (camera.ny > camera.nx)

include_tilt/tilt_utils.h

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,35 @@ void post_process_output(const std::vector<ColumnResult>& col_results,
4545
const bool switch_liq_cloud_optics,
4646
const bool switch_ice_cloud_optics);
4747

48-
void restore_bkg_profile(const int n_x, const int n_y,
48+
void restore_bkg_profile(const int n_x, const int n_y,
4949
const int n_full,
50-
const int n_tilt,
51-
const int bkg_start,
50+
const int n_tilt,
51+
const int bkg_start,
5252
std::vector<Float>& var,
5353
std::vector<Float>& var_w_bkg);
5454

55-
void restore_bkg_profile_bundle(const int n_col_x, const int n_col_y,
56-
const int n_lay, const int n_lev,
57-
const int n_lay_tot, const int n_lev_tot,
55+
void restore_bkg_profile_bundle(const int n_col_x, const int n_col_y,
56+
const int n_lay, const int n_lev,
57+
const int n_lay_tot, const int n_lev_tot,
5858
const int n_z_in, const int n_zh_in,
59-
const int bkg_start_z, const int bkg_start_zh,
60-
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
61-
Array<Float,2>* lwp_copy, Array<Float,2>* iwp_copy, Array<Float,2>* rel_copy, Array<Float,2>* dei_copy, Array<Float,2>* rh_copy,
59+
const int bkg_start_z, const int bkg_start_zh,
60+
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
61+
Array<Float,2>* lwp_copy, Array<Float,2>* iwp_copy, Array<Float,2>* rel_copy, Array<Float,2>* dei_copy, Array<Float,2>* rh_copy,
6262
Gas_concs& gas_concs_copy, Aerosol_concs& aerosol_concs_copy,
63-
Array<Float,2>* p_lay, Array<Float,2>* t_lay, Array<Float,2>* p_lev, Array<Float,2>* t_lev,
64-
Array<Float,2>* lwp, Array<Float,2>* iwp, Array<Float,2>* rel, Array<Float,2>* dei, Array<Float,2>* rh,
65-
Gas_concs& gas_concs, Aerosol_concs& aerosol_concs,
63+
Array<Float,2>* p_lay, Array<Float,2>* t_lay, Array<Float,2>* p_lev, Array<Float,2>* t_lev,
64+
Array<Float,2>* lwp, Array<Float,2>* iwp, Array<Float,2>* rel, Array<Float,2>* dei, Array<Float,2>* rh,
65+
Gas_concs& gas_concs, Aerosol_concs& aerosol_concs,
6666
std::vector<std::string> gas_names, std::vector<std::string> aerosol_names,
6767
bool switch_liq_cloud_optics, bool switch_ice_cloud_optics, bool switch_aerosol_optics
6868
);
6969

70-
void compress_columns_weighted_avg(const int n_x, const int n_y,
71-
const int n_out,
70+
void compress_columns_weighted_avg(const int n_x, const int n_y,
71+
const int n_out,
7272
const int n_tilt,
7373
const int compress_lay_start_idx,
7474
std::vector<Float>& var, std::vector<Float>& var_weighting);
7575

76-
void compress_columns_p_or_t(const int n_x, const int n_y,
76+
void compress_columns_p_or_t(const int n_x, const int n_y,
7777
const int n_out_lay, const int n_tilt,
7878
const int compress_lay_start_idx,
7979
std::vector<Float>& var_lev, std::vector<Float>& var_lay);
@@ -82,16 +82,16 @@ void tilt_fields(const int n_z_in, const int n_zh_in, const int n_col_x, const i
8282
const int n_z_tilt, const int n_zh_tilt, const int n_col,
8383
const Array<Float,1> zh, const Array<Float,1> z,
8484
const Array<Float,1> zh_tilt, const Array<ijk,1> path,
85-
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
86-
Array<Float,2>* rh_copy,
85+
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
86+
Array<Float,2>* rh_copy,
8787
Gas_concs& gas_concs_copy, const std::vector<std::string> gas_names,
8888
Aerosol_concs& aerosol_concs_copy, const std::vector<std::string> aerosol_names, const bool switch_aerosol_optics
8989
);
9090

9191
void compress_fields(const int compress_lay_start_idx, const int n_col_x, const int n_col_y,
9292
const int n_z_in, const int n_zh_in, const int n_z_tilt,
93-
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
94-
Array<Float,2>* rh_copy,
93+
Array<Float,2>* p_lay_copy, Array<Float,2>* t_lay_copy, Array<Float,2>* p_lev_copy, Array<Float,2>* t_lev_copy,
94+
Array<Float,2>* rh_copy,
9595
Gas_concs& gas_concs_copy, std::vector<std::string> gas_names,
9696
Aerosol_concs& aerosol_concs_copy, std::vector<std::string> aerosol_names, const bool switch_aerosol_optics);
9797

@@ -114,11 +114,11 @@ void tica_tilt(const Float sza, const Float azi,
114114
const int n_col_x, const int n_col_y, const int n_col,
115115
const int n_lay, const int n_lev, const int n_z_in, const int n_zh_in ,
116116
Array<Float,1> xh, Array<Float,1> yh, Array<Float,1> zh, Array<Float,1> z,
117-
Array<Float,2> p_lay, Array<Float,2> t_lay, Array<Float,2> p_lev, Array<Float,2> t_lev,
118-
Array<Float,2> lwp, Array<Float,2> iwp, Array<Float,2> rel, Array<Float,2> dei, Array<Float,2> rh,
117+
Array<Float,2> p_lay, Array<Float,2> t_lay, Array<Float,2> p_lev, Array<Float,2> t_lev,
118+
Array<Float,2> lwp, Array<Float,2> iwp, Array<Float,2> rel, Array<Float,2> dei, Array<Float,2> rh,
119119
Gas_concs gas_concs, Aerosol_concs aerosol_concs,
120-
Array<Float,2>& p_lay_out, Array<Float,2>& t_lay_out, Array<Float,2>& p_lev_out, Array<Float,2>& t_lev_out,
121-
Array<Float,2>& lwp_out, Array<Float,2>& iwp_out, Array<Float,2>& rel_out, Array<Float,2>& dei_out, Array<Float,2>& rh_out,
122-
Gas_concs& gas_concs_out, Aerosol_concs aerosol_concs_out,
120+
Array<Float,2>& p_lay_out, Array<Float,2>& t_lay_out, Array<Float,2>& p_lev_out, Array<Float,2>& t_lev_out,
121+
Array<Float,2>& lwp_out, Array<Float,2>& iwp_out, Array<Float,2>& rel_out, Array<Float,2>& dei_out, Array<Float,2>& rh_out,
122+
Gas_concs& gas_concs_out, Aerosol_concs& aerosol_concs_out,
123123
std::vector<std::string> gas_names, std::vector<std::string> aerosol_names,
124124
bool switch_cloud_optics, bool switch_liq_cloud_optics, bool switch_ice_cloud_optics, bool switch_aerosol_optics);

python/image_from_xyz.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@
7272

7373
# reshape RGB array
7474
RGB = RGB.reshape((3, ny, nx))
75-
RGB = RGB.swapaxes(0,2).swapaxes(0,1)[::-1,:]
76-
75+
RGB = RGB.swapaxes(0,2).swapaxes(0,1)[:,:]
76+
7777
# plot
7878
fig,ax = pl.subplots(figsize=(nx/args.dpi, ny/args.dpi), frameon=False)
7979
ax.grid(False)

python/set_virtual_camera.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
"yaw": "Horizontal direction of camera, 0: east, 90: north, 180/-180: weast, -90/270: south",
1818
"pitch": "Vertical direction of camera, -90: vertical upward, 0: horizontal, 90: vertically downward.",
1919
"roll": "Roll of camera over the direction of camera",
20-
"fisheye": "Whether to use fisheye lens (1) or a rectangular/square lens (0)",
21-
"f_zoom": "Zoom factor (if fisheye=1)",
20+
"cam_type": "camera type (0: fisheye lens, 1: rectangular lens, 2: top-of-atmosphere upwelling radiance)",
2221
"fov": "Field of view (if fisheye=0)",
2322
"px": "Location of camera in x-direction",
2423
"py": "Location of camera in y-direction",
@@ -30,6 +29,7 @@
3029
parser = argparse.ArgumentParser()
3130
parser.add_argument("--radiance", action='store_true', help="example settings for computing hemispheric radiance distributions with a sky view camera")
3231
parser.add_argument("--image", action='store_true', help="example settings for creating visual images with a square camera looking horizontally")
32+
parser.add_argument("--toa", action='store_true', help="example settings for obtaining top-of-atmosphere radiances")
3333
parser.add_argument("--sza", type=float, help="solar zenith angle")
3434
parser.add_argument("--azi", type=float, help="solar azimuth angle")
3535
parser.add_argument("--name", type=str, default='rte_rrtmgp_input.nc', help="raytracer input file")
@@ -54,17 +54,16 @@
5454
# add variables: if not available yet
5555
for var in camera_variables:
5656
try:
57-
cam.createVariable(var,"f8")
57+
cam.createVariable(var,"i4" if var in ['cam_type'] else "f8")
5858
except:
5959
pass
6060

61-
# example radiance settings
61+
# example camera radiance settings
6262
if args['radiance']:
6363
cam["yaw"][:] = 0
6464
cam["pitch"][:] = -90
6565
cam["roll"][:] = 0
66-
cam["fisheye"][:]= 1
67-
cam["f_zoom"][:]= 1
66+
cam["cam_type"][:]= 1
6867
cam["fov"][:] = 80
6968
cam["px"][:] = 0
7069
cam["py"][:] = 0
@@ -77,22 +76,27 @@
7776
cam["yaw"][:] = 0
7877
cam["pitch"][:] = 0
7978
cam["roll"][:] = 0
80-
cam["fisheye"][:]= 0
81-
cam["f_zoom"][:]= 1
79+
cam["cam_type"][:]= 0
8280
cam["fov"][:] = 80
8381
cam["px"][:] = 0.
8482
cam["py"][:] = 0.
8583
cam["pz"][:] = 500.
8684
cam["nx"][:] = 256
8785
cam["ny"][:] = 256
8886

87+
# example toa-radiance settings
88+
if args['toa']:
89+
cam["cam_type"][:]= 2
90+
cam["nx"][:] = 256
91+
cam["ny"][:] = 256
92+
8993
for var in camera_variables:
9094
if not args[var] is None:
9195
cam[var][:] = args[var]
9296

9397
if not args['sza'] is None:
9498
try:
95-
ncf.createVariable('sza','f4',ncf['mu0'].dimensions)
99+
ncf.createVariable('sza','f4',ncf['mu0'].dimensions)
96100
except:
97101
pass
98102
ncf['sza'][:] = np.deg2rad(args['sza'])
@@ -103,8 +107,12 @@
103107

104108
print("Camera settings:")
105109
for v in camera_variables.keys():
106-
print("{:6}{:>8}".format(v, str(cam[v][:])))
107-
print("{:6}{:>8}".format("sza", str(np.round(np.rad2deg(np.arccos(ncf['mu0'][:].flatten()[0])),1))))
108-
print("{:6}{:>8}".format("azi", str(np.round(np.rad2deg(ncf['azi'][:].flatten()[0]),1))))
110+
if v == 'cam_type':
111+
icam = int(cam[v][:])
112+
print("{:8}{:>8} ({:s})".format(v, str(icam), ['fisheye','rectangular','TOA radiance'][icam]))
113+
else:
114+
print("{:8}{:>8}".format(v, str(cam[v][:])))
115+
print("{:8}{:>8}".format("sza", str(np.round(np.rad2deg(np.arccos(ncf['mu0'][:].flatten()[0])),1))))
116+
print("{:8}{:>8}".format("azi", str(np.round(np.rad2deg(ncf['azi'][:].flatten()[0]),1))))
109117

110118
ncf.close()

src_kernels_cuda_rt/raytracer_kernels_bw.cu

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,23 +196,53 @@ namespace
196196
const Float i = (Float(ij_cam % camera.nx) + rng())/ Float(camera.nx);
197197
const Float j = (Float(ij_cam / camera.nx) + rng())/ Float(camera.ny);
198198

199-
if (camera.fisheye)
199+
200+
if (camera.cam_type == 0)
200201
{
201-
const Float photon_zenith = i * Float(.5) * M_PI / camera.f_zoom;
202+
// Fish eye camera
203+
const Float photon_zenith = i * Float(.5) * camera.fov / Float(180.) * M_PI;
202204
const Float photon_azimuth = j * Float(2.) * M_PI;
203-
const Vector<Float> dir_tmp = {sin(photon_zenith) * sin(photon_azimuth), sin(photon_zenith) * cos(photon_azimuth), cos(photon_zenith)};
205+
const Vector<Float> dir_tmp = {cos(photon_zenith), sin(photon_zenith) * cos(photon_azimuth), sin(photon_zenith) * sin(photon_azimuth)};
204206

205207
photon.direction.x = dot(camera.mx, dir_tmp);
206208
photon.direction.y = dot(camera.my, dir_tmp);
207-
photon.direction.z = dot(camera.mz, dir_tmp) * Float(-1);
209+
photon.direction.z = dot(camera.mz, dir_tmp);
210+
photon.position = camera.position + s_min;
208211
}
209-
else
212+
else if (camera.cam_type == 1)
210213
{
211214
// Rectangular camera based on Villefranque et al. 2019
212215
photon.direction = normalize(camera.cam_width * (Float(2.)*i-Float(1.0)) + camera.cam_height * (Float(2.)*j-Float(1.0)) + camera.cam_depth);
216+
photon.position = camera.position + s_min;
213217
}
218+
else
219+
{
220+
// Top-of-atmosphere upwelling radiances
221+
photon.direction = {Float(0.), Float(0.), Float(-1)};
222+
photon.position.x = (Float(ij_cam % camera.nx) + Float(0.5)) * (grid_size.x / camera.nx);
223+
photon.position.y = (Float(ij_cam / camera.nx) + Float(0.5)) * (grid_size.y / camera.ny);
224+
photon.position.z = z_lev_bg[kbg] - s_min;
225+
}
226+
227+
// if camera starts above domain top, bring photon towards domain top
228+
if ((photon.position.z > z_lev_bg[kbg]) and (photon.direction.z < Float(0.)))
229+
{
230+
Float ds = (photon.position.z - z_lev_bg[kbg]) / photon.direction.z;
214231

215-
photon.position = camera.position + s_min;
232+
photon.position.z = z_lev_bg[kbg] - s_min;
233+
photon.position.y += photon.direction.y * ds;
234+
photon.position.x += photon.direction.x * ds;
235+
236+
// Cyclic boundary condition in x.
237+
photon.position.x = fmod(photon.position.x, grid_size.x);
238+
if (photon.position.x < Float(0.))
239+
photon.position.x += grid_size.x;
240+
241+
// Cyclic boundary condition in y.
242+
photon.position.y = fmod(photon.position.y, grid_size.y);
243+
if (photon.position.y < Float(0.))
244+
photon.position.y += grid_size.y;
245+
}
216246

217247
photon.kind = Photon_kind::Direct;
218248
weight = 1;
@@ -764,23 +794,30 @@ void ray_tracer_kernel_bw(
764794
Float dist = 0;
765795
bool reached_cloud = false;
766796

767-
//const int pix = n * pixels_per_thread + ipix;
768797
const Float i = (Float(pix % camera.nx) + Float(0.5))/ Float(camera.nx);
769798
const Float j = (Float(pix / camera.nx) + Float(0.5))/ Float(camera.ny);
770799

771-
position = camera.position + s_eps;
772800

773-
if (camera.fisheye)
801+
if (camera.cam_type == 0)
774802
{
775803
const Float photon_zenith = i * Float(.5) * M_PI / camera.f_zoom;
776804
const Float photon_azimuth = j * Float(2.) * M_PI;
777805
const Vector<Float> dir_tmp = {sin(photon_zenith) * sin(photon_azimuth), sin(photon_zenith) * cos(photon_azimuth), cos(photon_zenith)};
778806

779807
direction = {dot(camera.mx, dir_tmp), dot(camera.my, dir_tmp), dot(camera.mz, dir_tmp) * Float(-1)};
808+
position = camera.position + s_eps;
780809
}
781-
else
810+
else if (camera.cam_type == 1)
782811
{
783812
direction = normalize(camera.cam_width * (Float(2.)*i-Float(1.0)) + camera.cam_height * (Float(2.)*j-Float(1.0)) + camera.cam_depth);
813+
position = camera.position + s_eps;
814+
}
815+
else
816+
{
817+
direction = {Float(0.), Float(0.), Float(-1)};
818+
position = {i * grid_size.x / camera.nx,
819+
j * grid_size.y / camera.ny,
820+
grid_size.z - 2*s_eps};
784821
}
785822

786823
// first bring photon to top of dynamical domain

src_test/Radiation_solver_bw.cu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ void Radiation_solver_longwave::solve_gpu(
630630
*/
631631
}
632632

633+
// color matchin functions from https://jcgt.org/published/0002/02/01/paper.pdf
634+
633635

634636
Float get_x(const Float wv)
635637
{

0 commit comments

Comments
 (0)