From 197fd1e113b1fac218379d7dbecdf23bd859e578 Mon Sep 17 00:00:00 2001 From: Luke Shingles Date: Mon, 9 Sep 2024 11:23:39 +0100 Subject: [PATCH] Replace PhotoionTarget *phixstargets with int phixstargetstart --- atomic.h | 8 +++++-- globals.h | 19 +++++++++------- input.cc | 65 ++++++++++++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/atomic.h b/atomic.h index 5b913361f..b7110d34e 100644 --- a/atomic.h +++ b/atomic.h @@ -94,7 +94,9 @@ inline auto get_nphixstargets(const int element, const int ion, const int level) assert_testmodeonly(phixstargetindex >= 0); assert_testmodeonly(phixstargetindex < get_nphixstargets(element, ion, level)); - return globals::elements[element].ions[ion].levels[level].phixstargets[phixstargetindex].levelindex; + return globals::allphixstargets[globals::elements[element].ions[ion].levels[level].phixstargetstart + + phixstargetindex] + .levelindex; } // Return the probability of a target state for photoionization of (element,ion,level). @@ -106,7 +108,9 @@ inline auto get_nphixstargets(const int element, const int ion, const int level) assert_testmodeonly(phixstargetindex >= 0); assert_testmodeonly(phixstargetindex < get_nphixstargets(element, ion, level)); - return globals::elements[element].ions[ion].levels[level].phixstargets[phixstargetindex].probability; + return globals::allphixstargets[globals::elements[element].ions[ion].levels[level].phixstargetstart + + phixstargetindex] + .probability; } // Return the statistical weight of (element,ion,level). diff --git a/globals.h b/globals.h index c1f74e21a..02afc2308 100644 --- a/globals.h +++ b/globals.h @@ -82,14 +82,16 @@ struct PhotoionTarget { struct EnergyLevel { double epsilon{-1}; // Excitation energy of this level relative to the neutral ground level. - int alltrans_startdown{}; // Allowed downward transitions from this level - int ndowntrans{0}; - int nuptrans{0}; - int phixsstart{-1}; // index to start of photoionisation cross-sections table in global::allphixs - int nphixstargets{0}; // length of phixstargets array: - float stat_weight{0.}; // Statistical weight of this level. - PhotoionTarget *phixstargets{}; // pointer to table of target states and probabilities - int cont_index{-1}; // Index of the continuum associated to this level. Negative number. + int alltrans_startdown{}; // index into globals::alltrans for first down transition from this level + int ndowntrans{0}; // Number of down transitions from this level + int nuptrans{0}; // Number of up transitions to this level + int phixsstart{-1}; // index to start of photoionisation cross-sections table in global::allphixs + int nphixstargets{0}; // number of target levels for photoionisation + float stat_weight{0.}; // statistical weight of this level + int phixstargetstart{}; // index into globals::allphixstargets + int cont_index{-1}; // index of the bound-free continuum (for first target) sorted by + // element/ion/level/phixstargetindex + // (not an index into the nu_edge-sorted allcont list!) int closestgroundlevelcont{-1}; }; @@ -256,6 +258,7 @@ inline std::vector ion_alpha_sp; // alpha_sp for each ion and temperatur inline float *allphixs{}; inline LevelTransition *alltrans; +inline std::vector allphixstargets; inline std::vector elements; diff --git a/input.cc b/input.cc index 78aba3e23..906d942bb 100644 --- a/input.cc +++ b/input.cc @@ -22,7 +22,6 @@ #include #include #include -#include #ifndef GPU_ON #include #endif @@ -87,10 +86,21 @@ constexpr std::array inputlinecomments = { CellCachePhixsTargets *chphixstargetsblock{}; +// use the temporary list, before it has been copied to node-shared memory +auto get_phixsupperlevel_tmp(const std::vector &temp_allphixstargets, const int element, const int ion, + const int level, const int phixstargetindex) { + return temp_allphixstargets[globals::elements[element].ions[ion].levels[level].phixstargetstart + phixstargetindex] + .levelindex; +} + void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_inputtable, const int element, const int lowerion, const int lowerlevel, const int upperion, int upperlevel_in, - std::vector &tmpallphixs, size_t *mem_usage_phixs, const int phixs_file_version) { + std::vector &tmpallphixs, std::vector &temp_allphixstargets, + size_t *mem_usage_phixs, const int phixs_file_version) { std::string phixsline; + assert_always(globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargetstart == -1); + globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargetstart = + static_cast(std::ssize(temp_allphixstargets)); if (upperlevel_in >= 0) { // file gives photoionisation to a single target state only int upperlevel = upperlevel_in - groundstate_index_in; assert_always(upperlevel >= 0); @@ -98,18 +108,12 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input globals::elements[element].ions[lowerion].levels[lowerlevel].nphixstargets = 1; *mem_usage_phixs += sizeof(PhotoionTarget); - assert_always(globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets == nullptr); - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets = - static_cast(malloc(sizeof(PhotoionTarget))); - assert_always(globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets != nullptr); - if (single_level_top_ion && (upperion == get_nions(element) - 1)) { // top ion has only one level, so send it to that level upperlevel = 0; } - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[0].levelindex = upperlevel; - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[0].probability = 1.; + temp_allphixstargets.push_back({.probability = 1., .levelindex = upperlevel}); } else { // upperlevel < 0, indicating that a table of upper levels and their probabilities will follow int in_nphixstargets = 0; assert_always(get_noncommentline(phixsfile, phixsline)); @@ -121,10 +125,6 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input globals::elements[element].ions[lowerion].levels[lowerlevel].nphixstargets = in_nphixstargets; *mem_usage_phixs += in_nphixstargets * sizeof(PhotoionTarget); - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets = - static_cast(malloc(in_nphixstargets * sizeof(PhotoionTarget))); - assert_always(globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets != nullptr); - double probability_sum = 0.; for (int i = 0; i < in_nphixstargets; i++) { double phixstargetprobability{NAN}; @@ -133,9 +133,8 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input const int upperlevel = upperlevel_in - groundstate_index_in; assert_always(upperlevel >= 0); assert_always(phixstargetprobability > 0); - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[i].levelindex = upperlevel; - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[i].probability = - phixstargetprobability; + temp_allphixstargets.push_back({.probability = phixstargetprobability, .levelindex = upperlevel}); + probability_sum += phixstargetprobability; } if (fabs(probability_sum - 1.0) > 0.01) { @@ -145,17 +144,13 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input } else { // file has table of target states and probabilities but our top ion is limited to one level globals::elements[element].ions[lowerion].levels[lowerlevel].nphixstargets = 1; *mem_usage_phixs += sizeof(PhotoionTarget); - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets = - static_cast(malloc(sizeof(PhotoionTarget))); - assert_always(globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets != nullptr); for (int i = 0; i < in_nphixstargets; i++) { assert_always(get_noncommentline(phixsfile, phixsline)); } // send it to the ground state of the top ion - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[0].levelindex = 0; - globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargets[0].probability = 1.; + temp_allphixstargets.push_back({.probability = 1., .levelindex = 0}); } } @@ -167,7 +162,10 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input if (lowerion < get_nions(element) - 1) { for (int phixstargetindex = 0; phixstargetindex < get_nphixstargets(element, lowerion, lowerlevel); phixstargetindex++) { - const int upperlevel = get_phixsupperlevel(element, lowerion, lowerlevel, phixstargetindex); + const int upperlevel = + temp_allphixstargets[globals::elements[element].ions[lowerion].levels[lowerlevel].phixstargetstart + + phixstargetindex] + .levelindex; if (upperlevel > get_maxrecombininglevel(element, lowerion + 1)) { globals::elements[element].ions[lowerion + 1].maxrecombininglevel = upperlevel; } @@ -183,7 +181,7 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input auto *levelphixstable = &tmpallphixs[tmpphixsstart]; if (phixs_file_version == 1) { assert_always(get_nphixstargets(element, lowerion, lowerlevel) == 1); - assert_always(get_phixsupperlevel(element, lowerion, lowerlevel, 0) == 0); + assert_always(get_phixsupperlevel_tmp(temp_allphixstargets, element, lowerion, lowerlevel, 0) == 0); const double nu_edge = (epsilon(element, upperion, 0) - epsilon(element, lowerion, lowerlevel)) / H; @@ -241,7 +239,8 @@ void read_phixs_data_table(std::fstream &phixsfile, const int nphixspoints_input } } -void read_phixs_file(const int phixs_file_version, std::vector &tmpallphixs) { +void read_phixs_file(const int phixs_file_version, std::vector &tmpallphixs, + std::vector &temp_allphixstargets) { size_t mem_usage_phixs = 0; printout("readin phixs data from %s\n", phixsdata_filenames[phixs_file_version]); @@ -309,7 +308,7 @@ void read_phixs_file(const int phixs_file_version, std::vector &tmpallphi // store only photoionization crosssections for ions that are part of the current model atom if (lowerion >= 0 && upperion < get_nions(element) && lowerlevel < get_ionisinglevels(element, lowerion)) { read_phixs_data_table(phixsfile, nphixspoints_inputtable, element, lowerion, lowerlevel, upperion, - upperlevel_in, tmpallphixs, &mem_usage_phixs, phixs_file_version); + upperlevel_in, tmpallphixs, temp_allphixstargets, &mem_usage_phixs, phixs_file_version); skip_this_phixs_table = false; } @@ -364,7 +363,7 @@ void read_ion_levels(std::fstream &adata, const int element, const int ion, cons const double currentlevelenergy = (energyoffset + levelenergy) * EV; globals::elements[element].ions[ion].levels[level].nphixstargets = 0; globals::elements[element].ions[ion].levels[level].phixsstart = -1; - globals::elements[element].ions[ion].levels[level].phixstargets = nullptr; + globals::elements[element].ions[ion].levels[level].phixstargetstart = -1; globals::elements[element].ions[ion].levels[level].epsilon = currentlevelenergy; globals::elements[element].ions[ion].levels[level].stat_weight = statweight; assert_always(statweight > 0.); @@ -843,6 +842,7 @@ void read_phixs_data() { globals::nbfcontinua_ground = 0; globals::nbfcontinua = 0; std::vector tmpallphixs; + std::vector temp_allphixstargets; // read in photoionisation cross sections phixs_file_version_exists[0] = false; @@ -860,10 +860,10 @@ void read_phixs_data() { "from phixsdata_v2.txt to interpolate the phixsdata.txt data\n"); } if (phixs_file_version_exists[2]) { - read_phixs_file(2, tmpallphixs); + read_phixs_file(2, tmpallphixs, temp_allphixstargets); } if (phixs_file_version_exists[1]) { - read_phixs_file(1, tmpallphixs); + read_phixs_file(1, tmpallphixs, temp_allphixstargets); } int cont_index = 0; @@ -887,8 +887,9 @@ void read_phixs_data() { // all levels in the ground term should be photoionisation targets from the lower ground state if (ion > 0 && ion < get_nions(element) - 1) { const int nphixstargets = get_nphixstargets(element, ion - 1, 0); - if (nphixstargets > 0 && get_phixsupperlevel(element, ion - 1, 0, 0) == 0) { - const int phixstargetlevels = get_phixsupperlevel(element, ion - 1, 0, nphixstargets - 1) + 1; + if (nphixstargets > 0 && get_phixsupperlevel_tmp(temp_allphixstargets, element, ion - 1, 0, 0) == 0) { + const int phixstargetlevels = + get_phixsupperlevel_tmp(temp_allphixstargets, element, ion - 1, 0, nphixstargets - 1) + 1; if (nlevels_groundterm != phixstargetlevels) { printout("WARNING: Z=%d ionstage %d nlevels_groundterm %d phixstargetlevels(ion-1) %d.\n", @@ -936,6 +937,10 @@ void read_phixs_data() { #endif } + temp_allphixstargets.shrink_to_fit(); + globals::allphixstargets = temp_allphixstargets; + // TODO: copy to node-shared memory + setup_phixs_list(); }