htgop

Optical properties of a gas mixture
git clone git://git.meso-star.fr/htgop.git
Log | Files | Refs | README | LICENSE

commit f187fa13f89458d34d7675d91250c9c04daf6bcf
parent 374d459992b2797e70ff1d1a58c1c8c067fad93f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 30 Jul 2018 11:21:05 +0200

Add the quadrature CDF

Diffstat:
Msrc/htgop.c | 56++++++++++++++++++++++++++++++++++++++------------------
Msrc/htgop.h | 10+++++++++-
Msrc/htgop_parse_layers_spectral_intervals_data.h | 2+-
Msrc/htgop_spectral_intervals.h | 16+++++++++++-----
Msrc/test_htgop_load.c | 20++++++++++++++++++--
5 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/src/htgop.c b/src/htgop.c @@ -274,7 +274,8 @@ parse_spectral_intervals { unsigned long ispecint; double* wave_numbers = NULL; - struct darray_double* quadratures = NULL; + struct darray_double* pdfs = NULL; + struct darray_double* cdfs = NULL; res_T res = RES_OK; (void)htgop; ASSERT(htgop && rdr && nspecints && specints); @@ -283,14 +284,18 @@ parse_spectral_intervals /* Allocate the memory space for the wave numbers and the quadratures */ CALL(darray_double_resize(&specints->wave_numbers, nspecints + 1)); - CALL(darray_dbllst_resize(&specints->quadratures, nspecints)); + CALL(darray_dbllst_resize(&specints->quadrature_pdfs, nspecints)); + CALL(darray_dbllst_resize(&specints->quadrature_cdfs, nspecints)); wave_numbers = darray_double_data_get(&specints->wave_numbers); - quadratures = darray_dbllst_data_get(&specints->quadratures); + pdfs = darray_dbllst_data_get(&specints->quadrature_pdfs); + cdfs = darray_dbllst_data_get(&specints->quadrature_cdfs); FOR_EACH(ispecint, 0, nspecints) { - double* quadrature = NULL; + double* pdf = NULL; + double* cdf = NULL; double wave_number_low; double wave_number_upp; + double sum = 0; unsigned long quad_len; unsigned long iquad; @@ -315,13 +320,21 @@ parse_spectral_intervals CALL(cstr_to_ulong(read_line(rdr), &quad_len)); /* Allocate the points of the quadrature */ - CALL(darray_double_resize(&quadratures[ispecint], quad_len)); - quadrature = darray_double_data_get(&quadratures[ispecint]); + CALL(darray_double_resize(&pdfs[ispecint], quad_len)); + CALL(darray_double_resize(&cdfs[ispecint], quad_len)); + pdf = darray_double_data_get(&pdfs[ispecint]); + cdf = darray_double_data_get(&cdfs[ispecint]); /* Read the weight of the quadrature points */ + sum = 0; FOR_EACH(iquad, 0, quad_len) { - CALL(cstr_to_double(read_line(rdr), &quadrature[iquad])); + CALL(cstr_to_double(read_line(rdr), &pdf[iquad])); + cdf[iquad] = iquad == 0 ? pdf[iquad] : pdf[iquad]+cdf[iquad-1]; + sum += pdf[iquad]; } + ASSERT(eq_eps(sum, 1.0, 1.e6)); + ASSERT(eq_eps(cdf[quad_len-1], 1.0, 1.e6)); + cdf[quad_len-1] = 1.0; /* Handle numerical imprecision */ } #undef CALL @@ -330,7 +343,8 @@ exit: return res; error: darray_double_clear(&specints->wave_numbers); - darray_dbllst_clear(&specints->quadratures); + darray_dbllst_clear(&specints->quadrature_pdfs); + darray_dbllst_clear(&specints->quadrature_cdfs); goto exit; } @@ -744,7 +758,7 @@ res_T htgop_get_lw_spectral_intervals_count(const struct htgop* htgop, size_t* nspecints) { if(!htgop || !nspecints) return RES_BAD_ARG; - *nspecints = darray_dbllst_size_get(&htgop->lw_specints.quadratures); + *nspecints = darray_dbllst_size_get(&htgop->lw_specints.quadrature_pdfs); return RES_OK; } @@ -752,7 +766,7 @@ res_T htgop_get_sw_spectral_intervals_count(const struct htgop* htgop, size_t* nspecints) { if(!htgop || !nspecints) return RES_BAD_ARG; - *nspecints = darray_dbllst_size_get(&htgop->sw_specints.quadratures); + *nspecints = darray_dbllst_size_get(&htgop->sw_specints.quadrature_pdfs); return RES_OK; } @@ -781,7 +795,8 @@ htgop_get_lw_spectral_interval struct htgop_spectral_interval* interval) { const double* wave_numbers; - const struct darray_double* quadratures; + const struct darray_double* quad_cdfs; + const struct darray_double* quad_pdfs; size_t n; if(!htgop || !interval) return RES_BAD_ARG; HTGOP(get_lw_spectral_intervals_count(htgop, &n)); @@ -791,11 +806,13 @@ htgop_get_lw_spectral_interval return RES_BAD_ARG; } wave_numbers = darray_double_cdata_get(&htgop->lw_specints.wave_numbers); - quadratures = darray_dbllst_cdata_get(&htgop->lw_specints.quadratures); + quad_pdfs = darray_dbllst_cdata_get(&htgop->lw_specints.quadrature_pdfs); + quad_cdfs = darray_dbllst_cdata_get(&htgop->lw_specints.quadrature_cdfs); interval->wave_numbers[0] = wave_numbers[ispecint+0]; interval->wave_numbers[1] = wave_numbers[ispecint+1]; - interval->quadrature = darray_double_cdata_get(&quadratures[ispecint]); - interval->quadrature_length = darray_double_size_get(&quadratures[ispecint]); + interval->quadrature_pdf = darray_double_cdata_get(&quad_pdfs[ispecint]); + interval->quadrature_cdf = darray_double_cdata_get(&quad_cdfs[ispecint]); + interval->quadrature_length = darray_double_size_get(&quad_pdfs[ispecint]); return RES_OK; } @@ -806,7 +823,8 @@ htgop_get_sw_spectral_interval struct htgop_spectral_interval* interval) { const double* wave_numbers; - const struct darray_double* quadratures; + const struct darray_double* quad_pdfs; + const struct darray_double* quad_cdfs; size_t n; if(!htgop || !interval) return RES_BAD_ARG; HTGOP(get_sw_spectral_intervals_count(htgop, &n)); @@ -816,11 +834,13 @@ htgop_get_sw_spectral_interval return RES_BAD_ARG; } wave_numbers = darray_double_cdata_get(&htgop->sw_specints.wave_numbers); - quadratures = darray_dbllst_cdata_get(&htgop->sw_specints.quadratures); + quad_pdfs = darray_dbllst_cdata_get(&htgop->sw_specints.quadrature_pdfs); + quad_cdfs = darray_dbllst_cdata_get(&htgop->sw_specints.quadrature_cdfs); interval->wave_numbers[0] = wave_numbers[ispecint+0]; interval->wave_numbers[1] = wave_numbers[ispecint+1]; - interval->quadrature = darray_double_cdata_get(&quadratures[ispecint]); - interval->quadrature_length = darray_double_size_get(&quadratures[ispecint]); + interval->quadrature_pdf = darray_double_cdata_get(&quad_pdfs[ispecint]); + interval->quadrature_cdf = darray_double_cdata_get(&quad_cdfs[ispecint]); + interval->quadrature_length = darray_double_size_get(&quad_pdfs[ispecint]); return RES_OK; } diff --git a/src/htgop.h b/src/htgop.h @@ -51,7 +51,8 @@ struct htgop_ground { struct htgop_spectral_interval { double wave_numbers[2]; /* Lower/Upper wave number of the interval in cm^-1 */ - const double* quadrature; /* Weights of the quadrature points */ + const double* quadrature_pdf; /* PDF of the quadrature */ + const double* quadrature_cdf; /* CDF of the quadrature */ size_t quadrature_length; /* #quadrature points of the interval */ }; @@ -202,6 +203,13 @@ htgop_get_sw_spectral_interval struct htgop_spectral_interval* interval); HTGOP_API res_T +htgop_sw_spectral_interval_sample_quadrature + (const struct htgop* htgop, + const size_t ispectral_interval, + const double r, /* Canonical random number in [0, 1[ */ + size_t* iquad); /* Id of the sampled interval */ + +HTGOP_API res_T htgop_layer_get_lw_spectral_interval (const struct htgop_layer* layer, const size_t ispectral_interval, diff --git a/src/htgop_parse_layers_spectral_intervals_data.h b/src/htgop_parse_layers_spectral_intervals_data.h @@ -54,7 +54,7 @@ CONCAT(parse_layers_spectral_intervals_, DATA) struct darray_double* XDATA(tab); quad = darray_dbllst_data_get - (&htgop->XDOMAIN(specints).quadratures) + ispecint; + (&htgop->XDOMAIN(specints).quadrature_pdfs) + ispecint; quad_len = darray_double_size_get(quad); /* Allocate the per layer data */ diff --git a/src/htgop_spectral_intervals.h b/src/htgop_spectral_intervals.h @@ -22,7 +22,8 @@ struct spectral_intervals { /* List of wave numbers, in cm^-1, sorted in ascending order. * #wave numbers == #intervals + 1 */ struct darray_double wave_numbers; - struct darray_dbllst quadratures; /* Per spectral interval quadrature weight */ + struct darray_dbllst quadrature_pdfs; /* Per spectral band quadrature pdf */ + struct darray_dbllst quadrature_cdfs; /* Per spectral band quadrature cdf */ }; static INLINE void @@ -31,7 +32,9 @@ spectral_intervals_init { ASSERT(sinters); darray_double_init(allocator, &sinters->wave_numbers); - darray_dbllst_init(allocator, &sinters->quadratures); + darray_dbllst_init(allocator, &sinters->quadrature_pdfs); + darray_dbllst_init(allocator, &sinters->quadrature_cdfs); + } static INLINE void @@ -39,7 +42,8 @@ spectral_intervals_release(struct spectral_intervals* sinters) { ASSERT(sinters); darray_double_release(&sinters->wave_numbers); - darray_dbllst_release(&sinters->quadratures); + darray_dbllst_release(&sinters->quadrature_pdfs); + darray_dbllst_release(&sinters->quadrature_cdfs); } static INLINE res_T @@ -50,7 +54,8 @@ spectral_intervals_copy ASSERT(dst && src); #define CALL(Func) { if(RES_OK != (res = Func)) return res; } (void)0 CALL(darray_double_copy(&dst->wave_numbers, &src->wave_numbers)); - CALL(darray_dbllst_copy(&dst->quadratures, &src->quadratures)); + CALL(darray_dbllst_copy(&dst->quadrature_pdfs, &src->quadrature_pdfs)); + CALL(darray_dbllst_copy(&dst->quadrature_cdfs, &src->quadrature_cdfs)); #undef CALL return RES_OK; } @@ -63,7 +68,8 @@ spectral_intervals_copy_and_release ASSERT(dst && src); #define CALL(Func) { if(RES_OK != (res = Func)) return res; } (void)0 CALL(darray_double_copy_and_release(&dst->wave_numbers, &src->wave_numbers)); - CALL(darray_dbllst_copy_and_release(&dst->quadratures, &src->quadratures)); + CALL(darray_dbllst_copy_and_release(&dst->quadrature_pdfs, &src->quadrature_pdfs)); + CALL(darray_dbllst_copy_and_release(&dst->quadrature_pdfs, &src->quadrature_cdfs)); #undef CALL spectral_intervals_release(src); return RES_OK; diff --git a/src/test_htgop_load.c b/src/test_htgop_load.c @@ -182,8 +182,16 @@ main(int argc, char** argv) FOR_EACH(iquad, 0, specint.quadrature_length) { CHK(cstr_to_double(read_line(&rdr), &dbl) == RES_OK); - CHK(specint.quadrature[iquad] == dbl); + CHK(specint.quadrature_pdf[iquad] == dbl); + if(iquad == 0) { + CHK(specint.quadrature_cdf[iquad] == dbl); + } else { + const double pdf = + specint.quadrature_cdf[iquad] - specint.quadrature_cdf[iquad-1]; + CHK(eq_eps(pdf, dbl, 1.e-6)); + } } + CHK(specint.quadrature_cdf[specint.quadrature_length-1] == 1.0); } /* Per SW spectral interval data */ @@ -212,7 +220,15 @@ main(int argc, char** argv) FOR_EACH(iquad, 0, specint.quadrature_length) { CHK(cstr_to_double(read_line(&rdr), &dbl) == RES_OK); - CHK(specint.quadrature[iquad] == dbl); + CHK(specint.quadrature_pdf[iquad] == dbl); + if(iquad == 0) { + CHK(specint.quadrature_cdf[iquad] == dbl); + } else { + const double pdf = + specint.quadrature_cdf[iquad] - specint.quadrature_cdf[iquad-1]; + CHK(eq_eps(pdf, dbl, 1.e-6)); + } + CHK(specint.quadrature_cdf[specint.quadrature_length-1] == 1.0); } }