From 259df5681fb21f782884f0f543722a413634af62 Mon Sep 17 00:00:00 2001 From: jhmatthews Date: Wed, 21 Sep 2016 12:13:29 +0100 Subject: [PATCH] changed get_atomicdata --- source/get_atomicdata.c | 4106 +++++++++++++++++++-------------------- source/hydro_import.c | 700 ++++--- source/python.c | 2 +- source/python.h | 1153 +++++------ source/wind_updates2d.c | 1876 +++++++----------- source/windsave.c | 300 ++- 6 files changed, 3702 insertions(+), 4435 deletions(-) diff --git a/source/get_atomicdata.c b/source/get_atomicdata.c index 2408476e9..9c6d750e1 100755 --- a/source/get_atomicdata.c +++ b/source/get_atomicdata.c @@ -10,7 +10,7 @@ // DEBUG is deprecated as described by #111 -//#define DEBUG 0 /* nonzero implies debug */ +//#define DEBUG 0 /* nonzero implies debug */ /*********************************************************** Space Telescope Science Institute @@ -163,11 +163,11 @@ get_atomic_data (masterfile) char word[LINELENGTH]; int n, m, i, j; - int n1, n2; //081115 nsh two new counters for DR - use new pointers to avoid any clashes! - int nparam; //081115 nsh temperary holder for number of DR parameters - double drp[MAX_DR_PARAMS]; //081115 nsh array to hold DR parameters prior to putting into structure - double btrr[T_RR_PARAMS]; //0712 nsh array to hole badnell total RR params before putting into structure - int ne, w; //081115 nsh new variables for DR variables + int n1, n2; //081115 nsh two new counters for DR - use new pointers to avoid any clashes! + int nparam; //081115 nsh temperary holder for number of DR parameters + double drp[MAX_DR_PARAMS]; //081115 nsh array to hold DR parameters prior to putting into structure + double btrr[T_RR_PARAMS]; //0712 nsh array to hole badnell total RR params before putting into structure + int ne, w; //081115 nsh new variables for DR variables int mstart, mstop; int nelem; double gl, gu; @@ -177,19 +177,18 @@ get_atomic_data (masterfile) int istate, z, nion; int iistate, zz; int levl, levu; - int in, il; //The levels used in inner shell data + int in, il; //The levels used in inner shell data double q; double freq, f, exx, lambda, alpha, beta, tm, et, p; double the_ground_frac[20]; char choice; - int lineno; /* the line number in the file beginning with 1 */ - int index_collisions (), index_lines (), index_phot_top (), index_inner_cross (), - index_phot_verner (), check_xsections(); + int lineno; /* the line number in the file beginning with 1 */ + int index_collisions (), index_lines (), index_phot_top (), index_inner_cross (), index_phot_verner (), check_xsections (); int nwords; int nlte, nmax; // - int mflag; //flag to identify reading data for macro atoms - int nconfigl, nconfigu; //internal labels for configurations + int mflag; //flag to identify reading data for macro atoms + int nconfigl, nconfigu; //internal labels for configurations // int islp, ilv, np; char configname[15]; @@ -204,21 +203,20 @@ get_atomic_data (masterfile) int ntop_phot_simple, ntop_phot_macro; int bb_max, bf_max; int lev_type; - int nn, nl, dumnn, dumnl, dumz, dumistate, n_verner, ion_index, - target_index; + int nn, nl, dumnn, dumnl, dumz, dumistate, n_verner, ion_index, target_index; double yield, dumE_th, dumE_0, dumya, dumyw, dumSigma, dumP, arad, etarad; double adi, t0di, bdi, t1di; - double part_eps; //Temporary storage for partition function epsilon data - int J, part_G, part_m; //Temporary storage for partiton function J, G and m data - double gstemp[BAD_GS_RR_PARAMS]; //Temporary storage for badnell resolved GS RR rates - double temp[LINELENGTH]; //Temporary storage for data read in off a line this is enogh if every character on the - char gsflag, drflag; //Flags to say what part of data is being read in for DR and RR - double gstmin, gstmax; //The range of temperatures for which all ions have GS RR rates - double gsqrdtemp, gfftemp, s1temp, s2temp, s3temp; //Temporary storage for gaunt factors - int n_elec_yield_tot; //The number of inner shell cross sections with matching electron yield arrays - int n_fluor_yield_tot; //The number of inner shell cross sections with matching fluorescent photon yield arrays - double I,Ea; //The ionization energy and mean electron energy for electron yields - double energy; //The energy of inner shell fluorescent photons + double part_eps; //Temporary storage for partition function epsilon data + int J, part_G, part_m; //Temporary storage for partiton function J, G and m data + double gstemp[BAD_GS_RR_PARAMS]; //Temporary storage for badnell resolved GS RR rates + double temp[LINELENGTH]; //Temporary storage for data read in off a line this is enogh if every character on the + char gsflag, drflag; //Flags to say what part of data is being read in for DR and RR + double gstmin, gstmax; //The range of temperatures for which all ions have GS RR rates + double gsqrdtemp, gfftemp, s1temp, s2temp, s3temp; //Temporary storage for gaunt factors + int n_elec_yield_tot; //The number of inner shell cross sections with matching electron yield arrays + int n_fluor_yield_tot; //The number of inner shell cross sections with matching fluorescent photon yield arrays + double I, Ea; //The ionization energy and mean electron energy for electron yields + double energy; //The energy of inner shell fluorescent photons /* define which files to read as data files */ @@ -226,88 +224,82 @@ get_atomic_data (masterfile) /* Allocate structures for storage of data */ if (ele != NULL) - { - free (ele); - } + { + free (ele); + } ele = (ElemPtr) calloc (sizeof (ele_dummy), NELEMENTS); if (ele == NULL) - { - Error - ("There is a problem in allocating memory for the element structure\n"); - exit (0); - } + { + Error ("There is a problem in allocating memory for the element structure\n"); + exit (0); + } else - { - Log_silent - ("Allocated %10d bytes for each of %6d elements of elements totaling %10.0f Mb \n", - sizeof (ele_dummy), NELEMENTS, - 1.e-6 * NELEMENTS * sizeof (ele_dummy)); - } + { + Log_silent + ("Allocated %10d bytes for each of %6d elements of elements totaling %10.0f Mb \n", + sizeof (ele_dummy), NELEMENTS, 1.e-6 * NELEMENTS * sizeof (ele_dummy)); + } if (ion != NULL) - { - free (ion); - } + { + free (ion); + } ion = (IonPtr) calloc (sizeof (ion_dummy), NIONS); if (ion == NULL) - { - Error - ("There is a problem in allocating memory for the ion structure\n"); - exit (0); - } + { + Error ("There is a problem in allocating memory for the ion structure\n"); + exit (0); + } else - { - Log_silent - ("Allocated %10d bytes for each of %6d elements of ions totaling %10.1f Mb \n", - sizeof (ion_dummy), NIONS, 1.e-6 * NIONS * sizeof (ion_dummy)); - } + { + Log_silent + ("Allocated %10d bytes for each of %6d elements of ions totaling %10.1f Mb \n", + sizeof (ion_dummy), NIONS, 1.e-6 * NIONS * sizeof (ion_dummy)); + } if (config != NULL) - { - free (config); - } + { + free (config); + } config = (ConfigPtr) calloc (sizeof (config_dummy), NLEVELS); if (config == NULL) - { - Error - ("There is a problem in allocating memory for the config structure\n"); - exit (0); - } + { + Error ("There is a problem in allocating memory for the config structure\n"); + exit (0); + } else - { - Log_silent - ("Allocated %10d bytes for each of %6d elements of config totaling %10.1f Mb \n", - sizeof (config_dummy), NLEVELS, - 1.e-6 * NLEVELS * sizeof (config_dummy)); - } + { + Log_silent + ("Allocated %10d bytes for each of %6d elements of config totaling %10.1f Mb \n", + sizeof (config_dummy), NLEVELS, 1.e-6 * NLEVELS * sizeof (config_dummy)); + } if (line != NULL) - { - free (line); - } + { + free (line); + } line = (LinePtr) calloc (sizeof (line_dummy), NLINES); if (line == NULL) - { - Error - ("There is a problem in allocating memory for the line structure\n"); - exit (0); - } + { + Error ("There is a problem in allocating memory for the line structure\n"); + exit (0); + } else - { - Log_silent - ("Allocated %10d bytes for each of %6d elements of line totaling %10.1f Mb \n", - sizeof (line_dummy), NLINES, 1.e-6 * NLINES * sizeof (line_dummy)); - } + { + Log_silent + ("Allocated %10d bytes for each of %6d elements of line totaling %10.1f Mb \n", + sizeof (line_dummy), NLINES, 1.e-6 * NLINES * sizeof (line_dummy)); + } @@ -319,197 +311,197 @@ get_atomic_data (masterfile) inner_freq_min = VERY_BIG; for (n = 0; n < NELEMENTS; n++) - { - strcpy (ele[n].name, "none"); - ele[n].z = (-1); - ele[n].abun = (-1); - ele[n].firstion = (-1); - ele[n].nions = (-1); - } + { + strcpy (ele[n].name, "none"); + ele[n].z = (-1); + ele[n].abun = (-1); + ele[n].firstion = (-1); + ele[n].nions = (-1); + } for (n = 0; n < NIONS; n++) - { - ion[n].z = (-1); - ion[n].istate = (-1); - ion[n].ip = (-1); - ion[n].g = (-1); - ion[n].nmax = (-1); - ion[n].firstlevel = (-1); - ion[n].nlevels = (-1); - ion[n].first_nlte_level = (-1); - ion[n].first_levden = (-1); - ion[n].nlte = (-1); - ion[n].phot_info = (-1); - ion[n].macro_info = (-1); //Initialise - don't know if using Macro Atoms or not: set to -1 (SS) - ion[n].ntop_first = 0; // The fact that ntop_first and ntop are initialized to 0 and not -1 is important - ion[n].ntop_ground = 0; //NSH 0312 initialize the new pointer for GS cross sections - ion[n].ntop = 0; - ion[n].nxphot = (-1); - ion[n].lev_type = (-1); // Initialise to indicate we don't know what types of configurations will be read - ion[n].drflag = 0; //Initialise to indicate as far as we know, there are no dielectronic recombination parameters associated with this ion. - ion[n].cpartflag = 0; //Initialise to indicate this ion has cardona partition function data - ion[n].nxcpart = -1; - ion[n].total_rrflag = 0; //Initialise to say this ion has no Badnell total recombination data - ion[n].nxtotalrr = -1; //Initialise the pointer into the bad_t_rr structure. - ion[n].bad_gs_rr_t_flag = 0; //Initialise to say this ion has no Badnell ground state recombination data - ion[n].bad_gs_rr_r_flag = 0; //Initialise to say this ion has no Badnell ground state recombination data - ion[n].nxbadgsrr = -1; //Initialise the pointer into the bad_gs_rr structure. - ion[n].dere_di_flag = 0; //Initialise to say this ion has no Dere DI rate data - ion[n].nxderedi = -1; //Initialise the pointer into the Dere DI rate structure - ion[n].n_inner = 0; //Initialise the pointer to say we have no inner shell ionization cross sections - for (i =0; i NELEMENTS) - { - Error - ("getatomic_data: file %s line %d: More elements than allowed. Increase NELEMENTS in atomic.h\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - break; + case 'e': + if (sscanf (aline, "%*s %d %s %le", &ele[nelements].z, ele[nelements].name, &ele[nelements].abun) != 3) + { + Error ("Get_atomic_data: file %s line %d: Element line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + ele[nelements].abun = pow (10., ele[nelements].abun - 12.0); /* Immediate replace by number density relative to H */ + nelements++; + if (nelements > NELEMENTS) + { + Error ("getatomic_data: file %s line %d: More elements than allowed. Increase NELEMENTS in atomic.h\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + break; //Ions @@ -707,81 +692,73 @@ But it is pretty unclear how nlte levels from ksl's version are actually used. ksl 04Apr ?? */ - case 'i': - - if ((nwords = sscanf - (aline, "%*s %*s %d %d %le %le %d %d", &z, &istate, - &gg, &p, &nmax, &nlte)) == 6) - { - } // It's a new style ion line specifying levels to treat in nlte - else if (nwords == 4) - { //It's an old style ion line - nlte = 0; - nmax = 10; - } - else - { - Error - ("get_atomic_data: file %s line %d: Ion istate line incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } + case 'i': + + if ((nwords = sscanf (aline, "%*s %*s %d %d %le %le %d %d", &z, &istate, &gg, &p, &nmax, &nlte)) == 6) + { + } // It's a new style ion line specifying levels to treat in nlte + else if (nwords == 4) + { //It's an old style ion line + nlte = 0; + nmax = 10; + } + else + { + Error ("get_atomic_data: file %s line %d: Ion istate line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } // Now check that an element line for this ion has already been read - n = 0; - while (ele[n].z != z && n < nelements) - n++; - if (n == nelements) - { - - Debug - ("get_atomic_data: file %s line %d has ion for unknown element with z %d\n", - file, lineno, z); - break; - } + n = 0; + while (ele[n].z != z && n < nelements) + n++; + if (n == nelements) + { + + Debug ("get_atomic_data: file %s line %d has ion for unknown element with z %d\n", file, lineno, z); + break; + } // Now populate the ion structure - if (nlte > 0) - { // Then we want to consider some of these levels as non-lte - ion[nions].first_levden = nlte_levels; /* This is the index to into - the levden aray */ - ion[nions].n_lte_max = nlte; //Reserve this many elements of levden - nlte_levels += nlte; - if (nlte_levels > NLTE_LEVELS) - { - Error - ("get_atomic_data: nlte_levels (%d) > NLTE_LEVELS (%d)\n", - nlte_levels, NLTE_LEVELS); - exit (0); - } - - } - ion[nions].z = z; - ion[nions].istate = istate; - ion[nions].g = gg; - ion[nions].ip = p * EV2ERGS; - ion[nions].nmax = nmax; + if (nlte > 0) + { // Then we want to consider some of these levels as non-lte + ion[nions].first_levden = nlte_levels; /* This is the index to into + the levden aray */ + ion[nions].n_lte_max = nlte; //Reserve this many elements of levden + nlte_levels += nlte; + if (nlte_levels > NLTE_LEVELS) + { + Error ("get_atomic_data: nlte_levels (%d) > NLTE_LEVELS (%d)\n", nlte_levels, NLTE_LEVELS); + exit (0); + } + + } + ion[nions].z = z; + ion[nions].istate = istate; + ion[nions].g = gg; + ion[nions].ip = p * EV2ERGS; + ion[nions].nmax = nmax; /* Use the keyword IonM to classify the ion as a macro-ion (IonM) or not (simply Ion) */ - if (strncmp (word, "IonM", 4) == 0) - { - ion[nions].macro_info = 1; - nions_macro++; - } - else - { - ion[nions].macro_info = 0; - nions_simple++; - } - nions++; - if (nions == NIONS) - { - Error - ("getatomic_data: file %s line %d: %d ions is more than %d allowed. Increase NIONS in atomic.h\n", - file, lineno, nions, NIONS); - exit (0); - } - break; + if (strncmp (word, "IonM", 4) == 0) + { + ion[nions].macro_info = 1; + nions_macro++; + } + else + { + ion[nions].macro_info = 0; + nions_simple++; + } + nions++; + if (nions == NIONS) + { + Error + ("getatomic_data: file %s line %d: %d ions is more than %d allowed. Increase NIONS in atomic.h\n", + file, lineno, nions, NIONS); + exit (0); + } + break; //Levels or Configurations /* This version of get_atomicdata can read various types of configuration inputs, some of which should gradually be @@ -884,7 +861,7 @@ Col */ - case 'N': + case 'N': /* 080809 - It's a non-lte level, i.e. one for which we are going to calculate populations, at least for some number of these. For these, we have to set aside space in the levden array in the plasma structure. This is used for topbase @@ -901,56 +878,46 @@ the program working in both cases, and certainly mixed cases 04apr ksl */ * last bit is not actually new. */ - if (strncmp (word, "LevTop", 6) == 0) - { //Its a TOPBASESTYLE level - sscanf (aline, - "%*s %d %d %d %d %le %le %le %le %le %15c \n", - &zz, &iistate, &islp, &ilv, &e, &exx, &ggg, - &qqnum, &rl, configname); - istate = iistate; - z = zz; - gg = ggg; - exx *= EV2ERGS; // Convert energy above ground to ergs - mflag = -1; //record that this is a LevTop not LevMacro read - lev_type = 2; // It's a topbase record - } - - else if (strncmp (word, "LevMacro", 8) == 0) - { //It's a Macro Atom level (SS) - sscanf (aline, - "%*s %d %d %d %le %le %le %le %15c \n", - &zz, &iistate, &ilv, &e, &exx, &ggg, &rl, - configname); - islp = -1; //these indices are not going to be used so just leave - qqnum = -1; //them at -1 - mflag = 1; //record Macro read - lev_type = 1; // It's a Macro record - istate = iistate; - z = zz; - gg = ggg; - exx *= EV2ERGS; // Convert energy to ergs - } - else - { - Error - ("get_atomic_data: file %s line %d: Level line incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } + if (strncmp (word, "LevTop", 6) == 0) + { //Its a TOPBASESTYLE level + sscanf (aline, + "%*s %d %d %d %d %le %le %le %le %le %15c \n", &zz, &iistate, &islp, &ilv, &e, &exx, &ggg, &qqnum, &rl, configname); + istate = iistate; + z = zz; + gg = ggg; + exx *= EV2ERGS; // Convert energy above ground to ergs + mflag = -1; //record that this is a LevTop not LevMacro read + lev_type = 2; // It's a topbase record + } + + else if (strncmp (word, "LevMacro", 8) == 0) + { //It's a Macro Atom level (SS) + sscanf (aline, "%*s %d %d %d %le %le %le %le %15c \n", &zz, &iistate, &ilv, &e, &exx, &ggg, &rl, configname); + islp = -1; //these indices are not going to be used so just leave + qqnum = -1; //them at -1 + mflag = 1; //record Macro read + lev_type = 1; // It's a Macro record + istate = iistate; + z = zz; + gg = ggg; + exx *= EV2ERGS; // Convert energy to ergs + } + else + { + Error ("get_atomic_data: file %s line %d: Level line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } // Now check that the ion for this level is already known. If not break out - n = 0; - while ((ion[n].z != z || ion[n].istate != istate) - && n < nions) - n++; - if (n == nions) - { - - Debug - ("get_atomic_data: file %s line %d has level for unknown ion \n", - file, lineno); - break; - } + n = 0; + while ((ion[n].z != z || ion[n].istate != istate) && n < nions) + n++; + if (n == nions) + { + + Debug ("get_atomic_data: file %s line %d has level for unknown ion \n", file, lineno); + break; + } /* So now we know that this level can be associated with an ion @@ -958,18 +925,18 @@ Now either set the type of level that will be used for this ion or set it if a level type has not been established */ - if (ion[n].lev_type == (-1)) - { - ion[n].lev_type = lev_type; - } - else if (ion[n].lev_type != lev_type) - { - //XXX Why are these lines commented out? ksl 160212 + if (ion[n].lev_type == (-1)) + { + ion[n].lev_type = lev_type; + } + else if (ion[n].lev_type != lev_type) + { + //XXX Why are these lines commented out? ksl 160212 //OLD Error //OLD ("Get_atomic_data: file %s Reading lev_type (%d) for ion %d with lev_type (%d). Not allowed\n", //OLD file, lev_type, n, ion[n].lev_type); - break; - } + break; + } /* Now check 1) if it was a LevMacro that there isn't already a LevTop (if there was then @@ -980,95 +947,88 @@ a level type has not been established // Next steps should never happen; we have added a more robust mechanism to prevent any kind of mix and match above - if (ion[n].macro_info == 1 && mflag == -1) - { //it is already flagged as macro atom - current read is for LevTop - don't use it (SS) - Error - ("Get_atomic_data: file %s Ignoring LevTop data for ion %d - already using Macro Atom data\n", - file, n); - break; - } - if (ion[n].macro_info == 0 && mflag == 1) - { //It is already flagged as simple atom and this is before MacroAtom data - so ignore. ksl - Error - ("Get_atomic_data: file %s Trying to read MacroAtom data after LevTop data for ion %d. Not allowed\n", - file, n); - break; - } - - - // case where data will be used (SS) - if (mflag == 1) - { - config[nlevels].macro_info = 1; - - /* Extra check added here to be sure that the level emissivities used in the - detailed spectrum calculation won't get messed up. The next loop should - never trigger and can probably be deleted but I just want to check it for now. - SS June 04. */ - - if (nlevels_macro != nlevels) - { - Error - ("get_atomicdata: Simple level has appeared before macro level. Not allowed.\n"); - exit (0); - } - nlevels_macro++; - - if (nlevels_macro > NLEVELS_MACRO) - { - Error - ("get_atomicdata: Too many macro atom levels. Increase NLEVELS_MACRO. Abort. \n"); - exit (0); - } - } - else - { - config[nlevels].macro_info = 0; - nlevels_simple++; - } - - config[nlevels].z = z; - config[nlevels].istate = istate; - config[nlevels].isp = islp; - config[nlevels].ilv = ilv; - config[nlevels].nion = n; //Internal index to ion structure - config[nlevels].q_num = qqnum; - config[nlevels].g = gg; - config[nlevels].ex = exx; - config[nlevels].rad_rate = rl; - /* SS Aug 2005 - Previously, the line above set the rad_rate to 0 and is was never used. - Now I'm setting it to the radiative lifetime of the level. - It will now be used in the macro atom calculation - if the lifetime is - set to be long (infinite) in the input data, the level is assumed to be - collisional supported by the ground state (i.e. has the LTE excitation - fraction relative to ground). - */ + if (ion[n].macro_info == 1 && mflag == -1) + { //it is already flagged as macro atom - current read is for LevTop - don't use it (SS) + Error ("Get_atomic_data: file %s Ignoring LevTop data for ion %d - already using Macro Atom data\n", file, n); + break; + } + if (ion[n].macro_info == 0 && mflag == 1) + { //It is already flagged as simple atom and this is before MacroAtom data - so ignore. ksl + Error ("Get_atomic_data: file %s Trying to read MacroAtom data after LevTop data for ion %d. Not allowed\n", file, n); + break; + } - if (ion[n].n_lte_max > 0) - { // Then this ion wants nlte levels - if (ion[n].first_nlte_level < 0) - { // Then this is the first one that has been found - ion[n].first_nlte_level = nlevels; - ion[n].nlte = 1; - config[nlevels].nden = ion[n].first_levden; - } - else if (ion[n].n_lte_max > ion[n].nlte) - { - config[nlevels].nden = - ion[n].first_levden + ion[n].nlte; - ion[n].nlte++; - } - else - { - config[nlevels].nden = -1; - } - } - else - { - config[nlevels].nden = -1; - } + // case where data will be used (SS) + if (mflag == 1) + { + config[nlevels].macro_info = 1; + + /* Extra check added here to be sure that the level emissivities used in the + detailed spectrum calculation won't get messed up. The next loop should + never trigger and can probably be deleted but I just want to check it for now. + SS June 04. */ + + if (nlevels_macro != nlevels) + { + Error ("get_atomicdata: Simple level has appeared before macro level. Not allowed.\n"); + exit (0); + } + nlevels_macro++; + + if (nlevels_macro > NLEVELS_MACRO) + { + Error ("get_atomicdata: Too many macro atom levels. Increase NLEVELS_MACRO. Abort. \n"); + exit (0); + } + } + else + { + config[nlevels].macro_info = 0; + nlevels_simple++; + } + + config[nlevels].z = z; + config[nlevels].istate = istate; + config[nlevels].isp = islp; + config[nlevels].ilv = ilv; + config[nlevels].nion = n; //Internal index to ion structure + config[nlevels].q_num = qqnum; + config[nlevels].g = gg; + config[nlevels].ex = exx; + config[nlevels].rad_rate = rl; + /* SS Aug 2005 + Previously, the line above set the rad_rate to 0 and is was never used. + Now I'm setting it to the radiative lifetime of the level. + It will now be used in the macro atom calculation - if the lifetime is + set to be long (infinite) in the input data, the level is assumed to be + collisional supported by the ground state (i.e. has the LTE excitation + fraction relative to ground). + */ + + + if (ion[n].n_lte_max > 0) + { // Then this ion wants nlte levels + if (ion[n].first_nlte_level < 0) + { // Then this is the first one that has been found + ion[n].first_nlte_level = nlevels; + ion[n].nlte = 1; + config[nlevels].nden = ion[n].first_levden; + } + else if (ion[n].n_lte_max > ion[n].nlte) + { + config[nlevels].nden = ion[n].first_levden + ion[n].nlte; + ion[n].nlte++; + } + else + { + config[nlevels].nden = -1; + } + } + else + { + config[nlevels].nden = -1; + } /* Now associate this config with the levden array where appropriate. The -1 is because ion[].nlte @@ -1077,159 +1037,143 @@ is already incremented 080810 -- 62 -- Also want to treat these as simple levels in cases where we want to sum everything */ - if (ion[n].firstlevel < 0) - { - ion[n].firstlevel = nlevels; - ion[n].nlevels = 1; - } - else - ion[n].nlevels++; - - - - nlevels++; - - if (nlevels > NLEVELS) - { - Error - ("getatomic_data: file %s line %d: More energy levels than allowed. Increase NLEVELS in atomic.h\n", - file, lineno); - exit (0); - } - break; - - case 'n': // Its an "LTE" level - - if (sscanf (aline, "%*s %d %d %d %le %le\n", &zz, &iistate, &qnum, &gg, &exx) == 5) //IT's KURUCZSTYLE - { - istate = iistate; - z = zz; - exx *= EV2ERGS; - qqnum = ilv = qnum; - lev_type = 0; // It's a Kurucz-style record - - } - else // Read an OLDSTYLE level description - if (sscanf (aline, "%*s %d %le %le\n", &qnum, &gg, &exx) - == 3) - { - exx *= EV2ERGS; - qqnum = ilv = qnum; - lev_type = -2; // It's an old style record, one which is only here for backward compatibility - } - else - { - Error - ("get_atomic_data: file %s line %d: Level line incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } + if (ion[n].firstlevel < 0) + { + ion[n].firstlevel = nlevels; + ion[n].nlevels = 1; + } + else + ion[n].nlevels++; + + + + nlevels++; + + if (nlevels > NLEVELS) + { + Error ("getatomic_data: file %s line %d: More energy levels than allowed. Increase NLEVELS in atomic.h\n", file, lineno); + exit (0); + } + break; + + case 'n': // Its an "LTE" level + + if (sscanf (aline, "%*s %d %d %d %le %le\n", &zz, &iistate, &qnum, &gg, &exx) == 5) //IT's KURUCZSTYLE + { + istate = iistate; + z = zz; + exx *= EV2ERGS; + qqnum = ilv = qnum; + lev_type = 0; // It's a Kurucz-style record + + } + else // Read an OLDSTYLE level description + if (sscanf (aline, "%*s %d %le %le\n", &qnum, &gg, &exx) == 3) + { + exx *= EV2ERGS; + qqnum = ilv = qnum; + lev_type = -2; // It's an old style record, one which is only here for backward compatibility + } + else + { + Error ("get_atomic_data: file %s line %d: Level line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } /* Check whether the ion for this level is known. If not, skip the level */ // Next section is identical already to case N - n = 0; - while ((ion[n].z != z || ion[n].istate != istate) - && n < nions) - n++; - if (n == nions) - { - - Debug - ("get_atomic_data: file %s line %d has level for unknown ion \n", - file, lineno); - break; - - } - - /* Now either set the type of level that will be used for this ion or set it if - * a level type has not been established - */ + n = 0; + while ((ion[n].z != z || ion[n].istate != istate) && n < nions) + n++; + if (n == nions) + { + + Debug ("get_atomic_data: file %s line %d has level for unknown ion \n", file, lineno); + break; + + } + + /* Now either set the type of level that will be used for this ion or set it if + * a level type has not been established + */ - if (ion[n].lev_type == (-1)) - { - ion[n].lev_type = lev_type; - } - else if (ion[n].lev_type != lev_type) - { + if (ion[n].lev_type == (-1)) + { + ion[n].lev_type = lev_type; + } + else if (ion[n].lev_type != lev_type) + { //OLD Error //OLD ("Get_atomic_data: file %s Reading lev_type (%d) for ion %d with lev_type (%d). Not allowed\n", //OLD file, lev_type, n, ion[n].lev_type) - break; - } + break; + } // End section known to be idential to case N /* Check whether this is a macro-ion. If it is a macro-ion, but the level appears to be described as a simple level (i.e without a keyword LeVMacro), then skip it, since a macro-ion has to have all the levels described as macro-levels. */ - if (ion[n].macro_info == 1) - { - Error - ("get_atomic_data: file %s line %d has simple level for ion[%d], which is a macro-ion\n", - file, lineno, n); - break; - } + if (ion[n].macro_info == 1) + { + Error ("get_atomic_data: file %s line %d has simple level for ion[%d], which is a macro-ion\n", file, lineno, n); + break; + } /* Check to prevent one from adding simple levels to an ionized that already has some nlte levels. Note that an ion may have simple levels, i.e. levels with no entries in the plasma structure levden array, but this will only be the case if there are too many of this type of level. */ - if (ion[n].nlte > 0) - { - Error - ("get_atomic_data: file %s line %d has simple level for ion[%d], which has non_lte_levels\n", - file, lineno, n); - break; - } + if (ion[n].nlte > 0) + { + Error ("get_atomic_data: file %s line %d has simple level for ion[%d], which has non_lte_levels\n", file, lineno, n); + break; + } /* Check whether we already have too many levels specified for this ion. If so, skip */ - if (ion[n].nmax == ion[n].nlevels) - { - - Debug - ("get_atomic_data: file %s line %d has level exceeding the number allowed for ion[%d]\n", - file, lineno, n); - - break; - } + if (ion[n].nmax == ion[n].nlevels) + { + + Debug ("get_atomic_data: file %s line %d has level exceeding the number allowed for ion[%d]\n", file, lineno, n); + + break; + } // So now we know that this level can be associated with an ion - config[nlevels].z = z; - config[nlevels].istate = istate; - config[nlevels].isp = islp; - config[nlevels].ilv = ilv; - config[nlevels].nion = n; //Internal index to ion structure - config[nlevels].q_num = qqnum; - config[nlevels].g = gg; - config[nlevels].ex = exx; - if (ion[n].firstlevel < 0) - { - ion[n].firstlevel = nlevels; - ion[n].nlevels = 1; - } - else - ion[n].nlevels++; + config[nlevels].z = z; + config[nlevels].istate = istate; + config[nlevels].isp = islp; + config[nlevels].ilv = ilv; + config[nlevels].nion = n; //Internal index to ion structure + config[nlevels].q_num = qqnum; + config[nlevels].g = gg; + config[nlevels].ex = exx; + if (ion[n].firstlevel < 0) + { + ion[n].firstlevel = nlevels; + ion[n].nlevels = 1; + } + else + ion[n].nlevels++; /* 080808 - ksl - Now declare that this level has no corresponding element in the levden array which is part of the plasma stucture. To do this set config[].ndent to -1 */ - config[nlevels].nden = -1; + config[nlevels].nden = -1; - config[nlevels].rad_rate = 0.0; // ?? Set emission oscillator strength for the level to zero + config[nlevels].rad_rate = 0.0; // ?? Set emission oscillator strength for the level to zero - nlevels_simple++; - nlevels++; - if (nlevels > NLEVELS) - { - Error - ("getatomic_data: file %s line %d: More energy levels than allowed. Increase NLEVELS in atomic.h\n", - file, lineno); - exit (0); - } - break; + nlevels_simple++; + nlevels++; + if (nlevels > NLEVELS) + { + Error ("getatomic_data: file %s line %d: More energy levels than allowed. Increase NLEVELS in atomic.h\n", file, lineno); + exit (0); + } + break; @@ -1308,521 +1252,477 @@ for the ionstate. one need modify only the higher level elements_ions file */ - case 'w': - if (strncmp (word, "PhotMacS", 8) == 0) - { - // It's a Macro atom entry - similar format to TOPBASE - see below (SS) - sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, &istate, - &levl, &levu, &exx, &np); - islp = -1; - ilv = -1; - - for (n = 0; n < np; n++) - { - //Read the photo. records but do nothing with them until verifyina a valid level - if (fgets (aline, LINELENGTH, fptr) == NULL) - { - Error - ("Get_atomic_data: Problem reading topbase photoionization record\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); - lineno++; - } - - // Locate upper state - n = 0; - while ((config[n].z != z || config[n].istate != (istate + 1) //note that the upper config will (SS) - || config[n].ilv != levu) && n < nlevels) //be the next ion up (istate +1) (SS) - n++; - if (n == nlevels) - { - Error_silent - ("get_atomic_data: No configuration found to match upper state for phot. line %d\n", - lineno); - break; //Need to match the configuration for macro atoms - break if not found. - } - - - // Locate lower state - m = 0; - while ((config[m].z != z || config[m].istate != istate //Now searching for the lower - || config[m].ilv != levl) && m < nlevels) //configuration (SS) - m++; - if (m == nlevels) - { - Error_silent - ("get_atomic_data: No configuration found to match lower state for phot. line %d\n", - lineno); - break; //Need to match the configuration for macro atoms - break if not found. - } - - // Populate upper state info - phot_top[ntop_phot].uplev = n; //store the level in the upper ion (SS) - config[n].bfd_jump[config[n].n_bfd_jump] = ntop_phot; //record the line index as a downward bf Macro Atom jump (SS) - phot_top[ntop_phot].down_index = config[n].n_bfd_jump; //record jump index in the photoionization structure - config[n].n_bfd_jump += 1; //note that there is one more downwards bf jump available (SS) - if (config[n].n_bfd_jump > NBFJUMPS) - { - Error - ("get_atomic_data: Too many downward b-f jump for ion %d\n", - config[n].istate); - exit (0); - } - - - // Populate lower state info - phot_top[ntop_phot].nlev = m; //store lower configuration then find upper configuration(SS) - config[m].bfu_jump[config[m].n_bfu_jump] = ntop_phot; //record the line index as an upward bf Macro Atom jump (SS) - phot_top[ntop_phot].up_index = config[m].n_bfu_jump; //record the jump index in the photoionization structure - config[m].n_bfu_jump += 1; //note that there is one more upwards bf jump available (SS) - if (config[m].n_bfu_jump > NBFJUMPS) - { - Error - ("get_atomic_data: Too many upward b-f jump for ion %d\n", - config[m].istate); - exit (0); - } - - - phot_top[ntop_phot].nion = config[m].nion; - phot_top[ntop_phot].z = z; - phot_top[ntop_phot].istate = istate; - phot_top[ntop_phot].np = np; - phot_top[ntop_phot].nlast = -1; - phot_top[ntop_phot].macro_info = 1; - - if (ion[config[m].nion].phot_info == -1) - { - ion[config[m].nion].phot_info = 1; /* Mark this ion as using TOPBASE photo */ - ion[config[m].nion].ntop_first = ntop_phot; - } - - /* JM 1508 -- next line sees if the topbase level just read in is the ground state - - if it is, the ion structure element ntop_ground is set to that topbase level number - note that m is the lower level here */ - if (m == config[ion[config[n].nion].first_nlte_level].ilv) - { - ion[config[n].nion].ntop_ground = ntop_phot; - } + case 'w': + if (strncmp (word, "PhotMacS", 8) == 0) + { + // It's a Macro atom entry - similar format to TOPBASE - see below (SS) + sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, &istate, &levl, &levu, &exx, &np); + islp = -1; + ilv = -1; + + for (n = 0; n < np; n++) + { + //Read the photo. records but do nothing with them until verifyina a valid level + if (fgets (aline, LINELENGTH, fptr) == NULL) + { + Error ("Get_atomic_data: Problem reading topbase photoionization record\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); + lineno++; + } + + // Locate upper state + n = 0; + while ((config[n].z != z || config[n].istate != (istate + 1) //note that the upper config will (SS) + || config[n].ilv != levu) && n < nlevels) //be the next ion up (istate +1) (SS) + n++; + if (n == nlevels) + { + Error_silent ("get_atomic_data: No configuration found to match upper state for phot. line %d\n", lineno); + break; //Need to match the configuration for macro atoms - break if not found. + } + + + // Locate lower state + m = 0; + while ((config[m].z != z || config[m].istate != istate //Now searching for the lower + || config[m].ilv != levl) && m < nlevels) //configuration (SS) + m++; + if (m == nlevels) + { + Error_silent ("get_atomic_data: No configuration found to match lower state for phot. line %d\n", lineno); + break; //Need to match the configuration for macro atoms - break if not found. + } + + // Populate upper state info + phot_top[ntop_phot].uplev = n; //store the level in the upper ion (SS) + config[n].bfd_jump[config[n].n_bfd_jump] = ntop_phot; //record the line index as a downward bf Macro Atom jump (SS) + phot_top[ntop_phot].down_index = config[n].n_bfd_jump; //record jump index in the photoionization structure + config[n].n_bfd_jump += 1; //note that there is one more downwards bf jump available (SS) + if (config[n].n_bfd_jump > NBFJUMPS) + { + Error ("get_atomic_data: Too many downward b-f jump for ion %d\n", config[n].istate); + exit (0); + } + + + // Populate lower state info + phot_top[ntop_phot].nlev = m; //store lower configuration then find upper configuration(SS) + config[m].bfu_jump[config[m].n_bfu_jump] = ntop_phot; //record the line index as an upward bf Macro Atom jump (SS) + phot_top[ntop_phot].up_index = config[m].n_bfu_jump; //record the jump index in the photoionization structure + config[m].n_bfu_jump += 1; //note that there is one more upwards bf jump available (SS) + if (config[m].n_bfu_jump > NBFJUMPS) + { + Error ("get_atomic_data: Too many upward b-f jump for ion %d\n", config[m].istate); + exit (0); + } + + + phot_top[ntop_phot].nion = config[m].nion; + phot_top[ntop_phot].z = z; + phot_top[ntop_phot].istate = istate; + phot_top[ntop_phot].np = np; + phot_top[ntop_phot].nlast = -1; + phot_top[ntop_phot].macro_info = 1; + + if (ion[config[m].nion].phot_info == -1) + { + ion[config[m].nion].phot_info = 1; /* Mark this ion as using TOPBASE photo */ + ion[config[m].nion].ntop_first = ntop_phot; + } + + /* JM 1508 -- next line sees if the topbase level just read in is the ground state - + if it is, the ion structure element ntop_ground is set to that topbase level number + note that m is the lower level here */ + if (m == config[ion[config[n].nion].first_nlte_level].ilv) + { + ion[config[n].nion].ntop_ground = ntop_phot; + } + + ion[config[m].nion].ntop++; + + // Finish up this section by storing the photionization data properly + + for (n = 0; n < np; n++) + { + phot_top[ntop_phot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency + phot_top[ntop_phot].x[n] = xx[n]; // leave cross sections in CGS + } + if (phot_freq_min > phot_top[ntop_phot].freq[0]) + phot_freq_min = phot_top[ntop_phot].freq[0]; + + + ntop_phot_macro++; + ntop_phot++; + nphot_total++; + + /* 080812 - Added check to assure we did not exceed the allowed number of photoionization records */ + if (nphot_total > NTOP_PHOT) + { + Error ("get_atomicdata: More macro photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", NTOP_PHOT); + exit (0); + } + break; + } + + + + else if (strncmp (word, "PhotTopS", 8) == 0) + { + // It's a TOPBASE style photoionization record, beginning with the summary record + sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, &istate, &islp, &ilv, &exx, &np); + for (n = 0; n < np; n++) + { //Read the topbase photoionization records + if (fgets (aline, LINELENGTH, fptr) == NULL) + { + Error ("Get_atomic_data: Problem reading topbase photoionization record\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); + lineno++; + + } + + n = 0; + + + /* 080812 - 63 - ksl - added additional check to assure that records were + * only matched with levels whose density was being tracked in levden. This + * is now necesary since a change was made to use topbase levels for calculating + * partition functions + */ + + while ((config[n].nden == -1 + || config[n].z != z || config[n].istate != istate || config[n].isp != islp || config[n].ilv != ilv) && n < nlevels) + n++; + if (n == nlevels) + { + + Debug ("No ion found to match PhotTop data in file %s on line %d. Data ignored.\n", file, lineno); + break; // There was no pre-existing ion + } + if (ion[config[n].nion].macro_info == 0) //this is not a macro atom level (SS) + { + phot_top[ntop_phot].nlev = n; // level associated with this crossection. + phot_top[ntop_phot].nion = config[n].nion; + phot_top[ntop_phot].z = z; + phot_top[ntop_phot].istate = istate; + phot_top[ntop_phot].np = np; + phot_top[ntop_phot].nlast = -1; + phot_top[ntop_phot].macro_info = 0; + + /* NSH 0312 - next line sees if the topbase level just read in is the ground state - + if it is, the ion structure element ntop_ground is set to that topbase level number */ + if (islp == config[ion[config[n].nion].first_nlte_level].isp && ilv == config[ion[config[n].nion].first_nlte_level].ilv) + { + ion[config[n].nion].ntop_ground = ntop_phot; + } + + + if (ion[config[n].nion].phot_info == -1) + { + ion[config[n].nion].phot_info = 1; /* Mark this ion as using TOPBASE photo */ + ion[config[n].nion].ntop_first = ntop_phot; + + } + else if (ion[config[n].nion].phot_info == (0)) + { + Error + ("Get_atomic_data: file %s VFKY and Topbase photoionization x-sections in wrong order for nion %d\n", + file, config[n].nion); + Error (" Read topbase x-sections before VFKY if using both types!!\n"); + exit (0); + } + ion[config[n].nion].ntop++; + for (n = 0; n < np; n++) + { + phot_top[ntop_phot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency + + phot_top[ntop_phot].x[n] = xx[n]; // leave cross sections in CGS + } + if (phot_freq_min > phot_top[ntop_phot].freq[0]) + phot_freq_min = phot_top[ntop_phot].freq[0]; + + + ntop_phot_simple++; + ntop_phot++; + nphot_total++; + + /* 080812 - Added check to assure we did not exceed the allowed number of photoionization records */ + if (nphot_total > NTOP_PHOT) + { + Error + ("get_atomicdata: More TopBase photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", NTOP_PHOT); + exit (0); + } + } + else + { + Error + ("Get_atomic_data: photoionisation data ignored since previously read Macro Atom input for the same ion. File: %s line: %d \n", + file, lineno); + } + break; + } + + + /* Check that there is an ion which has the same ionization state as this record + otherwise it must be a VFKY style record and so read with that format */ + + else if (strncmp (word, "PhotVfkyS", 8) == 0) + { + // It's a TOPBASE style photoionization record, beginning with the summary record + sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, &istate, &islp, &ilv, &exx, &np); + for (n = 0; n < np; n++) + { + //Read the topbase photoionization records + if (fgets (aline, LINELENGTH, fptr) == NULL) + { + Error ("Get_atomic_data: Problem reading Vfky photoionization record\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); + lineno++; + + } + + for (nion = 0; nion < nions; nion++) + { + if (ion[nion].z == z && ion[nion].istate == istate) + { + if (ion[nion].phot_info == -1) + { + /* Then there is a match */ + phot_top[nphot_total].nlev = ion[nion].firstlevel; // ground state + phot_top[nphot_total].nion = nion; + phot_top[nphot_total].z = z; + phot_top[nphot_total].istate = istate; + phot_top[nphot_total].np = np; + phot_top[nphot_total].nlast = -1; + phot_top[nphot_total].macro_info = 0; + + ion[nion].phot_info = 0; /* Mark this ion as using VFKY photo */ + ion[nion].nxphot = nphot_total; + + for (n = 0; n < np; n++) + { + phot_top[nphot_total].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency + phot_top[nphot_total].x[n] = xx[n]; // leave cross sections in CGS + } + if (phot_freq_min > phot_top[ntop_phot].freq[0]) + phot_freq_min = phot_top[ntop_phot].freq[0]; + nxphot++; + nphot_total++; + } + + else if (ion[nion].phot_info == 1 && ion[nion].macro_info != 1) + /* We already have a topbase cross section, but the VFKY + data is superior for the ground state, so we replace that data with the current data */ + /* JM 1508 -- don't do this with macro-atoms for the moment */ + { + phot_top[ion[nion].ntop_ground].nlev = ion[nion].firstlevel; // ground state + phot_top[ion[nion].ntop_ground].nion = nion; + phot_top[ion[nion].ntop_ground].z = z; + phot_top[ion[nion].ntop_ground].istate = istate; + phot_top[ion[nion].ntop_ground].np = np; + phot_top[ion[nion].ntop_ground].nlast = -1; + phot_top[ion[nion].ntop_ground].macro_info = 0; + ion[nion].phot_info = 2; //We mark this as having hybrid data - VFKY ground, TB excited, potentially VFKY innershell + for (n = 0; n < np; n++) + { + phot_top[ion[nion].ntop_ground].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency + phot_top[ion[nion].ntop_ground].x[n] = xx[n]; // leave cross sections in CGS + } + if (phot_freq_min > phot_top[ion[nion].ntop_ground].freq[0]) + phot_freq_min = phot_top[ion[nion].ntop_ground].freq[0]; +// + Debug + ("Get_atomic_data: file %s Replacing ground state topbase photoionization for ion %d with VFKY photoionization\n", + file, nion); + } + } + } + + if (nxphot > NIONS) + { + Error ("getatomic_data: file %s line %d: More photoionization edges than IONS.\n", file, lineno); + exit (0); + } + if (nphot_total > NTOP_PHOT) + { + Error ("get_atomicdata: More photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", NTOP_PHOT); + exit (0); + } + + break; + } + else + { + Error ("get_atomic_data: file %s line %d: photoionization line incorrectly formatted\n", file, lineno); + Log ("Make sure you are using the tabulated verner cross sections (photo_vfky_tabulated.data)\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + /* Input inner shell cross section data */ + - ion[config[m].nion].ntop++; - - // Finish up this section by storing the photionization data properly - - for (n = 0; n < np; n++) - { - phot_top[ntop_phot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency - phot_top[ntop_phot].x[n] = xx[n]; // leave cross sections in CGS - } - if (phot_freq_min > phot_top[ntop_phot].freq[0]) - phot_freq_min = phot_top[ntop_phot].freq[0]; - - - ntop_phot_macro++; - ntop_phot++; - nphot_total++; - - /* 080812 - Added check to assure we did not exceed the allowed number of photoionization records */ - if (nphot_total > NTOP_PHOT) - { - Error - ("get_atomicdata: More macro photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", - NTOP_PHOT); - exit (0); - } - break; - } - - - - else if (strncmp (word, "PhotTopS", 8) == 0) - { - // It's a TOPBASE style photoionization record, beginning with the summary record - sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, - &istate, &islp, &ilv, &exx, &np); - for (n = 0; n < np; n++) - { //Read the topbase photoionization records - if (fgets (aline, LINELENGTH, fptr) == NULL) - { - Error - ("Get_atomic_data: Problem reading topbase photoionization record\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); - lineno++; - - } - - n = 0; - - - /* 080812 - 63 - ksl - added additional check to assure that records were - * only matched with levels whose density was being tracked in levden. This - * is now necesary since a change was made to use topbase levels for calculating - * partition functions - */ - - while ((config[n].nden == -1 - || config[n].z != z - || config[n].istate != istate - || config[n].isp != islp - || config[n].ilv != ilv) && n < nlevels) - n++; - if (n == nlevels) - { - - Debug - ("No ion found to match PhotTop data in file %s on line %d. Data ignored.\n", - file, lineno); - break; // There was no pre-existing ion - } - if (ion[config[n].nion].macro_info == 0) //this is not a macro atom level (SS) - { - phot_top[ntop_phot].nlev = n; // level associated with this crossection. - phot_top[ntop_phot].nion = config[n].nion; - phot_top[ntop_phot].z = z; - phot_top[ntop_phot].istate = istate; - phot_top[ntop_phot].np = np; - phot_top[ntop_phot].nlast = -1; - phot_top[ntop_phot].macro_info = 0; - - /* NSH 0312 - next line sees if the topbase level just read in is the ground state - - if it is, the ion structure element ntop_ground is set to that topbase level number */ - if (islp == config[ion[config[n].nion].first_nlte_level].isp - && ilv == config[ion[config[n].nion].first_nlte_level].ilv) - { - ion[config[n].nion].ntop_ground = ntop_phot; - } - - - if (ion[config[n].nion].phot_info == -1) - { - ion[config[n].nion].phot_info = 1; /* Mark this ion as using TOPBASE photo */ - ion[config[n].nion].ntop_first = ntop_phot; - - } - else if (ion[config[n].nion].phot_info == (0)) - { - Error - ("Get_atomic_data: file %s VFKY and Topbase photoionization x-sections in wrong order for nion %d\n", - file, config[n].nion); - Error - (" Read topbase x-sections before VFKY if using both types!!\n"); - exit (0); - } - ion[config[n].nion].ntop++; - for (n = 0; n < np; n++) - { - phot_top[ntop_phot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency - - phot_top[ntop_phot].x[n] = xx[n]; // leave cross sections in CGS - } - if (phot_freq_min > phot_top[ntop_phot].freq[0]) - phot_freq_min = phot_top[ntop_phot].freq[0]; - - - ntop_phot_simple++; - ntop_phot++; - nphot_total++; - /* 080812 - Added check to assure we did not exceed the allowed number of photoionization records */ - if (nphot_total > NTOP_PHOT) - { - Error - ("get_atomicdata: More TopBase photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", - NTOP_PHOT); - exit (0); - } - } - else - { - Error - ("Get_atomic_data: photoionisation data ignored since previously read Macro Atom input for the same ion. File: %s line: %d \n", - file, lineno); - } - break; - } - - - /* Check that there is an ion which has the same ionization state as this record - otherwise it must be a VFKY style record and so read with that format */ - - else if (strncmp (word, "PhotVfkyS", 8) == 0) - { - // It's a TOPBASE style photoionization record, beginning with the summary record - sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, - &istate, &islp, &ilv, &exx, &np); - for (n = 0; n < np; n++) - { + case 'I': + if (sscanf (aline, "%*s %d %d %d %d %le %d\n", &z, &istate, &in, &il, &exx, &np) != 6) + { + Error ("Inner shell ionization data incorrectly formatted\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + for (n = 0; n < np; n++) + { //Read the topbase photoionization records if (fgets (aline, LINELENGTH, fptr) == NULL) - { - Error - ("Get_atomic_data: Problem reading Vfky photoionization record\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } + { + Error ("Get_atomic_data: Problem reading VY inner shell record\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); lineno++; - } - - for (nion = 0; nion < nions; nion++) + for (nion = 0; nion < nions; nion++) { if (ion[nion].z == z && ion[nion].istate == istate) - { - if (ion[nion].phot_info == -1) { /* Then there is a match */ - phot_top[nphot_total].nlev = ion[nion].firstlevel; // ground state - phot_top[nphot_total].nion = nion; - phot_top[nphot_total].z = z; - phot_top[nphot_total].istate = istate; - phot_top[nphot_total].np = np; - phot_top[nphot_total].nlast = -1; - phot_top[nphot_total].macro_info = 0; - - ion[nion].phot_info = 0; /* Mark this ion as using VFKY photo */ - ion[nion].nxphot = nphot_total; - + inner_cross[n_inner_tot].nion = nion; + inner_cross[n_inner_tot].np = np; + inner_cross[n_inner_tot].z = z; + inner_cross[n_inner_tot].istate = istate; + inner_cross[n_inner_tot].n = in; + inner_cross[n_inner_tot].l = il; + inner_cross[n_inner_tot].nlast = -1; + ion[nion].n_inner++; /*Increment the number of inner shells */ + ion[nion].nxinner[ion[nion].n_inner] = n_inner_tot; for (n = 0; n < np; n++) - { - phot_top[nphot_total].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency - phot_top[nphot_total].x[n] = xx[n]; // leave cross sections in CGS - } - if (phot_freq_min > phot_top[ntop_phot].freq[0]) - phot_freq_min = phot_top[ntop_phot].freq[0]; - nxphot++; - nphot_total++; - } + { + inner_cross[n_inner_tot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency + inner_cross[n_inner_tot].x[n] = xx[n]; // leave cross sections in CGS + } + if (inner_freq_min > inner_cross[n_inner_tot].freq[0]) + inner_freq_min = inner_cross[n_inner_tot].freq[0]; + n_inner_tot++; - else if (ion[nion].phot_info == 1 && ion[nion].macro_info != 1) - /* We already have a topbase cross section, but the VFKY - data is superior for the ground state, so we replace that data with the current data*/ - /* JM 1508 -- don't do this with macro-atoms for the moment */ - { - phot_top[ion[nion].ntop_ground].nlev = ion[nion].firstlevel; // ground state - phot_top[ion[nion].ntop_ground].nion = nion; - phot_top[ion[nion].ntop_ground].z = z; - phot_top[ion[nion].ntop_ground].istate = istate; - phot_top[ion[nion].ntop_ground].np = np; - phot_top[ion[nion].ntop_ground].nlast = -1; - phot_top[ion[nion].ntop_ground].macro_info = 0; - ion[nion].phot_info = 2; //We mark this as having hybrid data - VFKY ground, TB excited, potentially VFKY innershell - for (n = 0; n < np; n++) - { - phot_top[ion[nion].ntop_ground].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency - phot_top[ion[nion].ntop_ground].x[n] = xx[n]; // leave cross sections in CGS - } - if (phot_freq_min > phot_top[ion[nion].ntop_ground].freq[0]) - phot_freq_min = phot_top[ion[nion].ntop_ground].freq[0]; -// - Debug - ("Get_atomic_data: file %s Replacing ground state topbase photoionization for ion %d with VFKY photoionization\n", - file, nion); } - } - } - - if (nxphot > NIONS) - { - Error - ("getatomic_data: file %s line %d: More photoionization edges than IONS.\n", - file, lineno); - exit (0); - } - if (nphot_total > NTOP_PHOT) - { - Error - ("get_atomicdata: More photoionization cross sections that NTOP_PHOT (%d). Increase in atomic.h\n", - NTOP_PHOT); - exit (0); - } + } + if (n_inner_tot > N_INNER * NIONS) + { + Error ("getatomic_data: file %s line %d: Inner edges than we have room for.\n", file, lineno); + exit (0); + } + break; - break; - } - else - { - Error - ("get_atomic_data: file %s line %d: photoionization line incorrectly formatted\n", - file, lineno); - Log("Make sure you are using the tabulated verner cross sections (photo_vfky_tabulated.data)\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - /* Input inner shell cross section data */ - - - -case 'I': - if (sscanf (aline, "%*s %d %d %d %d %le %d\n", &z,&istate, &in, &il, &exx, &np) !=6) - { - Error ("Inner shell ionization data incorrectly formatted\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - for (n = 0; n < np; n++) - { - //Read the topbase photoionization records - if (fgets (aline, LINELENGTH, fptr) == NULL) - { - Error("Get_atomic_data: Problem reading VY inner shell record\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - sscanf (aline, "%*s %le %le", &xe[n], &xx[n]); - lineno++; - } - for (nion = 0; nion < nions; nion++) - { - if (ion[nion].z == z && ion[nion].istate == istate) - { - /* Then there is a match */ - inner_cross[n_inner_tot].nion = nion; - inner_cross[n_inner_tot].np = np; - inner_cross[n_inner_tot].z = z; - inner_cross[n_inner_tot].istate = istate; - inner_cross[n_inner_tot].n = in; - inner_cross[n_inner_tot].l = il; - inner_cross[n_inner_tot].nlast = -1; - ion[nion].n_inner++; /*Increment the number of inner shells*/ - ion[nion].nxinner[ion[nion].n_inner] = n_inner_tot; - for (n = 0; n < np; n++) - { - inner_cross[n_inner_tot].freq[n] = xe[n] * EV2ERGS / H; // convert from eV to freqency - inner_cross[n_inner_tot].x[n] = xx[n]; // leave cross sections in CGS - } - if (inner_freq_min > inner_cross[n_inner_tot].freq[0]) - inner_freq_min = inner_cross[n_inner_tot].freq[0]; - n_inner_tot++; - - } - } - if (n_inner_tot > N_INNER*NIONS) - { - Error("getatomic_data: file %s line %d: Inner edges than we have room for.\n",file, lineno); - exit (0); - } - break; - - /*Input data for innershell ionization followed by - Auger effect */ - - case 'A': - if (sscanf (aline, - "%*s %d %d %d %d %le %le %le %le %le %le %le", - &z, &istate, &nn, &nl, &yield, &arad, &etarad, - &adi, &t0di, &bdi, &t1di) != 11) - { - Error ("Auger input incorrectly formatted\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - if (nauger < NAUGER) - { - if ((vptr = - fopen ("atomic/photo_verner.data", "r")) == NULL) - { - Error - ("get_atomic data: Could not open photo_verner.data\n"); - exit (0); - } - ion_index = -2; - target_index = -1; - for (n_verner = 0; n_verner < 1696; n_verner++) - { - fscanf (vptr, - "%d %d %d %d %le %le %le %le %le %le\n", - &dumz, &dumistate, &dumnn, &dumnl, &dumE_th, - &dumE_0, &dumSigma, &dumya, &dumP, &dumyw); - if ((dumz == z) - && (dumistate == (dumz - istate + 1)) - && (dumnn == nn) && (dumnl == nl)) - { - /* Now need to check that this ion is really in the data set and find which it is */ - ion_index = -1; - for (n = 0; n < nions; n++) - { - if (ion[n].z == z - && ion[n].istate == istate) - { - ion_index = n; - augerion[nauger].nion = n; - augerion[nauger].yield = yield; - augerion[nauger].arad = arad; - augerion[nauger].etarad = etarad; - augerion[nauger].adi = adi; - augerion[nauger].t0di = t0di; - augerion[nauger].bdi = bdi; - augerion[nauger].t1di = t1di; - - augerion[nauger].z = z; - augerion[nauger].istate = istate; - augerion[nauger].n = nn; - augerion[nauger].l = nl; - augerion[nauger].freq_t = dumE_th / HEV; - augerion[nauger].E_0 = dumE_0; - augerion[nauger].Sigma = dumSigma * 1.e-18; //input - //in megabarns - augerion[nauger].ya = dumya; - augerion[nauger].yw = dumyw; - augerion[nauger].P = dumP; - nauger++; - } - - /*We also want the index for the - targe ion (i.e. the one that is - two ionization stages up from the - one found above */ - if (ion[n].z == z - && ion[n].istate == istate + 2) - { - target_index = n; - } - - } - if (ion_index == -1) - { - Error - ("Get_atomic_data: Failed to find ion to match Auger input data. Ignoring. %d %d %d %d\n", - dumz, dumistate, dumnn, dumnl); - } - else - { - augerion[nauger - 1].nion_target = - target_index; - } - } - } - fclose (vptr); - if (ion_index == -2) - { - Error - ("Get_atomic_data: Failed to find source data to match Auger input data. Ignoring. %d %d %d %d\n", - z, istate, nn, nl); - } - else - { - Log - ("Matched Auger ionization input to Z %d istate %d going to Z %d istate %d.\n", - ion[augerion[nauger - 1].nion].z, - ion[augerion[nauger - 1].nion].istate, - ion[augerion[nauger - 1].nion_target].z, - ion[augerion[nauger - 1].nion_target].istate); - } - } - else - { - Error - ("Get_atomic_data: NAUGER is filled up! Ignoring input data %d.\n", - nauger); - } - break; + /*Input data for innershell ionization followed by + Auger effect */ + + case 'A': + if (sscanf (aline, + "%*s %d %d %d %d %le %le %le %le %le %le %le", + &z, &istate, &nn, &nl, &yield, &arad, &etarad, &adi, &t0di, &bdi, &t1di) != 11) + { + Error ("Auger input incorrectly formatted\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + if (nauger < NAUGER) + { + if ((vptr = fopen ("atomic/photo_verner.data", "r")) == NULL) + { + Error ("get_atomic data: Could not open photo_verner.data\n"); + exit (0); + } + ion_index = -2; + target_index = -1; + for (n_verner = 0; n_verner < 1696; n_verner++) + { + fscanf (vptr, + "%d %d %d %d %le %le %le %le %le %le\n", + &dumz, &dumistate, &dumnn, &dumnl, &dumE_th, &dumE_0, &dumSigma, &dumya, &dumP, &dumyw); + if ((dumz == z) && (dumistate == (dumz - istate + 1)) && (dumnn == nn) && (dumnl == nl)) + { + /* Now need to check that this ion is really in the data set and find which it is */ + ion_index = -1; + for (n = 0; n < nions; n++) + { + if (ion[n].z == z && ion[n].istate == istate) + { + ion_index = n; + augerion[nauger].nion = n; + augerion[nauger].yield = yield; + augerion[nauger].arad = arad; + augerion[nauger].etarad = etarad; + augerion[nauger].adi = adi; + augerion[nauger].t0di = t0di; + augerion[nauger].bdi = bdi; + augerion[nauger].t1di = t1di; + + augerion[nauger].z = z; + augerion[nauger].istate = istate; + augerion[nauger].n = nn; + augerion[nauger].l = nl; + augerion[nauger].freq_t = dumE_th / HEV; + augerion[nauger].E_0 = dumE_0; + augerion[nauger].Sigma = dumSigma * 1.e-18; //input + //in megabarns + augerion[nauger].ya = dumya; + augerion[nauger].yw = dumyw; + augerion[nauger].P = dumP; + nauger++; + } + + /*We also want the index for the + targe ion (i.e. the one that is + two ionization stages up from the + one found above */ + if (ion[n].z == z && ion[n].istate == istate + 2) + { + target_index = n; + } + + } + if (ion_index == -1) + { + Error + ("Get_atomic_data: Failed to find ion to match Auger input data. Ignoring. %d %d %d %d\n", + dumz, dumistate, dumnn, dumnl); + } + else + { + augerion[nauger - 1].nion_target = target_index; + } + } + } + fclose (vptr); + if (ion_index == -2) + { + Error ("Get_atomic_data: Failed to find source data to match Auger input data. Ignoring. %d %d %d %d\n", z, istate, nn, nl); + } + else + { + Log + ("Matched Auger ionization input to Z %d istate %d going to Z %d istate %d.\n", + ion[augerion[nauger - 1].nion].z, + ion[augerion[nauger - 1].nion].istate, + ion[augerion[nauger - 1].nion_target].z, ion[augerion[nauger - 1].nion_target].istate); + } + } + else + { + Error ("Get_atomic_data: NAUGER is filled up! Ignoring input data %d.\n", nauger); + } + break; @@ -1886,365 +1786,321 @@ Col Basically this was accomplished by checking both the upper and lower level and breaking out if either was not accounted for. */ - case 'r': - if (strncmp (word, "LinMacro", 8) == 0) - { //It's a macro atoms line(SS) - if (mflag != 1) - { - Error - ("get_atomicdata: Can't read macro-line after some simple lines. Reorder the input files!\n"); - exit (0); - } - - mflag = 1; //flag to identify macro atom case (SS) - nwords = - sscanf (aline, - "%*s %d %d %le %le %le %le %le %le %d %d", &z, - &istate, &freq, &f, &gl, &gu, &el, &eu, &levl, - &levu); - if (nwords != 10) - { - Error - ("get_atomic_data: file %s line %d: LinMacro line incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - el = EV2ERGS * el; - eu = EV2ERGS * eu; - //need to identify the configurations associated with the upper and lower levels (SS) - n = 0; - while ((config[n].z != z || config[n].istate != istate - || config[n].ilv != levl) && n < nlevels) - n++; - if (n == nlevels) - { - Error_silent - ("Get_atomic_data: No configuration found to match lower level of line %d\n", - lineno); - break; - } - - - m = 0; - while ((config[m].z != z || config[m].istate != istate - || config[m].ilv != levu) && m < nlevels) - m++; - if (m == nlevels) - { - Error_silent - ("Get_atomic_data: No configuration found to match upper level of line %d\n", - lineno); - break; - } - - /* Now that we know this is a valid transition for the macro atom record the data */ - - nconfigl = n; //record lower configuration (SS) - config[n].bbu_jump[config[n].n_bbu_jump] = nlines; //record the line index as an upward bb Macro Atom jump(SS) - line[nlines].down_index = config[n].n_bbu_jump; //record the index for the jump in the line structure - config[n].n_bbu_jump += 1; //note that there is one more upwards jump available (SS) - if (config[n].n_bbu_jump > NBBJUMPS) - { - Error - ("get_atomic_data: Too many upward b-b jumps for ion %d\n", - config[n].istate); - exit (0); - } - - nconfigu = m; //record upper configuration (SS) - config[m].bbd_jump[config[m].n_bbd_jump] = nlines; //record the line index as a downward bb Macro Atom jump (SS) - line[nlines].up_index = config[m].n_bbd_jump; //record jump index in line structure - config[m].n_bbd_jump += 1; //note that there is one more downwards jump available (SS) - if (config[m].n_bbd_jump > NBBJUMPS) - { - Error - ("get_atomic_data: Too many downward b-b jumps for ion %d\n", - config[m].istate); - exit (0); - } - - - } - else - { //It's not a macro atom line (SS) + case 'r': + if (strncmp (word, "LinMacro", 8) == 0) + { //It's a macro atoms line(SS) + if (mflag != 1) + { + Error ("get_atomicdata: Can't read macro-line after some simple lines. Reorder the input files!\n"); + exit (0); + } + + mflag = 1; //flag to identify macro atom case (SS) + nwords = sscanf (aline, "%*s %d %d %le %le %le %le %le %le %d %d", &z, &istate, &freq, &f, &gl, &gu, &el, &eu, &levl, &levu); + if (nwords != 10) + { + Error ("get_atomic_data: file %s line %d: LinMacro line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + el = EV2ERGS * el; + eu = EV2ERGS * eu; + //need to identify the configurations associated with the upper and lower levels (SS) + n = 0; + while ((config[n].z != z || config[n].istate != istate || config[n].ilv != levl) && n < nlevels) + n++; + if (n == nlevels) + { + Error_silent ("Get_atomic_data: No configuration found to match lower level of line %d\n", lineno); + break; + } + + + m = 0; + while ((config[m].z != z || config[m].istate != istate || config[m].ilv != levu) && m < nlevels) + m++; + if (m == nlevels) + { + Error_silent ("Get_atomic_data: No configuration found to match upper level of line %d\n", lineno); + break; + } + + /* Now that we know this is a valid transition for the macro atom record the data */ + + nconfigl = n; //record lower configuration (SS) + config[n].bbu_jump[config[n].n_bbu_jump] = nlines; //record the line index as an upward bb Macro Atom jump(SS) + line[nlines].down_index = config[n].n_bbu_jump; //record the index for the jump in the line structure + config[n].n_bbu_jump += 1; //note that there is one more upwards jump available (SS) + if (config[n].n_bbu_jump > NBBJUMPS) + { + Error ("get_atomic_data: Too many upward b-b jumps for ion %d\n", config[n].istate); + exit (0); + } + + nconfigu = m; //record upper configuration (SS) + config[m].bbd_jump[config[m].n_bbd_jump] = nlines; //record the line index as a downward bb Macro Atom jump (SS) + line[nlines].up_index = config[m].n_bbd_jump; //record jump index in line structure + config[m].n_bbd_jump += 1; //note that there is one more downwards jump available (SS) + if (config[m].n_bbd_jump > NBBJUMPS) + { + Error ("get_atomic_data: Too many downward b-b jumps for ion %d\n", config[m].istate); + exit (0); + } + + + } + else + { //It's not a macro atom line (SS) // It would have been better to define mflag = 0 since that is what we want to set // macro_info to if it is an old-style line, but keep it this way for now. ksl - mflag = -1; //a flag to mark this as not a macro atom case (SS) - nconfigl = -1; - nconfigu = -1; - nwords = - sscanf (aline, - "%*s %d %2d %le %le %le %le %le %le %d %d", - &z, &istate, &freq, &f, &gl, &gu, &el, &eu, - &levl, &levu); - if (nwords == 6) - { - el = 0.0; - eu = H * C / (freq * 1e-8); // Convert Angstroms to ergs - levl = -1; - levu = -1; - - } - else if (nwords == 8) - { // Then the file contains the energy levels of the transitions - - el = EV2ERGS * el; - eu = EV2ERGS * eu; - levl = -1; - levu = -1; - } - else if (nwords == 10) - { // Then the file contains energy levels and level numbers - el = EV2ERGS * el; - eu = EV2ERGS * eu; - } - - else - { - Error - ("get_atomic_data: file %s line %d: Resonance line incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - } - - if (el > eu) - Error - ("get_atomic_data: file %s line %d : line has el (%f) > eu (%f)\n", - file, lineno, el, eu); - for (n = 0; n < nions; n++) - { - if (ion[n].z == z && ion[n].istate == istate) - { /* Then there is a match */ - if (freq == 0 || f <= 0 || gl == 0 || gu == 0) - { - Error_silent - ("getatomic_data: line input incomplete: %s\n", - aline); - break; - } - // - //define macro atom case (SS) + mflag = -1; //a flag to mark this as not a macro atom case (SS) + nconfigl = -1; + nconfigu = -1; + nwords = sscanf (aline, "%*s %d %2d %le %le %le %le %le %le %d %d", &z, &istate, &freq, &f, &gl, &gu, &el, &eu, &levl, &levu); + if (nwords == 6) + { + el = 0.0; + eu = H * C / (freq * 1e-8); // Convert Angstroms to ergs + levl = -1; + levu = -1; + + } + else if (nwords == 8) + { // Then the file contains the energy levels of the transitions + + el = EV2ERGS * el; + eu = EV2ERGS * eu; + levl = -1; + levu = -1; + } + else if (nwords == 10) + { // Then the file contains energy levels and level numbers + el = EV2ERGS * el; + eu = EV2ERGS * eu; + } + + else + { + Error ("get_atomic_data: file %s line %d: Resonance line incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + } + + if (el > eu) + Error ("get_atomic_data: file %s line %d : line has el (%f) > eu (%f)\n", file, lineno, el, eu); + for (n = 0; n < nions; n++) + { + if (ion[n].z == z && ion[n].istate == istate) + { /* Then there is a match */ + if (freq == 0 || f <= 0 || gl == 0 || gu == 0) + { + Error_silent ("getatomic_data: line input incomplete: %s\n", aline); + break; + } + // + //define macro atom case (SS) /* ?? 04 April ksl -- Right now have enforced a clean separation between macro-ions and simple-ions but this is proably not what we want if we move all bf & fb transitions to macro-ion approach. We would like to have simple lines for macro-ions */ - if (ion[n].macro_info == 1 && mflag == -1) - { - Error - ("Get_atomic_data: Simple line data ignored for Macro-ion: %d\n", - n); - break; - } - - if (ion[n].macro_info == -1 && mflag == 1) - { - Error - ("Getatomic_data: Macro Atom line data supplied for ion %d\n but there is no suitable level data\n", - n); - exit (0); - } - line[nlines].nion = n; - line[nlines].z = z; - line[nlines].istate = istate; - line[nlines].freq = C / (freq * 1e-8); /* convert Angstroms to frequency */ - line[nlines].f = f; - line[nlines].gl = gl; - line[nlines].gu = gu; - line[nlines].levl = levl; - line[nlines].levu = levu; - line[nlines].el = el; - line[nlines].eu = eu; - line[nlines].nconfigl = nconfigl; - line[nlines].nconfigu = nconfigu; - if (mflag == -1) - { - line[nlines].macro_info = 0; // It's an old-style line` - nlines_simple++; - } - else - { - line[nlines].macro_info = 1; //It's a macro line - nlines_macro++; - } - nlines++; - } - } - if (nlines > NLINES) - { - Error - ("getatomic_data: file %s line %d: More lines than allowed. Increase NLINES in atomic.h\n", - file, lineno); - exit (0); - } - break; + if (ion[n].macro_info == 1 && mflag == -1) + { + Error ("Get_atomic_data: Simple line data ignored for Macro-ion: %d\n", n); + break; + } + + if (ion[n].macro_info == -1 && mflag == 1) + { + Error ("Getatomic_data: Macro Atom line data supplied for ion %d\n but there is no suitable level data\n", n); + exit (0); + } + line[nlines].nion = n; + line[nlines].z = z; + line[nlines].istate = istate; + line[nlines].freq = C / (freq * 1e-8); /* convert Angstroms to frequency */ + line[nlines].f = f; + line[nlines].gl = gl; + line[nlines].gu = gu; + line[nlines].levl = levl; + line[nlines].levu = levu; + line[nlines].el = el; + line[nlines].eu = eu; + line[nlines].nconfigl = nconfigl; + line[nlines].nconfigu = nconfigu; + if (mflag == -1) + { + line[nlines].macro_info = 0; // It's an old-style line` + nlines_simple++; + } + else + { + line[nlines].macro_info = 1; //It's a macro line + nlines_macro++; + } + nlines++; + } + } + if (nlines > NLINES) + { + Error ("getatomic_data: file %s line %d: More lines than allowed. Increase NLINES in atomic.h\n", file, lineno); + exit (0); + } + break; // Ground state fractions - case 'f': - if (sscanf - (aline, - "%*s %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", - &z, &istate, &the_ground_frac[0], &the_ground_frac[1], - &the_ground_frac[2], &the_ground_frac[3], - &the_ground_frac[4], &the_ground_frac[5], - &the_ground_frac[6], &the_ground_frac[7], - &the_ground_frac[8], &the_ground_frac[9], - &the_ground_frac[10], &the_ground_frac[11], - &the_ground_frac[12], &the_ground_frac[13], - &the_ground_frac[14], &the_ground_frac[15], - &the_ground_frac[16], &the_ground_frac[17], - &the_ground_frac[18], &the_ground_frac[19]) != 22) - { - Error - ("get_atomic_data: file %s line %d ground state fracs frac table incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - for (n = 0; n < nions; n++) - { - if (ion[n].z == z && ion[n].istate == istate) - { /* Then there is a match */ - ground_frac[n].z = z; - ground_frac[n].istate = istate; - for (j = 0; j < 20; j++) - { - ground_frac[n].frac[j] = the_ground_frac[j]; - } - } - } - break; + case 'f': + if (sscanf + (aline, + "%*s %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", + &z, &istate, &the_ground_frac[0], &the_ground_frac[1], + &the_ground_frac[2], &the_ground_frac[3], + &the_ground_frac[4], &the_ground_frac[5], + &the_ground_frac[6], &the_ground_frac[7], + &the_ground_frac[8], &the_ground_frac[9], + &the_ground_frac[10], &the_ground_frac[11], + &the_ground_frac[12], &the_ground_frac[13], + &the_ground_frac[14], &the_ground_frac[15], + &the_ground_frac[16], &the_ground_frac[17], &the_ground_frac[18], &the_ground_frac[19]) != 22) + { + Error ("get_atomic_data: file %s line %d ground state fracs frac table incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + for (n = 0; n < nions; n++) + { + if (ion[n].z == z && ion[n].istate == istate) + { /* Then there is a match */ + ground_frac[n].z = z; + ground_frac[n].istate = istate; + for (j = 0; j < 20; j++) + { + ground_frac[n].frac[j] = the_ground_frac[j]; + } + } + } + break; // Collision strengths --- Not currently used - case 'x': /*The line contains collision strength information--Gaetz & Salpeter */ - if (sscanf (aline, "%*s %*s %d %d %le %le %le %le %le", - &z, &istate, &exx, &lambda, &alpha, &beta, - &tm) != 7) - { - Error - ("get_atomic_data: file %s line %d: Collision strengths incorrectly formatted\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - for (n = 0; n < nions; n++) - { - if (ion[n].z == z && ion[n].istate == istate) - { /* Then there is a match */ - xcol[nxcol].nion = n; - xcol[nxcol].z = z; - xcol[nxcol].istate = istate; - xcol[nxcol].ex = exx * EV2ERGS; - xcol[nxcol].freq = C / (lambda * 1.e-8); - xcol[nxcol].alpha = alpha; - xcol[nxcol].beta = beta; - xcol[nxcol].tm = pow (10., tm); - nxcol++; - } - } - - break; - - - - - - case 'D': /* Dielectronic recombination data read in. */ - nparam = sscanf (aline, "%*s %s %d %d %le %le %le %le %le %le %le %le %le", &drflag, &z, &ne, &drp[0], &drp[1], &drp[2], &drp[3], &drp[4], &drp[5], &drp[6], &drp[7], &drp[8]); //split and assign the line - nparam -= 3; //take 4 off the nparam to give the number of actual parameters - if (nparam > 9 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... - { - Error - ("Something wrong with dielectronic recombination data\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - istate = ne; // get the ionisation state we are recombining from -// istate--; // we will associate the rate with the ion we are recombining to - - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].drflag == 0) //This is the first time we have dealt with this ion - { - drecomb[ndrecomb].nion = n; //put the ion number into the DR structure - drecomb[ndrecomb].nparam = nparam; //Put the number of parameters we ware going to read in, into the DR structure so we know what to iterate over later - ion[n].nxdrecomb = ndrecomb; //put the number of the DR into the ion - drecomb[ndrecomb].type = DRTYPE_BADNELL; //define the type of data - ndrecomb++; //increment the counter of number of dielectronic recombination parameter sets - ion[n].drflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... - - } - if (drflag == 'E') // this ion has no parameters, so it must be the first time through - { - - n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through - for (n2 = 0; n2 < nparam; n2++) - { - drecomb[n1].e[n2] = drp[n2]; //we are getting e parameters - } - - - } - else if (drflag == 'C') // must be the second time though, so no need to read in all the other things - { - n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through - for (n2 = 0; n2 < nparam; n2++) - { - drecomb[n1].c[n2] = drp[n2]; // we are getting e parameters - } - } - - } //close if statement that selects appropriate ion to add data to - } //close loop over ions - - - break; - - case 'S': - nparam = sscanf (aline, "%*s %d %d %le %le %le %le ", &z, &ne, &drp[0], &drp[1], &drp[2], &drp[3]); //split and assign the line - nparam -= 2; //take 4 off the nparam to give the number of actual parameters - if (nparam > 4 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... - { - Error - ("Something wrong with dielectronic recombination data\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - istate = ne; // get the ionisation state we are recombining from -// istate--; // we will associate the rate with the ion we are recombining to - - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].drflag == 0) //This is the first time we have dealt with this ion - { - drecomb[ndrecomb].nion = n; //put the ion number into the DR structure - drecomb[ndrecomb].nparam = nparam; //Put the number of parameters we ware going to read in, into the DR structure so we know what to iterate over later - ion[n].nxdrecomb = ndrecomb; //put the number of the DR into the ion - drecomb[ndrecomb].type = DRTYPE_SHULL; //define the type of data - ndrecomb++; //increment the counter of number of dielectronic recombination parameter sets - ion[n].drflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... - - } - n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through - for (n2 = 0; n2 < nparam; n2++) - { - drecomb[n1].shull[n2] = drp[n2]; //we are getting e parameters - } - } - } - break; + case 'x': /*The line contains collision strength information--Gaetz & Salpeter */ + if (sscanf (aline, "%*s %*s %d %d %le %le %le %le %le", &z, &istate, &exx, &lambda, &alpha, &beta, &tm) != 7) + { + Error ("get_atomic_data: file %s line %d: Collision strengths incorrectly formatted\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + for (n = 0; n < nions; n++) + { + if (ion[n].z == z && ion[n].istate == istate) + { /* Then there is a match */ + xcol[nxcol].nion = n; + xcol[nxcol].z = z; + xcol[nxcol].istate = istate; + xcol[nxcol].ex = exx * EV2ERGS; + xcol[nxcol].freq = C / (lambda * 1.e-8); + xcol[nxcol].alpha = alpha; + xcol[nxcol].beta = beta; + xcol[nxcol].tm = pow (10., tm); + nxcol++; + } + } + + break; + + + + + + case 'D': /* Dielectronic recombination data read in. */ + nparam = sscanf (aline, "%*s %s %d %d %le %le %le %le %le %le %le %le %le", &drflag, &z, &ne, &drp[0], &drp[1], &drp[2], &drp[3], &drp[4], &drp[5], &drp[6], &drp[7], &drp[8]); //split and assign the line + nparam -= 3; //take 4 off the nparam to give the number of actual parameters + if (nparam > 9 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... + { + Error ("Something wrong with dielectronic recombination data\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + istate = ne; // get the ionisation state we are recombining from +// istate--; // we will associate the rate with the ion we are recombining to + + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].drflag == 0) //This is the first time we have dealt with this ion + { + drecomb[ndrecomb].nion = n; //put the ion number into the DR structure + drecomb[ndrecomb].nparam = nparam; //Put the number of parameters we ware going to read in, into the DR structure so we know what to iterate over later + ion[n].nxdrecomb = ndrecomb; //put the number of the DR into the ion + drecomb[ndrecomb].type = DRTYPE_BADNELL; //define the type of data + ndrecomb++; //increment the counter of number of dielectronic recombination parameter sets + ion[n].drflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... + + } + if (drflag == 'E') // this ion has no parameters, so it must be the first time through + { + + n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through + for (n2 = 0; n2 < nparam; n2++) + { + drecomb[n1].e[n2] = drp[n2]; //we are getting e parameters + } + + + } + else if (drflag == 'C') // must be the second time though, so no need to read in all the other things + { + n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through + for (n2 = 0; n2 < nparam; n2++) + { + drecomb[n1].c[n2] = drp[n2]; // we are getting e parameters + } + } + + } //close if statement that selects appropriate ion to add data to + } //close loop over ions + + + break; + + case 'S': + nparam = sscanf (aline, "%*s %d %d %le %le %le %le ", &z, &ne, &drp[0], &drp[1], &drp[2], &drp[3]); //split and assign the line + nparam -= 2; //take 4 off the nparam to give the number of actual parameters + if (nparam > 4 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... + { + Error ("Something wrong with dielectronic recombination data\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + istate = ne; // get the ionisation state we are recombining from +// istate--; // we will associate the rate with the ion we are recombining to + + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].drflag == 0) //This is the first time we have dealt with this ion + { + drecomb[ndrecomb].nion = n; //put the ion number into the DR structure + drecomb[ndrecomb].nparam = nparam; //Put the number of parameters we ware going to read in, into the DR structure so we know what to iterate over later + ion[n].nxdrecomb = ndrecomb; //put the number of the DR into the ion + drecomb[ndrecomb].type = DRTYPE_SHULL; //define the type of data + ndrecomb++; //increment the counter of number of dielectronic recombination parameter sets + ion[n].drflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... + + } + n1 = ion[n].nxdrecomb; // Get the pointer to the correct bit of the recombination coefficient array. This should already be set from the first time through + for (n2 = 0; n2 < nparam; n2++) + { + drecomb[n1].shull[n2] = drp[n2]; //we are getting e parameters + } + } + } + break; @@ -2262,31 +2118,29 @@ CPART 4 1 183127.29 250 2 the first number is the element number, then the ion, then the three parameters */ - case 'P': /* Partition function data */ - if (sscanf - (aline, "%*s %d %d %le %d %d ", &z, &J, &part_eps, - &part_G, &part_m) != 5) - { - Error ("Something wrong with cardona partition function data\n", file, lineno); /*Standard error state */ - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - istate = J + 1; // - for (n = 0; n < nions; n++) - { - if (ion[n].z == z && ion[n].istate == istate) - { /* Then there is a match */ - cpart[ncpart].nion = n; - cpart[ncpart].part_eps = part_eps; //Mean energy term - cpart[ncpart].part_G = part_G; //Mean multiplicity term - cpart[ncpart].part_m = part_m; - ion[n].cpartflag = 1; //Set the flag to say we have data for this ion - ion[n].nxcpart = ncpart; //Set the pointer - ncpart++; //increment the pointer - - } - } - break; + case 'P': /* Partition function data */ + if (sscanf (aline, "%*s %d %d %le %d %d ", &z, &J, &part_eps, &part_G, &part_m) != 5) + { + Error ("Something wrong with cardona partition function data\n", file, lineno); /*Standard error state */ + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + istate = J + 1; // + for (n = 0; n < nions; n++) + { + if (ion[n].z == z && ion[n].istate == istate) + { /* Then there is a match */ + cpart[ncpart].nion = n; + cpart[ncpart].part_eps = part_eps; //Mean energy term + cpart[ncpart].part_G = part_G; //Mean multiplicity term + cpart[ncpart].part_m = part_m; + ion[n].cpartflag = 1; //Set the flag to say we have data for this ion + ion[n].nxcpart = ncpart; //Set the pointer + ncpart++; //increment the pointer + + } + } + break; /*!RR RATE COEFFICIENT FITS (C)20110412 N. R. BADNELL, DEPARTMENT OF PHYSICS, UNIVERSITY OF STRATHCLYDE, GLASGOW G4 0NG, UK. !This is total radiative rate into all possible states or the recombined ion. @@ -2301,348 +2155,332 @@ BAD_T_RR 3 0 1 1 2.867E-10 0.7493 2.108E+01 6.268E+06 BAD_T_RR 4 0 1 1 3.375E-10 0.7475 4.628E+01 1.121E+07 BAD_T_RR 5 0 1 1 4.647E-10 0.7484 6.142E+01 1.753E+07*/ - case 'T': /*Badnell type total raditive rate coefficients read in */ - - nparam = sscanf (aline, "%*s %d %d %d %le %le %le %le %le %le", &z, &ne, &w, &btrr[0], &btrr[1], &btrr[2], &btrr[3], &btrr[4], &btrr[5]); //split and assign the line - nparam -= 3; //take 4 off the nparam to give the number of actual parameters - if (nparam > 6 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... - { - Error ("Something wrong with badnell total RR data\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - istate = ne; // get the traditional ionisation state -// istate--; // we will associate the rate with the ion we are recombining to - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].total_rrflag == 0) // this ion has no parameters, so it must be the first time through - { - total_rr[n_total_rr].nion = n; //put the ion number into the bad_t_rr structure - ion[n].nxtotalrr = n_total_rr; /*put the number of the bad_t_rr into the ion - structure so we can go either way. */ - total_rr[n_total_rr].type = RRTYPE_BADNELL; - for (n1 = 0; n1 < nparam; n1++) - { - total_rr[n_total_rr].params[n1] = btrr[n1]; //we are getting parameters - } - ion[n].total_rrflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... - n_total_rr++; //increment the counter of number of dielectronic recombination parameter sets - } - else if (ion[n].total_rrflag > 0) // unexpected second line matching z and charge - { - Error - ("More than one badnell total RR rate for ion %i\n", - n); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - else //if flag is not a positive number, we have a problem - { - Error - ("Total radiative recombination flag giving odd results\n"); - exit (0); - } - } //close if statement that selects appropriate ion to add data to - } //close loop over ions - - - - break; - - case 's': - nparam = sscanf (aline, "%*s %d %d %le %le ", &z, &ne, &btrr[0], &btrr[1]); //split and assign the line - nparam -= 2; //take 4 off the nparam to give the number of actual parameters - if (nparam > 6 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... - { - Error ("Something wrong with shull total RR data\n", - file, lineno); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - - istate = ne; // get the traditional ionisation state -// istate--; // we will associate the rate with the ion we are recombining to - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].total_rrflag == 0) // this ion has no parameters, so it must be the first time through - { - total_rr[n_total_rr].nion = n; //put the ion number into the bad_t_rr structure - ion[n].nxtotalrr = n_total_rr; /*put the number of the bad_t_rr into the ion - structure so we can go either way. */ - total_rr[n_total_rr].type = RRTYPE_SHULL; - for (n1 = 0; n1 < nparam; n1++) - { - total_rr[n_total_rr].params[n1] = btrr[n1]; //we are getting parameters - } - ion[n].total_rrflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... - n_total_rr++; //increment the counter of number of dielectronic recombination parameter sets - } - else if (ion[n].total_rrflag > 0) // unexpected second line matching z and charge - { - Error - ("More than one total RR rate for ion %i\n", - n); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - else //if flag is not a positive number, we have a problem - { - Error - ("Total radiative recombination flag giving odd results\n"); - exit (0); - } - } //close if statement that selects appropriate ion to add data to - } //close loop over ions - break; - - - - - case 'G': - nparam = sscanf (aline, "%*s %s %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", &gsflag, &z, &ne, &gstemp[0], &gstemp[1], &gstemp[2], &gstemp[3], &gstemp[4], &gstemp[5], &gstemp[6], &gstemp[7], &gstemp[8], &gstemp[9], &gstemp[10], &gstemp[11], &gstemp[12], &gstemp[13], &gstemp[14], &gstemp[15], &gstemp[16], &gstemp[17], &gstemp[18]); //split and assign the line - nparam -= 3; //take 4 off the nparam to give the number of actual parameters - if (nparam > 19 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... - { - Error ("Something wrong with badnell GS RR data\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - istate = z - ne + 1; // get the traditional ionisation state -// istate--; // we will associate the rate with the ion we are recombining to - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].bad_gs_rr_t_flag == 0 && ion[n].bad_gs_rr_r_flag == 0) //This is first set of this type of data for this ion - { - bad_gs_rr[n_bad_gs_rr].nion = n; //put the ion number into the bad_t_rr structure - ion[n].nxbadgsrr = n_bad_gs_rr; //put the number of the bad_t_rr into the ion structure so we can go either way. - n_bad_gs_rr++; //increment the counter of number of ground state RR - } - /*Now work out what type of line it is, and where it needs to go */ - if (gsflag == 'T') //it is a temperature line - { - if (ion[n].bad_gs_rr_t_flag == 0) //and we need a temp line for this ion - { - if (gstemp[0] > gstmin) - gstmin = gstemp[0]; - if (gstemp[18] < gstmax) - gstmax = gstemp[18]; - ion[n].bad_gs_rr_t_flag = 1; //set the flag - for (n1 = 0; n1 < nparam; n1++) - { - bad_gs_rr[ion[n].nxbadgsrr].temps[n1] = - gstemp[n1]; - } - } - else if (ion[n].bad_gs_rr_t_flag == 1) //we already have a temp line for this ion - { - Error - ("More than one temp line for badnell GS RR rate for ion %i\n", - n); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - else //some other odd thing had happened - { - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - } - else if (gsflag == 'R') //it is a rate line - { - if (ion[n].bad_gs_rr_r_flag == 0) //and we need a rate line for this ion - { - ion[n].bad_gs_rr_r_flag = 1; //set the flag - for (n1 = 0; n1 < nparam; n1++) - { - bad_gs_rr[ion[n].nxbadgsrr].rates[n1] = - gstemp[n1]; - } - } - else if (ion[n].bad_gs_rr_r_flag == 1) //we already have a rate line for this ion - { - Error - ("More than one rate line for badnell GS RR rate for ion %i\n", - n); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - else //some other odd thing had happened - { - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - } - else //We have some problem with this line - { - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - } //end of loop over dealing with data for a discovered ion - } //end of loop over ions - - break; + case 'T': /*Badnell type total raditive rate coefficients read in */ + + nparam = sscanf (aline, "%*s %d %d %d %le %le %le %le %le %le", &z, &ne, &w, &btrr[0], &btrr[1], &btrr[2], &btrr[3], &btrr[4], &btrr[5]); //split and assign the line + nparam -= 3; //take 4 off the nparam to give the number of actual parameters + if (nparam > 6 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... + { + Error ("Something wrong with badnell total RR data\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + istate = ne; // get the traditional ionisation state +// istate--; // we will associate the rate with the ion we are recombining to + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].total_rrflag == 0) // this ion has no parameters, so it must be the first time through + { + total_rr[n_total_rr].nion = n; //put the ion number into the bad_t_rr structure + ion[n].nxtotalrr = n_total_rr; /*put the number of the bad_t_rr into the ion + structure so we can go either way. */ + total_rr[n_total_rr].type = RRTYPE_BADNELL; + for (n1 = 0; n1 < nparam; n1++) + { + total_rr[n_total_rr].params[n1] = btrr[n1]; //we are getting parameters + } + ion[n].total_rrflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... + n_total_rr++; //increment the counter of number of dielectronic recombination parameter sets + } + else if (ion[n].total_rrflag > 0) // unexpected second line matching z and charge + { + Error ("More than one badnell total RR rate for ion %i\n", n); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + else //if flag is not a positive number, we have a problem + { + Error ("Total radiative recombination flag giving odd results\n"); + exit (0); + } + } //close if statement that selects appropriate ion to add data to + } //close loop over ions + + + + break; + + case 's': + nparam = sscanf (aline, "%*s %d %d %le %le ", &z, &ne, &btrr[0], &btrr[1]); //split and assign the line + nparam -= 2; //take 4 off the nparam to give the number of actual parameters + if (nparam > 6 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... + { + Error ("Something wrong with shull total RR data\n", file, lineno); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + + istate = ne; // get the traditional ionisation state +// istate--; // we will associate the rate with the ion we are recombining to + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].total_rrflag == 0) // this ion has no parameters, so it must be the first time through + { + total_rr[n_total_rr].nion = n; //put the ion number into the bad_t_rr structure + ion[n].nxtotalrr = n_total_rr; /*put the number of the bad_t_rr into the ion + structure so we can go either way. */ + total_rr[n_total_rr].type = RRTYPE_SHULL; + for (n1 = 0; n1 < nparam; n1++) + { + total_rr[n_total_rr].params[n1] = btrr[n1]; //we are getting parameters + } + ion[n].total_rrflag++; //increment the flag by 1. We will do this rather than simply setting it to 1 so we will get errors if we do this more than once.... + n_total_rr++; //increment the counter of number of dielectronic recombination parameter sets + } + else if (ion[n].total_rrflag > 0) // unexpected second line matching z and charge + { + Error ("More than one total RR rate for ion %i\n", n); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + else //if flag is not a positive number, we have a problem + { + Error ("Total radiative recombination flag giving odd results\n"); + exit (0); + } + } //close if statement that selects appropriate ion to add data to + } //close loop over ions + break; + + + + + case 'G': + nparam = sscanf (aline, "%*s %s %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", &gsflag, &z, &ne, &gstemp[0], &gstemp[1], &gstemp[2], &gstemp[3], &gstemp[4], &gstemp[5], &gstemp[6], &gstemp[7], &gstemp[8], &gstemp[9], &gstemp[10], &gstemp[11], &gstemp[12], &gstemp[13], &gstemp[14], &gstemp[15], &gstemp[16], &gstemp[17], &gstemp[18]); //split and assign the line + nparam -= 3; //take 4 off the nparam to give the number of actual parameters + if (nparam > 19 || nparam < 1) // trap errors - not as robust as usual because there are a varaible number of parameters... + { + Error ("Something wrong with badnell GS RR data\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + istate = z - ne + 1; // get the traditional ionisation state +// istate--; // we will associate the rate with the ion we are recombining to + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].bad_gs_rr_t_flag == 0 && ion[n].bad_gs_rr_r_flag == 0) //This is first set of this type of data for this ion + { + bad_gs_rr[n_bad_gs_rr].nion = n; //put the ion number into the bad_t_rr structure + ion[n].nxbadgsrr = n_bad_gs_rr; //put the number of the bad_t_rr into the ion structure so we can go either way. + n_bad_gs_rr++; //increment the counter of number of ground state RR + } + /*Now work out what type of line it is, and where it needs to go */ + if (gsflag == 'T') //it is a temperature line + { + if (ion[n].bad_gs_rr_t_flag == 0) //and we need a temp line for this ion + { + if (gstemp[0] > gstmin) + gstmin = gstemp[0]; + if (gstemp[18] < gstmax) + gstmax = gstemp[18]; + ion[n].bad_gs_rr_t_flag = 1; //set the flag + for (n1 = 0; n1 < nparam; n1++) + { + bad_gs_rr[ion[n].nxbadgsrr].temps[n1] = gstemp[n1]; + } + } + else if (ion[n].bad_gs_rr_t_flag == 1) //we already have a temp line for this ion + { + Error ("More than one temp line for badnell GS RR rate for ion %i\n", n); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + else //some other odd thing had happened + { + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + } + else if (gsflag == 'R') //it is a rate line + { + if (ion[n].bad_gs_rr_r_flag == 0) //and we need a rate line for this ion + { + ion[n].bad_gs_rr_r_flag = 1; //set the flag + for (n1 = 0; n1 < nparam; n1++) + { + bad_gs_rr[ion[n].nxbadgsrr].rates[n1] = gstemp[n1]; + } + } + else if (ion[n].bad_gs_rr_r_flag == 1) //we already have a rate line for this ion + { + Error ("More than one rate line for badnell GS RR rate for ion %i\n", n); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + else //some other odd thing had happened + { + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + } + else //We have some problem with this line + { + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + } //end of loop over dealing with data for a discovered ion + } //end of loop over ions + + break; /* NSH 120921 The following are lines to read in temperature averaged gaunt factors from the data of Sutherland (1997). The atomic file is basically unchanged * from the data on the website, just with the top few lines commented out, and a label prepended to each line */ - case 'g': - nparam = sscanf (aline, "%*s %le %le %le %le %le", &gsqrdtemp, &gfftemp, &s1temp, &s2temp, &s3temp); //split and assign the line - if (nparam > 5 || nparam < 1) // trap errors - { - Error ("Something wrong with sutherland gaunt data\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - if (gaunt_n_gsqrd == 0 || gsqrdtemp > gaunt_total[gaunt_n_gsqrd - 1].log_gsqrd) //We will use it if it's our first piece of data or is in order - { - gaunt_total[gaunt_n_gsqrd].log_gsqrd = gsqrdtemp; //The scaled electron temperature squared for this array - gaunt_total[gaunt_n_gsqrd].gff = gfftemp; - gaunt_total[gaunt_n_gsqrd].s1 = s1temp; - gaunt_total[gaunt_n_gsqrd].s2 = s2temp; - gaunt_total[gaunt_n_gsqrd].s3 = s3temp; - gaunt_n_gsqrd++; - } - else - { - Error ("Something wrong with gaunt data\n"); - Error ("Get_atomic_data %s\n", aline); - exit (0); - } - - - - break; - -case 'd': - nparam = sscanf (aline, "%*s %d %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", &z, &istate, &nspline, &et, &tmin, &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], &temp[15], &temp[16], &temp[17], &temp[18], &temp[19],&temp[20],&temp[21],&temp[22],&temp[23],&temp[24],&temp[25],&temp[26],&temp[27],&temp[28],&temp[29],&temp[30],&temp[31],&temp[32],&temp[33],&temp[34],&temp[35],&temp[36],&temp[37],&temp[38],&temp[39]); //split and assign the line - - if (nparam != 5+(nspline*2)) // trap errors - { - Error ("Something wrong with Dere DI data\n"); - Error ("Get_atomic_data: %s\n", aline); - exit (0); - } - for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data - { - if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with - { - if (ion[n].dere_di_flag == 0) //This is first set of this type of data for this ion - { -ion[n].dere_di_flag=1; - dere_di_rate[n_dere_di_rate].nion = n; //put the ion number into the dere_di_rate structure - ion[n].nxderedi = n_dere_di_rate; //put the number of the dere_di_rate into the ion structure so we can go either way. - dere_di_rate[n_dere_di_rate].xi=et; - dere_di_rate[n_dere_di_rate].min_temp=tmin; - dere_di_rate[n_dere_di_rate].nspline=nspline; - for (n1=0;n1 5 || nparam < 1) // trap errors + { + Error ("Something wrong with sutherland gaunt data\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + if (gaunt_n_gsqrd == 0 || gsqrdtemp > gaunt_total[gaunt_n_gsqrd - 1].log_gsqrd) //We will use it if it's our first piece of data or is in order + { + gaunt_total[gaunt_n_gsqrd].log_gsqrd = gsqrdtemp; //The scaled electron temperature squared for this array + gaunt_total[gaunt_n_gsqrd].gff = gfftemp; + gaunt_total[gaunt_n_gsqrd].s1 = s1temp; + gaunt_total[gaunt_n_gsqrd].s2 = s2temp; + gaunt_total[gaunt_n_gsqrd].s3 = s3temp; + gaunt_n_gsqrd++; + } + else + { + Error ("Something wrong with gaunt data\n"); + Error ("Get_atomic_data %s\n", aline); + exit (0); + } + + + + break; + + case 'd': + nparam = sscanf (aline, "%*s %d %d %d %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le %le", &z, &istate, &nspline, &et, &tmin, &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], &temp[15], &temp[16], &temp[17], &temp[18], &temp[19], &temp[20], &temp[21], &temp[22], &temp[23], &temp[24], &temp[25], &temp[26], &temp[27], &temp[28], &temp[29], &temp[30], &temp[31], &temp[32], &temp[33], &temp[34], &temp[35], &temp[36], &temp[37], &temp[38], &temp[39]); //split and assign the line + + if (nparam != 5 + (nspline * 2)) // trap errors + { + Error ("Something wrong with Dere DI data\n"); + Error ("Get_atomic_data: %s\n", aline); + exit (0); + } + for (n = 0; n < nions; n++) //Loop over ions to find the correct place to put the data + { + if (ion[n].z == z && ion[n].istate == istate) // this works out which ion we are dealing with + { + if (ion[n].dere_di_flag == 0) //This is first set of this type of data for this ion + { + ion[n].dere_di_flag = 1; + dere_di_rate[n_dere_di_rate].nion = n; //put the ion number into the dere_di_rate structure + ion[n].nxderedi = n_dere_di_rate; //put the number of the dere_di_rate into the ion structure so we can go either way. + dere_di_rate[n_dere_di_rate].xi = et; + dere_di_rate[n_dere_di_rate].min_temp = tmin; + dere_di_rate[n_dere_di_rate].nspline = nspline; + for (n1 = 0; n1 < nspline; n1++) + { + dere_di_rate[n_dere_di_rate].temps[n1] = temp[n1]; + dere_di_rate[n_dere_di_rate].rates[n1] = temp[n1 + nspline] * 1e-6; + + } + n_dere_di_rate++; //increment the counter of number of ground state RR + } + else + { + Error ("Get_atomic_data: More than one Dere DI rate for ion %i\n", n); + } + } + } + break; + + case 'K': + nparam = sscanf (aline, "%*s %d %d %d %d %le %le %le %le %le %le %le %le %le %le %le %le", &z, &istate, &in, &il, &I, &Ea, + &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9]); + if (nparam != 16) + { + Error ("Something wrong with electron yield data\n"); + Error ("Get_atomic_data %s\n", aline); + exit (0); + } + for (n = 0; n < n_inner_tot; n++) + { + if (inner_cross[n].z == z && inner_cross[n].istate == istate && inner_cross[n].n == in && inner_cross[n].l == il) + { + if (inner_cross[n].n_elec_yield == -1) /*This is the first yield data for this vacancy */ + { + inner_elec_yield[n_elec_yield_tot].nion = n; /*This yield refers to this ion */ + inner_cross[n].n_elec_yield = n_elec_yield_tot; + inner_elec_yield[n_elec_yield_tot].z = z; + inner_elec_yield[n_elec_yield_tot].istate = istate; + inner_elec_yield[n_elec_yield_tot].n = in; + inner_elec_yield[n_elec_yield_tot].l = il; + inner_elec_yield[n_elec_yield_tot].I = I * EV2ERGS; + inner_elec_yield[n_elec_yield_tot].Ea = Ea * EV2ERGS; + for (n1 = 0; n1 < 10; n1++) + { + inner_elec_yield[n_elec_yield_tot].prob[n1] = temp[n1] / 10000.0; + } + n_elec_yield_tot++; + } + else + { + Error ("Get_atomic_data: more than one electron yield record for inner_cross %i\n", n); + } + } + } + break; + + case 'F': + nparam = sscanf (aline, "%*s %d %d %d %d %le %le ", &z, &istate, &in, &il, &energy, &yield); + if (nparam != 6) + { + Error ("Something wrong with fluorescent yield data\n"); + Error ("Get_atomic_data %s\n", aline); + exit (0); + } + for (n = 0; n < n_inner_tot; n++) + { + if (inner_cross[n].z == z && inner_cross[n].istate == istate && inner_cross[n].n == in && inner_cross[n].l == il) + { + if (inner_cross[n].n_fluor_yield == -1) /*This is the first yield data for this vacancy */ + { + inner_fluor_yield[n_fluor_yield_tot].nion = n; /*This yield refers to this ion */ + inner_cross[n].n_fluor_yield = n_fluor_yield_tot; + inner_fluor_yield[n_fluor_yield_tot].z = z; + inner_fluor_yield[n_fluor_yield_tot].istate = istate; + inner_fluor_yield[n_fluor_yield_tot].n = in; + inner_fluor_yield[n_fluor_yield_tot].l = il; + inner_fluor_yield[n_fluor_yield_tot].freq = energy / HEV; + inner_fluor_yield[n_fluor_yield_tot].yield = yield; + n_fluor_yield_tot++; + } + else + { + Error ("Get_atomic_data: more than one electron yield record for inner_cross %i\n", n); + } + } + } + break; + + case 'c': /* It was a comment line so do nothing */ + break; + case 'z': + default: + Error ("get_atomicdata: Could not interpret line %d in file %s: %s\n", lineno, file, aline); + break; + } + + strcpy (aline, ""); + } + + fclose (fptr); } + /*End of do loop for reading a particular file of data */ + } /* End of main do loop for reading all of the the data. At this point we can close the masterfile @@ -2651,44 +2489,36 @@ ion[n].dere_di_flag=1; fclose (mptr); /* OK now summarize the data that has been read*/ - n_elec_yield_tot=0; //Reset this numnber, we are now going to use it to check we have yields for all inner shells - n_fluor_yield_tot=0; //Reset this numnber, we are now going to use it to check we have yields for all inner shells + n_elec_yield_tot = 0; //Reset this numnber, we are now going to use it to check we have yields for all inner shells + n_fluor_yield_tot = 0; //Reset this numnber, we are now going to use it to check we have yields for all inner shells - for (n=0;n 0) -// { +// { // /index_phot_verner (); // tabulate_verner(); //Create a tabulated version of the data -// } +// } /* Index the topbase photoionization structure by threshold freqeuncy */ - if (ntop_phot+nxphot > 0) + if (ntop_phot + nxphot > 0) index_phot_top (); /* Index the topbase photoionization structure by threshold freqeuncy */ if (n_inner_tot > 0) index_inner_cross (); - check_xsections(); // debug routine, only prints if verbosity > 4 + check_xsections (); // debug routine, only prints if verbosity > 4 return (0); } @@ -3019,11 +2818,11 @@ index_lines () freqs[0] = 0; for (n = 0; n < nlines; n++) - freqs[n + 1] = line[n].freq; /* So filled matrix - elements run from 1 to nlines */ + freqs[n + 1] = line[n].freq; /* So filled matrix + elements run from 1 to nlines */ - indexx (nlines, freqs, index); /* Note that this math recipes routine - expects arrays to run from 1 to nlines inclusive */ + indexx (nlines, freqs, index); /* Note that this math recipes routine + expects arrays to run from 1 to nlines inclusive */ /* The for loop indices are complicated by the numerical recipes routine, which is a simple translation of a fortran routine. @@ -3036,10 +2835,10 @@ index_lines () for (n = 0; n < nlines; n++) - { - lin_ptr[n] = &line[index[n + 1] - 1]; - line[index[n + 1] - 1].where_in_list = n; - } + { + lin_ptr[n] = &line[index[n + 1] - 1]; + line[index[n + 1] - 1].where_in_list = n; + } /* Free the memory for the arrays */ free (freqs); @@ -3067,11 +2866,11 @@ index_phot_top () freqs[0] = 0; for (n = 0; n < ntop_phot + nxphot; n++) - freqs[n + 1] = phot_top[n].freq[0]; /* So filled matrix - elements run from 1 to ntop_phot */ + freqs[n + 1] = phot_top[n].freq[0]; /* So filled matrix + elements run from 1 to ntop_phot */ - indexx (ntop_phot + nxphot, freqs, index); /* Note that this math recipes routine - expects arrays to run from 1 to nlines inclusive */ + indexx (ntop_phot + nxphot, freqs, index); /* Note that this math recipes routine + expects arrays to run from 1 to nlines inclusive */ /* The for loop indices are complicated by the numerical recipes routine, which is a simple translation of a fortran routine. @@ -3080,9 +2879,9 @@ index_phot_top () pointer array is only filled from elements 0 to nlines -1 */ for (n = 0; n < ntop_phot + nxphot; n++) - { - phot_top_ptr[n] = &phot_top[index[n + 1] - 1]; - } + { + phot_top_ptr[n] = &phot_top[index[n + 1] - 1]; + } /* Free the memory for the arrays */ free (freqs); @@ -3106,11 +2905,11 @@ index_inner_cross () freqs[0] = 0; for (n = 0; n < n_inner_tot; n++) - freqs[n + 1] = inner_cross[n].freq[0]; /* So filled matrix - elements run from 1 to ntop_phot */ + freqs[n + 1] = inner_cross[n].freq[0]; /* So filled matrix + elements run from 1 to ntop_phot */ - indexx (n_inner_tot, freqs, index); /* Note that this math recipes routine - expects arrays to run from 1 to nlines inclusive */ + indexx (n_inner_tot, freqs, index); /* Note that this math recipes routine + expects arrays to run from 1 to nlines inclusive */ /* The for loop indices are complicated by the numerical recipes routine, which is a simple translation of a fortran routine. @@ -3119,9 +2918,9 @@ index_inner_cross () pointer array is only filled from elements 0 to nlines -1 */ for (n = 0; n < n_inner_tot; n++) - { - inner_cross_ptr[n] = &inner_cross[index[n + 1] - 1]; - } + { + inner_cross_ptr[n] = &inner_cross[index[n + 1] - 1]; + } /* Free the memory for the arrays */ free (freqs); @@ -3154,14 +2953,14 @@ index_collisions () freqs[0] = 0; for (n = 0; n < nxcol; n++) - freqs[n + 1] = xcol[n].freq; /* So filled matrix - elements run from 1 to ntrans */ + freqs[n + 1] = xcol[n].freq; /* So filled matrix + elements run from 1 to ntrans */ - if (nxcol > 0) //if statement added (SS, feb 04) - { - indexx (nxcol, freqs, index); /* Note that this math recipes routine - expects arrays to run from 1 to nlines inclusive */ - } + if (nxcol > 0) //if statement added (SS, feb 04) + { + indexx (nxcol, freqs, index); /* Note that this math recipes routine + expects arrays to run from 1 to nlines inclusive */ + } /* The for loop indices are complicated by the numerical recipes routine, @@ -3171,9 +2970,9 @@ index_collisions () pointer array is only filled from elements 0 to nlines -1 */ for (n = 0; n < nxcol; n++) - { - xcol_ptr[n] = &xcol[index[n + 1] - 1]; - } + { + xcol_ptr[n] = &xcol[index[n + 1] - 1]; + } /* Free the memory for the arrays */ free (freqs); @@ -3193,46 +2992,46 @@ indexx (n, arrin, indx) int l, j, ir, indxt, i; float q; /* NSH 1408 - This routine fails in the very odd circumstance that n=1 so we now do a little test here */ -if (n<2) - { - Log_silent("Nothing for indexx to do! Only one element\n"); - return; - } + if (n < 2) + { + Log_silent ("Nothing for indexx to do! Only one element\n"); + return; + } for (j = 1; j <= n; j++) indx[j] = j; l = (n >> 1) + 1; ir = n; for (;;) + { + if (l > 1) + q = arrin[(indxt = indx[--l])]; + else + { + q = arrin[(indxt = indx[ir])]; + indx[ir] = indx[1]; + if (--ir == 1) + { + indx[1] = indxt; + return; + } + } + i = l; + j = l << 1; + while (j <= ir) { - if (l > 1) - q = arrin[(indxt = indx[--l])]; + if (j < ir && arrin[indx[j]] < arrin[indx[j + 1]]) + j++; + if (q < arrin[indx[j]]) + { + indx[i] = indx[j]; + j += (i = j); + } else - { - q = arrin[(indxt = indx[ir])]; - indx[ir] = indx[1]; - if (--ir == 1) - { - indx[1] = indxt; - return; - } - } - i = l; - j = l << 1; - while (j <= ir) - { - if (j < ir && arrin[indx[j]] < arrin[indx[j + 1]]) - j++; - if (q < arrin[indx[j]]) - { - indx[i] = indx[j]; - j += (i = j); - } - else - j = ir + 1; - } - indx[i] = indxt; + j = ir + 1; } + indx[i] = indxt; + } } /*********************************************************** @@ -3293,43 +3092,43 @@ limit_lines (freqmin, freqmax) if (freqmin > lin_ptr[nlines - 1]->freq || freqmax < lin_ptr[0]->freq) - { - nline_min = 0; - nline_max = 0; - nline_delt = 0; - return (0); - } + { + nline_min = 0; + nline_max = 0; + nline_delt = 0; + return (0); + } f = freqmin; nmin = 0; nmax = nlines - 1; - n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift + n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift while (n != nmin) - { - if (lin_ptr[n]->freq < f) - nmin = n; - if (lin_ptr[n]->freq >= f) - nmax = n; - n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift - } + { + if (lin_ptr[n]->freq < f) + nmin = n; + if (lin_ptr[n]->freq >= f) + nmax = n; + n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift + } nline_min = nmin; f = freqmax; nmin = 0; nmax = nlines - 1; - n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift + n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift while (n != nmin) - { - if (lin_ptr[n]->freq <= f) - nmin = n; - if (lin_ptr[n]->freq > f) - nmax = n; - n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift - } + { + if (lin_ptr[n]->freq <= f) + nmin = n; + if (lin_ptr[n]->freq > f) + nmax = n; + n = (nmin + nmax) >> 1; // Compute a midpoint >> is a bitwise right shift + } nline_max = nmax; @@ -3341,7 +3140,8 @@ limit_lines (freqmin, freqmax) /* check_xsections is a routine which checks xsections are ok. Only prints out each xsection with verbosity > 4 as uses Debug function */ -int check_xsections() +int +check_xsections () { int nion, n; @@ -3349,22 +3149,23 @@ int check_xsections() { nion = phot_top[n].nion; if (ion[nion].phot_info == 1) - Debug("Topbase Ion %i Z %i istate %i nground %i ilv %i ntop %i f0 %8.4e IP %8.4e\n", - nion, ion[nion].z, ion[nion].istate, ion[nion].ntop_ground, phot_top[n].nlev, ion[nion].ntop, phot_top[n].freq[0], ion[nion].ip); + Debug ("Topbase Ion %i Z %i istate %i nground %i ilv %i ntop %i f0 %8.4e IP %8.4e\n", + nion, ion[nion].z, ion[nion].istate, ion[nion].ntop_ground, phot_top[n].nlev, ion[nion].ntop, phot_top[n].freq[0], + ion[nion].ip); else if (ion[nion].phot_info == 0) - Debug("Vfky Ion %i Z %i istate %i nground %i f0 %8.4e IP %8.4e\n", - nion, ion[nion].z, ion[nion].istate, ion[nion].nxphot, phot_top[n].freq[0], ion[nion].ip); + Debug ("Vfky Ion %i Z %i istate %i nground %i f0 %8.4e IP %8.4e\n", + nion, ion[nion].z, ion[nion].istate, ion[nion].nxphot, phot_top[n].freq[0], ion[nion].ip); /* some simple checks -- could be made more robust */ if (ion[nion].n_lte_max == 0 && ion[nion].phot_info == 1) { - Error("get_atomicdata: not tracking levels for ion %i z %i istate %i, yet marked as topbase xsection!\n", + Error ("get_atomicdata: not tracking levels for ion %i z %i istate %i, yet marked as topbase xsection!\n", nion, ion[nion].z, ion[nion].istate); //exit(0); } if (ion[nion].phot_info != 1 && ion[nion].macro_info) { - Error("get_atomicdata: macro atom but no topbase xsection! ion %i z %i istate %i, yet marked as topbase xsection!\n", + Error ("get_atomicdata: macro atom but no topbase xsection! ion %i z %i istate %i, yet marked as topbase xsection!\n", nion, ion[nion].z, ion[nion].istate); //exit(0); } @@ -3372,4 +3173,3 @@ int check_xsections() return 0; } - diff --git a/source/hydro_import.c b/source/hydro_import.c index 961acad1b..c39759252 100755 --- a/source/hydro_import.c +++ b/source/hydro_import.c @@ -6,12 +6,12 @@ double hydro_r_edge[MAXHYDRO]; double hydro_theta_cent[MAXHYDRO]; double hydro_theta_edge[MAXHYDRO]; int ihydro_r, ihydro_theta, j_hydro_thetamax, ihydro_mod; -double hydro_thetamax; //The angle at which we want to truncate the theta grid -double v_r_input[MAXHYDRO*MAXHYDRO]; -double v_theta_input[MAXHYDRO*MAXHYDRO]; -double v_phi_input[MAXHYDRO*MAXHYDRO]; -double rho_input[MAXHYDRO*MAXHYDRO]; -double temp_input[MAXHYDRO*MAXHYDRO]; +double hydro_thetamax; //The angle at which we want to truncate the theta grid +double v_r_input[MAXHYDRO * MAXHYDRO]; +double v_theta_input[MAXHYDRO * MAXHYDRO]; +double v_phi_input[MAXHYDRO * MAXHYDRO]; +double rho_input[MAXHYDRO * MAXHYDRO]; +double temp_input[MAXHYDRO * MAXHYDRO]; /* @@ -120,25 +120,25 @@ int get_hydro_wind_params (ndom) int ndom; { - Log ("Creating a wind model using a Hydro calculation = domain %i\n",ndom); + Log ("Creating a wind model using a Hydro calculation = domain %i\n", ndom); get_hydro (ndom); /* Assign the generic parameters for the wind the generic parameters of the wind */ - geo.rmin = zdom[ndom].rmin=hydro_r_edge[0]; + geo.rmin = zdom[ndom].rmin = hydro_r_edge[0]; - geo.rmax = zdom[ndom].rmax = hydro_r_edge[ihydro_r] + 2.0 * (hydro_r_cent[ihydro_r] - hydro_r_edge[ihydro_r]); //Set the outer edge of the wind to the outer edge of the final defined cell + geo.rmax = zdom[ndom].rmax = hydro_r_edge[ihydro_r] + 2.0 * (hydro_r_cent[ihydro_r] - hydro_r_edge[ihydro_r]); //Set the outer edge of the wind to the outer edge of the final defined cell Log ("rmax=%e\n", geo.rmax); - geo.rmax_sq=geo.rmax*geo.rmax; + geo.rmax_sq = geo.rmax * geo.rmax; Log ("rmax_sq=%e\n", geo.rmax); - geo.wind_rho_min =zdom[ndom].wind_rho_min= 0.0; //Set wind_rmin 0.0, otherwise wind cones dont work properly + geo.wind_rho_min = zdom[ndom].wind_rho_min = 0.0; //Set wind_rmin 0.0, otherwise wind cones dont work properly Log ("rho_min=%e\n", zdom[ndom].wind_rho_min); - geo.wind_rho_max = zdom[ndom].wind_rho_max = zdom[ndom].rmax; //This is the outer edge of the + geo.wind_rho_max = zdom[ndom].wind_rho_max = zdom[ndom].rmax; //This is the outer edge of the Log ("rho_max=%e\n", zdom[ndom].wind_rho_max); - zdom[ndom].zmax = zdom[ndom].rmax; //This is the outer edge of the + zdom[ndom].zmax = zdom[ndom].rmax; //This is the outer edge of the Log ("zmax=%e\n", zdom[ndom].zmax); - zdom[ndom].wind_thetamin= hydro_theta_edge[0]; + zdom[ndom].wind_thetamin = hydro_theta_edge[0]; Log ("theta_min=%e\n", zdom[ndom].wind_thetamin); Log ("theta_max=%e\n", zdom[ndom].wind_thetamax); Log ("geo.rmin=%e\n", zdom[ndom].rmin); @@ -150,10 +150,10 @@ get_hydro_wind_params (ndom) /* if modes.adjust_grid is 1 then we have already adjusted the grid manually */ if (modes.adjust_grid == 0) - { - zdom[ndom].xlog_scale = 0.3 * geo.rstar; - zdom[ndom].zlog_scale = 0.3 * geo.rstar; - } + { + zdom[ndom].xlog_scale = 0.3 * geo.rstar; + zdom[ndom].zlog_scale = 0.3 * geo.rstar; + } return (0); } @@ -162,7 +162,7 @@ get_hydro_wind_params (ndom) int get_hydro (ndom) - int ndom; + int ndom; { FILE *fopen (), *fptr; @@ -175,7 +175,7 @@ get_hydro (ndom) double theta, theta_edge, temp; double vr, vtheta, vphi; int irmax, ithetamax, itest; - int ndim,mdim; + int ndim, mdim; /*Write something into the file name strings */ @@ -183,33 +183,32 @@ get_hydro (ndom) for (k = 0; k < MAXHYDRO; k++) - { - hydro_r_cent[k] = 0; - hydro_theta_cent[k] = 0; - } + { + hydro_r_cent[k] = 0; + hydro_theta_cent[k] = 0; + } /* - hydro_ptr = (HydroPtr) calloc (sizeof (hydro_dummy), MAXHYDRO * MAXHYDRO); + hydro_ptr = (HydroPtr) calloc (sizeof (hydro_dummy), MAXHYDRO * MAXHYDRO); - if (hydro_ptr == NULL) - { - Error - ("There is a problem in allocating memory for the hydro structure\n"); - exit (0); - } -*/ + if (hydro_ptr == NULL) + { + Error + ("There is a problem in allocating memory for the hydro structure\n"); + exit (0); + } + */ rdstr ("hydro_file", datafile); if ((fptr = fopen (datafile, "r")) == NULL) - { - Error ("Could not open %s\n", datafile); - exit (0); - } + { + Error ("Could not open %s\n", datafile); + exit (0); + } hydro_thetamax = 89.9; - rddoub ("Hydro_thetamax(degrees:negative_means_no_maximum)", - &hydro_thetamax); + rddoub ("Hydro_thetamax(degrees:negative_means_no_maximum)", &hydro_thetamax); //If we have set the maximum angle to a negaive value, we mean that we dont want to restrict. if (hydro_thetamax < 0.0) @@ -219,104 +218,98 @@ get_hydro (ndom) ihydro_r = 0; - j_hydro_thetamax = 0; /* NSH 130605 to remove o3 compile error */ + j_hydro_thetamax = 0; /* NSH 130605 to remove o3 compile error */ irmax = 0; - ithetamax = 0; //Zero counters to check all cells actually have data + ithetamax = 0; //Zero counters to check all cells actually have data while (fgets (aline, LINE, fptr) != NULL) - { - - if (aline[0] != '#') { - sscanf (aline, "%s", word); - if (strncmp (word, "ir", 2) == 0) + if (aline[0] != '#') + { + sscanf (aline, "%s", word); + + if (strncmp (word, "ir", 2) == 0) { - Log - ("We have a hydro title line, we might do something with this in the future \n"); + Log ("We have a hydro title line, we might do something with this in the future \n"); } - else + else { - itest = - sscanf (aline, "%d %lf %lf %d %lf %lf %lf %lf %lf %lf %lf", - &i, &r, &r_edge, &j, &theta, &theta_edge, &vr, - &vtheta, &vphi, &rho, &temp); - if (itest != 11) //We have an line which does not match what we expect, so quit - { - Error ("hydro.c data file improperly formatted\n"); - exit (0); - } - // read read the r and theta coordinates into arrays - hydro_r_edge[i] = r_edge; - hydro_r_cent[i] = r; - hydro_theta_cent[j] = theta; - hydro_theta_edge[j] = theta_edge; - //keep track of how many r and theta cells there are - if (j > ithetamax) - ithetamax = j; - if (i > irmax) - irmax = i; - //If the value of theta in this cell, the edge, is greater than out theta_max, we want to make a note. - if (hydro_theta_edge[j] > hydro_thetamax - && hydro_theta_edge[j - 1] <= hydro_thetamax) - { - j_hydro_thetamax = j - 1; - Log - ("current theta (%f) > theta_max (%f) so setting j_hydro_thetamax=%i\n", - theta * RADIAN, hydro_thetamax * RADIAN, - j_hydro_thetamax); - } - //If theta is greater than thetamax, then we will replace rho with the last density above the disk - else if (hydro_theta_edge[j] > hydro_thetamax) - { - /* NSH 130327 - for the time being, if theta is in the disk, replace with the last - density above the disk */ - rho=rho_input[i * MAXHYDRO + j_hydro_thetamax]; - } + itest = + sscanf (aline, "%d %lf %lf %d %lf %lf %lf %lf %lf %lf %lf", + &i, &r, &r_edge, &j, &theta, &theta_edge, &vr, &vtheta, &vphi, &rho, &temp); + if (itest != 11) //We have an line which does not match what we expect, so quit + { + Error ("hydro.c data file improperly formatted\n"); + exit (0); + } + // read read the r and theta coordinates into arrays + hydro_r_edge[i] = r_edge; + hydro_r_cent[i] = r; + hydro_theta_cent[j] = theta; + hydro_theta_edge[j] = theta_edge; + //keep track of how many r and theta cells there are + if (j > ithetamax) + ithetamax = j; + if (i > irmax) + irmax = i; + //If the value of theta in this cell, the edge, is greater than out theta_max, we want to make a note. + if (hydro_theta_edge[j] > hydro_thetamax && hydro_theta_edge[j - 1] <= hydro_thetamax) + { + j_hydro_thetamax = j - 1; + Log + ("current theta (%f) > theta_max (%f) so setting j_hydro_thetamax=%i\n", + theta * RADIAN, hydro_thetamax * RADIAN, j_hydro_thetamax); + } + //If theta is greater than thetamax, then we will replace rho with the last density above the disk + else if (hydro_theta_edge[j] > hydro_thetamax) + { + /* NSH 130327 - for the time being, if theta is in the disk, replace with the last + density above the disk */ + rho = rho_input[i * MAXHYDRO + j_hydro_thetamax]; + } // hydro_ptr[i * MAXHYDRO + j].temp = temp; // hydro_ptr[i * MAXHYDRO + j].rho = rho; // hydro_ptr[i * MAXHYDRO + j].v[0] = vr; // hydro_ptr[i * MAXHYDRO + j].v[1] = vtheta; // hydro_ptr[i * MAXHYDRO + j].v[2] = vphi; - rho_input[i * MAXHYDRO + j] = rho; - temp_input[i * MAXHYDRO + j] = temp; - v_r_input[i * MAXHYDRO + j] = vr; - v_theta_input[i * MAXHYDRO + j] = vtheta; - v_phi_input[i * MAXHYDRO + j] = vphi; + rho_input[i * MAXHYDRO + j] = rho; + temp_input[i * MAXHYDRO + j] = temp; + v_r_input[i * MAXHYDRO + j] = vr; + v_theta_input[i * MAXHYDRO + j] = vtheta; + v_phi_input[i * MAXHYDRO + j] = vphi; } - } } + } if (j_hydro_thetamax == 0 || j_hydro_thetamax == i - 1) - { - Log ("HYDRO j_hydro_thetamax never bracketed, using all data\n"); - ihydro_theta = ithetamax; - zdom[ndom].wind_thetamax=90. / RADIAN; - hydro_thetamax = 90.0 / RADIAN; - mdim = zdom[ndom].mdim = ihydro_theta + 2; - } + { + Log ("HYDRO j_hydro_thetamax never bracketed, using all data\n"); + ihydro_theta = ithetamax; + zdom[ndom].wind_thetamax = 90. / RADIAN; + hydro_thetamax = 90.0 / RADIAN; + mdim = zdom[ndom].mdim = ihydro_theta + 2; + } else - { - Log - ("HYDRO j_hydro_thetamax=%i, bracketing cells have theta = %f and %f\n", - j_hydro_thetamax, hydro_theta_cent[j_hydro_thetamax] * RADIAN, - hydro_theta_cent[j_hydro_thetamax + 1] * RADIAN); - ihydro_theta = j_hydro_thetamax; - zdom[ndom].wind_thetamax= hydro_thetamax; - mdim = zdom[ndom].mdim = ihydro_theta + 2; - } + { + Log + ("HYDRO j_hydro_thetamax=%i, bracketing cells have theta = %f and %f\n", + j_hydro_thetamax, hydro_theta_cent[j_hydro_thetamax] * RADIAN, hydro_theta_cent[j_hydro_thetamax + 1] * RADIAN); + ihydro_theta = j_hydro_thetamax; + zdom[ndom].wind_thetamax = hydro_thetamax; + mdim = zdom[ndom].mdim = ihydro_theta + 2; + } if (hydro_r_edge[0] < geo.rstar) - { - Error - ("Major problem, innermost edge of hydro radial grid begins inside geo.rstar\n"); - exit (0); - } + { + Error ("Major problem, innermost edge of hydro radial grid begins inside geo.rstar\n"); + exit (0); + } ihydro_r = irmax; @@ -326,20 +319,20 @@ get_hydro (ndom) /* Set a couple of last tags */ - zdom[ndom].coord_type = RTHETA; //At the moment we only deal with RTHETA - in the future we might want to do some clever stuff - ndim = zdom[ndom].ndim = ihydro_r + 3; //We need an inner radial cell to bridge the star and the inside of the wind, and an outer cell + zdom[ndom].coord_type = RTHETA; //At the moment we only deal with RTHETA - in the future we might want to do some clever stuff + ndim = zdom[ndom].ndim = ihydro_r + 3; //We need an inner radial cell to bridge the star and the inside of the wind, and an outer cell //geo.ndim2 = NDIM2 += zdom[ndom].ndim * zdom[ndom].mdim; - /* - for (i=0;i= 1.) - { - theta = PI / 2.; - } + { + theta = PI / 2.; + } else theta = asin (xxx); - // printf ("Proga_theta x %.2g %.2g %.2g -> r= %.2g theta = %.5g\n", x[0], x[1], x[2], r,theta); + // printf ("Proga_theta x %.2g %.2g %.2g -> r= %.2g theta = %.5g\n", x[0], x[1], x[2], r,theta); im = jm = ii = jj = 0; - f1=f2=0.0; -hydro_frac (r,hydro_r_cent,ihydro_r,&im,&ii,&f1); -hydro_frac (theta,hydro_theta_cent,ihydro_theta,&jm,&jj,&f2); -v_r_interp=hydro_interp_value(v_r_input,im,ii,jm,jj,f1,f2); + f1 = f2 = 0.0; + hydro_frac (r, hydro_r_cent, ihydro_r, &im, &ii, &f1); + hydro_frac (theta, hydro_theta_cent, ihydro_theta, &jm, &jj, &f2); + v_r_interp = hydro_interp_value (v_r_input, im, ii, jm, jj, f1, f2); -im = jm = ii = jj = 0; -f1=f2=0.0; + im = jm = ii = jj = 0; + f1 = f2 = 0.0; + + hydro_frac (r, hydro_r_cent, ihydro_r, &im, &ii, &f1); + hydro_frac (theta, hydro_theta_cent, ihydro_theta, &jm, &jj, &f2); -hydro_frac (r,hydro_r_cent,ihydro_r,&im,&ii,&f1); -hydro_frac (theta,hydro_theta_cent,ihydro_theta,&jm,&jj,&f2); + v_theta_interp = hydro_interp_value (v_theta_input, im, ii, jm, jj, f1, f2); - v_theta_interp=hydro_interp_value(v_theta_input,im,ii,jm,jj,f1,f2); - -im = jm = ii = jj = 0; -f1=f2=0.0; -hydro_frac (r,hydro_r_cent,ihydro_r,&im,&ii,&f1); -hydro_frac (theta,hydro_theta_cent,ihydro_theta,&jm,&jj,&f2); -v_phi_interp=hydro_interp_value(v_phi_input,im,ii,jm,jj,f1,f2); + im = jm = ii = jj = 0; + f1 = f2 = 0.0; + hydro_frac (r, hydro_r_cent, ihydro_r, &im, &ii, &f1); + hydro_frac (theta, hydro_theta_cent, ihydro_theta, &jm, &jj, &f2); + v_phi_interp = hydro_interp_value (v_phi_input, im, ii, jm, jj, f1, f2); //printf ("TEST7 %e cos %e sin %e\n",theta,cos(theta),sin(theta)); @@ -428,9 +421,9 @@ v_phi_interp=hydro_interp_value(v_phi_input,im,ii,jm,jj,f1,f2); speed = sqrt (v[0] * v[0] + v[1] * v[1] * v[2] * v[2]); if (sane_check (speed)) - { - Error ("hydro_velocity:sane_check v %e %e %e\n", v[0], v[1], v[2]); - } + { + Error ("hydro_velocity:sane_check v %e %e %e\n", v[0], v[1], v[2]); + } return (speed); } @@ -451,19 +444,19 @@ hydro_rho (x) theta = asin (sqrt (x[0] * x[0] + x[1] * x[1]) / r); //printf ("NSH hydro_rho x %e %e %e -> r= %e theta = %f ", x[0], x[1], x[2], r, theta); - if (( hydro_r_cent[ihydro_r] -r )/r < -1e-6) - { - Log (" r outside hydro grid in hydro_rho %e > %e %e\n",r,hydro_r_cent[ihydro_r],(hydro_r_cent[ihydro_r] -r )/r); - rrho = 1.e-23; - return (rrho); - } + if ((hydro_r_cent[ihydro_r] - r) / r < -1e-6) + { + Log (" r outside hydro grid in hydro_rho %e > %e %e\n", r, hydro_r_cent[ihydro_r], (hydro_r_cent[ihydro_r] - r) / r); + rrho = 1.e-23; + return (rrho); + } im = jm = ii = jj = 0; - f1=f2=0.0; - hydro_frac (r,hydro_r_cent,ihydro_r,&im,&ii,&f1); - hydro_frac (theta,hydro_theta_cent,ihydro_theta,&jm,&jj,&f2); + f1 = f2 = 0.0; + hydro_frac (r, hydro_r_cent, ihydro_r, &im, &ii, &f1); + hydro_frac (theta, hydro_theta_cent, ihydro_theta, &jm, &jj, &f2); - rrho=hydro_interp_value(rho_input,im,ii,jm,jj,f1,f2); + rrho = hydro_interp_value (rho_input, im, ii, jm, jj, f1, f2); if (rrho < 1e-23) rrho = 1e-23; @@ -508,31 +501,31 @@ hydro_temp (x) theta = asin (sqrt (x[0] * x[0] + x[1] * x[1]) / r); // printf ("x %.2g %.2g %.2g -> r= %.2g theta = %.2g\n", x[0], x[1], x[2], r, // theta); - - + + im = jm = ii = jj = 0; - f1=f2=0.0; + f1 = f2 = 0.0; - if (( hydro_r_cent[ihydro_r] -r )/r < -1e-6) - { - Log (" r outside hydro grid in hydro_temp %e > %e %e\n",r,hydro_r_cent[ihydro_r],(hydro_r_cent[ihydro_r] -r )/r); - temp = 1e4; - return (temp); - } - + if ((hydro_r_cent[ihydro_r] - r) / r < -1e-6) + { + Log (" r outside hydro grid in hydro_temp %e > %e %e\n", r, hydro_r_cent[ihydro_r], (hydro_r_cent[ihydro_r] - r) / r); + temp = 1e4; + return (temp); + } - hydro_frac (r,hydro_r_cent,ihydro_r,&im,&ii,&f1); - hydro_frac (theta,hydro_theta_cent,ihydro_theta,&jm,&jj,&f2); - temp=hydro_interp_value(temp_input,im,ii,jm,jj,f1,f2); + hydro_frac (r, hydro_r_cent, ihydro_r, &im, &ii, &f1); + hydro_frac (theta, hydro_theta_cent, ihydro_theta, &jm, &jj, &f2); + temp = hydro_interp_value (temp_input, im, ii, jm, jj, f1, f2); - /* NSH 16/2/29 - removed lower limit - set this in the hydro translation software or hydro model */ -// if (temp < 1e4) //Set a lower limit. + /* NSH 16/2/29 - removed lower limit - set this in the hydro translation software or hydro model */ + +// if (temp < 1e4) //Set a lower limit. // temp = 1e4; - + return (temp); } @@ -571,70 +564,70 @@ rtheta_make_hydro_grid (w, ndom) { double theta, thetacen, dtheta; int i, j, n; - int ndim,mdim; + int ndim, mdim; - ndim=zdom[ndom].ndim; - mdim=zdom[ndom].mdim; + ndim = zdom[ndom].ndim; + mdim = zdom[ndom].mdim; for (i = 0; i < ndim; i++) - { - for (j = 0; j < mdim; j++) { - wind_ij_to_n (ndom, i, j, &n); - w[n].inwind = W_ALL_INWIND; - if (i == 0) // The inner edge of the grid should be geo.rstar + for (j = 0; j < mdim; j++) + { + wind_ij_to_n (ndom, i, j, &n); + w[n].inwind = W_ALL_INWIND; + if (i == 0) // The inner edge of the grid should be geo.rstar { - w[n].r = geo.rstar; //So we set the inner edge to be the stellar (or QSO) radius - w[n].rcen = (geo.rstar + hydro_r_edge[0]) / 2.0; //It will be a big cell - w[n].inwind = W_NOT_INWIND; + w[n].r = geo.rstar; //So we set the inner edge to be the stellar (or QSO) radius + w[n].rcen = (geo.rstar + hydro_r_edge[0]) / 2.0; //It will be a big cell + w[n].inwind = W_NOT_INWIND; } - else if (i - 1 > ihydro_r) // We are at the radial limit of the data, this last cell will be a ghost cell of our own + else if (i - 1 > ihydro_r) // We are at the radial limit of the data, this last cell will be a ghost cell of our own { - w[n].r = geo.rmax; // so we set the outer cell to be the edge of the wind - w[n].rcen = geo.rmax; // And it has zero volume - w[n].inwind = W_NOT_INWIND; + w[n].r = geo.rmax; // so we set the outer cell to be the edge of the wind + w[n].rcen = geo.rmax; // And it has zero volume + w[n].inwind = W_NOT_INWIND; } - else + else { - w[n].r = hydro_r_edge[i - 1]; //The -1 is to take account of the fact that i=0 cell is the inner part of the geometry inside the wind - w[n].rcen = hydro_r_cent[i - 1]; + w[n].r = hydro_r_edge[i - 1]; //The -1 is to take account of the fact that i=0 cell is the inner part of the geometry inside the wind + w[n].rcen = hydro_r_cent[i - 1]; } - dtheta = 2.0 * (hydro_theta_cent[j] - hydro_theta_edge[j]); + dtheta = 2.0 * (hydro_theta_cent[j] - hydro_theta_edge[j]); - if (hydro_theta_cent[j] + (dtheta / 2.0) > hydro_thetamax && hydro_theta_cent[j] - (dtheta / 2.0) < hydro_thetamax) //This cell bridges the boundary - we reset it so the lower edge is at the disk boundary + if (hydro_theta_cent[j] + (dtheta / 2.0) > hydro_thetamax && hydro_theta_cent[j] - (dtheta / 2.0) < hydro_thetamax) //This cell bridges the boundary - we reset it so the lower edge is at the disk boundary { - theta = hydro_theta_edge[j]; - thetacen = ((hydro_thetamax + theta) / 2.0); + theta = hydro_theta_edge[j]; + thetacen = ((hydro_thetamax + theta) / 2.0); } - else if (j > ihydro_theta) //We are setting up a cell past where there is any data + else if (j > ihydro_theta) //We are setting up a cell past where there is any data { - thetacen = hydro_thetamax; //Set the center and the edge to the maximum extent of the data/interest - theta = hydro_thetamax; - w[n].inwind = W_NOT_INWIND; + thetacen = hydro_thetamax; //Set the center and the edge to the maximum extent of the data/interest + theta = hydro_thetamax; + w[n].inwind = W_NOT_INWIND; } - else + else { - thetacen = hydro_theta_cent[j]; - theta = hydro_theta_edge[j]; + thetacen = hydro_theta_cent[j]; + theta = hydro_theta_edge[j]; } - w[n].theta = theta * RADIAN; - w[n].thetacen = thetacen * RADIAN; - w[n].x[1] = w[n].xcen[1] = 0.0; - w[n].x[0] = w[n].r * sin (theta); - w[n].x[2] = w[n].r * cos (theta); - w[n].xcen[0] = w[n].rcen * sin (thetacen); - w[n].xcen[2] = w[n].rcen * cos (thetacen); + w[n].theta = theta * RADIAN; + w[n].thetacen = thetacen * RADIAN; + w[n].x[1] = w[n].xcen[1] = 0.0; + w[n].x[0] = w[n].r * sin (theta); + w[n].x[2] = w[n].r * cos (theta); + w[n].xcen[0] = w[n].rcen * sin (thetacen); + w[n].xcen[2] = w[n].rcen * cos (thetacen); - } } + } /* Now set up the wind cones that are needed for calclating ds in a cell */ - rtheta_make_cones (ndom, w); //NSH 130821 broken out into a seperate routine + rtheta_make_cones (ndom, w); //NSH 130821 broken out into a seperate routine @@ -682,38 +675,33 @@ rtheta_hydro_volumes (ndom, w) //printf ("NSH here in hydro_volumes\n"); for (i = 0; i < one_dom->ndim; i++) - { - for (j = 0; j < one_dom->mdim; j++) { + for (j = 0; j < one_dom->mdim; j++) + { - wind_ij_to_n (ndom, i, j, &n); - if (w[n].inwind == W_ALL_INWIND) + wind_ij_to_n (ndom, i, j, &n); + if (w[n].inwind == W_ALL_INWIND) { - rmin = one_dom->wind_x[i]; - rmax = one_dom->wind_x[i + 1]; - thetamin = one_dom->wind_z[j] / RADIAN; - thetamax = one_dom->wind_z[j + 1] / RADIAN; - - //leading factor of 2 added to allow for volume above and below plane (SSMay04) - w[n].vol = - 2. * 2. / 3. * PI * (rmax * rmax * rmax - - rmin * rmin * rmin) * (cos (thetamin) - - cos (thetamax)); - //printf ("NSH_vols %i %i rmin %e rmax %e thetamin %e thatmax %e vol %e\n",i,j,rmin,rmax,thetamin,thetamax,w[n].vol); - - if (w[n].vol == 0.0) - { - Log - ("Found wind cell (%i) with no volume (%e) in wind, resetting\n", - n, w[n].vol); - w[n].inwind = W_NOT_INWIND; - } + rmin = one_dom->wind_x[i]; + rmax = one_dom->wind_x[i + 1]; + thetamin = one_dom->wind_z[j] / RADIAN; + thetamax = one_dom->wind_z[j + 1] / RADIAN; + + //leading factor of 2 added to allow for volume above and below plane (SSMay04) + w[n].vol = 2. * 2. / 3. * PI * (rmax * rmax * rmax - rmin * rmin * rmin) * (cos (thetamin) - cos (thetamax)); + //printf ("NSH_vols %i %i rmin %e rmax %e thetamin %e thatmax %e vol %e\n",i,j,rmin,rmax,thetamin,thetamax,w[n].vol); + + if (w[n].vol == 0.0) + { + Log ("Found wind cell (%i) with no volume (%e) in wind, resetting\n", n, w[n].vol); + w[n].inwind = W_NOT_INWIND; + } } - else - w[n].vol = 0.0; - } + else + w[n].vol = 0.0; } + } return (0); } @@ -750,55 +738,55 @@ rtheta_hydro_volumes (ndom, w) int - hydro_frac (coord,coord_array,imax,cell1,cell2,frac) - double coord; - double coord_array[]; - int imax; - int *cell1,*cell2; - double *frac; - { - int ii; - ii=0; - *cell1=0; - *cell2=0; +hydro_frac (coord, coord_array, imax, cell1, cell2, frac) + double coord; + double coord_array[]; + int imax; + int *cell1, *cell2; + double *frac; +{ + int ii; + ii = 0; + *cell1 = 0; + *cell2 = 0; + + while (coord_array[ii] < coord && ii < imax) //Search through array, until array value is greater than your coordinate + ii++; - while (coord_array[ii] < coord && ii < imax) //Search through array, until array value is greater than your coordinate - ii++; - //if (ii > 0 && ii < imax) - if (ii > imax) - { // r is greater than anything in Proga's model + if (ii > imax) + { // r is greater than anything in Proga's model // printf ("I DONT THINK WE CAN EVER GET HERE\n"); - *frac = 1; //If we are outside the model set fractional position to 1 - *cell1 = *cell2 = imax; //And the bin to the outermost - return(0); - } - else if (ii==0) - { - *frac = 1; //Otherwise, we must be inside the innermost bin, so again, set fration to 1 - *cell1 = *cell2 = 0; // And the bin to the innermost. Lines below to the same for theta. - return(0); - } - else if (ii>0) - { //r is in the normal range + *frac = 1; //If we are outside the model set fractional position to 1 + *cell1 = *cell2 = imax; //And the bin to the outermost + return (0); + } + else if (ii == 0) + { + *frac = 1; //Otherwise, we must be inside the innermost bin, so again, set fration to 1 + *cell1 = *cell2 = 0; // And the bin to the innermost. Lines below to the same for theta. + return (0); + } + else if (ii > 0) + { //r is in the normal range - *frac = (coord - coord_array[ii - 1]) / (coord_array[ii] - coord_array[ii - 1]); //Work out fractional position in the ii-1th radial bin where you want to be - *cell1 = ii - 1; //This is the radial bin below your value of r + *frac = (coord - coord_array[ii - 1]) / (coord_array[ii] - coord_array[ii - 1]); //Work out fractional position in the ii-1th radial bin where you want to be + *cell1 = ii - 1; //This is the radial bin below your value of r *cell2 = ii; - return(0); - } - - - + return (0); + } - return(0); + + + + return (0); } /*********************************************************** @@ -828,29 +816,29 @@ int double - hydro_interp_value(array,im,ii,jm,jj,f1,f2) - double array[]; - int im,ii; //the two cells surrounding the cell in the first dim (r) - int jm,jj; //the two cells surrounding the cell in the second dim (theta) - double f1,f2; //the fraction between the two values in first and second dim - { - double value; - double d1,d2; - +hydro_interp_value (array, im, ii, jm, jj, f1, f2) + double array[]; + int im, ii; //the two cells surrounding the cell in the first dim (r) + int jm, jj; //the two cells surrounding the cell in the second dim (theta) + double f1, f2; //the fraction between the two values in first and second dim +{ + double value; + double d1, d2; + // printf ("TEST7b %i %i %i %i %e %e %e\n",im,ii,jm,jj,f1,f2,array[im * MAXHYDRO + jm]); - d1=array[im * MAXHYDRO + jm]+f1*(array[ii * MAXHYDRO + jm]-array[im * MAXHYDRO + jm]); - d2=array[im * MAXHYDRO + jj]+f1*(array[ii * MAXHYDRO + jj]-array[im * MAXHYDRO + jj]); - value=d1+f2*(d2-d1); + d1 = array[im * MAXHYDRO + jm] + f1 * (array[ii * MAXHYDRO + jm] - array[im * MAXHYDRO + jm]); + d2 = array[im * MAXHYDRO + jj] + f1 * (array[ii * MAXHYDRO + jj] - array[im * MAXHYDRO + jj]); + value = d1 + f2 * (d2 - d1); // printf ("TEST3 %e %e %e\n",d1,d2,value); - - -// f1 * ((1. - f2) * array[ii * MAXHYDRO + jm] + f2 * array[ii * MAXHYDRO + jj]); - return(value); - } - - - + + +// f1 * ((1. - f2) * array[ii * MAXHYDRO + jm] + f2 * array[ii * MAXHYDRO + jj]); + return (value); +} + + + /*********************************************************** Southampton @@ -875,65 +863,65 @@ double **************************************************************/ - - - - - - int - hydro_restart(ndom) - int ndom; - { - int n,nion; - int nwind; - double x[3]; - double old_density; - int nstart, nstop, ndim2; - WindPtr w; - - w = wmain; - zdom[ndom].wind_type = 3; //Temporarily set the wind type to hydro, so we can use the normal routines - - /* note that we will have passed the wind domain number as default */ - nstart = zdom[ndom].nstart; - nstop = zdom[ndom].nstop; - ndim2 = zdom[ndom].ndim2; - - for (n = nstart; n < nstop; n++) - { - /* 04aug -- ksl -52 -- The next couple of lines are part of the changes - * made in the program to allow more that one coordinate system in python - */ - - model_velocity (ndom, w[n].x, w[n].v); - model_vgrad (ndom, w[n].x, w[n].v_grad); - } - - /* JM XXX PLACEHOLDER -- unsure how we loop over the plasma cells just in one domain */ - for (n = 0; n < NPLASMA; n++) - { - nwind = plasmamain[n].nwind; - stuff_v (w[nwind].xcen, x); - old_density = plasmamain[n].rho; + + + + + +int +hydro_restart (ndom) + int ndom; +{ + int n, nion; + int nwind; + double x[3]; + double old_density; + int nstart, nstop, ndim2; + WindPtr w; + + w = wmain; + zdom[ndom].wind_type = 3; //Temporarily set the wind type to hydro, so we can use the normal routines + + /* note that we will have passed the wind domain number as default */ + nstart = zdom[ndom].nstart; + nstop = zdom[ndom].nstop; + ndim2 = zdom[ndom].ndim2; + + for (n = nstart; n < nstop; n++) + { + /* 04aug -- ksl -52 -- The next couple of lines are part of the changes + * made in the program to allow more that one coordinate system in python + */ + + model_velocity (ndom, w[n].x, w[n].v); + model_vgrad (ndom, w[n].x, w[n].v_grad); + } + + /* JM XXX PLACEHOLDER -- unsure how we loop over the plasma cells just in one domain */ + for (n = 0; n < NPLASMA; n++) + { + nwind = plasmamain[n].nwind; + stuff_v (w[nwind].xcen, x); + old_density = plasmamain[n].rho; plasmamain[n].rho = model_rho (ndom, x) / zdom[ndom].fill; - plasmamain[n].t_r = plasmamain[n].t_e = hydro_temp (x); - - for (nion=0;nion the grid spacing will be logarithmic in x and z, 1-> linear */ - double xlog_scale, zlog_scale; /* Scale factors for setting up a logarithmic grid, the [1,1] cell - will be located at xlog_scale,zlog_scale */ - - /* The next few structures define the boundaries of an emission region */ - struct cone windcone[2]; /* The cones that define the boundary of winds like SV or kwd */ - struct plane windplane[2]; /* Planes which define the top and bottom of a layer */ - double rho_min,rho_max; /* These are used for the inneer and outer boundary of a pillbox */ - - double wind_x[NDIM_MAX], wind_z[NDIM_MAX]; /* These define the edges of the cells in the x and z directions */ - double wind_midx[NDIM_MAX], wind_midz[NDIM_MAX]; /* These define the midpoints of the cells in the x and z directions */ - -ConePtr cones_rtheta; /*A ptr to the cones that define the theta directions in rtheta coods */ + char name[LINELENGTH]; + int wind_type; + int ndim, mdim, ndim2; + int nstart, nstop; //the beginning and end (-1) location in wmain of this component + enum coord_type_enum coord_type; + int log_linear; /*0 -> the grid spacing will be logarithmic in x and z, 1-> linear */ + double xlog_scale, zlog_scale; /* Scale factors for setting up a logarithmic grid, the [1,1] cell + will be located at xlog_scale,zlog_scale */ + + /* The next few structures define the boundaries of an emission region */ + struct cone windcone[2]; /* The cones that define the boundary of winds like SV or kwd */ + struct plane windplane[2]; /* Planes which define the top and bottom of a layer */ + double rho_min, rho_max; /* These are used for the inneer and outer boundary of a pillbox */ + + double wind_x[NDIM_MAX], wind_z[NDIM_MAX]; /* These define the edges of the cells in the x and z directions */ + double wind_midx[NDIM_MAX], wind_midz[NDIM_MAX]; /* These define the midpoints of the cells in the x and z directions */ + + ConePtr cones_rtheta; /*A ptr to the cones that define the theta directions in rtheta coods */ /* Next two lines are for cyl_var coordinates. They are used in locating the appropriate * locating the appropriate cell, for example by cylvar_where_in_grid */ -double wind_z_var[NDIM_MAX][NDIM_MAX]; -double wind_midz_var[NDIM_MAX][NDIM_MAX]; + double wind_z_var[NDIM_MAX][NDIM_MAX]; + double wind_midz_var[NDIM_MAX][NDIM_MAX]; /* Since in principle we can mix and match arbitrarily the next parameters now have to be part of the domain structure */ /* Generic parameters for the wind */ - double wind_mdot, stellar_wind_mdot; /* Mass loss rate in disk and stellar wind */ - double rmin, rmax; /*Spherical extent of the wind */ - double zmax; /* Vertical extent of the wind, often the same as rmas */ - double wind_rho_min, wind_rho_max; /*Min/Max rho for wind in disk plane */ - double wind_thetamin, wind_thetamax; /*Angles defining inner and outer cones of wind, measured from disk plane */ - double mdot_norm; /*A normalization factor used in SV wind, and Knigge wind */ + double wind_mdot, stellar_wind_mdot; /* Mass loss rate in disk and stellar wind */ + double rmin, rmax; /*Spherical extent of the wind */ + double zmax; /* Vertical extent of the wind, often the same as rmas */ + double wind_rho_min, wind_rho_max; /*Min/Max rho for wind in disk plane */ + double wind_thetamin, wind_thetamax; /*Angles defining inner and outer cones of wind, measured from disk plane */ + double mdot_norm; /*A normalization factor used in SV wind, and Knigge wind */ - double twind; // ksl 1508 -- added in case domains have different initial temperatures + double twind; // ksl 1508 -- added in case domains have different initial temperatures /* Parameters defining Shlossman & Vitello Wind */ - double sv_lambda; /* power law exponent describing from what portion of disk wind is radiated */ - double sv_rmin, sv_rmax, sv_thetamin, sv_thetamax, sv_gamma; /* parameters defining the goemetry of the wind */ - double sv_v_zero; /* velocity at base of wind */ - double sv_r_scale, sv_alpha; /* the scale length and power law exponent for the velocity law */ - double sv_v_infinity; /* the factor by which the velocity at infinity exceeds the excape velocity */ + double sv_lambda; /* power law exponent describing from what portion of disk wind is radiated */ + double sv_rmin, sv_rmax, sv_thetamin, sv_thetamax, sv_gamma; /* parameters defining the goemetry of the wind */ + double sv_v_zero; /* velocity at base of wind */ + double sv_r_scale, sv_alpha; /* the scale length and power law exponent for the velocity law */ + double sv_v_infinity; /* the factor by which the velocity at infinity exceeds the excape velocity */ /* Paramater for the Elvis AGN wind - closely based on SV */ - double elvis_offset; /*This is a vertical offset for a region where the - wind rises vertically from the disk */ + double elvis_offset; /*This is a vertical offset for a region where the + wind rises vertically from the disk */ /* Parameters defining Knigge Wind */ - double kn_dratio; /* parameter describing collimation of wind */ - double kn_lambda; /* power law exponent describing from what portion of disk wind is radiated */ - double kn_r_scale, kn_alpha; /* the scale length and power law exponent for the velocity law */ - double kn_v_infinity; /* the factor by which the velocity at infinity exceeds the excape velocity */ - double kn_v_zero; /* NSH 19/04/11 - Added in as the multiple of the sound speed to use as the initial velocity */ + double kn_dratio; /* parameter describing collimation of wind */ + double kn_lambda; /* power law exponent describing from what portion of disk wind is radiated */ + double kn_r_scale, kn_alpha; /* the scale length and power law exponent for the velocity law */ + double kn_v_infinity; /* the factor by which the velocity at infinity exceeds the excape velocity */ + double kn_v_zero; /* NSH 19/04/11 - Added in as the multiple of the sound speed to use as the initial velocity */ /* Parameters describing Castor and Larmors spherical wind */ - double cl_v_zero, cl_v_infinity, cl_beta; /* Power law exponent */ + double cl_v_zero, cl_v_infinity, cl_beta; /* Power law exponent */ double cl_rmin, cl_rmax; /* Parameters describing a spherical shell test wind */ @@ -259,19 +259,19 @@ double wind_midz_var[NDIM_MAX][NDIM_MAX]; double shell_rmin, shell_rmax; /*Parameters defining a corona in a ring above a disk */ - double corona_rmin, corona_rmax; /*the minimum and maximu radius of the corona */ - double corona_zmax; /*The maximum vertical extent of the corona */ - double corona_base_density, corona_scale_height; /*the density at the base of the corona and the scale height */ - double corona_vel_frac; /* the radial velocity of the corona in units of the keplerian velocity */ + double corona_rmin, corona_rmax; /*the minimum and maximu radius of the corona */ + double corona_zmax; /*The maximum vertical extent of the corona */ + double corona_base_density, corona_scale_height; /*the density at the base of the corona and the scale height */ + double corona_vel_frac; /* the radial velocity of the corona in units of the keplerian velocity */ /* The filling factior for the wind or corona */ /* JM 1601 -- Moved here from geo, see #212 */ double fill; } -domain_dummy, *DomainPtr; // One structure for each domain +domain_dummy, *DomainPtr; // One structure for each domain -DomainPtr zdom; //This is the array pointer that contains the domains -int current_domain; // This integer is used by py_wind only +DomainPtr zdom; //This is the array pointer that contains the domains +int current_domain; // This integer is used by py_wind only /* the geometry structure contains information that applies to all domains or alternatimve @@ -290,9 +290,9 @@ int current_domain; // This integer is used by py_wind only struct geometry { -int ndomain; /*The number of domains in a model*/ -int ndim2; /* The total number of windcells in all domains */ -int nplasma, nmacro; /*The total number of cells in the plasma and macro structures in all domains */ + int ndomain; /*The number of domains in a model */ + int ndim2; /* The total number of windcells in all domains */ + int nplasma, nmacro; /*The total number of cells in the plasma and macro structures in all domains */ /* variables which store the domain numbers of the wind, disk atmosphere. Other components should be added here. Right now we need a wind_domain @@ -300,25 +300,25 @@ int nplasma, nmacro; /*The total number of cells in the plasma and macro structu interrsed. The first step will be to put this information into alocal variale in python.c. We should not have to carry this forward */ - int wind_domain_number; - int atmos_domain_number; + int wind_domain_number; + int atmos_domain_number; /* 67 - ksl This section added to allow for restarting the program, and adds parameters used * in the calculation */ - int wcycle, pcycle; /* The number of completed ionization and spectrum cycles */ - int wcycles, pcycles; /* The number of ionization and spectrum cycles desired */ + int wcycle, pcycle; /* The number of completed ionization and spectrum cycles */ + int wcycles, pcycles; /* The number of ionization and spectrum cycles desired */ /* 1509 - ksl - Moved parameters which describe the spectra to be extracted from main into the * geometry structure */ #define NSPEC 20 - int nangles; - double angle[NSPEC], phase[NSPEC]; - int scat_select[NSPEC], top_bot_select[NSPEC]; - double rho_select[NSPEC], z_select[NSPEC], az_select[NSPEC], r_select[NSPEC]; - double swavemin, swavemax; - int select_extract,select_spectype; + int nangles; + double angle[NSPEC], phase[NSPEC]; + int scat_select[NSPEC], top_bot_select[NSPEC]; + double rho_select[NSPEC], z_select[NSPEC], az_select[NSPEC], r_select[NSPEC]; + double swavemin, swavemax; + int select_extract, select_spectype; /* Begin description of the actual geometery */ @@ -326,126 +326,126 @@ int nplasma, nmacro; /*The total number of cells in the plasma and macro structu * outside these regions are assumed to have hit something or be freely moving through space. */ - double rmin, rmax, rmax_sq; /* The maximum distance to which a photon should be followed */ - double wind_rho_min, wind_rho_max; /*Min/Max rho for wind in disk plane */ + double rmin, rmax, rmax_sq; /* The maximum distance to which a photon should be followed */ + double wind_rho_min, wind_rho_max; /*Min/Max rho for wind in disk plane */ /* Basic paremeters of the system, as opposed to elements of the wind or winds */ - double mstar, rstar, rstar_sq, tstar, gstar; /* Basic parameters for the WD */ - double twind; /* temperature of wind */ - double tmax; /*NSH 120817 the maximum temperature of any element of the model - - used to help estimate things for an exponential representation of the spectrum in a cell */ + double mstar, rstar, rstar_sq, tstar, gstar; /* Basic parameters for the WD */ + double twind; /* temperature of wind */ + double tmax; /*NSH 120817 the maximum temperature of any element of the model + - used to help estimate things for an exponential representation of the spectrum in a cell */ - int system_type; /* See allowed types above */ + int system_type; /* See allowed types above */ #define DISK_NONE 0 #define DISK_FLAT 1 #define DISK_VERTICALLY_EXTENDED 2 - int disk_type; - -#define DISK_ILLUM_ABSORB_AND_DESTROY 0 /* Disk simply absorbs the radiation and it is lost */ -#define DISK_ILLUM_SCATTER 1 /* Disk reradiates the radiation immediately via electron scattering - */ -#define DISK_ILLUM_ABSORB_AND_HEAT 2 /* Correct disk temperature for illumination by photons - which hit the dsik. Disk radiation is absorbed and changes - the temperature of the disk for future ionization cycles - */ -#define DISK_ILLUM_HEATED_BY_STAR 3 /* Correct disk temperature for illumination by star */ - - int disk_illum; /*Treatment of effects of illumination on the disk. - */ - - int disk_atmosphere; /* 0 --> no - 1 --> yes - */ - int disk_tprofile; /* This is an variable used to specify a standard accretion disk (0) or - one that has been read in and stored. */ - double disk_mdot; /* mdot of DISK */ + int disk_type; + +#define DISK_ILLUM_ABSORB_AND_DESTROY 0 /* Disk simply absorbs the radiation and it is lost */ +#define DISK_ILLUM_SCATTER 1 /* Disk reradiates the radiation immediately via electron scattering + */ +#define DISK_ILLUM_ABSORB_AND_HEAT 2 /* Correct disk temperature for illumination by photons + which hit the dsik. Disk radiation is absorbed and changes + the temperature of the disk for future ionization cycles + */ +#define DISK_ILLUM_HEATED_BY_STAR 3 /* Correct disk temperature for illumination by star */ + + int disk_illum; /*Treatment of effects of illumination on the disk. + */ + + int disk_atmosphere; /* 0 --> no + 1 --> yes + */ + int disk_tprofile; /* This is an variable used to specify a standard accretion disk (0) or + one that has been read in and stored. */ + double disk_mdot; /* mdot of DISK */ double diskrad, diskrad_sq; - double disk_z0, disk_z1; /* For vertically extended disk, z=disk_z0*(r/diskrad)**disk_z1 */ + double disk_z0, disk_z1; /* For vertically extended disk, z=disk_z0*(r/diskrad)**disk_z1 */ int run_type; /*1508 - New variable that describes whether this is a continuation of a previous run - Added in order to separate the question of whether we are continuing an old run fro - the type of wind model. Bascially if run_type is 0, this is a run from scratch, - if SYSTEM_TYPE_PREVIOUS it is an old run */ - int star_radiation, disk_radiation; /* 1 means consider radiation from star, disk, bl, and/or wind */ + Added in order to separate the question of whether we are continuing an old run fro + the type of wind model. Bascially if run_type is 0, this is a run from scratch, + if SYSTEM_TYPE_PREVIOUS it is an old run */ + int star_radiation, disk_radiation; /* 1 means consider radiation from star, disk, bl, and/or wind */ int bl_radiation, wind_radiation, agn_radiation; int search_light_radiation; /* 1605 - ksl - Added to implement 1d testing */ - int matom_radiation; /* Added by SS Jun 2004: for use in macro atom computations of detailed spectra - - 1 means use emissivities for BOTH macro atom levels and kpkts. 0 means don't - (which is correct for the ionization cycles. */ - int ioniz_mode; /* describes the type of ionization calculation which will - be carried out. 0=on the spot, 1=LTE, 2=fixed ionization - fractions, 3 means to recalculate the ionization structure - based on the energy absorbed in the wind (mod_on_the_spot), 4 - is a test. It is currently set to do the same as 3, except - that ground state mulitpliciites are used instead of - a partition function */ - int macro_ioniz_mode; /* Added by SS Apr04 to control the use of macro atom populations and - ionization fractions. If it is set to 1 then macro atom populations - computed from estimators are used. If set to 0 then the macro atom - populations are computed as for minor ions. By default it is set to - 0 initially in python.c and then set to 1 the first time that - Monte Carlo estimators are normalised. */ - int ioniz_or_extract; /* Set to 1 (true) during ionization cycles, set to 0 (false) during calculation of - detailed spectrum. Originally introduced by SS in July04 as he added - macro atoms. Name changed by ksl (57h) since this variable can be used more - generally to speed up the extract portion of the calculation. - */ - int macro_simple; /* Added by SS May04 for diagnostics. As default this is set to 0. A full - Macro Atom calculation is performed in that case. If it is set to 1 it means - that although Macro Atom data has been read in, all lines/continua are treated - using the simplified two-level approximation. Such a calculation should reproduce - the same results as pre-Macro Atom versions of the code. */ - int partition_mode; /* Diagnostic to force the partition function to be calculated in - a specific way. */ - int line_mode; /*0, the atomosphere is a completely absorbing and no photons - will be scattered. In this mode, assuming the wind is a source - of emission, the emissivity will be the Einstein A coefficient - 1, the atmosphere is completely scattering, there will be no - interchange of energy between the photons and the electrons - as a result of readiation transfer - 2, then a simple single scattering approximation is applied in which - case the scattered flux is just A21/(C21+A21). - 3, then radiation trapping is included as well. - 6, If set to 6 initially, this switches on the macro atom stuff - and then behaves like 3. (SS) - */ - int scatter_mode; /*The way in which scattering for resonance lines is treated - 0 isotropic - 1 anisotropic - 2 thermally broadened anisotropic - */ - - int rt_mode; /* radiative transfer mode. 2 for Macro Atom method, 1 for non-Macro Atom methods */ + int matom_radiation; /* Added by SS Jun 2004: for use in macro atom computations of detailed spectra + - 1 means use emissivities for BOTH macro atom levels and kpkts. 0 means don't + (which is correct for the ionization cycles. */ + int ioniz_mode; /* describes the type of ionization calculation which will + be carried out. 0=on the spot, 1=LTE, 2=fixed ionization + fractions, 3 means to recalculate the ionization structure + based on the energy absorbed in the wind (mod_on_the_spot), 4 + is a test. It is currently set to do the same as 3, except + that ground state mulitpliciites are used instead of + a partition function */ + int macro_ioniz_mode; /* Added by SS Apr04 to control the use of macro atom populations and + ionization fractions. If it is set to 1 then macro atom populations + computed from estimators are used. If set to 0 then the macro atom + populations are computed as for minor ions. By default it is set to + 0 initially in python.c and then set to 1 the first time that + Monte Carlo estimators are normalised. */ + int ioniz_or_extract; /* Set to 1 (true) during ionization cycles, set to 0 (false) during calculation of + detailed spectrum. Originally introduced by SS in July04 as he added + macro atoms. Name changed by ksl (57h) since this variable can be used more + generally to speed up the extract portion of the calculation. + */ + int macro_simple; /* Added by SS May04 for diagnostics. As default this is set to 0. A full + Macro Atom calculation is performed in that case. If it is set to 1 it means + that although Macro Atom data has been read in, all lines/continua are treated + using the simplified two-level approximation. Such a calculation should reproduce + the same results as pre-Macro Atom versions of the code. */ + int partition_mode; /* Diagnostic to force the partition function to be calculated in + a specific way. */ + int line_mode; /*0, the atomosphere is a completely absorbing and no photons + will be scattered. In this mode, assuming the wind is a source + of emission, the emissivity will be the Einstein A coefficient + 1, the atmosphere is completely scattering, there will be no + interchange of energy between the photons and the electrons + as a result of readiation transfer + 2, then a simple single scattering approximation is applied in which + case the scattered flux is just A21/(C21+A21). + 3, then radiation trapping is included as well. + 6, If set to 6 initially, this switches on the macro atom stuff + and then behaves like 3. (SS) + */ + int scatter_mode; /*The way in which scattering for resonance lines is treated + 0 isotropic + 1 anisotropic + 2 thermally broadened anisotropic + */ + + int rt_mode; /* radiative transfer mode. 2 for Macro Atom method, 1 for non-Macro Atom methods */ /* The frequency bands used when calculating parameters like a power law slope in limited regions. */ -#define NXBANDS 20 /* the maximum number of bands that can be defined */ +#define NXBANDS 20 /* the maximum number of bands that can be defined */ - int nxfreq; /* the number of bands actually used */ - double xfreq[NXBANDS + 1]; /* the band limits */ + int nxfreq; /* the number of bands actually used */ + double xfreq[NXBANDS + 1]; /* the band limits */ /* The next set pf variables assign a SPECTYPE (see above) for each possible source of radiation in a model. The value assigned can be different for - the ionization and detaled spectrum generation part of the code */ + the ionization and detaled spectrum generation part of the code */ - int star_ion_spectype, star_spectype; /* The type of spectrum used to create the continuum - for the star in the ionization and final spectrum calculation */ - int disk_ion_spectype, disk_spectype; /* Same as above but for the disk */ - int bl_ion_spectype, bl_spectype; /* Same as above but for the boundary layer */ - int agn_ion_spectype, agn_spectype; /* Same as above but for the AGN */ + int star_ion_spectype, star_spectype; /* The type of spectrum used to create the continuum + for the star in the ionization and final spectrum calculation */ + int disk_ion_spectype, disk_spectype; /* Same as above but for the disk */ + int bl_ion_spectype, bl_spectype; /* Same as above but for the boundary layer */ + int agn_ion_spectype, agn_spectype; /* Same as above but for the AGN */ int search_light_ion_spectype, search_light_spectype; /* Same as above but for the search_light. Created for 1d test */ - char model_list[NCOMPS][LINELENGTH]; /* The file which contains the model names and the associated values for the model */ + char model_list[NCOMPS][LINELENGTH]; /* The file which contains the model names and the associated values for the model */ - double mdot_norm; /*A normalization factor used in SV wind, and Knigge wind */ - int adiabatic; /*0-> Do not include adiabatic heating in calculating the cooling of the wind - 1-> Use adiabatic heating in calculating the cooling of the wind - */ - int auger_ionization; /*0 -> Do not include innershell photoionization /Auger effects; 1-> include them */ + double mdot_norm; /*A normalization factor used in SV wind, and Knigge wind */ + int adiabatic; /*0-> Do not include adiabatic heating in calculating the cooling of the wind + 1-> Use adiabatic heating in calculating the cooling of the wind + */ + int auger_ionization; /*0 -> Do not include innershell photoionization /Auger effects; 1-> include them */ /* Initial values for defining wind structure for a planar geometry. These are currently only used by balance and this may not be the best approach generally and depending on where this ends up. Some consolidation is desirable */ @@ -453,64 +453,64 @@ int nplasma, nmacro; /*The total number of cells in the plasma and macro structu double pl_t_r, pl_t_e, pl_w; double pl_nh; - double lum_tot, lum_star, lum_disk, lum_bl, lum_wind; /* The total luminosities of the disk, star, bl, & wind - are actually not used in a fundamental way in the program */ - double lum_agn; /*The total luminosity of the AGN or point source at the center */ - int pl_geometry; /* geometry of X-ray point source */ + double lum_tot, lum_star, lum_disk, lum_bl, lum_wind; /* The total luminosities of the disk, star, bl, & wind + are actually not used in a fundamental way in the program */ + double lum_agn; /*The total luminosity of the AGN or point source at the center */ + int pl_geometry; /* geometry of X-ray point source */ #define PL_GEOMETRY_SPHERE 0 #define PL_GEOMETRY_LAMP_POST 1 - double lamp_post_height; /* height of X-ray point source if lamp post */ + double lamp_post_height; /* height of X-ray point source if lamp post */ /* The next four variables added by nsh Apr 2012 to allow broken power law to match the cloudy table command */ - double agn_cltab_low; //break at which the low frequency power law ends - double agn_cltab_hi; //break at which the high frequency power law cuts in - double agn_cltab_low_alpha; //photon index for the low frequency end - double agn_cltab_hi_alpha; //photon index for the high frequency end + double agn_cltab_low; //break at which the low frequency power law ends + double agn_cltab_hi; //break at which the high frequency power law cuts in + double agn_cltab_low_alpha; //photon index for the low frequency end + double agn_cltab_hi_alpha; //photon index for the high frequency end - double lum_ff, lum_fb, lum_lines; /* The luminosity of the wind as a result of ff, fb, and line radiation */ - double lum_comp; /*1108 NSH The luminosity of the wind as a result of compton cooling */ - double lum_di; /* 1409 NSH The direct ionization luminosity */ - double lum_dr; /*1109 NSH The luminosity of the wind due to dielectronic recombination */ - double lum_adiabatic; /*1209 NSH The cooling of the wind due to adiabatic expansion */ - double heat_adiabatic; /*1307 NSH The heating of the wind due to adiabatic heating - split out from lum_adiabatic to get an accurate idea of whether it is important */ - double f_tot, f_star, f_disk, f_bl, f_agn, f_wind; /* The integrated specific L between a freq min and max which are - used to establish the fraction of photons of various types */ + double lum_ff, lum_fb, lum_lines; /* The luminosity of the wind as a result of ff, fb, and line radiation */ + double lum_comp; /*1108 NSH The luminosity of the wind as a result of compton cooling */ + double lum_di; /* 1409 NSH The direct ionization luminosity */ + double lum_dr; /*1109 NSH The luminosity of the wind due to dielectronic recombination */ + double lum_adiabatic; /*1209 NSH The cooling of the wind due to adiabatic expansion */ + double heat_adiabatic; /*1307 NSH The heating of the wind due to adiabatic heating - split out from lum_adiabatic to get an accurate idea of whether it is important */ + double f_tot, f_star, f_disk, f_bl, f_agn, f_wind; /* The integrated specific L between a freq min and max which are + used to establish the fraction of photons of various types */ /* These variables are copies of the lum variables above, and are only calculated during ionization cycles This is a bugfix for JM130621, windsave bug */ - double lum_ff_ioniz, lum_fb_ioniz, lum_lines_ioniz; + double lum_ff_ioniz, lum_fb_ioniz, lum_lines_ioniz; double lum_comp_ioniz; - double lum_di_ioniz; /* 1409 NSH The direct ionization luminosity */ - double lum_dr_ioniz; - double lum_adiabatic_ioniz; + double lum_di_ioniz; /* 1409 NSH The direct ionization luminosity */ + double lum_dr_ioniz; + double lum_adiabatic_ioniz; double lum_wind_ioniz, lum_star_ioniz, lum_disk_ioniz, lum_bl_ioniz, lum_tot_ioniz; - double f_matom, f_kpkt; /*Added by SS Jun 2004 - to be used in computations of detailed spectra - the - energy emitted in the band via k-packets and macro atoms respectively. */ + double f_matom, f_kpkt; /*Added by SS Jun 2004 - to be used in computations of detailed spectra - the + energy emitted in the band via k-packets and macro atoms respectively. */ // The next set of parameters relate to the secondary - double m_sec, q; /* Mass of the secondary, mass ratio of system */ - double period; /* Period of the systems in seconds */ - double a, l1, l2, phi; /* Separation of primary and secondary, distance of l1 from primary,phi at l1 */ - double l1_from_m2, r2_far; /* Distance to l1 from m2, distance to far side of secondary from primary */ - double r2_width; /* Maximum width of Roche surface of secondary in the plane of orbit */ + double m_sec, q; /* Mass of the secondary, mass ratio of system */ + double period; /* Period of the systems in seconds */ + double a, l1, l2, phi; /* Separation of primary and secondary, distance of l1 from primary,phi at l1 */ + double l1_from_m2, r2_far; /* Distance to l1 from m2, distance to far side of secondary from primary */ + double r2_width; /* Maximum width of Roche surface of secondary in the plane of orbit */ - double t_bl; /*temperature of the boundary layer */ - double weight; /*weight factor for photons/defined in define_phot */ + double t_bl; /*temperature of the boundary layer */ + double weight; /*weight factor for photons/defined in define_phot */ // The next set of parameters relate to the central source of an AGN - double brem_temp; /*The temperature of a bremsstrahlung source */ - double brem_alpha; /*The exponent of the nu term for a bremstrahlung source */ + double brem_temp; /*The temperature of a bremsstrahlung source */ + double brem_alpha; /*The exponent of the nu term for a bremstrahlung source */ - double pl_low_cutoff; /* accessible only in advanced mode- see #34. default to zero */ + double pl_low_cutoff; /* accessible only in advanced mode- see #34. default to zero */ - double alpha_agn; /*The power law index of a BH at the center of an AGN. Note that the luminosity - of the agn is elsewhere in the structure - */ - double const_agn; /*The constant for the Power law, there are lots of ways of defining the PL which is best? */ - double r_agn; /* radius of the "photosphere" of the BH in the AGN. */ - double d_agn; /* the distance to the agn - only used in balance to calculate the ioinsation fraction */ + double alpha_agn; /*The power law index of a BH at the center of an AGN. Note that the luminosity + of the agn is elsewhere in the structure + */ + double const_agn; /*The constant for the Power law, there are lots of ways of defining the PL which is best? */ + double r_agn; /* radius of the "photosphere" of the BH in the AGN. */ + double d_agn; /* the distance to the agn - only used in balance to calculate the ioinsation fraction */ //70i - nsh 111007 - put lum_ioniz and n_ioniz into the geo structure. This will allow a simple estimate of ionisation parameter to be computed; @@ -518,42 +518,45 @@ int nplasma, nmacro; /*The total number of cells in the plasma and macro structu double n_ioniz, lum_ioniz; // The next set of parameters describe the input datafiles that are read - char atomic_filename[132]; /* 54e -- The masterfile for the atomic data */ - char fixed_con_file[132]; /* 54e -- For fixed concentrations, the file specifying concentrations */ + char atomic_filename[132]; /* 54e -- The masterfile for the atomic data */ + char fixed_con_file[132]; /* 54e -- For fixed concentrations, the file specifying concentrations */ //Added by SWM for reverberation mapping - enum reverb_enum {REV_NONE=0, REV_PHOTON=1, REV_WIND=2, REV_MATOM=3} reverb; - enum reverb_vis_enum {REV_VIS_NONE=0, REV_VIS_VTK=1, REV_VIS_DUMP=2, REV_VIS_BOTH=3} reverb_vis; + enum reverb_enum + { REV_NONE = 0, REV_PHOTON = 1, REV_WIND = 2, REV_MATOM = 3 } reverb; + enum reverb_vis_enum + { REV_VIS_NONE = 0, REV_VIS_VTK = 1, REV_VIS_DUMP = 2, REV_VIS_BOTH = 3 + } reverb_vis; int reverb_wind_cycles; - int reverb_path_bins, reverb_angle_bins; //SWM - Number of bins for path arrays, vtk output angular bins - int reverb_dump_cells; //SWM - Number of cells to dump, list of cells to dump 'nwind' values - double *reverb_dump_x, *reverb_dump_z; //SWM - x & z values of the cells to dump - int reverb_lines, *reverb_line; //SWM - Number of lines to track, and array of line 'nres' values + int reverb_path_bins, reverb_angle_bins; //SWM - Number of bins for path arrays, vtk output angular bins + int reverb_dump_cells; //SWM - Number of cells to dump, list of cells to dump 'nwind' values + double *reverb_dump_x, *reverb_dump_z; //SWM - x & z values of the cells to dump + int reverb_lines, *reverb_line; //SWM - Number of lines to track, and array of line 'nres' values } geo; -#define NRINGS 301 /* The actual number of rings completely defined - is NRINGS-1 ... or from 0 to NRINGS-2. This is - because you need an outer radius...but the rest - of this element is not filled in. */ +#define NRINGS 301 /* The actual number of rings completely defined + is NRINGS-1 ... or from 0 to NRINGS-2. This is + because you need an outer radius...but the rest + of this element is not filled in. */ struct xdisk { - double r[NRINGS]; /* The inner radius of an annulus */ - double t[NRINGS]; /* The temperature at the middle of the annulus */ - double g[NRINGS]; /* The gravity at the middle of the annulus */ - double v[NRINGS]; /* The velocity at the middle of the annulus */ - double heat[NRINGS]; /* The total energy flux of photons hitting each annulus */ - double ave_freq[NRINGS]; /* The flux weighted average of frequency of photons hiiting each annulus */ - double w[NRINGS]; /* The radiative weight of the photons that hit the disk */ - double t_hit[NRINGS]; /* The effective T of photons hitting the disk */ - int nphot[NRINGS]; /*The number of photons created in each annulus */ - int nhit[NRINGS]; /*The number of photons which hit each annulus */ + double r[NRINGS]; /* The inner radius of an annulus */ + double t[NRINGS]; /* The temperature at the middle of the annulus */ + double g[NRINGS]; /* The gravity at the middle of the annulus */ + double v[NRINGS]; /* The velocity at the middle of the annulus */ + double heat[NRINGS]; /* The total energy flux of photons hitting each annulus */ + double ave_freq[NRINGS]; /* The flux weighted average of frequency of photons hiiting each annulus */ + double w[NRINGS]; /* The radiative weight of the photons that hit the disk */ + double t_hit[NRINGS]; /* The effective T of photons hitting the disk */ + int nphot[NRINGS]; /*The number of photons created in each annulus */ + int nhit[NRINGS]; /*The number of photons which hit each annulus */ } -disk, qdisk; /* disk defines zones in the disk which in a specified frequency band emit equal amounts - of radiation. qdisk stores the amount of heating of the disk as a result of - illumination by the star or wind. It's boundaries are fixed throughout a cycle */ +disk, qdisk; /* disk defines zones in the disk which in a specified frequency band emit equal amounts + of radiation. qdisk stores the amount of heating of the disk as a result of + illumination by the star or wind. It's boundaries are fixed throughout a cycle */ #define NBLMODEL 100 @@ -575,10 +578,10 @@ blmod; */ typedef struct wind_paths { - double* ad_path_flux; //Array[by frequency, then path] of total flux of photons with the given v&p - int* ai_path_num; //Array[by frequency, then path] of the number of photons in this bin - double d_flux, d_path; //Total flux, average path - int i_num; //Number of photons hitting this cell + double *ad_path_flux; //Array[by frequency, then path] of total flux of photons with the given v&p + int *ai_path_num; //Array[by frequency, then path] of the number of photons in this bin + double d_flux, d_path; //Total flux, average path + int i_num; //Number of photons hitting this cell } wind_paths_dummy, *Wind_Paths_Ptr; /* This structure defines the wind. The structure w is allocated in the main @@ -597,11 +600,11 @@ Note that most of the macro atom information is in a separate structure. This w done to make it easier to control the size of the entire structure 06jul-ksl */ -#define NIONIZ 5 /*The number of ions (normally H and He) for which one separately tracks ionization - and recombinations */ -#define LPDF 3 /*The number of bins into which the line luminosity is divided in the course pdf - created by total_line_emission - Reduced from 10 to 3 by SS for testing data with few lines. */ +#define NIONIZ 5 /*The number of ions (normally H and He) for which one separately tracks ionization + and recombinations */ +#define LPDF 3 /*The number of bins into which the line luminosity is divided in the course pdf + created by total_line_emission + Reduced from 10 to 3 by SS for testing data with few lines. */ /* 061104 -- 58b -- ksl -- Added definitions to characterize whether a cell is in the wind. */ @@ -619,33 +622,33 @@ and PART in whatever, as n and n+1 typedef struct wind { - int ndom; /*The domain associated with this element of the wind */ - int nwind; /*A self-reference to this cell in the wind structure */ - int nplasma; /*A cross refrence to the corresponding cell in the plasma structure */ - double x[3]; /*position of inner vertex of cell */ - double xcen[3]; /*position of the "center" of a cell (Added by ksl for 52a--04Aug) */ - double r, rcen; /*radial location of cell (Used for spherical, spherical polar - coordinates. (Added by ksl for 52a --04Aug) */ - double theta, thetacen; /*Angle of coordinate from z axis (Added by ksl for 52a -- 04Aug) */ - double dtheta,dr; /* widths of bins, used in hydro import mode*/ - struct cone wcone; /*56d -- cone structure that defines the bottom edge of the cell in - CYLVAR coordinates */ - double v[3]; /*velocity at inner vertex of cell. For 2d coordinate systems this - is defined in the xz plane */ - double v_grad[3][3]; /*velocity gradient tensor at the inner vertex of the cell NEW */ - double div_v; /*Divergence of v at center of cell */ - double dvds_ave; /* Average value of dvds */ - double dvds_max, lmn[3]; /*The maximum value of dvds, and the direction in a cell in cylindrical coords */ - double vol; /* valid volume of this cell (that is the volume of the cell that is considered - to be in the wind. This differs from the volume in the Plasma structure - where the volume is the volume that is actually filled with material. */ - double dfudge; /* A number which defines a push through distance for this cell, which replaces the - global variable DFUDGE in many instances */ + int ndom; /*The domain associated with this element of the wind */ + int nwind; /*A self-reference to this cell in the wind structure */ + int nplasma; /*A cross refrence to the corresponding cell in the plasma structure */ + double x[3]; /*position of inner vertex of cell */ + double xcen[3]; /*position of the "center" of a cell (Added by ksl for 52a--04Aug) */ + double r, rcen; /*radial location of cell (Used for spherical, spherical polar + coordinates. (Added by ksl for 52a --04Aug) */ + double theta, thetacen; /*Angle of coordinate from z axis (Added by ksl for 52a -- 04Aug) */ + double dtheta, dr; /* widths of bins, used in hydro import mode */ + struct cone wcone; /*56d -- cone structure that defines the bottom edge of the cell in + CYLVAR coordinates */ + double v[3]; /*velocity at inner vertex of cell. For 2d coordinate systems this + is defined in the xz plane */ + double v_grad[3][3]; /*velocity gradient tensor at the inner vertex of the cell NEW */ + double div_v; /*Divergence of v at center of cell */ + double dvds_ave; /* Average value of dvds */ + double dvds_max, lmn[3]; /*The maximum value of dvds, and the direction in a cell in cylindrical coords */ + double vol; /* valid volume of this cell (that is the volume of the cell that is considered + to be in the wind. This differs from the volume in the Plasma structure + where the volume is the volume that is actually filled with material. */ + double dfudge; /* A number which defines a push through distance for this cell, which replaces the + global variable DFUDGE in many instances */ enum inwind_enum - { W_IN_DISK=-5, W_IGNORE=-2, W_NOT_INWIND=-1, - W_ALL_INWIND=0, W_PART_INWIND=1 - } inwind; - Wind_Paths_Ptr paths, *line_paths; // SWM 6-2-15 Path data struct for each cell + { W_IN_DISK = -5, W_IGNORE = -2, W_NOT_INWIND = -1, + W_ALL_INWIND = 0, W_PART_INWIND = 1 + } inwind; + Wind_Paths_Ptr paths, *line_paths; // SWM 6-2-15 Path data struct for each cell } wind_dummy, *WindPtr; @@ -664,158 +667,158 @@ They are now pointers in the array. */ typedef struct plasma { - int nwind; /*A cross reference to the corresponding cell in the wind structure */ - int nplasma; /*A self reference to this in the plasma structure */ - double ne; /* electron density in the shell */ - double rho; /*density at the center of the cell. For clumped models, this is rho of the clump */ - double vol; /* volume of this cell (more specifically the volume that is filled with material - which can differe from the valid volume of the cell due to clumping. */ - double *density; /*The number density of a specific ion. This needs to correspond - to the ion order obtained by get_atomic_data. 78 - changed to dynamic allocation*/ - double *partition; /*The partition function for each ion. 78 - changed to dynamic allocation */ - double levden[NLTE_LEVELS]; /*The number density (occupation number?) of a specific level */ - - double *PWdenom; /*The denominator in the pairwise ionization solver. Sicne this is computed at a temperature - chosen from basic ioinzation proerties to be good for this ion, it should not change - very much from cycle to cycle - hence we shold be able to speed up the code by storing - it and refering to it if the temperature has not changed much. 78 - changed to dynamic allocation */ - double *PWdtemp; /*The temperature at which the pairwise denominator was calculated last. 78 - changed to dynamic allocation */ - double *PWnumer; /* The numberator in the pairwise approach. When we are chasing the true density - by carying n_e - this value will not change, so we canspeed things up a lot - by not recomputing it!. 78 - changed to dynamic allocation */ - double *PWntemp; /* The temperature at which the stored pairwise numerator was last computed at. This - is used in the BB version of the pairwise correction factor. 78 - changed to dynamic allocation */ - - double kappa_ff_factor; /* Multiplicative factor for calculating the FF heating for a photon. */ - - - double recomb_simple[NTOP_PHOT]; /* "alpha_e - alpha" (in Leon's notation) for b-f processes in simple atoms. */ + int nwind; /*A cross reference to the corresponding cell in the wind structure */ + int nplasma; /*A self reference to this in the plasma structure */ + double ne; /* electron density in the shell */ + double rho; /*density at the center of the cell. For clumped models, this is rho of the clump */ + double vol; /* volume of this cell (more specifically the volume that is filled with material + which can differe from the valid volume of the cell due to clumping. */ + double *density; /*The number density of a specific ion. This needs to correspond + to the ion order obtained by get_atomic_data. 78 - changed to dynamic allocation */ + double *partition; /*The partition function for each ion. 78 - changed to dynamic allocation */ + double levden[NLTE_LEVELS]; /*The number density (occupation number?) of a specific level */ + + double *PWdenom; /*The denominator in the pairwise ionization solver. Sicne this is computed at a temperature + chosen from basic ioinzation proerties to be good for this ion, it should not change + very much from cycle to cycle - hence we shold be able to speed up the code by storing + it and refering to it if the temperature has not changed much. 78 - changed to dynamic allocation */ + double *PWdtemp; /*The temperature at which the pairwise denominator was calculated last. 78 - changed to dynamic allocation */ + double *PWnumer; /* The numberator in the pairwise approach. When we are chasing the true density + by carying n_e - this value will not change, so we canspeed things up a lot + by not recomputing it!. 78 - changed to dynamic allocation */ + double *PWntemp; /* The temperature at which the stored pairwise numerator was last computed at. This + is used in the BB version of the pairwise correction factor. 78 - changed to dynamic allocation */ + + double kappa_ff_factor; /* Multiplicative factor for calculating the FF heating for a photon. */ + + + double recomb_simple[NTOP_PHOT]; /* "alpha_e - alpha" (in Leon's notation) for b-f processes in simple atoms. */ /* Begining of macro information */ - double kpkt_emiss; /*This is the specific emissivity due to the conversion k-packet -> r-packet in the cell - in the frequency range that is required for the final spectral synthesis. (SS) */ + double kpkt_emiss; /*This is the specific emissivity due to the conversion k-packet -> r-packet in the cell + in the frequency range that is required for the final spectral synthesis. (SS) */ - double kpkt_abs; /* k-packet equivalent of matom_abs. (SS) */ + double kpkt_abs; /* k-packet equivalent of matom_abs. (SS) */ - int kbf_use[NTOP_PHOT]; /* List of the indices of the photoionization processes to be used for kappa_bf. (SS) */ - int kbf_nuse; /* Total number of photoionization processes to be used for kappa_bf. (SS) */ + int kbf_use[NTOP_PHOT]; /* List of the indices of the photoionization processes to be used for kappa_bf. (SS) */ + int kbf_nuse; /* Total number of photoionization processes to be used for kappa_bf. (SS) */ /* End of macro information */ - double t_r, t_r_old; /*radiation temperature of cell */ - double t_e, t_e_old; /*electron temperature of cell */ - double dt_e, dt_e_old; /*How much t_e changed in the previous iteration */ - double heat_tot, heat_tot_old; /* heating from all sources */ + double t_r, t_r_old; /*radiation temperature of cell */ + double t_e, t_e_old; /*electron temperature of cell */ + double dt_e, dt_e_old; /*How much t_e changed in the previous iteration */ + double heat_tot, heat_tot_old; /* heating from all sources */ double heat_lines, heat_ff; - double heat_comp; /* 1108 NSH The compton heating for the cell */ - double heat_ind_comp; /* 1205 NSH The induced compton heatingfor the cell */ - double heat_lines_macro, heat_photo_macro; /* bb and bf heating due to macro atoms. Subset of heat_lines - and heat_photo. SS June 04. */ - double heat_photo, heat_z; /*photoionization heating total and of metals */ - double heat_auger; /* photoionization heating due to inner shell ionizations */ - double w; /*The dilution factor of the wind */ + double heat_comp; /* 1108 NSH The compton heating for the cell */ + double heat_ind_comp; /* 1205 NSH The induced compton heatingfor the cell */ + double heat_lines_macro, heat_photo_macro; /* bb and bf heating due to macro atoms. Subset of heat_lines + and heat_photo. SS June 04. */ + double heat_photo, heat_z; /*photoionization heating total and of metals */ + double heat_auger; /* photoionization heating due to inner shell ionizations */ + double w; /*The dilution factor of the wind */ - int ntot; /*Total number of photon passages */ + int ntot; /*Total number of photon passages */ /* counters of the number of photon passages by origin */ int ntot_star; int ntot_bl; - int ntot_disk; + int ntot_disk; int ntot_wind; - int ntot_agn; - - - int nscat_es; /* The number of electrons scatters in the cell */ - int nscat_res; /* The number of resonant line scatters in the cell */ - - double mean_ds; /* NSH 6/9/12 Added to allow a check that a thin shell is really optcially thin */ - int n_ds; /* NSH 6/9/12 Added to allow the mean dsto be computed */ - int nrad; /* Total number of photons radiated within the cell */ - int nioniz; /* Total number of photons capable of ionizing H */ - double *ioniz, *recomb; /* Number of ionizations and recombinations for each ion. - The sense is ionization from ion[n], and recombinations - to each ion[n] . 78 - changed to dynamic allocation*/ - int *scatters; /* 68b - The number of scatters in this cell for each ion. 78 - changed to dynamic allocation*/ - double *xscatters; /* 68b - Diagnostic measure of energy scattered out of beam on extract. 78 - changed to dynamic allocation */ - double *heat_ion; /* The amount of energy being transferred to the electron pool - sby this ion via photoionization. 78 - changed to dynamic allocation */ - double *lum_ion; /* The amount of energy being released from the electron pool - by this ion via recombination. 78 - changed to dynamic allocation */ - double j, ave_freq, lum; /*Respectively mean intensity, intensity_averaged frequency, - luminosity and absorbed luminosity of shell */ - double xj[NXBANDS], xave_freq[NXBANDS]; /* 1108 NSH frequency limited versions of j and ave_freq */ - double fmin[NXBANDS]; /* the minimum freqneucy photon seen in a band - this is incremented during photon flight */ - double fmax[NXBANDS]; /* the maximum frequency photon seen in a band - this is incremented during photon flight */ - double fmin_mod[NXBANDS]; /* the minimum freqneucy that the model should be applied for */ - double fmax_mod[NXBANDS]; /* the maximum frequency that the model should be applied for */ - - - - double j_direct,j_scatt; /* 1309 NSH mean intensity due to direct photons and scattered photons */ - double ip_direct,ip_scatt; /* 1309 NSH mean intensity due to direct photons and scattered photons */ - double xsd_freq[NXBANDS]; /*1208 NSH the standard deviation of the frequency in the band */ - int nxtot[NXBANDS]; /* 1108 NSH the total number of photon passages in frequency bands */ - double max_freq; /*1208 NSH The maximum frequency photon seen in this cell */ + int ntot_agn; + + + int nscat_es; /* The number of electrons scatters in the cell */ + int nscat_res; /* The number of resonant line scatters in the cell */ + + double mean_ds; /* NSH 6/9/12 Added to allow a check that a thin shell is really optcially thin */ + int n_ds; /* NSH 6/9/12 Added to allow the mean dsto be computed */ + int nrad; /* Total number of photons radiated within the cell */ + int nioniz; /* Total number of photons capable of ionizing H */ + double *ioniz, *recomb; /* Number of ionizations and recombinations for each ion. + The sense is ionization from ion[n], and recombinations + to each ion[n] . 78 - changed to dynamic allocation */ + int *scatters; /* 68b - The number of scatters in this cell for each ion. 78 - changed to dynamic allocation */ + double *xscatters; /* 68b - Diagnostic measure of energy scattered out of beam on extract. 78 - changed to dynamic allocation */ + double *heat_ion; /* The amount of energy being transferred to the electron pool + sby this ion via photoionization. 78 - changed to dynamic allocation */ + double *lum_ion; /* The amount of energy being released from the electron pool + by this ion via recombination. 78 - changed to dynamic allocation */ + double j, ave_freq, lum; /*Respectively mean intensity, intensity_averaged frequency, + luminosity and absorbed luminosity of shell */ + double xj[NXBANDS], xave_freq[NXBANDS]; /* 1108 NSH frequency limited versions of j and ave_freq */ + double fmin[NXBANDS]; /* the minimum freqneucy photon seen in a band - this is incremented during photon flight */ + double fmax[NXBANDS]; /* the maximum frequency photon seen in a band - this is incremented during photon flight */ + double fmin_mod[NXBANDS]; /* the minimum freqneucy that the model should be applied for */ + double fmax_mod[NXBANDS]; /* the maximum frequency that the model should be applied for */ + + + + double j_direct, j_scatt; /* 1309 NSH mean intensity due to direct photons and scattered photons */ + double ip_direct, ip_scatt; /* 1309 NSH mean intensity due to direct photons and scattered photons */ + double xsd_freq[NXBANDS]; /*1208 NSH the standard deviation of the frequency in the band */ + int nxtot[NXBANDS]; /* 1108 NSH the total number of photon passages in frequency bands */ + double max_freq; /*1208 NSH The maximum frequency photon seen in this cell */ double lum_lines, lum_ff, lum_adiabatic; - double lum_comp; /* 1108 NSH The compton luminosity of the cell */ - double lum_di; /* 1409 NSH The direct ionization luminosity */ - double lum_dr; /* 1109 NSH The dielectronic recombination luminosity of the cell */ - double lum_fb, lum_z; /*fb luminosity & fb of metals metals */ - double lum_rad, lum_rad_old; /* The specfic radiative luminosity in frequencies defined by freqmin - and freqmax. This will depend on the last call to total_emission */ + double lum_comp; /* 1108 NSH The compton luminosity of the cell */ + double lum_di; /* 1409 NSH The direct ionization luminosity */ + double lum_dr; /* 1109 NSH The dielectronic recombination luminosity of the cell */ + double lum_fb, lum_z; /*fb luminosity & fb of metals metals */ + double lum_rad, lum_rad_old; /* The specfic radiative luminosity in frequencies defined by freqmin + and freqmax. This will depend on the last call to total_emission */ double lum_ioniz; double lum_lines_ioniz, lum_ff_ioniz, lum_adiabatic_ioniz; - double lum_comp_ioniz; /* 1108 NSH The compton luminosity of the cell */ - double lum_di_ioniz; /* 1409 NSH The direct ionization luminosity */ - double lum_dr_ioniz; /* 1109 NSH The dielectronic recombination luminosity of the cell */ - double lum_fb_ioniz, lum_z_ioniz; /*fb luminosity & fb of metals metals */ - double lum_rad_ioniz; /* The specfic radiative luminosity in frequencies defined by freqmin - and freqmax. This will depend on the last call to total_emission */ - - - double dmo_dt[3]; /*Radiative force of wind */ - int npdf; /* The number of points actually used in the luminosity pdf */ - int pdf_x[LPDF]; /* The line numbers of *line_ptr which form the boundaries the luminosity pdf */ - double pdf_y[LPDF]; /* Where the pdf is stored -- values between 0 and 1 */ - double gain; /* The gain being used in interations of the structure */ - double converge_t_r, converge_t_e, converge_hc; /* Three measures of whether the program believes the grid is converged. - The first wo are the fraction changes in t_r, t_e between this and the last cycle. The third - number is the fraction between heating and cooling divided by the sum of the 2 */ - int trcheck, techeck, hccheck; /* NSH the individual convergence checks used to calculate converge_whole. Each of these values - is 0 if the fractional change or in the case of the last check error is less than a value, currently - set to 0.05. ksl 111126 -NSH 130725 - this number is now also used to say if the cell is over temperature - it is set to 2 in this case */ - int converge_whole, converging; /* converge_whole is the sum of the indvidual convergence checks. It is 0 if all of the - convergence checks indicated convergence.subroutine convergence feels point is converged, converging is an - indicator of whether the program thought the cell is on the way to convergence 0 implies converging */ - - - - double gamma_inshl[NAUGER]; /*MC estimator that will record the inner shell ionization rate - very similar to macro atom-style estimators */ + double lum_comp_ioniz; /* 1108 NSH The compton luminosity of the cell */ + double lum_di_ioniz; /* 1409 NSH The direct ionization luminosity */ + double lum_dr_ioniz; /* 1109 NSH The dielectronic recombination luminosity of the cell */ + double lum_fb_ioniz, lum_z_ioniz; /*fb luminosity & fb of metals metals */ + double lum_rad_ioniz; /* The specfic radiative luminosity in frequencies defined by freqmin + and freqmax. This will depend on the last call to total_emission */ + + + double dmo_dt[3]; /*Radiative force of wind */ + int npdf; /* The number of points actually used in the luminosity pdf */ + int pdf_x[LPDF]; /* The line numbers of *line_ptr which form the boundaries the luminosity pdf */ + double pdf_y[LPDF]; /* Where the pdf is stored -- values between 0 and 1 */ + double gain; /* The gain being used in interations of the structure */ + double converge_t_r, converge_t_e, converge_hc; /* Three measures of whether the program believes the grid is converged. + The first wo are the fraction changes in t_r, t_e between this and the last cycle. The third + number is the fraction between heating and cooling divided by the sum of the 2 */ + int trcheck, techeck, hccheck; /* NSH the individual convergence checks used to calculate converge_whole. Each of these values + is 0 if the fractional change or in the case of the last check error is less than a value, currently + set to 0.05. ksl 111126 + NSH 130725 - this number is now also used to say if the cell is over temperature - it is set to 2 in this case */ + int converge_whole, converging; /* converge_whole is the sum of the indvidual convergence checks. It is 0 if all of the + convergence checks indicated convergence.subroutine convergence feels point is converged, converging is an + indicator of whether the program thought the cell is on the way to convergence 0 implies converging */ + + + + double gamma_inshl[NAUGER]; /*MC estimator that will record the inner shell ionization rate - very similar to macro atom-style estimators */ /* 1108 Increase sim estimators to cover all of the bands */ /* 1208 Add parameters for an exponential representation, and a switch to say which we prefer. */ - enum spec_mod_type_enum - { - SPEC_MOD_PL=1, - SPEC_MOD_EXP=2, - SPEC_MOD_FAIL=-1 - } spec_mod_type[NXBANDS]; /* NSH 120817 A switch to say which type of representation we are using for this band in this cell. Negative means we have no useful representation, 0 means power law, 1 means exponential */ - - double pl_alpha[NXBANDS]; /*Computed spectral index for a power law spectrum representing this cell NSH 120817 - changed name from sim_alpha to PL_alpha */ -// double pl_w[NXBANDS]; /*This is the computed weight of a PL spectrum in this cell - not the same as the dilution factor NSH 120817 - changed name from sim_w to pl_w */ - double pl_log_w[NXBANDS]; /* NSH 131106 - this is the log version of the power law weight. It is in an attempt to allow very large values of alpha to work with the PL spectral model to avoide NAN problems. The pl_w version can be deleted once testing is complete */ - - - double exp_temp[NXBANDS]; /*NSH 120817 - The effective temperature of an exponential representation of the radiation field in a cell */ - double exp_w[NXBANDS]; /*NSH 120817 - The prefector of an exponential representation of the radiation field in a cell */ - double sim_ip; /*Ionisation parameter for the cell as defined in Sim etal 2010 */ - double ferland_ip; /* IP calculaterd from equation 5.4 in hazy1 - assuming allphotons come from 0,0,0 and the wind is transparent */ - double ip; /*NSH 111004 Ionization parameter calculated as number of photons over the lyman limit entering a cell, divided by the number density of hydrogen for the cell */ - double xi; /*NSH 151109 Ionization parameter as defined by Tartar et al 1969 and described in Hazy. Its the ionizing flux over the number of hydrogen atoms */ + enum spec_mod_type_enum + { + SPEC_MOD_PL = 1, + SPEC_MOD_EXP = 2, + SPEC_MOD_FAIL = -1 + } spec_mod_type[NXBANDS]; /* NSH 120817 A switch to say which type of representation we are using for this band in this cell. Negative means we have no useful representation, 0 means power law, 1 means exponential */ + + double pl_alpha[NXBANDS]; /*Computed spectral index for a power law spectrum representing this cell NSH 120817 - changed name from sim_alpha to PL_alpha */ +// double pl_w[NXBANDS]; /*This is the computed weight of a PL spectrum in this cell - not the same as the dilution factor NSH 120817 - changed name from sim_w to pl_w */ + double pl_log_w[NXBANDS]; /* NSH 131106 - this is the log version of the power law weight. It is in an attempt to allow very large values of alpha to work with the PL spectral model to avoide NAN problems. The pl_w version can be deleted once testing is complete */ + + + double exp_temp[NXBANDS]; /*NSH 120817 - The effective temperature of an exponential representation of the radiation field in a cell */ + double exp_w[NXBANDS]; /*NSH 120817 - The prefector of an exponential representation of the radiation field in a cell */ + double sim_ip; /*Ionisation parameter for the cell as defined in Sim etal 2010 */ + double ferland_ip; /* IP calculaterd from equation 5.4 in hazy1 - assuming allphotons come from 0,0,0 and the wind is transparent */ + double ip; /*NSH 111004 Ionization parameter calculated as number of photons over the lyman limit entering a cell, divided by the number density of hydrogen for the cell */ + double xi; /*NSH 151109 Ionization parameter as defined by Tartar et al 1969 and described in Hazy. Its the ionizing flux over the number of hydrogen atoms */ } plasma_dummy, *PlasmaPtr; PlasmaPtr plasmamain; @@ -828,7 +831,7 @@ the same procedure could be used for line photons */ #define NSTORE 10 typedef struct photon_store { - int n; /* This is the photon number that was last used */ + int n; /* This is the photon number that was last used */ double t, f1, f2, freq[NSTORE]; } photon_store_dummy, *PhotStorePtr; @@ -860,7 +863,7 @@ typedef struct macro double *gamma_e_old; double *alpha_st; - /* Same as gamma but for stimulated recombination rather than photoionisation. (SS)*/ + /* Same as gamma but for stimulated recombination rather than photoionisation. (SS) */ double *alpha_st_old; @@ -879,7 +882,7 @@ typedef struct macro /* This is the specific emissivity due to the de-activation of macro atoms in the cell in the frequency range that is required for the final spectral synthesis. (SS) */ - double *matom_abs; + double *matom_abs; /* This is the energy absorbed by the macro atom levels - recorded during the ionization cycles and used to get matom_emiss (SS) */ @@ -902,109 +905,109 @@ typedef struct macro MacroPtr macromain; -int xxxpdfwind; // When 1, line luminosity calculates pdf +int xxxpdfwind; // When 1, line luminosity calculates pdf int size_Jbar_est, size_gamma_est, size_alpha_est; -#define TMAX_FACTOR 1.5 /*Factor by which t_e can exceed - t_r in order for absorbed to - match emitted flux */ +#define TMAX_FACTOR 1.5 /*Factor by which t_e can exceed + t_r in order for absorbed to + match emitted flux */ #define TMIN 2000. /* ??? TMIN appears to be used both for the minimum temperature and for calculating the fraction of recombinations that go to the ground state. This looks like a problem ksl-98jul???? */ -#define TMAX 5e8/*NSH 130725 - this is the maximum temperature permitted - this was introduced following problems with adaibatically heated cells increasing forever. The value was suggested by DP as a sensible compton teperature for the PK05/P05 Zeus models.*/ +#define TMAX 5e8 /*NSH 130725 - this is the maximum temperature permitted - this was introduced following problems with adaibatically heated cells increasing forever. The value was suggested by DP as a sensible compton teperature for the PK05/P05 Zeus models. */ //These constants are used in the various routines which compute ionization state -#define SAHA 4.82907e15 /* 2* (2.*PI*MELEC*k)**1.5 / h**3 (Calculated in constants) */ -#define MAXITERATIONS 200 //The number of loops to do to try to converge in ne -#define FRACTIONAL_ERROR 0.03 //The change in n_e which causes a break out of the loop for ne -#define THETAMAX 1e4 //Used in initial calculation of n_e -#define MIN_TEMP 100. // ??? this is another minimum temperature - it is used as the minimum tempersture in (JM -- in what??) +#define SAHA 4.82907e15 /* 2* (2.*PI*MELEC*k)**1.5 / h**3 (Calculated in constants) */ +#define MAXITERATIONS 200 //The number of loops to do to try to converge in ne +#define FRACTIONAL_ERROR 0.03 //The change in n_e which causes a break out of the loop for ne +#define THETAMAX 1e4 //Used in initial calculation of n_e +#define MIN_TEMP 100. // ??? this is another minimum temperature - it is used as the minimum tempersture in (JM -- in what??) // these definitions are for various ionization modes -#define IONMODE_ML93_FIXTE 0 // Lucy Mazzali using existing t_e (no HC balance) -#define IONMODE_LTE 1 // LTE using t_r -#define IONMODE_FIXED 2 // Hardwired concentrations -#define IONMODE_ML93 3 // Lucy Mazzali -#define IONMODE_LTE_SIM 4 // LTE with SIM correction -#define IONMODE_PAIRWISE_ML93 6 // pairwise version of Lucy Mazzali -#define IONMODE_PAIRWISE_SPECTRALMODEL 7 // pariwise modeled J_nu approach -#define IONMODE_MATRIX_BB 8 // matrix solver BB model -#define IONMODE_MATRIX_SPECTRALMODEL 9 // matrix solver spectral model +#define IONMODE_ML93_FIXTE 0 // Lucy Mazzali using existing t_e (no HC balance) +#define IONMODE_LTE 1 // LTE using t_r +#define IONMODE_FIXED 2 // Hardwired concentrations +#define IONMODE_ML93 3 // Lucy Mazzali +#define IONMODE_LTE_SIM 4 // LTE with SIM correction +#define IONMODE_PAIRWISE_ML93 6 // pairwise version of Lucy Mazzali +#define IONMODE_PAIRWISE_SPECTRALMODEL 7 // pariwise modeled J_nu approach +#define IONMODE_MATRIX_BB 8 // matrix solver BB model +#define IONMODE_MATRIX_SPECTRALMODEL 9 // matrix solver spectral model // and the corresponding modes in nebular_concentrations -#define NEBULARMODE_TR 0 // LTE using t_r -#define NEBULARMODE_TE 1 // LTE using t_e -#define NEBULARMODE_ML93 2 // ML93 using correction -#define NEBULARMODE_NLTE_SIM 3 // Non_LTE with SS modification (Probably could be removed) -#define NEBULARMODE_LTE_GROUND 4 // A test mode which foces all levels to the GS (Probably could be removed) -#define NEBULARMODE_PAIRWISE_ML93 6 // pairwise ML93 -#define NEBULARMODE_PAIRWISE_SPECTRALMODEL 7 // pairwise spectral models -#define NEBULARMODE_MATRIX_BB 8 // matrix solver BB model -#define NEBULARMODE_MATRIX_SPECTRALMODEL 9 // matrix solver spectral model +#define NEBULARMODE_TR 0 // LTE using t_r +#define NEBULARMODE_TE 1 // LTE using t_e +#define NEBULARMODE_ML93 2 // ML93 using correction +#define NEBULARMODE_NLTE_SIM 3 // Non_LTE with SS modification (Probably could be removed) +#define NEBULARMODE_LTE_GROUND 4 // A test mode which foces all levels to the GS (Probably could be removed) +#define NEBULARMODE_PAIRWISE_ML93 6 // pairwise ML93 +#define NEBULARMODE_PAIRWISE_SPECTRALMODEL 7 // pairwise spectral models +#define NEBULARMODE_MATRIX_BB 8 // matrix solver BB model +#define NEBULARMODE_MATRIX_SPECTRALMODEL 9 // matrix solver spectral model typedef struct photon { - double x[3]; /* Vector containing position of packet */ - double lmn[3]; /*direction cosines of this packet */ - double freq, freq_orig; /* current and original frequency of this packet */ - double w,w_orig; /* current and original weight of this packet */ + double x[3]; /* Vector containing position of packet */ + double lmn[3]; /*direction cosines of this packet */ + double freq, freq_orig; /* current and original frequency of this packet */ + double w, w_orig; /* current and original weight of this packet */ double tau; - enum istat_enum - { - P_INWIND =0, //in wind, - P_SCAT =1, //in process of scattering, - P_ESCAPE =2, //Escaped to reach the universe, - P_HIT_STAR =3, //absorbed by photosphere of star, - P_HIT_DISK =7, //Banged into disk - P_ABSORB =6, //Photoabsorbed within wind - P_TOO_MANY_SCATTERS=4, //in wind after MAXSCAT scatters - P_ERROR =5, //Too many calls to translate without something happening - P_SEC =8, //Photon hit secondary - P_ADIABATIC =9 //records that a photon created a kpkt which was destroyed by adiabatic cooling - } istat; /*status of photon.*/ - - int nscat; /*number of scatterings */ - int nres; /*The line number in lin_ptr of last scatter or wind line creation. Continuum if > nlines. */ - int nnscat; /* Used for the thermal trapping model of - anisotropic scattering to carry the number of - scattering to "extract" when needed for wind - generated photons SS05. */ - int nrscat; /* number of resonance scatterings */ - int grid; /*grid position of the photon in the wind, if - the photon is in the wind. If the photon is not - in the wind, then -1 implies inside the wind cone and - -2 implies outside the wind */ + enum istat_enum + { + P_INWIND = 0, //in wind, + P_SCAT = 1, //in process of scattering, + P_ESCAPE = 2, //Escaped to reach the universe, + P_HIT_STAR = 3, //absorbed by photosphere of star, + P_HIT_DISK = 7, //Banged into disk + P_ABSORB = 6, //Photoabsorbed within wind + P_TOO_MANY_SCATTERS = 4, //in wind after MAXSCAT scatters + P_ERROR = 5, //Too many calls to translate without something happening + P_SEC = 8, //Photon hit secondary + P_ADIABATIC = 9 //records that a photon created a kpkt which was destroyed by adiabatic cooling + } istat; /*status of photon. */ + + int nscat; /*number of scatterings */ + int nres; /*The line number in lin_ptr of last scatter or wind line creation. Continuum if > nlines. */ + int nnscat; /* Used for the thermal trapping model of + anisotropic scattering to carry the number of + scattering to "extract" when needed for wind + generated photons SS05. */ + int nrscat; /* number of resonance scatterings */ + int grid; /*grid position of the photon in the wind, if + the photon is in the wind. If the photon is not + in the wind, then -1 implies inside the wind cone and + -2 implies outside the wind */ enum origin_enum - { PTYPE_STAR=0, - PTYPE_BL=1, - PTYPE_DISK=2, - PTYPE_WIND=3, - PTYPE_AGN=4, - PTYPE_STAR_MATOM=10, - PTYPE_BL_MATOM=11, - PTYPE_DISK_MATOM=12, - PTYPE_WIND_MATOM=13, - PTYPE_AGN_MATOM=14 - } origin; /* Where this photon originated. If the photon has - scattered it's "origin" may be changed to "wind".*/ - /* note that we add 10 to origin when processed by a macro-atom - which means we need these values in the enum list */ - int np; /*NSH 13/4/11 - an internal pointer to the photon number so - so we can write out details of where the photon goes */ - double path; /* SWM - Photon path length */ + { PTYPE_STAR = 0, + PTYPE_BL = 1, + PTYPE_DISK = 2, + PTYPE_WIND = 3, + PTYPE_AGN = 4, + PTYPE_STAR_MATOM = 10, + PTYPE_BL_MATOM = 11, + PTYPE_DISK_MATOM = 12, + PTYPE_WIND_MATOM = 13, + PTYPE_AGN_MATOM = 14 + } origin; /* Where this photon originated. If the photon has + scattered it's "origin" may be changed to "wind". */ + /* note that we add 10 to origin when processed by a macro-atom + which means we need these values in the enum list */ + int np; /*NSH 13/4/11 - an internal pointer to the photon number so + so we can write out details of where the photon goes */ + double path; /* SWM - Photon path length */ } p_dummy, *PhotPtr; -PhotPtr photmain; /* A pointer to all of the photons that have been created in a subcycle. Added to ease - breaking the main routine of python into separate rooutines for inputs and running the - program */ +PhotPtr photmain; /* A pointer to all of the photons that have been created in a subcycle. Added to ease + breaking the main routine of python into separate rooutines for inputs and running the + program */ /* minimum value for tau for p_escape_from_tau function- below this we set to p_escape_ to 1 */ @@ -1041,10 +1044,10 @@ basis_cartesian; #define MSPEC 7 -int nspectra; /* After create_spectrum, the number of elements allocated for s, or - alternatively the number of spectra one has to work with. Note that - general s[0],s[1] and s[2] are the escaping, scattered and absorbed photons, - while elements higher than this will contain spectra as seen by different observers */ +int nspectra; /* After create_spectrum, the number of elements allocated for s, or + alternatively the number of spectra one has to work with. Note that + general s[0],s[1] and s[2] are the escaping, scattered and absorbed photons, + while elements higher than this will contain spectra as seen by different observers */ int nscat[MAXSCAT + 1], nres[MAXSCAT + 1], nstat[NSTAT]; @@ -1053,31 +1056,31 @@ typedef struct spectrum { char name[40]; float freqmin, freqmax, dfreq; - float lfreqmin, lfreqmax, ldfreq; /* NSH 1302 - values for logarithmic spectra */ + float lfreqmin, lfreqmax, ldfreq; /* NSH 1302 - values for logarithmic spectra */ double lmn[3]; - double mmax, mmin; /* Used only in live or die situations, mmax=cos(angle-DANG_LIVE_OR_DIE) - and mmim=cos(angle+DANG_LIVE_OR_DIE). In actually defining this - one has to worry about signs and exactly whether you are above - or below the plane */ - double renorm; /* Factor used in Live or die option where it is 4*PI/domega; - 1.0 otherwise */ - int nphot[NSTAT]; /* Used to help define what happened to photons when trying to construct this - particular spectrum */ - int nscat; /* nscat>999 -> select everything - 0 < nscat < MAXScat select only those photons which have - scattered nscat times, number of scattering photons in spectrum, if nscat is negative - then all photons with more than |nscat| are included. */ - int top_bot; /* 0 ->select photons regardless of location - >0 -> select only photons whose "last" position is above the disk - <0 -> select only photons whose last position is below the disk */ - double x[3], r; /* The position and radius of a special region from which to extract spectra */ + double mmax, mmin; /* Used only in live or die situations, mmax=cos(angle-DANG_LIVE_OR_DIE) + and mmim=cos(angle+DANG_LIVE_OR_DIE). In actually defining this + one has to worry about signs and exactly whether you are above + or below the plane */ + double renorm; /* Factor used in Live or die option where it is 4*PI/domega; + 1.0 otherwise */ + int nphot[NSTAT]; /* Used to help define what happened to photons when trying to construct this + particular spectrum */ + int nscat; /* nscat>999 -> select everything + 0 < nscat < MAXScat select only those photons which have + scattered nscat times, number of scattering photons in spectrum, if nscat is negative + then all photons with more than |nscat| are included. */ + int top_bot; /* 0 ->select photons regardless of location + >0 -> select only photons whose "last" position is above the disk + <0 -> select only photons whose last position is below the disk */ + double x[3], r; /* The position and radius of a special region from which to extract spectra */ double f[NWAVE]; - double lf[NWAVE]; /* a second array to hole the extracted spectrum in log units */ - double lfreq[NWAVE]; /* We need to hold what freqeuncy intervals our logarithmic spectrum has been taken over */ + double lf[NWAVE]; /* a second array to hole the extracted spectrum in log units */ + double lfreq[NWAVE]; /* We need to hold what freqeuncy intervals our logarithmic spectrum has been taken over */ - double f_wind[NWAVE]; /* The spectrum of photons created in the wind or scattered in the wind. Created for - reflection studies but possible useful for other reasons as well. */ - double lf_wind[NWAVE]; /* The logarithmic version of this */ + double f_wind[NWAVE]; /* The spectrum of photons created in the wind or scattered in the wind. Created for + reflection studies but possible useful for other reasons as well. */ + double lf_wind[NWAVE]; /* The logarithmic version of this */ } spectrum_dummy, *SpecPtr; @@ -1094,7 +1097,7 @@ SpecPtr xxspec; */ int py_wind_min, py_wind_max, py_wind_delta, py_wind_project; -double *aaa; // A pointer to an array used by py_wind +double *aaa; // A pointer to an array used by py_wind /* This is the structure needed for a cumulative distribution function. The CDFs are generated from a function which is usually only proportional to the probability density @@ -1105,15 +1108,15 @@ properly create the CDF, this was added for python_43.2 */ typedef struct Pdf { - double x[NPDF + 1]; /* Positions for which the probability density - is calculated */ - double y[NPDF + 1]; /* The value of the CDF at x */ - double d[NPDF + 1]; /* 57i -- the rate of change of the probability - density at x */ - double limit1, limit2; /* Limits (running from 0 to 1) that define a portion - of the CDF to sample */ - double x1, x2; /* limits if they exist on what is returned */ - double norm; //The scaling factor which would renormalize the pdf + double x[NPDF + 1]; /* Positions for which the probability density + is calculated */ + double y[NPDF + 1]; /* The value of the CDF at x */ + double d[NPDF + 1]; /* 57i -- the rate of change of the probability + density at x */ + double limit1, limit2; /* Limits (running from 0 to 1) that define a portion + of the CDF to sample */ + double x1, x2; /* limits if they exist on what is returned */ + double norm; //The scaling factor which would renormalize the pdf } *PdfPtr, pdf_dummy; @@ -1122,16 +1125,16 @@ typedef struct Pdf an even occurs */ int itest, jtest; -char hubeny_list[132]; //Location of listing of files representing hubeny atmospheres +char hubeny_list[132]; //Location of listing of files representing hubeny atmospheres // Allow for a diagnostic file -FILE *epltptr; //TEST +FILE *epltptr; //TEST // diag_on_off is deprecated see #111, #120 -//int diag_on_off; // on is non-zero //TEST +//int diag_on_off; // on is non-zero //TEST /* These variables are stored or used by the routines for anisotropic scattering */ @@ -1165,12 +1168,12 @@ struct xbands double alpha[NBANDS]; double pl_const[NBANDS]; double min_fraction[NBANDS]; - double nat_fraction[NBANDS]; // The fraction of the accepted luminosity in this band + double nat_fraction[NBANDS]; // The fraction of the accepted luminosity in this band double used_fraction[NBANDS]; - double flux[NBANDS]; //The "luminosity" within a band + double flux[NBANDS]; //The "luminosity" within a band double weight[NBANDS]; int nphot[NBANDS]; - int nbands; // Actual number of bands in use + int nbands; // Actual number of bands in use } xband; @@ -1180,10 +1183,10 @@ xband; * assuming the array has been initialized, which can take a few minutes */ -#define NTEMPS 60 // The number of temperatures which are stored in each fbstruct - /* NSH this was increased from 30 to 60 to take account of 3 extra OOM - intemperature we wanted to have in fb */ -#define NFB 10 // The maximum number of frequency intervals for which the fb emission is calculated +#define NTEMPS 60 // The number of temperatures which are stored in each fbstruct + /* NSH this was increased from 30 to 60 to take account of 3 extra OOM + intemperature we wanted to have in fb */ +#define NFB 10 // The maximum number of frequency intervals for which the fb emission is calculated struct fbstruc { @@ -1192,9 +1195,9 @@ struct fbstruc } freebound[NFB]; -double xnrecomb[NIONS][NTEMPS]; // There is only one set of recombination coefficients +double xnrecomb[NIONS][NTEMPS]; // There is only one set of recombination coefficients double fb_t[NTEMPS]; -int nfb; // Actual number of freqency intervals calculated +int nfb; // Actual number of freqency intervals calculated //This is a new structure to contain the frequency range of the final spectrum @@ -1203,12 +1206,12 @@ int nfb; // Actual number of freqency intervals calculated //synthesis part of the code (SS June04). struct emiss_range { - double fmin, fmax; // min and max frequency required in the final spectrum + double fmin, fmax; // min and max frequency required in the final spectrum } em_rnge; -#include "version.h" /*54f -- Added so that version can be read directly */ +#include "version.h" /*54f -- Added so that version can be read directly */ #include "templates.h" #include "recipes.h" @@ -1219,11 +1222,11 @@ double kap_bf[NLEVELS]; // 12jun nsh - some commands to enable photon logging in given cells. There is also a pointer in the geo -FILE *pstatptr; //NSH 120601 - pointer to a diagnostic file that will contain photon data for given cells -int cell_phot_stats; //1=do it, 0=dont do it -#define NCSTAT 10 //The maximum number of cells we are going to log -int ncstat; // the actual number we are going to log -int ncell_stats[NCSTAT]; //the numbers of the cells we are going to log +FILE *pstatptr; //NSH 120601 - pointer to a diagnostic file that will contain photon data for given cells +int cell_phot_stats; //1=do it, 0=dont do it +#define NCSTAT 10 //The maximum number of cells we are going to log +int ncstat; // the actual number we are going to log +int ncell_stats[NCSTAT]; //the numbers of the cells we are going to log /* Added variables which count number of times two situations occur (See #91) */ @@ -1250,13 +1253,13 @@ struct advanced_modes int keep_photoabs; // keep photoabsorption in final spectrum int quit_after_inputs; // quit after inputs read in, testing mode int fixed_temp; // do not alter temperature from that set in the parameter file - int zeus_connect; // We are connecting to zeus, do not seek new temp and output a heating and cooling file + int zeus_connect; // We are connecting to zeus, do not seek new temp and output a heating and cooling file int rand_seed_usetime; // default random number seed is fixed, not based on time } modes; -FILE *optr; //pointer to a diagnostic file that will contain dvds information +FILE *optr; //pointer to a diagnostic file that will contain dvds information @@ -1268,11 +1271,11 @@ struct filenames char specsave[LINELENGTH]; // spec save filename char diag[LINELENGTH]; // diag file char diagfolder[LINELENGTH]; // diag folder - char old_windsave[LINELENGTH];// old windsave name + char old_windsave[LINELENGTH]; // old windsave name char input[LINELENGTH]; // input name if creating new pf file - char lwspec[LINELENGTH]; // log_spec_tot file name + char lwspec[LINELENGTH]; // log_spec_tot file name char wspec[LINELENGTH]; // spectot file name - char lwspec_wind[LINELENGTH]; // log_spec_tot filename for wind photons + char lwspec_wind[LINELENGTH]; // log_spec_tot filename for wind photons char wspec_wind[LINELENGTH]; // spectot filename for wind photons char disk[LINELENGTH]; // disk diag file name char tprofile[LINELENGTH]; // non standard tprofile fname @@ -1280,14 +1283,14 @@ struct filenames char windrad[LINELENGTH]; // wind rad file char spec[LINELENGTH]; // .spec file char spec_wind[LINELENGTH]; // .spec file for wind photons - char lspec[LINELENGTH]; // .spec file - char lspec_wind[LINELENGTH]; // .spec file for wind photons + char lspec[LINELENGTH]; // .spec file + char lspec_wind[LINELENGTH]; // .spec file for wind photons } files; - -#define NMAX_OPTIONS 20 + +#define NMAX_OPTIONS 20 /* these two variables are used by xdefine_phot() in photon_gen.c to set the mode for get_matom_f()in matom.c and tell it diff --git a/source/wind_updates2d.c b/source/wind_updates2d.c index 689c52720..1a789df82 100644 --- a/source/wind_updates2d.c +++ b/source/wind_updates2d.c @@ -133,8 +133,7 @@ WindPtr (w); /* the commbuffer needs to be larger enough to pack all variables in MPI_Pack and MPI_Unpack routines NSH 1407 - the NIONS changed to nions for the 12 arrays in plasma that are now dynamically allocated */ size_of_commbuffer = - 8 * (12 * nions + NLTE_LEVELS + 2 * NTOP_PHOT + 12 * NXBANDS + - 2 * LPDF + NAUGER + 106) * (floor (NPLASMA / np_mpi_global) + 1); + 8 * (12 * nions + NLTE_LEVELS + 2 * NTOP_PHOT + 12 * NXBANDS + 2 * LPDF + NAUGER + 106) * (floor (NPLASMA / np_mpi_global) + 1); commbuffer = (char *) malloc (size_of_commbuffer * sizeof (char)); /* JM 1409 -- Initialise parallel only variables */ @@ -159,873 +158,470 @@ WindPtr (w); /* this section distributes the remainder over the threads if the cells do not divide evenly by thread */ if (rank_global < num_mpi_extra) - { - my_nmin = rank_global * (num_mpi_cells + 1); - my_nmax = (rank_global + 1) * (num_mpi_cells + 1); - } + { + my_nmin = rank_global * (num_mpi_cells + 1); + my_nmax = (rank_global + 1) * (num_mpi_cells + 1); + } else - { - my_nmin = - num_mpi_extra * (num_mpi_cells + 1) + (rank_global - - num_mpi_extra) * - (num_mpi_cells); - my_nmax = - num_mpi_extra * (num_mpi_cells + 1) + (rank_global - - num_mpi_extra + - 1) * (num_mpi_cells); - } + { + my_nmin = num_mpi_extra * (num_mpi_cells + 1) + (rank_global - num_mpi_extra) * (num_mpi_cells); + my_nmax = num_mpi_extra * (num_mpi_cells + 1) + (rank_global - num_mpi_extra + 1) * (num_mpi_cells); + } ndo = my_nmax - my_nmin; #endif /* Before we do anything let's record the average tr and te from the last cycle */ /* JM 1409 -- Added for issue #110 to ensure correct reporting in parallel */ for (n = 0; n < NPLASMA; n++) - { - t_r_ave_old += plasmamain[n].t_r; - t_e_ave_old += plasmamain[n].t_e; - } + { + t_r_ave_old += plasmamain[n].t_r; + t_e_ave_old += plasmamain[n].t_e; + } /* we now know how many cells this thread has to process - note this will be 0-NPLASMA in serial mode */ for (n = my_nmin; n < my_nmax; n++) + { + + + nwind = plasmamain[n].nwind; + volume = w[nwind].vol; + + //volume = plasmamain[n].vol; // 1411 JM -- we want volume to be the filled volume + //1504 -- JM No we don't! The mean intensity shouldn't change if we *just* clump + + + /* Start with a call to the routine which normalises all the macro atom + monte carlo radiation field estimators. It's best to do this first since + some of the estimators include temperature terms (stimulated correction + terms) which were included during the monte carlo simulation so we want + to be sure that the SAME temperatures are used here. (SS - Mar 2004). */ + + if (geo.rt_mode == 2 && geo.macro_simple == 0) //test for macro atoms { + mc_estimator_normalise (nwind); + macromain[n].kpkt_rates_known = -1; + } + /* Store some information so one can determine how much the temps are changing */ + t_r_old = plasmamain[n].t_r; + t_e_old = plasmamain[n].t_e; + iave++; - nwind = plasmamain[n].nwind; - volume = w[nwind].vol; + if (plasmamain[n].ntot < 100) + { + Log + ("!!wind_update: Cell %4d Dom %d Vol. %8.2e r %8.2e theta %8.2e has only %4d photons\n", + n, w[nwind].ndom, volume, w[nwind].rcen, w[nwind].thetacen, plasmamain[n].ntot); + } - //volume = plasmamain[n].vol; // 1411 JM -- we want volume to be the filled volume - //1504 -- JM No we don't! The mean intensity shouldn't change if we *just* clump + if (plasmamain[n].ntot > 0) + { + wtest = plasmamain[n].ave_freq; + plasmamain[n].ave_freq /= plasmamain[n].j; /* Normalization to frequency moment */ + if (sane_check (plasmamain[n].ave_freq)) + { + Error ("wind_update:sane_check %d ave_freq %e j %e ntot %d\n", n, wtest, plasmamain[n].j, plasmamain[n].ntot); + } + plasmamain[n].j /= (4. * PI * volume); //Factor of 2 has been removed from this line (SS, May04) + plasmamain[n].j_direct /= (4. * PI * volume); + plasmamain[n].j_scatt /= (4. * PI * volume); - /* Start with a call to the routine which normalises all the macro atom - monte carlo radiation field estimators. It's best to do this first since - some of the estimators include temperature terms (stimulated correction - terms) which were included during the monte carlo simulation so we want - to be sure that the SAME temperatures are used here. (SS - Mar 2004). */ - if (geo.rt_mode == 2 && geo.macro_simple == 0) //test for macro atoms - { - mc_estimator_normalise (nwind); - macromain[n].kpkt_rates_known = -1; - } - /* Store some information so one can determine how much the temps are changing */ - t_r_old = plasmamain[n].t_r; - t_e_old = plasmamain[n].t_e; - iave++; + trad = plasmamain[n].t_r = H * plasmamain[n].ave_freq / (BOLTZMANN * 3.832); + plasmamain[n].w = PI * plasmamain[n].j / (STEFAN_BOLTZMANN * trad * trad * trad * trad); - if (plasmamain[n].ntot < 100) - { - Log - ("!!wind_update: Cell %4d Dom %d Vol. %8.2e r %8.2e theta %8.2e has only %4d photons\n", - n, w[nwind].ndom, volume, w[nwind].rcen, w[nwind].thetacen, - plasmamain[n].ntot); - } - if (plasmamain[n].ntot > 0) - { - wtest = plasmamain[n].ave_freq; - plasmamain[n].ave_freq /= plasmamain[n].j; /* Normalization to frequency moment */ - if (sane_check (plasmamain[n].ave_freq)) - { - Error - ("wind_update:sane_check %d ave_freq %e j %e ntot %d\n", - n, wtest, plasmamain[n].j, plasmamain[n].ntot); - } - - plasmamain[n].j /= (4. * PI * volume); //Factor of 2 has been removed from this line (SS, May04) - plasmamain[n].j_direct /= (4. * PI * volume); - plasmamain[n].j_scatt /= (4. * PI * volume); - - - - trad = plasmamain[n].t_r = - H * plasmamain[n].ave_freq / (BOLTZMANN * 3.832); - plasmamain[n].w = - PI * plasmamain[n].j / (STEFAN_BOLTZMANN * trad * trad * - trad * trad); - - - if (plasmamain[n].w > 1e10) - { - Error - ("wind_update: Huge w %8.2e in cell %d trad %10.2e j %8.2e\n", - plasmamain[n].w, n, trad, plasmamain[n].j); - } - if (sane_check (trad) || sane_check (plasmamain[n].w)) - { - Error ("wind_update:sane_check %d trad %8.2e w %8.2g\n", n, - trad, plasmamain[n].w); - Error ("wind_update: ave_freq %8.2e j %8.2e\n", - plasmamain[n].ave_freq, plasmamain[n].j); - exit (0); - } - } - else - { // It is not clear what to do with no photons in a cell - - plasmamain[n].j = plasmamain[n].j_direct = - plasmamain[n].j_scatt = 0; - trad = plasmamain[n].t_r; - plasmamain[n].t_e *= 0.7; - if (plasmamain[n].t_e < TMIN) - plasmamain[n].t_e = TMIN; - plasmamain[n].w = 0; - } + if (plasmamain[n].w > 1e10) + { + Error ("wind_update: Huge w %8.2e in cell %d trad %10.2e j %8.2e\n", plasmamain[n].w, n, trad, plasmamain[n].j); + } + if (sane_check (trad) || sane_check (plasmamain[n].w)) + { + Error ("wind_update:sane_check %d trad %8.2e w %8.2g\n", n, trad, plasmamain[n].w); + Error ("wind_update: ave_freq %8.2e j %8.2e\n", plasmamain[n].ave_freq, plasmamain[n].j); + exit (0); + } + } + else + { // It is not clear what to do with no photons in a cell + + plasmamain[n].j = plasmamain[n].j_direct = plasmamain[n].j_scatt = 0; + trad = plasmamain[n].t_r; + plasmamain[n].t_e *= 0.7; + if (plasmamain[n].t_e < TMIN) + plasmamain[n].t_e = TMIN; + plasmamain[n].w = 0; + } - /* 1108 NSH/KSL This loop is to calculate the frequency banded j and ave_freq variables */ + /* 1108 NSH/KSL This loop is to calculate the frequency banded j and ave_freq variables */ - /* 71 - 111279 - ksl - Small modification to reflect the fact that nxfreq has been moved into the geo structure */ - for (i = 0; i < geo.nxfreq; i++) - { /*loop over number of bands */ - if (plasmamain[n].nxtot[i] > 0) - { /*Check we actually have some photons in the cell in this band */ - - plasmamain[n].xave_freq[i] /= plasmamain[n].xj[i]; /*Normalise the average frequency */ - plasmamain[n].xsd_freq[i] /= plasmamain[n].xj[i]; /*Normalise the mean square frequency */ - plasmamain[n].xsd_freq[i] = sqrt (plasmamain[n].xsd_freq[i] - (plasmamain[n].xave_freq[i] * plasmamain[n].xave_freq[i])); /*Compute standard deviation */ - plasmamain[n].xj[i] /= (4 * PI * volume); /*Convert to radiation density */ - - } - else - { - plasmamain[n].xj[i] = 0; /*If no photons, set both radiation estimators to zero */ - plasmamain[n].xave_freq[i] = 0; - plasmamain[n].xsd_freq[i] = 0; /*NSH 120815 and also the SD ???? */ - } - } + /* 71 - 111279 - ksl - Small modification to reflect the fact that nxfreq has been moved into the geo structure */ + for (i = 0; i < geo.nxfreq; i++) + { /*loop over number of bands */ + if (plasmamain[n].nxtot[i] > 0) + { /*Check we actually have some photons in the cell in this band */ + + plasmamain[n].xave_freq[i] /= plasmamain[n].xj[i]; /*Normalise the average frequency */ + plasmamain[n].xsd_freq[i] /= plasmamain[n].xj[i]; /*Normalise the mean square frequency */ + plasmamain[n].xsd_freq[i] = sqrt (plasmamain[n].xsd_freq[i] - (plasmamain[n].xave_freq[i] * plasmamain[n].xave_freq[i])); /*Compute standard deviation */ + plasmamain[n].xj[i] /= (4 * PI * volume); /*Convert to radiation density */ + + } + else + { + plasmamain[n].xj[i] = 0; /*If no photons, set both radiation estimators to zero */ + plasmamain[n].xave_freq[i] = 0; + plasmamain[n].xsd_freq[i] = 0; /*NSH 120815 and also the SD ???? */ + } + } /* 1108 NSH End of loop */ - nh = plasmamain[n].rho * rho2nh; + nh = plasmamain[n].rho * rho2nh; /* 1110 NSH Normalise IP, which at this point should be the number of photons in a cell by dividing by volume and number density of hydrogen in the cell */ - plasmamain[n].ip /= (C * volume * nh); - plasmamain[n].ip_direct /= (C * volume * nh); - plasmamain[n].ip_scatt /= (C * volume * nh); + plasmamain[n].ip /= (C * volume * nh); + plasmamain[n].ip_direct /= (C * volume * nh); + plasmamain[n].ip_scatt /= (C * volume * nh); /* 1510 NSH Normalise xi, which at this point should be the luminosity of ionizing photons in a cell (just the sum of photon weights) */ - plasmamain[n].xi *= 4. * PI; - plasmamain[n].xi /= (volume * nh); - - /* If geo.adiabatic is true, then alculate the adiabatic cooling using the current, i.e - * previous value of t_e. Note that this may not be best way to determien the cooling. - * Changes made here should also be reflected in wind2d.c. At present, adiabatic colling - * is not included in updates to the temperature, even if the adiabatic cooling is calculated - * here. 04nov -- ksl - * 05apr -- ksl -- The index being used was incorrect. This has been fixed now - * 11sep -- nsh -- The index for the wind (&w) for adiabatic cooling was incorrect - - * was being called with the plasma cell rather than the approriate wind cell - fixed - * old: adiabatic_cooling (&w[n], plasmamain[n].t_e); - */ - - if (geo.adiabatic) - plasmamain[n].lum_adiabatic = - adiabatic_cooling (&w[nwind], plasmamain[n].t_e); - else - plasmamain[n].lum_adiabatic = 0.0; + plasmamain[n].xi *= 4. * PI; + plasmamain[n].xi /= (volume * nh); + /* If geo.adiabatic is true, then alculate the adiabatic cooling using the current, i.e + * previous value of t_e. Note that this may not be best way to determien the cooling. + * Changes made here should also be reflected in wind2d.c. At present, adiabatic colling + * is not included in updates to the temperature, even if the adiabatic cooling is calculated + * here. 04nov -- ksl + * 05apr -- ksl -- The index being used was incorrect. This has been fixed now + * 11sep -- nsh -- The index for the wind (&w) for adiabatic cooling was incorrect - + * was being called with the plasma cell rather than the approriate wind cell - fixed + * old: adiabatic_cooling (&w[n], plasmamain[n].t_e); + */ - /* Calculate the densities in various ways depending on the ioniz_mode */ + if (geo.adiabatic) + plasmamain[n].lum_adiabatic = adiabatic_cooling (&w[nwind], plasmamain[n].t_e); + else + plasmamain[n].lum_adiabatic = 0.0; - ion_abundances (&plasmamain[n], geo.ioniz_mode); + /* Calculate the densities in various ways depending on the ioniz_mode */ + ion_abundances (&plasmamain[n], geo.ioniz_mode); - /* Perform checks to see how much temperatures have changed in this iteration */ - if ((fabs (t_r_old - plasmamain[n].t_r)) > fabs (dt_r)) - { - dt_r = plasmamain[n].t_r - t_r_old; - nmax_r = n; - } - if ((fabs (t_e_old - plasmamain[n].t_e)) > fabs (dt_e)) - { - dt_e = plasmamain[n].t_e - t_e_old; - nmax_e = n; - } - t_r_ave += plasmamain[n].t_r; - t_e_ave += plasmamain[n].t_e; + + /* Perform checks to see how much temperatures have changed in this iteration */ + + if ((fabs (t_r_old - plasmamain[n].t_r)) > fabs (dt_r)) + { + dt_r = plasmamain[n].t_r - t_r_old; + nmax_r = n; + } + if ((fabs (t_e_old - plasmamain[n].t_e)) > fabs (dt_e)) + { + dt_e = plasmamain[n].t_e - t_e_old; + nmax_e = n; } + t_r_ave += plasmamain[n].t_r; + t_e_ave += plasmamain[n].t_e; + } /*This is the end of the update loop that is parallised. We now need to exchange data between the tasks. */ #ifdef MPI_ON for (n_mpi = 0; n_mpi < np_mpi_global; n_mpi++) - { - position = 0; + { + position = 0; - if (rank_global == n_mpi) - { - Log - ("MPI task %d is working on cells %d to max %d (total size %d).\n", - rank_global, my_nmin, my_nmax, NPLASMA); - MPI_Pack (&ndo, 1, MPI_INT, commbuffer, size_of_commbuffer, - &position, MPI_COMM_WORLD); - for (n = my_nmin; n < my_nmax; n++) - { - MPI_Pack (&n, 1, MPI_INT, commbuffer, size_of_commbuffer, - &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].nwind, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].nplasma, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ne, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].rho, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].vol, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].density, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].partition, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].levden, NLTE_LEVELS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].PWdenom, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].PWdtemp, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].PWnumer, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].PWntemp, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].kappa_ff_factor, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].nscat_es, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].recomb_simple, NTOP_PHOT, - MPI_DOUBLE, commbuffer, size_of_commbuffer, - &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].kpkt_emiss, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].kpkt_abs, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].kbf_use, NTOP_PHOT, MPI_INT, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].kbf_nuse, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].t_r, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].t_r_old, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].t_e, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].t_e_old, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].dt_e, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].dt_e_old, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_tot, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_tot_old, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_lines, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_ff, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_comp, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_ind_comp, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_lines_macro, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_photo_macro, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_photo, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_auger, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].heat_z, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].w, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot_star, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot_bl, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot_disk, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot_wind, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ntot_agn, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].mean_ds, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].n_ds, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].nrad, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].nioniz, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].ioniz, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].recomb, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].scatters, nions, MPI_INT, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].xscatters, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].heat_ion, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].lum_ion, nions, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].j, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].j_direct, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].j_scatt, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ave_freq, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].xj, NXBANDS, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].xave_freq, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].xsd_freq, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].nxtot, NXBANDS, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].max_freq, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_lines, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_ff, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_adiabatic, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_comp, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_dr, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_di, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_fb, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_z, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_rad, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_rad_old, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_lines_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_ff_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_adiabatic_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_comp_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_dr_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_di_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_fb_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_z_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].lum_rad_ioniz, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].dmo_dt, 3, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].npdf, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].pdf_x, LPDF, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].pdf_y, LPDF, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].gain, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].converge_t_r, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].converge_t_e, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].converge_hc, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].trcheck, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].techeck, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].hccheck, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].converge_whole, 1, MPI_INT, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].converging, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].gamma_inshl, NAUGER, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].spec_mod_type, NXBANDS, MPI_INT, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].pl_alpha, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].pl_log_w, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].exp_temp, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].exp_w, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].fmin_mod, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (plasmamain[n].fmax_mod, NXBANDS, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].sim_ip, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ferland_ip, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ip, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ip_direct, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].ip_scatt, 1, MPI_DOUBLE, - commbuffer, size_of_commbuffer, &position, - MPI_COMM_WORLD); - MPI_Pack (&plasmamain[n].xi, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&dt_e, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&dt_r, 1, MPI_DOUBLE, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&nmax_e, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - MPI_Pack (&nmax_r, 1, MPI_INT, commbuffer, - size_of_commbuffer, &position, MPI_COMM_WORLD); - } - - Log ("MPI task %d broadcasting plasma update information.\n", - rank_global); - } + if (rank_global == n_mpi) + { + Log ("MPI task %d is working on cells %d to max %d (total size %d).\n", rank_global, my_nmin, my_nmax, NPLASMA); + MPI_Pack (&ndo, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + for (n = my_nmin; n < my_nmax; n++) + { + MPI_Pack (&n, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].nwind, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].nplasma, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ne, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].rho, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].vol, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].density, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].partition, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].levden, NLTE_LEVELS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].PWdenom, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].PWdtemp, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].PWnumer, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].PWntemp, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].kappa_ff_factor, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].nscat_es, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].recomb_simple, NTOP_PHOT, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].kpkt_emiss, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].kpkt_abs, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].kbf_use, NTOP_PHOT, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].kbf_nuse, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].t_r, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].t_r_old, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].t_e, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].t_e_old, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].dt_e, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].dt_e_old, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_tot, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_tot_old, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_lines, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_ff, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_comp, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_ind_comp, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_lines_macro, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_photo_macro, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_photo, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_auger, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].heat_z, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].w, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot_star, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot_bl, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot_disk, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot_wind, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ntot_agn, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].mean_ds, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].n_ds, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].nrad, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].nioniz, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].ioniz, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].recomb, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].scatters, nions, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].xscatters, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].heat_ion, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].lum_ion, nions, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].j, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].j_direct, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].j_scatt, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ave_freq, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].xj, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].xave_freq, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].xsd_freq, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].nxtot, NXBANDS, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].max_freq, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_lines, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_ff, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_adiabatic, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_comp, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_dr, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_di, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_fb, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_z, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_rad, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_rad_old, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_lines_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_ff_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_adiabatic_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_comp_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_dr_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_di_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_fb_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_z_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].lum_rad_ioniz, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].dmo_dt, 3, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].npdf, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].pdf_x, LPDF, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].pdf_y, LPDF, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].gain, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].converge_t_r, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].converge_t_e, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].converge_hc, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].trcheck, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].techeck, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].hccheck, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].converge_whole, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].converging, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].gamma_inshl, NAUGER, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].spec_mod_type, NXBANDS, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].pl_alpha, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].pl_log_w, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].exp_temp, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].exp_w, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].fmin_mod, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (plasmamain[n].fmax_mod, NXBANDS, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].sim_ip, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ferland_ip, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ip, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ip_direct, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].ip_scatt, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&plasmamain[n].xi, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&dt_e, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&dt_r, 1, MPI_DOUBLE, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&nmax_e, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + MPI_Pack (&nmax_r, 1, MPI_INT, commbuffer, size_of_commbuffer, &position, MPI_COMM_WORLD); + } + + Log ("MPI task %d broadcasting plasma update information.\n", rank_global); + } - MPI_Barrier (MPI_COMM_WORLD); - MPI_Bcast (commbuffer, size_of_commbuffer, MPI_PACKED, n_mpi, - MPI_COMM_WORLD); - MPI_Barrier (MPI_COMM_WORLD); - Log ("MPI task %d survived broadcasting plasma update information.\n", - rank_global); + MPI_Barrier (MPI_COMM_WORLD); + MPI_Bcast (commbuffer, size_of_commbuffer, MPI_PACKED, n_mpi, MPI_COMM_WORLD); + MPI_Barrier (MPI_COMM_WORLD); + Log ("MPI task %d survived broadcasting plasma update information.\n", rank_global); - position = 0; + position = 0; - if (rank_global != n_mpi) + if (rank_global != n_mpi) + { + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &num_comm, 1, MPI_INT, MPI_COMM_WORLD); + for (n_mpi2 = 0; n_mpi2 < num_comm; n_mpi2++) + { + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &n, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].nwind, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].nplasma, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ne, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].rho, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].vol, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].density, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].partition, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].levden, NLTE_LEVELS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].PWdenom, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].PWdtemp, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].PWnumer, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].PWntemp, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].kappa_ff_factor, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].nscat_es, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].recomb_simple, NTOP_PHOT, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].kpkt_emiss, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].kpkt_abs, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].kbf_use, NTOP_PHOT, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].kbf_nuse, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].t_r, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].t_r_old, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].t_e, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].t_e_old, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].dt_e, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].dt_e_old, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_tot, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_tot_old, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_lines, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_ff, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_comp, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_ind_comp, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_lines_macro, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_photo_macro, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_photo, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_auger, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].heat_z, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].w, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot_star, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot_bl, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot_disk, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot_wind, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ntot_agn, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].mean_ds, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].n_ds, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].nrad, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].nioniz, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].ioniz, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].recomb, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].scatters, nions, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].xscatters, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].heat_ion, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].lum_ion, nions, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].j, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].j_direct, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].j_scatt, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ave_freq, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].xj, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].xave_freq, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].xsd_freq, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].nxtot, NXBANDS, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].max_freq, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_lines, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_ff, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_adiabatic, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_comp, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_dr, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_di, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_fb, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_z, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_rad, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_rad_old, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_lines_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_ff_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_adiabatic_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_comp_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_dr_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_di_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_fb_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_z_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].lum_rad_ioniz, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].dmo_dt, 3, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].npdf, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].pdf_x, LPDF, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].pdf_y, LPDF, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].gain, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].converge_t_r, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].converge_t_e, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].converge_hc, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].trcheck, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].techeck, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].hccheck, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].converge_whole, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].converging, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].gamma_inshl, NAUGER, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].spec_mod_type, NXBANDS, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].pl_alpha, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].pl_log_w, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].exp_temp, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].exp_w, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].fmin_mod, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, plasmamain[n].fmax_mod, NXBANDS, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].sim_ip, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ferland_ip, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ip, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ip_direct, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].ip_scatt, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &plasmamain[n].xi, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &dt_e_temp, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &dt_r_temp, 1, MPI_DOUBLE, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &nmax_e_temp, 1, MPI_INT, MPI_COMM_WORLD); + MPI_Unpack (commbuffer, size_of_commbuffer, &position, &nmax_r_temp, 1, MPI_INT, MPI_COMM_WORLD); + + /* JM 1409 -- Altered for issue #110 to ensure correct reporting in parallel */ + if (fabs (dt_e_temp) >= fabs (dt_e)) { - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &num_comm, 1, MPI_INT, MPI_COMM_WORLD); - for (n_mpi2 = 0; n_mpi2 < num_comm; n_mpi2++) - { - MPI_Unpack (commbuffer, size_of_commbuffer, &position, &n, - 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].nwind, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].nplasma, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ne, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].rho, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].vol, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].density, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].partition, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].levden, NLTE_LEVELS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].PWdenom, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].PWdtemp, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].PWnumer, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].PWntemp, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].kappa_ff_factor, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].nscat_es, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].recomb_simple, NTOP_PHOT, - MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].kpkt_emiss, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].kpkt_abs, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].kbf_use, NTOP_PHOT, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].kbf_nuse, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].t_r, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].t_r_old, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].t_e, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].t_e_old, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].dt_e, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].dt_e_old, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_tot, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_tot_old, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_lines, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_ff, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_comp, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_ind_comp, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_lines_macro, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_photo_macro, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_photo, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_auger, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].heat_z, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].w, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot_star, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot_bl, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot_disk, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot_wind, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ntot_agn, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].mean_ds, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].n_ds, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].nrad, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].nioniz, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].ioniz, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].recomb, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].scatters, nions, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].xscatters, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].heat_ion, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].lum_ion, nions, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].j, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].j_direct, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].j_scatt, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ave_freq, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].xj, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].xave_freq, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].xsd_freq, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].nxtot, NXBANDS, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].max_freq, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_lines, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_ff, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_adiabatic, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_comp, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_dr, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_di, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_fb, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_z, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_rad, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_rad_old, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_lines_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_ff_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_adiabatic_ioniz, 1, - MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_comp_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_dr_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_di_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_fb_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_z_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].lum_rad_ioniz, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].dmo_dt, 3, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].npdf, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].pdf_x, LPDF, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].pdf_y, LPDF, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].gain, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].converge_t_r, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].converge_t_e, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].converge_hc, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].trcheck, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].techeck, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].hccheck, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].converge_whole, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].converging, 1, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].gamma_inshl, NAUGER, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].spec_mod_type, NXBANDS, MPI_INT, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].pl_alpha, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].pl_log_w, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].exp_temp, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].exp_w, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].fmin_mod, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - plasmamain[n].fmax_mod, NXBANDS, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].sim_ip, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ferland_ip, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ip, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ip_direct, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].ip_scatt, 1, MPI_DOUBLE, - MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &plasmamain[n].xi, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &dt_e_temp, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &dt_r_temp, 1, MPI_DOUBLE, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &nmax_e_temp, 1, MPI_INT, MPI_COMM_WORLD); - MPI_Unpack (commbuffer, size_of_commbuffer, &position, - &nmax_r_temp, 1, MPI_INT, MPI_COMM_WORLD); - - /* JM 1409 -- Altered for issue #110 to ensure correct reporting in parallel */ - if (fabs (dt_e_temp) >= fabs (dt_e)) - { - /* Check if any other threads found a higher maximum for te */ - dt_e = dt_e_temp; - nmax_e = nmax_e_temp; - } - - if (fabs (dt_r_temp) >= fabs (dt_r)) - { - /* Check if any other threads found a higher maximum for tr */ - dt_r = dt_r_temp; - nmax_r = nmax_r_temp; - } - - t_r_ave += plasmamain[n].t_r; - t_e_ave += plasmamain[n].t_e; - iave++; - - } + /* Check if any other threads found a higher maximum for te */ + dt_e = dt_e_temp; + nmax_e = nmax_e_temp; + } + if (fabs (dt_r_temp) >= fabs (dt_r)) + { + /* Check if any other threads found a higher maximum for tr */ + dt_r = dt_r_temp; + nmax_r = nmax_r_temp; } + t_r_ave += plasmamain[n].t_r; + t_e_ave += plasmamain[n].t_e; + iave++; + + } + } + + } free (commbuffer); #endif @@ -1045,23 +641,21 @@ WindPtr (w); */ for (ndom = 0; ndom < geo.ndomain; ndom++) + { + if (zdom[ndom].coord_type == CYLIND) + cylind_extend_density (ndom, w); + else if (zdom[ndom].coord_type == RTHETA) + rtheta_extend_density (ndom, w); + else if (zdom[ndom].coord_type == SPHERICAL) + spherical_extend_density (ndom, w); + else if (zdom[ndom].coord_type == CYLVAR) + cylvar_extend_density (ndom, w); + else { - if (zdom[ndom].coord_type == CYLIND) - cylind_extend_density (ndom, w); - else if (zdom[ndom].coord_type == RTHETA) - rtheta_extend_density (ndom, w); - else if (zdom[ndom].coord_type == SPHERICAL) - spherical_extend_density (ndom, w); - else if (zdom[ndom].coord_type == CYLVAR) - cylvar_extend_density (ndom, w); - else - { - Error - ("Wind_update2d: Unknown coordinate type %d for domain %d \n", - zdom[ndom].coord_type, ndom); - exit (0); - } + Error ("Wind_update2d: Unknown coordinate type %d for domain %d \n", zdom[ndom].coord_type, ndom); + exit (0); } + } /* Finished updating region outside of wind */ @@ -1070,68 +664,58 @@ WindPtr (w); sprintf (string, "# Wind update: Number %d", num_updates); if (modes.zeus_connect == 1) //If we are running in zeus connect mode - we open a file for heatcool rates - { - Log ("Outputting heatcool file for connecting to zeus\n"); - fptr = fopen ("py_heatcool.dat", "w"); - fprintf (fptr, - "i j rcen thetacen vol temp xi ne heat_xray heat_comp heat_lines heat_ff cool_comp cool_lines cool_ff rho n_h\n"); + { + Log ("Outputting heatcool file for connecting to zeus\n"); + fptr = fopen ("py_heatcool.dat", "w"); + fprintf (fptr, "i j rcen thetacen vol temp xi ne heat_xray heat_comp heat_lines heat_ff cool_comp cool_lines cool_ff rho n_h\n"); - } + } /* Check the balance between the absorbed and the emitted flux */ xsum = psum = ausum = lsum = fsum = csum = icsum = 0; //1108 NSH zero the new csum counter for compton heating for (nplasma = 0; nplasma < NPLASMA; nplasma++) - { - if (sane_check (plasmamain[nplasma].heat_tot)) - Error ("wind_update:sane_check w(%d).heat_tot is %e\n", nplasma, - plasmamain[nplasma].heat_tot); - if (sane_check (plasmamain[nplasma].heat_photo)) - Error ("wind_update:sane_check w(%d).heat_photo is %e\n", - nplasma, plasmamain[nplasma].heat_photo); - if (sane_check (plasmamain[nplasma].heat_auger)) - Error ("wind_update:sane_check w(%d).heat_auger is %e\n", - nplasma, plasmamain[nplasma].heat_auger); - if (sane_check (plasmamain[nplasma].heat_photo_macro)) - Error ("wind_update:sane_check w(%d).heat_photo_macro is %e\n", - nplasma, plasmamain[nplasma].heat_photo_macro); - if (sane_check (plasmamain[nplasma].heat_ff)) - Error ("wind_update:sane_check w(%d).heat_ff is %e\n", nplasma, - plasmamain[nplasma].heat_ff); - if (sane_check (plasmamain[nplasma].heat_lines)) - Error ("wind_update:sane_check w(%d).heat_lines is %e\n", - nplasma, plasmamain[nplasma].heat_lines); - if (sane_check (plasmamain[nplasma].heat_lines_macro)) - Error ("wind_update:sane_check w(%d).heat_lines_macro is %e\n", - nplasma, plasmamain[nplasma].heat_lines_macro); - /* 1108 NSH extra Sane check for compton heating */ - if (sane_check (plasmamain[nplasma].heat_comp)) - Error ("wind_update:sane_check w(%d).heat_comp is %e\n", - nplasma, plasmamain[nplasma].heat_comp); - xsum += plasmamain[nplasma].heat_tot; - psum += plasmamain[nplasma].heat_photo; - ausum += plasmamain[nplasma].heat_auger; - fsum += plasmamain[nplasma].heat_ff; - lsum += plasmamain[nplasma].heat_lines; - csum += plasmamain[nplasma].heat_comp; //1108 NSH Increment the compton heating counter - icsum += plasmamain[nplasma].heat_ind_comp; //1205 NSH Increment the induced compton heating counter - - /* JM130621- bugfix for windsave bug- needed so that we have the luminosities from ionization - cycles in the windsavefile even if the spectral cycles are run */ - plasmamain[nplasma].lum_ioniz = plasmamain[nplasma].lum; - plasmamain[nplasma].lum_ff_ioniz = plasmamain[nplasma].lum_ff; - plasmamain[nplasma].lum_fb_ioniz = plasmamain[nplasma].lum_fb; - plasmamain[nplasma].lum_z_ioniz = plasmamain[nplasma].lum_z; - plasmamain[nplasma].lum_lines_ioniz = plasmamain[nplasma].lum_lines; - plasmamain[nplasma].lum_comp_ioniz = plasmamain[nplasma].lum_comp; - plasmamain[nplasma].lum_dr_ioniz = plasmamain[nplasma].lum_dr; - plasmamain[nplasma].lum_di_ioniz = plasmamain[nplasma].lum_di; - plasmamain[nplasma].lum_rad_ioniz = plasmamain[nplasma].lum_rad; - plasmamain[nplasma].lum_adiabatic_ioniz = - plasmamain[nplasma].lum_adiabatic; - - } + { + if (sane_check (plasmamain[nplasma].heat_tot)) + Error ("wind_update:sane_check w(%d).heat_tot is %e\n", nplasma, plasmamain[nplasma].heat_tot); + if (sane_check (plasmamain[nplasma].heat_photo)) + Error ("wind_update:sane_check w(%d).heat_photo is %e\n", nplasma, plasmamain[nplasma].heat_photo); + if (sane_check (plasmamain[nplasma].heat_auger)) + Error ("wind_update:sane_check w(%d).heat_auger is %e\n", nplasma, plasmamain[nplasma].heat_auger); + if (sane_check (plasmamain[nplasma].heat_photo_macro)) + Error ("wind_update:sane_check w(%d).heat_photo_macro is %e\n", nplasma, plasmamain[nplasma].heat_photo_macro); + if (sane_check (plasmamain[nplasma].heat_ff)) + Error ("wind_update:sane_check w(%d).heat_ff is %e\n", nplasma, plasmamain[nplasma].heat_ff); + if (sane_check (plasmamain[nplasma].heat_lines)) + Error ("wind_update:sane_check w(%d).heat_lines is %e\n", nplasma, plasmamain[nplasma].heat_lines); + if (sane_check (plasmamain[nplasma].heat_lines_macro)) + Error ("wind_update:sane_check w(%d).heat_lines_macro is %e\n", nplasma, plasmamain[nplasma].heat_lines_macro); + /* 1108 NSH extra Sane check for compton heating */ + if (sane_check (plasmamain[nplasma].heat_comp)) + Error ("wind_update:sane_check w(%d).heat_comp is %e\n", nplasma, plasmamain[nplasma].heat_comp); + xsum += plasmamain[nplasma].heat_tot; + psum += plasmamain[nplasma].heat_photo; + ausum += plasmamain[nplasma].heat_auger; + fsum += plasmamain[nplasma].heat_ff; + lsum += plasmamain[nplasma].heat_lines; + csum += plasmamain[nplasma].heat_comp; //1108 NSH Increment the compton heating counter + icsum += plasmamain[nplasma].heat_ind_comp; //1205 NSH Increment the induced compton heating counter + + /* JM130621- bugfix for windsave bug- needed so that we have the luminosities from ionization + cycles in the windsavefile even if the spectral cycles are run */ + plasmamain[nplasma].lum_ioniz = plasmamain[nplasma].lum; + plasmamain[nplasma].lum_ff_ioniz = plasmamain[nplasma].lum_ff; + plasmamain[nplasma].lum_fb_ioniz = plasmamain[nplasma].lum_fb; + plasmamain[nplasma].lum_z_ioniz = plasmamain[nplasma].lum_z; + plasmamain[nplasma].lum_lines_ioniz = plasmamain[nplasma].lum_lines; + plasmamain[nplasma].lum_comp_ioniz = plasmamain[nplasma].lum_comp; + plasmamain[nplasma].lum_dr_ioniz = plasmamain[nplasma].lum_dr; + plasmamain[nplasma].lum_di_ioniz = plasmamain[nplasma].lum_di; + plasmamain[nplasma].lum_rad_ioniz = plasmamain[nplasma].lum_rad; + plasmamain[nplasma].lum_adiabatic_ioniz = plasmamain[nplasma].lum_adiabatic; + + } @@ -1152,13 +736,10 @@ WindPtr (w); /* Added this system which counts number of times two situations occur (See #91) We only report these every 100,000 times (one can typically get ) */ - Log - ("wind_update: note, errors from mean intensity can be high in a working model\n"); + Log ("wind_update: note, errors from mean intensity can be high in a working model\n"); Log ("wind_update: can be a problem with photon numbers if there are also errors from spectral_estimators and low photon number warnings\n"); - Log - ("wind_update: mean_intensity: %8.4e occurrences, this cycle, this thread of 'no model exists in a band'\n", - (1.0 * nerr_no_Jmodel)); + Log ("wind_update: mean_intensity: %8.4e occurrences, this cycle, this thread of 'no model exists in a band'\n", (1.0 * nerr_no_Jmodel)); Log ("wind_update: mean intensity: %8.4e occurrences, this cycle, this thread of 'photon freq is outside frequency range of spectral model'\n", (1.0 * nerr_Jmodel_wrong_freq)); @@ -1174,27 +755,26 @@ WindPtr (w); if (modes.zeus_connect == 1) //If we are running in zeus connect mode, we output heating and cooling rates. + { + for (nplasma = 0; nplasma < NPLASMA; nplasma++) { - for (nplasma = 0; nplasma < NPLASMA; nplasma++) - { - wind_n_to_ij (geo.wind_domain_number, plasmamain[nplasma].nwind, - &i, &j); - vol = w[plasmamain[nplasma].nwind].vol; - fprintf (fptr, "%d %d %e %e %e ", i, j, w[plasmamain[nplasma].nwind].rcen, w[plasmamain[nplasma].nwind].thetacen / RADIAN, vol); //output geometric things - fprintf (fptr, "%e %e %e ", plasmamain[nplasma].t_e, plasmamain[nplasma].xi, plasmamain[nplasma].ne); //output temp, xi and ne to ease plotting of heating rates - fprintf (fptr, "%e ", (plasmamain[nplasma].heat_photo + plasmamain[nplasma].heat_auger) / vol); //Xray heating - or photoionization - fprintf (fptr, "%e ", (plasmamain[nplasma].heat_comp) / vol); //Compton heating - fprintf (fptr, "%e ", (plasmamain[nplasma].heat_lines) / vol); //Line heating 28/10/15 - not currently used in zeus - fprintf (fptr, "%e ", (plasmamain[nplasma].heat_ff) / vol); //FF heating 28/10/15 - not currently used in zeus - fprintf (fptr, "%e ", (plasmamain[nplasma].lum_comp) / vol); //Compton cooling - fprintf (fptr, "%e ", (plasmamain[nplasma].lum_lines + plasmamain[nplasma].lum_fb + plasmamain[nplasma].lum_dr) / vol); //Line cooling must include all recombinatiobs cooling - fprintf (fptr, "%e ", (plasmamain[nplasma].lum_ff) / vol); //ff cooling - fprintf (fptr, "%e ", plasmamain[nplasma].rho); //density - fprintf (fptr, "%e\n", plasmamain[nplasma].rho * rho2nh); //hydrogen number density - } - fclose (fptr); + wind_n_to_ij (geo.wind_domain_number, plasmamain[nplasma].nwind, &i, &j); + vol = w[plasmamain[nplasma].nwind].vol; + fprintf (fptr, "%d %d %e %e %e ", i, j, w[plasmamain[nplasma].nwind].rcen, w[plasmamain[nplasma].nwind].thetacen / RADIAN, vol); //output geometric things + fprintf (fptr, "%e %e %e ", plasmamain[nplasma].t_e, plasmamain[nplasma].xi, plasmamain[nplasma].ne); //output temp, xi and ne to ease plotting of heating rates + fprintf (fptr, "%e ", (plasmamain[nplasma].heat_photo + plasmamain[nplasma].heat_auger) / vol); //Xray heating - or photoionization + fprintf (fptr, "%e ", (plasmamain[nplasma].heat_comp) / vol); //Compton heating + fprintf (fptr, "%e ", (plasmamain[nplasma].heat_lines) / vol); //Line heating 28/10/15 - not currently used in zeus + fprintf (fptr, "%e ", (plasmamain[nplasma].heat_ff) / vol); //FF heating 28/10/15 - not currently used in zeus + fprintf (fptr, "%e ", (plasmamain[nplasma].lum_comp) / vol); //Compton cooling + fprintf (fptr, "%e ", (plasmamain[nplasma].lum_lines + plasmamain[nplasma].lum_fb + plasmamain[nplasma].lum_dr) / vol); //Line cooling must include all recombinatiobs cooling + fprintf (fptr, "%e ", (plasmamain[nplasma].lum_ff) / vol); //ff cooling + fprintf (fptr, "%e ", plasmamain[nplasma].rho); //density + fprintf (fptr, "%e\n", plasmamain[nplasma].rho * rho2nh); //hydrogen number density } + fclose (fptr); + } /* 1108 NSH Added commands to report compton heating */ Log @@ -1204,8 +784,7 @@ WindPtr (w); /* 1306 Added line to split out absorbed flux from wind heating */ Log ("!!wind_update: Wind heating %8.2e (photo %8.2e ff %8.2e compton %8.2e auger %8.2e induced_compton %8.2e lines %8.2e adiabatic %8.2e)\n", - xsum + geo.heat_adiabatic, psum, fsum, csum, ausum, icsum, lsum, - geo.heat_adiabatic); + xsum + geo.heat_adiabatic, psum, fsum, csum, ausum, icsum, lsum, geo.heat_adiabatic); /* 1108 NSH added commands to report compton cooling 1110 removed, * this line now just reports cooling mechanisms that will generate photons */ @@ -1217,41 +796,33 @@ WindPtr (w); Log ("!!wind_update: Wind cooling %8.2e (recomb %8.2e ff %8.2e compton %8.2e DR %8.2e DI %8.2e lines %8.2e adiabatic %8.2e) after update\n", asum + geo.lum_comp + geo.lum_dr + geo.lum_di + geo.lum_adiabatic, - geo.lum_fb, geo.lum_ff, geo.lum_comp, geo.lum_dr, geo.lum_di, - geo.lum_lines, geo.lum_adiabatic); + geo.lum_fb, geo.lum_ff, geo.lum_comp, geo.lum_dr, geo.lum_di, geo.lum_lines, geo.lum_adiabatic); /* Print out some diagnositics of the changes in the wind update */ if (modes.zeus_connect == 1 || modes.fixed_temp == 1) //There is no point in computing temperature changes, because we have fixed them! - { - Log - ("!!wind_update: We are running in fixed temperature mode - no temperature report\n"); - } + { + Log ("!!wind_update: We are running in fixed temperature mode - no temperature report\n"); + } else - { - t_r_ave_old /= iave; - t_e_ave_old /= iave; - t_r_ave /= iave; - t_e_ave /= iave; - - wind_n_to_ij (wmain[nmax_r].ndom, nmax_r, &i, &j); - Log ("!!wind_update: Max change in t_r %6.0f at cell %4d (%d,%d)\n", - dt_r, nmax_r, i, j); - Log ("!!wind_update: Ave change in t_r %6.0f from %6.0f to %6.0f\n", - (t_r_ave - t_r_ave_old), t_r_ave_old, t_r_ave); - - wind_n_to_ij (wmain[nmax_e].ndom, nmax_e, &i, &j); - Log ("!!wind_update: Max change in t_e %6.0f at cell %4d (%d,%d)\n", - dt_e, nmax_e, i, j); - Log ("!!wind_update: Ave change in t_e %6.0f from %6.0f to %6.0f\n", - (t_e_ave - t_e_ave_old), t_e_ave_old, t_e_ave); - - Log ("Summary t_e %6.0f %6.0f #t_e and dt_e on this update\n", - t_e_ave, (t_e_ave - t_e_ave_old)); - Log ("Summary t_r %6.0f %6.0f #t_r and dt_r on this update\n", - t_r_ave, (t_r_ave - t_r_ave_old)); - } + { + t_r_ave_old /= iave; + t_e_ave_old /= iave; + t_r_ave /= iave; + t_e_ave /= iave; + + wind_n_to_ij (wmain[nmax_r].ndom, nmax_r, &i, &j); + Log ("!!wind_update: Max change in t_r %6.0f at cell %4d (%d,%d)\n", dt_r, nmax_r, i, j); + Log ("!!wind_update: Ave change in t_r %6.0f from %6.0f to %6.0f\n", (t_r_ave - t_r_ave_old), t_r_ave_old, t_r_ave); + + wind_n_to_ij (wmain[nmax_e].ndom, nmax_e, &i, &j); + Log ("!!wind_update: Max change in t_e %6.0f at cell %4d (%d,%d)\n", dt_e, nmax_e, i, j); + Log ("!!wind_update: Ave change in t_e %6.0f from %6.0f to %6.0f\n", (t_e_ave - t_e_ave_old), t_e_ave_old, t_e_ave); + + Log ("Summary t_e %6.0f %6.0f #t_e and dt_e on this update\n", t_e_ave, (t_e_ave - t_e_ave_old)); + Log ("Summary t_r %6.0f %6.0f #t_r and dt_r on this update\n", t_r_ave, (t_r_ave - t_r_ave_old)); + } check_convergence (); @@ -1263,90 +834,78 @@ WindPtr (w); * with thin shell mode.We will only want this to run if the wind mode is 9, for test or thin shell mode. */ for (ndom = 0; ndom < geo.ndomain; ndom++) + { + + if (zdom[ndom].wind_type == SHELL) { + nstart = zdom[ndom].nstart; + n = plasmamain[nstart].nwind; + for (i = 0; i < geo.nxfreq; i++) + { /*loop over number of bands */ + Log + ("Band %i f1 %e f2 %e model %i pl_alpha %f pl_log_w %e exp_t %e exp_w %e\n", + i, geo.xfreq[i], geo.xfreq[i + 1], + plasmamain[nstart].spec_mod_type[i], + plasmamain[nstart].pl_alpha[i], plasmamain[nstart].pl_log_w[i], plasmamain[nstart].exp_temp[i], plasmamain[nstart].exp_w[i]); + } + /* Get some line diagnostics */ + nsh_lum_hhe = 0.0; + nsh_lum_metals = 0.0; + + for (i = 0; i < nlines; i++) + { + if (lin_ptr[i]->z < 3) + nsh_lum_hhe = nsh_lum_hhe + lin_ptr[i]->pow; + else + nsh_lum_metals = nsh_lum_metals + lin_ptr[i]->pow; + } + agn_ip = geo.const_agn * (((pow (50000 / HEV, geo.alpha_agn + 1.0)) - pow (100 / HEV, geo.alpha_agn + 1.0)) / (geo.alpha_agn + 1.0)); + agn_ip /= (w[n].r * w[n].r); + agn_ip /= plasmamain[nstart].rho * rho2nh; + /* Report luminosities, IP and other diagnositic quantities */ + Log + ("OUTPUT Lum_agn= %e T_e= %e N_h= %e N_e= %e alpha= %f IP(sim_2010)= %e Measured_IP(cloudy)= %e Measured_Xi= %e distance= %e volume= %e mean_ds=%e\n", + geo.lum_agn, plasmamain[nstart].t_e, + plasmamain[nstart].rho * rho2nh, plasmamain[nstart].ne, + geo.alpha_agn, agn_ip, plasmamain[nstart].ip, + plasmamain[nstart].xi, w[n].r, w[n].vol, plasmamain[nstart].mean_ds / plasmamain[nstart].n_ds); - if (zdom[ndom].wind_type == SHELL) + /* 1108 NSH Added commands to report compton heating */ + Log + ("OUTPUT Absorbed_flux(ergs-1cm-3) %8.2e (photo %8.2e ff %8.2e compton %8.2e induced_compton %8.2e lines %8.2e auger %8.2e )\n", + xsum / w[n].vol, psum / w[n].vol, fsum / w[n].vol, csum / w[n].vol, icsum / w[n].vol, lsum / w[n].vol, ausum / w[n].vol); + + /* 1110 NSH Added this line to report all cooling mechanisms, including those that do not generate photons. */ + Log + ("OUTPUT Wind_cooling(ergs-1cm-3) %8.2e (recomb %8.2e ff %8.2e compton %8.2e DR %8.2e DI %8.2e adiabatic %8.2e lines %8.2e ) after update\n", + (asum + geo.lum_comp + geo.lum_dr + geo.lum_di + + geo.lum_adiabatic) / w[n].vol, geo.lum_fb / w[n].vol, + geo.lum_ff / w[n].vol, geo.lum_comp / w[n].vol, + geo.lum_dr / w[n].vol, geo.lum_di / w[n].vol, geo.lum_adiabatic / w[n].vol, geo.lum_lines / w[n].vol); + + Log ("OUTPUT Wind_line_cooling(ergs-1cm-3) HHe %8.2e Metals %8.2e\n", nsh_lum_hhe / w[n].vol, nsh_lum_metals / w[n].vol); + + /* 1110 NSH Added this line to report all cooling mechanisms, including those that do not generate photons. */ + Log + ("OUTPUT Balance Cooling=%8.2e Heating=%8.2e Lum=%8.2e T_e=%e after update\n", + asum + geo.lum_comp + geo.lum_dr + geo.lum_di + geo.lum_adiabatic, xsum, asum, plasmamain[nstart].t_e); + + for (n = 0; n < nelements; n++) + { + first = ele[n].firstion; + last = first + ele[n].nions; + Log ("OUTPUT %-5s ", ele[n].name); + tot = 0; + for (m = first; m < last; m++) + tot += plasmamain[nstart].density[m]; + for (m = first; m < last; m++) { - nstart = zdom[ndom].nstart; - n = plasmamain[nstart].nwind; - for (i = 0; i < geo.nxfreq; i++) - { /*loop over number of bands */ - Log - ("Band %i f1 %e f2 %e model %i pl_alpha %f pl_log_w %e exp_t %e exp_w %e\n", - i, geo.xfreq[i], geo.xfreq[i + 1], - plasmamain[nstart].spec_mod_type[i], - plasmamain[nstart].pl_alpha[i], - plasmamain[nstart].pl_log_w[i], - plasmamain[nstart].exp_temp[i], plasmamain[nstart].exp_w[i]); - } - /* Get some line diagnostics */ - nsh_lum_hhe = 0.0; - nsh_lum_metals = 0.0; - - for (i = 0; i < nlines; i++) - { - if (lin_ptr[i]->z < 3) - nsh_lum_hhe = nsh_lum_hhe + lin_ptr[i]->pow; - else - nsh_lum_metals = nsh_lum_metals + lin_ptr[i]->pow; - } - agn_ip = - geo.const_agn * - (((pow (50000 / HEV, geo.alpha_agn + 1.0)) - - pow (100 / HEV, geo.alpha_agn + 1.0)) / (geo.alpha_agn + 1.0)); - agn_ip /= (w[n].r * w[n].r); - agn_ip /= plasmamain[nstart].rho * rho2nh; - /* Report luminosities, IP and other diagnositic quantities */ - Log - ("OUTPUT Lum_agn= %e T_e= %e N_h= %e N_e= %e alpha= %f IP(sim_2010)= %e Measured_IP(cloudy)= %e Measured_Xi= %e distance= %e volume= %e mean_ds=%e\n", - geo.lum_agn, plasmamain[nstart].t_e, - plasmamain[nstart].rho * rho2nh, plasmamain[nstart].ne, - geo.alpha_agn, agn_ip, plasmamain[nstart].ip, - plasmamain[nstart].xi, w[n].r, w[n].vol, - plasmamain[nstart].mean_ds / plasmamain[nstart].n_ds); - - /* 1108 NSH Added commands to report compton heating */ - Log - ("OUTPUT Absorbed_flux(ergs-1cm-3) %8.2e (photo %8.2e ff %8.2e compton %8.2e induced_compton %8.2e lines %8.2e auger %8.2e )\n", - xsum / w[n].vol, psum / w[n].vol, fsum / w[n].vol, - csum / w[n].vol, icsum / w[n].vol, lsum / w[n].vol, - ausum / w[n].vol); - - /* 1110 NSH Added this line to report all cooling mechanisms, including those that do not generate photons. */ - Log - ("OUTPUT Wind_cooling(ergs-1cm-3) %8.2e (recomb %8.2e ff %8.2e compton %8.2e DR %8.2e DI %8.2e adiabatic %8.2e lines %8.2e ) after update\n", - (asum + geo.lum_comp + geo.lum_dr + geo.lum_di + - geo.lum_adiabatic) / w[n].vol, geo.lum_fb / w[n].vol, - geo.lum_ff / w[n].vol, geo.lum_comp / w[n].vol, - geo.lum_dr / w[n].vol, geo.lum_di / w[n].vol, - geo.lum_adiabatic / w[n].vol, geo.lum_lines / w[n].vol); - - Log - ("OUTPUT Wind_line_cooling(ergs-1cm-3) HHe %8.2e Metals %8.2e\n", - nsh_lum_hhe / w[n].vol, nsh_lum_metals / w[n].vol); - - /* 1110 NSH Added this line to report all cooling mechanisms, including those that do not generate photons. */ - Log - ("OUTPUT Balance Cooling=%8.2e Heating=%8.2e Lum=%8.2e T_e=%e after update\n", - asum + geo.lum_comp + geo.lum_dr + geo.lum_di + - geo.lum_adiabatic, xsum, asum, plasmamain[nstart].t_e); - - for (n = 0; n < nelements; n++) - { - first = ele[n].firstion; - last = first + ele[n].nions; - Log ("OUTPUT %-5s ", ele[n].name); - tot = 0; - for (m = first; m < last; m++) - tot += plasmamain[nstart].density[m]; - for (m = first; m < last; m++) - { - Log (" %8.2e", plasmamain[nstart].density[m] / tot); - } - Log ("\n"); - } + Log (" %8.2e", plasmamain[nstart].density[m] / tot); } + Log ("\n"); + } } + } @@ -1410,142 +969,128 @@ wind_rad_init () for (n = 0; n < NPLASMA; n++) - { - plasmamain[n].j = plasmamain[n].ave_freq = plasmamain[n].ntot = 0; - plasmamain[n].j_direct = plasmamain[n].j_scatt = 0, 0; //NSH 1309 zero j banded by number of scatters - plasmamain[n].ip = 0.0; - plasmamain[n].xi = 0.0; - plasmamain[n].ip_direct = plasmamain[n].ip_scatt = 0.0; - plasmamain[n].mean_ds = 0.0; - plasmamain[n].n_ds = 0; - plasmamain[n].ntot_disk = plasmamain[n].ntot_agn = 0; //NSH 15/4/11 counters to see where photons come from - plasmamain[n].ntot_star = plasmamain[n].ntot_bl = - plasmamain[n].ntot_wind = 0; - plasmamain[n].heat_tot = plasmamain[n].heat_ff = - plasmamain[n].heat_photo = plasmamain[n].heat_lines = 0.0; - plasmamain[n].heat_z = 0.0; - plasmamain[n].max_freq = 0.0; //NSH 120814 Zero the counter which works out the maximum frequency seen in a cell and hence the maximum applicable frequency of the power law estimators. - plasmamain[n].lum = plasmamain[n].lum_rad = - plasmamain[n].lum_lines = plasmamain[n].lum_ff = 0.0; - plasmamain[n].lum_fb = plasmamain[n].lum_z = 0.0; - plasmamain[n].nrad = plasmamain[n].nioniz = 0; - plasmamain[n].lum_comp = 0.0; //1108 NSH Zero the compton luminosity for the cell - plasmamain[n].heat_comp = 0.0; //1108 NSH Zero the compton heating for the cell - plasmamain[n].heat_ind_comp = 0.0; //1108 NSH Zero the induced compton heating for the cell - plasmamain[n].heat_auger = 0.0; //1108 NSH Zero the auger heating for the cell - - if (nlevels_macro > 1) - macromain[n].kpkt_rates_known = -1; + { + plasmamain[n].j = plasmamain[n].ave_freq = plasmamain[n].ntot = 0; + plasmamain[n].j_direct = plasmamain[n].j_scatt = 0, 0; //NSH 1309 zero j banded by number of scatters + plasmamain[n].ip = 0.0; + plasmamain[n].xi = 0.0; + plasmamain[n].ip_direct = plasmamain[n].ip_scatt = 0.0; + plasmamain[n].mean_ds = 0.0; + plasmamain[n].n_ds = 0; + plasmamain[n].ntot_disk = plasmamain[n].ntot_agn = 0; //NSH 15/4/11 counters to see where photons come from + plasmamain[n].ntot_star = plasmamain[n].ntot_bl = plasmamain[n].ntot_wind = 0; + plasmamain[n].heat_tot = plasmamain[n].heat_ff = plasmamain[n].heat_photo = plasmamain[n].heat_lines = 0.0; + plasmamain[n].heat_z = 0.0; + plasmamain[n].max_freq = 0.0; //NSH 120814 Zero the counter which works out the maximum frequency seen in a cell and hence the maximum applicable frequency of the power law estimators. + plasmamain[n].lum = plasmamain[n].lum_rad = plasmamain[n].lum_lines = plasmamain[n].lum_ff = 0.0; + plasmamain[n].lum_fb = plasmamain[n].lum_z = 0.0; + plasmamain[n].nrad = plasmamain[n].nioniz = 0; + plasmamain[n].lum_comp = 0.0; //1108 NSH Zero the compton luminosity for the cell + plasmamain[n].heat_comp = 0.0; //1108 NSH Zero the compton heating for the cell + plasmamain[n].heat_ind_comp = 0.0; //1108 NSH Zero the induced compton heating for the cell + plasmamain[n].heat_auger = 0.0; //1108 NSH Zero the auger heating for the cell + + if (nlevels_macro > 1) + macromain[n].kpkt_rates_known = -1; /* 1108 NSH Loop to zero the frequency banded radiation estimators */ /* 71 - 111279 - ksl - Small modification to reflect the fact that nxfreq has been moved into the geo structure */ - for (i = 0; i < geo.nxfreq; i++) - { - plasmamain[n].xj[i] = plasmamain[n].xave_freq[i] = - plasmamain[n].nxtot[i] = 0; - plasmamain[n].xsd_freq[i] = 0.0; /* NSH 120815 Zero the standard deviation counter */ - plasmamain[n].fmin[i] = geo.xfreq[i + 1]; /* Set the minium frequency to the max frequency in the band */ - plasmamain[n].fmax[i] = geo.xfreq[i]; /* Set the maximum frequency to the min frequency in the band */ - } + for (i = 0; i < geo.nxfreq; i++) + { + plasmamain[n].xj[i] = plasmamain[n].xave_freq[i] = plasmamain[n].nxtot[i] = 0; + plasmamain[n].xsd_freq[i] = 0.0; /* NSH 120815 Zero the standard deviation counter */ + plasmamain[n].fmin[i] = geo.xfreq[i + 1]; /* Set the minium frequency to the max frequency in the band */ + plasmamain[n].fmax[i] = geo.xfreq[i]; /* Set the maximum frequency to the min frequency in the band */ + } - for (i = 0; i < nions; i++) - { - plasmamain[n].ioniz[i] = plasmamain[n].recomb[i] = - plasmamain[n].heat_ion[i] = plasmamain[n].lum_ion[i] = 0.0; + for (i = 0; i < nions; i++) + { + plasmamain[n].ioniz[i] = plasmamain[n].recomb[i] = plasmamain[n].heat_ion[i] = plasmamain[n].lum_ion[i] = 0.0; - } + } - /*Block added (Dec 08) to zero the auger rate estimators */ - for (i = 0; i < nauger; i++) - { - plasmamain[n].gamma_inshl[i] = 0.0; - } + /*Block added (Dec 08) to zero the auger rate estimators */ + for (i = 0; i < nauger; i++) + { + plasmamain[n].gamma_inshl[i] = 0.0; + } - /* Next blocks added by SS Mar 2004 to zero the Macro Atom estimators. */ + /* Next blocks added by SS Mar 2004 to zero the Macro Atom estimators. */ - /* 57h -- 0608 -- These sections actually involve enough calculations that - they are noticeable in term sof the overall speed. One would if possible - like to avoid this section, since it requires the creation of macromain, - even though macromain is not used -- ksl */ + /* 57h -- 0608 -- These sections actually involve enough calculations that + they are noticeable in term sof the overall speed. One would if possible + like to avoid this section, since it requires the creation of macromain, + even though macromain is not used -- ksl */ - for (i = 0; i < nlevels_macro; i++) //57h + for (i = 0; i < nlevels_macro; i++) //57h + { + for (njump = 0; njump < config[i].n_bbu_jump; njump++) + { + macromain[n].jbar[config[i].bbu_indx_first + njump] = 0.0; // mean intensity + } + for (njump = 0; njump < config[i].n_bfu_jump; njump++) + { + macromain[n].gamma[config[i].bfu_indx_first + njump] = 0.0; + macromain[n].gamma_e[config[i].bfu_indx_first + njump] = 0.0; + macromain[n].alpha_st[config[i].bfd_indx_first + njump] = 0.0; //stimulated recombination + macromain[n].alpha_st_e[config[i].bfd_indx_first + njump] = 0.0; + } + + + /* Next block to set spontaneous recombination rates for next iteration. (SS July 04) */ + for (njump = 0; njump < config[i].n_bfd_jump; njump++) + { + if (plasmamain[n].t_e > 1.0) { - for (njump = 0; njump < config[i].n_bbu_jump; njump++) - { - macromain[n].jbar[config[i].bbu_indx_first + njump] = 0.0; // mean intensity - } - for (njump = 0; njump < config[i].n_bfu_jump; njump++) - { - macromain[n].gamma[config[i].bfu_indx_first + njump] = 0.0; - macromain[n].gamma_e[config[i].bfu_indx_first + njump] = 0.0; - macromain[n].alpha_st[config[i].bfd_indx_first + njump] = 0.0; //stimulated recombination - macromain[n].alpha_st_e[config[i].bfd_indx_first + njump] = 0.0; - } - - - /* Next block to set spontaneous recombination rates for next iteration. (SS July 04) */ - for (njump = 0; njump < config[i].n_bfd_jump; njump++) - { - if (plasmamain[n].t_e > 1.0) - { - //04Jul--ksl-modified these calls to reflect changed alpha_sp - macromain[n].recomb_sp[config[i].bfd_indx_first + - njump] = - alpha_sp (&phot_top[config[i].bfd_jump[njump]], - &plasmamain[n], 0); - macromain[n].recomb_sp_e[config[i].bfd_indx_first + - njump] = - alpha_sp (&phot_top[config[i].bfd_jump[njump]], - &plasmamain[n], 2); - } - else - { - macromain[n].recomb_sp[config[i].bfd_indx_first + - njump] = 0.0; - macromain[n].recomb_sp_e[config[i].bfd_indx_first + - njump] = 0.0; - } - - } + //04Jul--ksl-modified these calls to reflect changed alpha_sp + macromain[n].recomb_sp[config[i].bfd_indx_first + njump] = alpha_sp (&phot_top[config[i].bfd_jump[njump]], &plasmamain[n], 0); + macromain[n].recomb_sp_e[config[i].bfd_indx_first + njump] = alpha_sp (&phot_top[config[i].bfd_jump[njump]], &plasmamain[n], 2); } - - for (i = 0; i < ntop_phot; i++) + else { - /* 57h -- recomb_simple is only required for we are using a macro atom approach, and only non-zero when - this particular phot_tob xsection is treated as a simple x-section. Stuart, is this correct?? I've added - checks so that macro_info is only 0 (false) or true (1), and so the logic of the next section can be - simplified. 0608-ksl */ - if (geo.macro_simple || phot_top[i].macro_info) - { - - plasmamain[n].recomb_simple[i] = 0.0; - } - else - { //we want a macro approach, but not for this ion so need recomb_simple - plasmamain[n].recomb_simple[i] = - alpha_sp (&phot_top[i], &plasmamain[n], 2); - } + macromain[n].recomb_sp[config[i].bfd_indx_first + njump] = 0.0; + macromain[n].recomb_sp_e[config[i].bfd_indx_first + njump] = 0.0; } + } + } - //zero the emissivities that are needed for the spectral synthesis step. - plasmamain[n].kpkt_emiss = 0.0; - plasmamain[n].kpkt_abs = 0.0; - for (i = 0; i < nlevels_macro; i++) //57h - { - macromain[n].matom_abs[i] = 0.0; + for (i = 0; i < ntop_phot; i++) + { + /* 57h -- recomb_simple is only required for we are using a macro atom approach, and only non-zero when + this particular phot_tob xsection is treated as a simple x-section. Stuart, is this correct?? I've added + checks so that macro_info is only 0 (false) or true (1), and so the logic of the next section can be + simplified. 0608-ksl */ + if (geo.macro_simple || phot_top[i].macro_info) + { + + plasmamain[n].recomb_simple[i] = 0.0; + } + else + { //we want a macro approach, but not for this ion so need recomb_simple + plasmamain[n].recomb_simple[i] = alpha_sp (&phot_top[i], &plasmamain[n], 2); + } + } - macromain[n].matom_emiss[i] = 0.0; - } + //zero the emissivities that are needed for the spectral synthesis step. + plasmamain[n].kpkt_emiss = 0.0; + plasmamain[n].kpkt_abs = 0.0; + for (i = 0; i < nlevels_macro; i++) //57h + { + macromain[n].matom_abs[i] = 0.0; + + macromain[n].matom_emiss[i] = 0.0; - /* End of added material. */ } + /* End of added material. */ + } + return (0); } @@ -1587,39 +1132,36 @@ wind_rad_summary (w, filename, mode) /* Open or reopen the file where you want to put the summary of the radiation properties of the wind */ if (istat_wind_rad_summary == 0) - { /*First time through recreate the file regardless */ - if ((fptr = fopen (filename, "w")) == NULL) - { - Error ("wind_rad_summary: Unable to open %s\n", filename); - exit (0); - } - + { /*First time through recreate the file regardless */ + if ((fptr = fopen (filename, "w")) == NULL) + { + Error ("wind_rad_summary: Unable to open %s\n", filename); + exit (0); } + + } else + { + if ((fptr = fopen (filename, mode)) == NULL) { - if ((fptr = fopen (filename, mode)) == NULL) - { - Error ("wind_rad_summary: Unable to reopen %s with mode %s\n", - filename, mode); - exit (0); - } + Error ("wind_rad_summary: Unable to reopen %s with mode %s\n", filename, mode); + exit (0); } + } istat_wind_rad_summary++; - fprintf (fptr, - "n x z j ntot ave_freq T_rad W Lum Lum_abs\n"); + fprintf (fptr, "n x z j ntot ave_freq T_rad W Lum Lum_abs\n"); for (n = 0; n < NDIM2 - 1; n++) - { - nplasma = w[n].nplasma; - fprintf (fptr, - "%-3d %8.3e %8.3e %8.3e %8d %8.3e %8.3e %8.3e %8.3e %8.3e\n", - n, w[n].x[0], w[n].x[2], plasmamain[n].j, - plasmamain[n].ntot, plasmamain[nplasma].ave_freq, - plasmamain[nplasma].t_r, plasmamain[nplasma].w, - plasmamain[nplasma].lum, plasmamain[nplasma].heat_tot); + { + nplasma = w[n].nplasma; + fprintf (fptr, + "%-3d %8.3e %8.3e %8.3e %8d %8.3e %8.3e %8.3e %8.3e %8.3e\n", + n, w[n].x[0], w[n].x[2], plasmamain[n].j, + plasmamain[n].ntot, plasmamain[nplasma].ave_freq, + plasmamain[nplasma].t_r, plasmamain[nplasma].w, plasmamain[nplasma].lum, plasmamain[nplasma].heat_tot); - } + } fclose (fptr); @@ -1661,27 +1203,21 @@ wind_ip () int n; float r; for (n = 0; n < NPLASMA; n++) - { - r = sqrt ((wmain[plasmamain[n].nwind].xcen[0] * - wmain[plasmamain[n].nwind].xcen[0] + - wmain[plasmamain[n].nwind].xcen[1] * - wmain[plasmamain[n].nwind].xcen[1] + - wmain[plasmamain[n].nwind].xcen[2] * - wmain[plasmamain[n].nwind].xcen[2])); - - plasmamain[n].ferland_ip = - geo.n_ioniz / (4 * PI * C * plasmamain[n].rho * rho2nh * (r * r)); - - r = sqrt ((wmain[plasmamain[n].nwind].x[0] * - wmain[plasmamain[n].nwind].x[0] + - wmain[plasmamain[n].nwind].x[1] * - wmain[plasmamain[n].nwind].x[1] + - wmain[plasmamain[n].nwind].x[2] * - wmain[plasmamain[n].nwind].x[2])); - - plasmamain[n].ferland_ip = - geo.n_ioniz / (4 * PI * C * plasmamain[n].rho * rho2nh * (r * r)); + { + r = sqrt ((wmain[plasmamain[n].nwind].xcen[0] * + wmain[plasmamain[n].nwind].xcen[0] + + wmain[plasmamain[n].nwind].xcen[1] * + wmain[plasmamain[n].nwind].xcen[1] + wmain[plasmamain[n].nwind].xcen[2] * wmain[plasmamain[n].nwind].xcen[2])); - } + plasmamain[n].ferland_ip = geo.n_ioniz / (4 * PI * C * plasmamain[n].rho * rho2nh * (r * r)); + + r = sqrt ((wmain[plasmamain[n].nwind].x[0] * + wmain[plasmamain[n].nwind].x[0] + + wmain[plasmamain[n].nwind].x[1] * + wmain[plasmamain[n].nwind].x[1] + wmain[plasmamain[n].nwind].x[2] * wmain[plasmamain[n].nwind].x[2])); + + plasmamain[n].ferland_ip = geo.n_ioniz / (4 * PI * C * plasmamain[n].rho * rho2nh * (r * r)); + + } return (0); } diff --git a/source/windsave.c b/source/windsave.c index 85674537d..a31cd2f0a 100755 --- a/source/windsave.c +++ b/source/windsave.c @@ -67,96 +67,69 @@ wind_save (filename) int n, m; if ((fptr = fopen (filename, "w")) == NULL) - { - Error ("wind_save: Unable to open %s\n", filename); - exit (0); - } + { + Error ("wind_save: Unable to open %s\n", filename); + exit (0); + } sprintf (line, "Version %s\n", VERSION); n = fwrite (line, sizeof (line), 1, fptr); n += fwrite (&geo, sizeof (geo), 1, fptr); n += fwrite (zdom, sizeof (domain_dummy), geo.ndomain, fptr); n += fwrite (wmain, sizeof (wind_dummy), NDIM2, fptr); - n += fwrite(&disk, sizeof (disk), 1, fptr); - n += fwrite(&qdisk, sizeof (disk), 1, fptr); + n += fwrite (&disk, sizeof (disk), 1, fptr); + n += fwrite (&qdisk, sizeof (disk), 1, fptr); n += fwrite (plasmamain, sizeof (plasma_dummy), NPLASMA, fptr); /* NSH 1407 - The following loop writes out the variable length arrays in the plasma structure */ for (m = 0; m < NPLASMA; m++) - { - n += fwrite (plasmamain[m].density, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].partition, sizeof (double), nions, fptr); + { + n += fwrite (plasmamain[m].density, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].partition, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].PWdenom, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].PWdtemp, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].PWnumer, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].PWntemp, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].PWdenom, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].PWdtemp, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].PWnumer, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].PWntemp, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].ioniz, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].recomb, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].ioniz, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].recomb, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].scatters, sizeof (int), nions, fptr); - n += fwrite (plasmamain[m].xscatters, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].scatters, sizeof (int), nions, fptr); + n += fwrite (plasmamain[m].xscatters, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].heat_ion, sizeof (double), nions, fptr); - n += fwrite (plasmamain[m].lum_ion, sizeof (double), nions, fptr); - } + n += fwrite (plasmamain[m].heat_ion, sizeof (double), nions, fptr); + n += fwrite (plasmamain[m].lum_ion, sizeof (double), nions, fptr); + } /* Now write out the macro atom info */ if (geo.nmacro) + { + n += fwrite (macromain, sizeof (macro_dummy), NPLASMA, fptr); + for (m = 0; m < NPLASMA; m++) { - n += fwrite (macromain, sizeof (macro_dummy), NPLASMA, fptr); - for (m = 0; m < NPLASMA; m++) - { - n += - fwrite (macromain[m].jbar, sizeof (double), size_Jbar_est, fptr); - n += - fwrite (macromain[m].jbar_old, sizeof (double), size_Jbar_est, - fptr); - n += - fwrite (macromain[m].gamma, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].gamma_old, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].gamma_e, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].gamma_e_old, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].alpha_st, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].alpha_st_old, sizeof (double), - size_gamma_est, fptr); - n += - fwrite (macromain[m].alpha_st_e, sizeof (double), size_gamma_est, - fptr); - n += - fwrite (macromain[m].alpha_st_e_old, sizeof (double), - size_gamma_est, fptr); - n += - fwrite (macromain[m].recomb_sp, sizeof (double), size_alpha_est, - fptr); - n += - fwrite (macromain[m].recomb_sp_e, sizeof (double), size_alpha_est, - fptr); - n += - fwrite (macromain[m].matom_emiss, sizeof (double), nlevels_macro, - fptr); - n += - fwrite (macromain[m].matom_abs, sizeof (double), nlevels_macro, - fptr); - - } + n += fwrite (macromain[m].jbar, sizeof (double), size_Jbar_est, fptr); + n += fwrite (macromain[m].jbar_old, sizeof (double), size_Jbar_est, fptr); + n += fwrite (macromain[m].gamma, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].gamma_old, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].gamma_e, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].gamma_e_old, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].alpha_st, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].alpha_st_old, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].alpha_st_e, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].alpha_st_e_old, sizeof (double), size_gamma_est, fptr); + n += fwrite (macromain[m].recomb_sp, sizeof (double), size_alpha_est, fptr); + n += fwrite (macromain[m].recomb_sp_e, sizeof (double), size_alpha_est, fptr); + n += fwrite (macromain[m].matom_emiss, sizeof (double), nlevels_macro, fptr); + n += fwrite (macromain[m].matom_abs, sizeof (double), nlevels_macro, fptr); } + } + fclose (fptr); Log @@ -190,15 +163,13 @@ wind_read (filename) char version[LINELENGTH]; if ((fptr = fopen (filename, "r")) == NULL) - { - return (-1); - } + { + return (-1); + } n = fread (line, sizeof (line), 1, fptr); sscanf (line, "%*s %s", version); - Log - ("Reading Windfile %s created with python version %s with python version %s\n", - filename, version, VERSION); + Log ("Reading Windfile %s created with python version %s with python version %s\n", filename, version, VERSION); n += fread (&geo, sizeof (geo), 1, fptr); @@ -224,8 +195,8 @@ wind_read (filename) /* Read the disk and qdisk structures */ - n += fread(&disk, sizeof (disk), 1, fptr); - n += fread(&qdisk, sizeof (disk), 1, fptr); + n += fread (&disk, sizeof (disk), 1, fptr); + n += fread (&qdisk, sizeof (disk), 1, fptr); calloc_plasma (NPLASMA); @@ -237,85 +208,59 @@ wind_read (filename) for (m = 0; m < NPLASMA; m++) - { + { - n += fread (plasmamain[m].density, sizeof (double), nions, fptr); - n += fread (plasmamain[m].partition, sizeof (double), nions, fptr); + n += fread (plasmamain[m].density, sizeof (double), nions, fptr); + n += fread (plasmamain[m].partition, sizeof (double), nions, fptr); - n += fread (plasmamain[m].PWdenom, sizeof (double), nions, fptr); - n += fread (plasmamain[m].PWdtemp, sizeof (double), nions, fptr); - n += fread (plasmamain[m].PWnumer, sizeof (double), nions, fptr); - n += fread (plasmamain[m].PWntemp, sizeof (double), nions, fptr); + n += fread (plasmamain[m].PWdenom, sizeof (double), nions, fptr); + n += fread (plasmamain[m].PWdtemp, sizeof (double), nions, fptr); + n += fread (plasmamain[m].PWnumer, sizeof (double), nions, fptr); + n += fread (plasmamain[m].PWntemp, sizeof (double), nions, fptr); - n += fread (plasmamain[m].ioniz, sizeof (double), nions, fptr); - n += fread (plasmamain[m].recomb, sizeof (double), nions, fptr); + n += fread (plasmamain[m].ioniz, sizeof (double), nions, fptr); + n += fread (plasmamain[m].recomb, sizeof (double), nions, fptr); - n += fread (plasmamain[m].scatters, sizeof (int), nions, fptr); - n += fread (plasmamain[m].xscatters, sizeof (double), nions, fptr); + n += fread (plasmamain[m].scatters, sizeof (int), nions, fptr); + n += fread (plasmamain[m].xscatters, sizeof (double), nions, fptr); - n += fread (plasmamain[m].heat_ion, sizeof (double), nions, fptr); - n += fread (plasmamain[m].lum_ion, sizeof (double), nions, fptr); - } + n += fread (plasmamain[m].heat_ion, sizeof (double), nions, fptr); + n += fread (plasmamain[m].lum_ion, sizeof (double), nions, fptr); + } /*Allocate space for macro-atoms */ if (geo.nmacro > 0) - { - calloc_macro (NPLASMA); - n += fread (macromain, sizeof (macro_dummy), NPLASMA, fptr); - calloc_estimators (NPLASMA); - - for (m = 0; m < NPLASMA; m++) - { - n += - fread (macromain[m].jbar, sizeof (double), size_Jbar_est, fptr); - n += - fread (macromain[m].jbar_old, sizeof (double), size_Jbar_est, - fptr); - n += - fread (macromain[m].gamma, sizeof (double), size_gamma_est, fptr); - n += - fread (macromain[m].gamma_old, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].gamma_e, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].gamma_e_old, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].alpha_st, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].alpha_st_old, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].alpha_st_e, sizeof (double), size_gamma_est, - fptr); - n += - fread (macromain[m].alpha_st_e_old, sizeof (double), - size_gamma_est, fptr); - n += - fread (macromain[m].recomb_sp, sizeof (double), size_alpha_est, - fptr); - n += - fread (macromain[m].recomb_sp_e, sizeof (double), size_alpha_est, - fptr); - n += - fread (macromain[m].matom_emiss, sizeof (double), nlevels_macro, - fptr); - n += - fread (macromain[m].matom_abs, sizeof (double), nlevels_macro, - fptr); - - /* Force recalculation of kpkt_rates */ - - macromain[m].kpkt_rates_known = 0; - } + { + calloc_macro (NPLASMA); + n += fread (macromain, sizeof (macro_dummy), NPLASMA, fptr); + calloc_estimators (NPLASMA); + for (m = 0; m < NPLASMA; m++) + { + n += fread (macromain[m].jbar, sizeof (double), size_Jbar_est, fptr); + n += fread (macromain[m].jbar_old, sizeof (double), size_Jbar_est, fptr); + n += fread (macromain[m].gamma, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].gamma_old, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].gamma_e, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].gamma_e_old, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].alpha_st, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].alpha_st_old, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].alpha_st_e, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].alpha_st_e_old, sizeof (double), size_gamma_est, fptr); + n += fread (macromain[m].recomb_sp, sizeof (double), size_alpha_est, fptr); + n += fread (macromain[m].recomb_sp_e, sizeof (double), size_alpha_est, fptr); + n += fread (macromain[m].matom_emiss, sizeof (double), nlevels_macro, fptr); + n += fread (macromain[m].matom_abs, sizeof (double), nlevels_macro, fptr); + + /* Force recalculation of kpkt_rates */ + + macromain[m].kpkt_rates_known = 0; } + } + fclose (fptr); wind_complete (wmain); @@ -348,31 +293,30 @@ wind_complete (w) /* JM Loop over number of domains */ for (ndom = 0; ndom < geo.ndomain; ndom++) + { + if (zdom[ndom].coord_type == SPHERICAL) { - if (zdom[ndom].coord_type == SPHERICAL) - { - spherical_wind_complete (ndom, w); - } - else if (zdom[ndom].coord_type == CYLIND) - { - cylind_wind_complete (ndom, w); - } - else if (zdom[ndom].coord_type == RTHETA) - { - rtheta_wind_complete (ndom, w); - } - else if (zdom[ndom].coord_type == CYLVAR) - { - cylvar_wind_complete (ndom, w); - } - else - { - Error ("wind_complete: Don't know how to complete coord_type %d\n", - zdom[ndom].coord_type); - exit (0); - } - + spherical_wind_complete (ndom, w); + } + else if (zdom[ndom].coord_type == CYLIND) + { + cylind_wind_complete (ndom, w); } + else if (zdom[ndom].coord_type == RTHETA) + { + rtheta_wind_complete (ndom, w); + } + else if (zdom[ndom].coord_type == CYLVAR) + { + cylvar_wind_complete (ndom, w); + } + else + { + Error ("wind_complete: Don't know how to complete coord_type %d\n", zdom[ndom].coord_type); + exit (0); + } + + } return (0); } @@ -386,10 +330,10 @@ spec_save (filename) int n; if ((fptr = fopen (filename, "w")) == NULL) - { - Error ("spec_save: Unable to open %s\n", filename); - exit (0); - } + { + Error ("spec_save: Unable to open %s\n", filename); + exit (0); + } sprintf (line, "Version %s nspectra %d\n", VERSION, nspectra); n = fwrite (line, sizeof (line), 1, fptr); @@ -411,29 +355,25 @@ spec_read (filename) char version[LINELENGTH]; if ((fptr = fopen (filename, "r")) == NULL) - { - Error ("spec_read: Unable to open %s\n", filename); - exit (0); - } + { + Error ("spec_read: Unable to open %s\n", filename); + exit (0); + } n = fread (line, sizeof (line), 1, fptr); sscanf (line, "%*s %s %*s %d", version, &nspectra); - Log - ("Reading specfile %s with %d spectra created with python version %s with python version %s\n", - filename, nspectra, version, VERSION); + Log ("Reading specfile %s with %d spectra created with python version %s with python version %s\n", filename, nspectra, version, VERSION); /* First allocate space */ xxspec = calloc (sizeof (spectrum_dummy), nspectra); if (xxspec == NULL) - { - Error - ("spectrum_init: Could not allocate memory for %d spectra with %d wavelengths\n", - nspectra, NWAVE); - exit (0); - } + { + Error ("spectrum_init: Could not allocate memory for %d spectra with %d wavelengths\n", nspectra, NWAVE); + exit (0); + } /* Now read the rest of the file */