@@ -384,11 +384,12 @@ def linear_spline_coefficients(x, y, check_inputs=True):
384384
385385
386386
387- def generate_s_poly_coeffs (tau_arr , TEMPER , WVNMLO , WVNMHI , ** kwargs ):
387+ def generate_s_poly_coeffs (tau_arr , TEMPER , WVNMLO , WVNMHI , omega_arr = None , ** kwargs ):
388388 """Generate DISORT-equivalent ``s_poly_coeffs`` for input into ``pydisort``.
389389 This convenience function is provided to help match the inputs for Stamnes' DISORT to those for PythonicDISORT.
390- Users will have to manually adjust emissivities, however, and they should note that PythonicDISORT allows much
391- more flexibility in choosing blackbody emission profiles than DISORT.
390+ If ``omega_arr`` is specified, the coefficients will be multiplied by emissivity factors equal to ``1 - omega_arr``
391+ per Kirchoff's law of thermal radiation, and Kirchoff's law is enforced in Stamnes' DISORT.
392+ Otherwise, the emissivities will be set to 1 and users can multiply their own emissivity factors.
392393
393394 Parameters
394395 ----------
@@ -401,6 +402,8 @@ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, **kwargs):
401402 Lower bound of wavenumber interval with units m^-1. This variable is identically named in Stamnes' DISORT.
402403 WVNMHI : scalar
403404 Upper bound of wavenumber interval with units m^-1. This variable is identically named in Stamnes' DISORT.
405+ omega_arr : optional, array or scalar
406+ Single-scattering albedo of each atmospheric layer.
404407 **kwargs
405408 Keyword arguments to pass to ``scipy.integrate.quad_vec``.
406409
@@ -414,12 +417,35 @@ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, **kwargs):
414417 """
415418 tau_arr = np .atleast_1d (tau_arr )
416419 if not len (TEMPER ) == len (tau_arr ) + 1 :
417- raise ValueError ("Missing temperature specification at some boundaries / interfaces." )
418-
420+ raise ValueError (
421+ "Missing temperature specification at some boundaries / interfaces."
422+ )
423+
419424 tau_arr_with_0 = np .insert (tau_arr , 0 , 0 )
420- blackbody_emission_at_each_boundary = sc .integrate .quad_vec (lambda WVNM : Planck (TEMPER , WVNM ), WVNMLO , WVNMHI , ** kwargs )[0 ]
421-
422- return linear_spline_coefficients (tau_arr_with_0 , blackbody_emission_at_each_boundary , check_inputs = False )
425+ blackbody_emission_at_each_boundary = sc .integrate .quad_vec (
426+ lambda WVNM : Planck (TEMPER , WVNM ), WVNMLO , WVNMHI , ** kwargs
427+ )[0 ]
428+
429+ if omega_arr == None :
430+ return (
431+ linear_spline_coefficients (
432+ tau_arr_with_0 , blackbody_emission_at_each_boundary , check_inputs = False
433+ )
434+ )
435+ elif np .isscalar (omega_arr ):
436+ return (
437+ linear_spline_coefficients (
438+ tau_arr_with_0 , blackbody_emission_at_each_boundary , check_inputs = False
439+ )
440+ * (1 - omega_arr )
441+ )
442+ else :
443+ return (
444+ linear_spline_coefficients (
445+ tau_arr_with_0 , blackbody_emission_at_each_boundary , check_inputs = False
446+ )
447+ * (1 - omega_arr )[:, None ]
448+ )
423449
424450
425451
@@ -448,7 +474,9 @@ def generate_emissivity_from_BDRF(N, zeroth_BDRF_Fourier_mode):
448474 return 1 - zeroth_BDRF_Fourier_mode
449475 else :
450476 mu_arr_pos , W = Gauss_Legendre_quad (N )
451- return 1 - 2 * zeroth_BDRF_Fourier_mode (mu_arr_pos , mu_arr_pos ) * mu_arr_pos [None , :] @ W
477+ return (
478+ 1 - 2 * zeroth_BDRF_Fourier_mode (mu_arr_pos , mu_arr_pos ) * mu_arr_pos [None , :] @ W
479+ )
452480
453481
454482
@@ -778,7 +806,7 @@ def mathscr_b(i):
778806
779807
780808
781- def _compare (results , mu_to_compare , reorder_mu , flux_up , flux_down , u = None ):
809+ def _compare (results , mu_to_compare , reorder_mu , flux_up , flux_down , u = None , div_threshold = 1e-15 ):
782810 """Performs pointwise comparisons between results from Stamnes' DISORT,
783811 which are stored in ``.npz`` files, against results from PythonicDISORT. Used in our PyTests.
784812
@@ -807,7 +835,7 @@ def _compare(results, mu_to_compare, reorder_mu, flux_up, flux_down, u=None):
807835 diff_flux_up ,
808836 flup ,
809837 out = np .zeros_like (diff_flux_up ),
810- where = flup > 1e-8 ,
838+ where = flup > div_threshold ,
811839 )
812840 print ("Difference =" , np .max (diff_flux_up ))
813841 print ("Difference ratio =" , np .max (ratio_flux_up ))
@@ -820,7 +848,7 @@ def _compare(results, mu_to_compare, reorder_mu, flux_up, flux_down, u=None):
820848 diff_flux_down_diffuse ,
821849 rfldn ,
822850 out = np .zeros_like (diff_flux_down_diffuse ),
823- where = rfldn > 1e-8 ,
851+ where = rfldn > div_threshold ,
824852 )
825853 print ("Difference =" , np .max (diff_flux_down_diffuse ))
826854 print (
@@ -836,7 +864,7 @@ def _compare(results, mu_to_compare, reorder_mu, flux_up, flux_down, u=None):
836864 diff_flux_down_direct ,
837865 rfldir ,
838866 out = np .zeros_like (diff_flux_down_direct ),
839- where = rfldir > 1e-8 ,
867+ where = rfldir > div_threshold ,
840868 )
841869 print ("Difference =" , np .max (diff_flux_down_direct ))
842870 print (
@@ -852,7 +880,7 @@ def _compare(results, mu_to_compare, reorder_mu, flux_up, flux_down, u=None):
852880 diff ,
853881 uu [mu_to_compare ],
854882 out = np .zeros_like (diff ),
855- where = uu [mu_to_compare ] > 1e-8 ,
883+ where = uu [mu_to_compare ] > div_threshold ,
856884 )
857885 max_diff_tau_index = np .argmax (np .max (np .max (diff , axis = 0 ), axis = 1 ))
858886 max_ratio_tau_index = np .argmax (np .max (np .max (diff_ratio , axis = 0 ), axis = 1 ))
0 commit comments