mirror of
https://git.gfz-potsdam.de/naaice/iphreeqc.git
synced 2025-12-15 16:18:22 +01:00
81f180a0 Fixed bugs in inverse 6d575967 strcpy_safe and strcat_safe 6d98c4e1 trying different header files 72796f15 added <cstring> e8481607 warnings, strcat, strcpy 988bdee0 Try using goto(s) 9b10ce3f Try updated logical expression 812061be Turn off optimizing on k_temp git-subtree-dir: src git-subtree-split: 81f180a069285bcb4d180c860664b4b2a193854d
1814 lines
49 KiB
C++
1814 lines
49 KiB
C++
#include "Phreeqc.h"
|
|
#include "phqalloc.h"
|
|
#include "Solution.h"
|
|
#include "Utils.h"
|
|
|
|
#if defined(PHREEQCI_GUI)
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#endif
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
read_isotopes(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Reads master species information for isotopes
|
|
*
|
|
* Arguments:
|
|
* none
|
|
*
|
|
* Returns:
|
|
* KEYWORD if keyword encountered, input_error may be incremented if
|
|
* a keyword is encountered in an unexpected position
|
|
* EOF if eof encountered while reading mass balance concentrations
|
|
* ERROR if error occurred reading data
|
|
*
|
|
*/
|
|
|
|
int l;
|
|
class master_isotope *master_isotope_ptr;
|
|
char token[MAX_LENGTH];
|
|
class element *elt_ptr;
|
|
|
|
int return_value, opt, opt_save;
|
|
const char* next_char;
|
|
const char *opt_list[] = {
|
|
"isotope", /* 0 */
|
|
"total_is_major" /* 1 */
|
|
};
|
|
int count_opt_list = 2;
|
|
|
|
master_isotope_ptr = NULL;
|
|
elt_ptr = NULL;
|
|
/*
|
|
* Read name followed by options
|
|
*/
|
|
opt_save = OPTION_DEFAULT;
|
|
return_value = UNKNOWN;
|
|
for (;;)
|
|
{
|
|
opt = get_option(opt_list, count_opt_list, &next_char);
|
|
if (opt == OPTION_DEFAULT)
|
|
{
|
|
opt = opt_save;
|
|
}
|
|
switch (opt)
|
|
{
|
|
case OPTION_EOF: /* end of file */
|
|
return_value = EOF;
|
|
break;
|
|
case OPTION_KEYWORD: /* keyword */
|
|
return_value = KEYWORD;
|
|
break;
|
|
case OPTION_ERROR:
|
|
input_error++;
|
|
error_msg("Unknown input in SPECIES keyword.", CONTINUE);
|
|
error_msg(line_save, CONTINUE);
|
|
break;
|
|
case 0: /* isotope */
|
|
if (elt_ptr == NULL)
|
|
{
|
|
error_string = sformatf(
|
|
"The element of which this isotope is a minor isotope has not been defined, %s. ISOTOPES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
/*
|
|
* Save an isotope
|
|
*/
|
|
master_isotope_ptr = NULL;
|
|
copy_token(token, &next_char, &l);
|
|
master_isotope_ptr = master_isotope_store(token, TRUE);
|
|
master_isotope_ptr->elt = elt_ptr;
|
|
master_isotope_ptr->minor_isotope = TRUE;
|
|
master_isotope_ptr->total_is_major = FALSE;
|
|
/*
|
|
* Read units
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting units for isotopic values, %s. ISOTOPES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
master_isotope_ptr->units = string_hsave(token);
|
|
/*
|
|
* Read standard
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting isotope ratio of standard, %s. ISOTOPES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
(void)sscanf(token, SCANFORMAT, &(master_isotope_ptr->standard));
|
|
opt_save = OPTION_DEFAULT;
|
|
break;
|
|
case 1: /* total_is_major_isotope */
|
|
error_string = sformatf(
|
|
"Obsolete identifier. The total of the element must be the sum of all isotopes. ISOTOPES data block.\n%s",
|
|
line);
|
|
warning_msg(error_string);
|
|
break;
|
|
case OPTION_DEFAULT:
|
|
/*
|
|
* Read and element name
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting an element name for isotope definition, %s. ISOTOPES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
elt_ptr = element_store(token);
|
|
master_isotope_ptr = master_isotope_store(token, TRUE);
|
|
master_isotope_ptr->elt = elt_ptr;
|
|
master_isotope_ptr->minor_isotope = FALSE;
|
|
master_isotope_ptr->total_is_major = FALSE;
|
|
opt_save = OPTION_DEFAULT;
|
|
break;
|
|
}
|
|
if (return_value == EOF || return_value == KEYWORD)
|
|
break;
|
|
}
|
|
return (return_value);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
read_calculate_values(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Reads basic code with which to calculate calculate_value
|
|
*
|
|
* Arguments:
|
|
* none
|
|
*
|
|
* Returns:
|
|
* KEYWORD if keyword encountered, input_error may be incremented if
|
|
* a keyword is encountered in an unexpected position
|
|
* EOF if eof encountered while reading mass balance concentrations
|
|
* ERROR if error occurred reading data
|
|
*
|
|
*/
|
|
int l;
|
|
int return_value, opt, opt_save;
|
|
char token[MAX_LENGTH];
|
|
class calculate_value *calculate_value_ptr;
|
|
const char* next_char;
|
|
const char *opt_list[] = {
|
|
"start", /* 0 */
|
|
"end" /* 1 */
|
|
};
|
|
int count_opt_list = 2;
|
|
opt_save = OPTION_DEFAULT;
|
|
/*
|
|
* Read lines
|
|
*/
|
|
return_value = UNKNOWN;
|
|
calculate_value_ptr = NULL;
|
|
for (;;)
|
|
{
|
|
opt = get_option(opt_list, count_opt_list, &next_char);
|
|
if (opt == OPTION_DEFAULT)
|
|
{
|
|
opt = opt_save;
|
|
}
|
|
switch (opt)
|
|
{
|
|
case OPTION_EOF: /* end of file */
|
|
return_value = EOF;
|
|
break;
|
|
case OPTION_KEYWORD: /* keyword */
|
|
return_value = KEYWORD;
|
|
break;
|
|
case OPTION_ERROR:
|
|
input_error++;
|
|
error_msg("Unknown input in CALCULATE_VALUE keyword.", CONTINUE);
|
|
error_msg(line_save, CONTINUE);
|
|
break;
|
|
case 0: /* start */
|
|
opt_save = OPT_1;
|
|
break;
|
|
case 1: /* end */
|
|
opt_save = OPTION_DEFAULT;
|
|
break;
|
|
case OPTION_DEFAULT: /* read calculate_value name */
|
|
/*
|
|
* Read calculate_value name
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting a name for calculate_value definition, %s. CALCULATE_VALUES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
calculate_value_ptr = calculate_value_store(token, TRUE);
|
|
calculate_value_ptr->new_def = TRUE;
|
|
calculate_value_ptr->commands.clear();
|
|
calculate_value_ptr->linebase = NULL;
|
|
calculate_value_ptr->varbase = NULL;
|
|
calculate_value_ptr->loopbase = NULL;
|
|
opt_save = OPT_1;
|
|
break;
|
|
|
|
case OPT_1: /* read command */
|
|
if (calculate_value_ptr)
|
|
{
|
|
calculate_value_ptr->commands.append(";\0");
|
|
calculate_value_ptr->commands.append(line);
|
|
opt_save = OPT_1;
|
|
}
|
|
else
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting a calculate_value definition, %s. CALCULATE_VALUES data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
}
|
|
break;
|
|
}
|
|
if (return_value == EOF || return_value == KEYWORD)
|
|
break;
|
|
}
|
|
/* output_msg(sformatf( "%s", calculate_value[0].commands));
|
|
*/ return (return_value);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
read_isotope_ratios(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Reads isotope_ratio info, ratios are calculated with
|
|
* Basic programs read in CALCULATE_VALUE data block
|
|
*
|
|
* Arguments:
|
|
* none
|
|
*
|
|
* Returns:
|
|
* KEYWORD if keyword encountered, input_error may be incremented if
|
|
* a keyword is encountered in an unexpected position
|
|
* EOF if eof encountered while reading mass balance concentrations
|
|
* ERROR if error occurred reading data
|
|
*
|
|
*/
|
|
int l;
|
|
int return_value, opt, opt_save;
|
|
char token[MAX_LENGTH];
|
|
class isotope_ratio *isotope_ratio_ptr;
|
|
const char* next_char;
|
|
const char *opt_list[] = {
|
|
"no_options" /* 0 */
|
|
};
|
|
int count_opt_list = 0;
|
|
opt_save = OPTION_DEFAULT;
|
|
/*
|
|
* Read lines
|
|
*/
|
|
return_value = UNKNOWN;
|
|
isotope_ratio_ptr = NULL;
|
|
for (;;)
|
|
{
|
|
opt = get_option(opt_list, count_opt_list, &next_char);
|
|
if (opt == OPTION_DEFAULT)
|
|
{
|
|
opt = opt_save;
|
|
}
|
|
switch (opt)
|
|
{
|
|
case OPTION_EOF: /* end of file */
|
|
return_value = EOF;
|
|
break;
|
|
case OPTION_KEYWORD: /* keyword */
|
|
return_value = KEYWORD;
|
|
break;
|
|
case OPTION_ERROR:
|
|
input_error++;
|
|
error_msg("Unknown input in ISOTOPE_RATIOS keyword.", CONTINUE);
|
|
error_msg(line_save, CONTINUE);
|
|
break;
|
|
case OPTION_DEFAULT: /* read isotope_ratio name */
|
|
/*
|
|
* Read isotope_ratio name
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting a name for isotope_ratio definition, %s. ISOTOPE_RATIOS data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
isotope_ratio_ptr = isotope_ratio_store(token, TRUE);
|
|
/*
|
|
* Read isotope
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting a name of isotope for an isotope_ratio definition, %s. ISOTOPE_RATIOS data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
isotope_ratio_ptr->isotope_name = string_hsave(token);
|
|
opt_save = OPTION_DEFAULT;
|
|
break;
|
|
}
|
|
if (return_value == EOF || return_value == KEYWORD)
|
|
break;
|
|
}
|
|
return (return_value);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
read_isotope_alphas(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Reads isotope_alpha info, ratios are calculated with
|
|
* Basic programs read in CALCULATE_VALUE data block
|
|
*
|
|
* Arguments:
|
|
* none
|
|
*
|
|
* Returns:
|
|
* KEYWORD if keyword encountered, input_error may be incremented if
|
|
* a keyword is encountered in an unexpected position
|
|
* EOF if eof encountered while reading mass balance concentrations
|
|
* ERROR if error occurred reading data
|
|
*
|
|
*/
|
|
int l;
|
|
int return_value, opt, opt_save;
|
|
char token[MAX_LENGTH];
|
|
class isotope_alpha *isotope_alpha_ptr;
|
|
const char* next_char;
|
|
const char *opt_list[] = {
|
|
"no_options" /* 0 */
|
|
};
|
|
int count_opt_list = 0;
|
|
opt_save = OPTION_DEFAULT;
|
|
/*
|
|
* Read lines
|
|
*/
|
|
return_value = UNKNOWN;
|
|
isotope_alpha_ptr = NULL;
|
|
for (;;)
|
|
{
|
|
opt = get_option(opt_list, count_opt_list, &next_char);
|
|
if (opt == OPTION_DEFAULT)
|
|
{
|
|
opt = opt_save;
|
|
}
|
|
switch (opt)
|
|
{
|
|
case OPTION_EOF: /* end of file */
|
|
return_value = EOF;
|
|
break;
|
|
case OPTION_KEYWORD: /* keyword */
|
|
return_value = KEYWORD;
|
|
break;
|
|
case OPTION_ERROR:
|
|
input_error++;
|
|
error_msg("Unknown input in ISOTOPE_ALPHAS keyword.", CONTINUE);
|
|
error_msg(line_save, CONTINUE);
|
|
break;
|
|
case OPTION_DEFAULT: /* read isotope_alpha name */
|
|
/*
|
|
* Read isotope_alpha name
|
|
*/
|
|
if (copy_token(token, &next_char, &l) == EMPTY)
|
|
{
|
|
error_string = sformatf(
|
|
"Expecting a name for isotope_alpha definition, %s. ISOTOPE_ALPHAS data block.",
|
|
line);
|
|
error_msg(error_string, CONTINUE);
|
|
input_error++;
|
|
break;
|
|
}
|
|
isotope_alpha_ptr = isotope_alpha_store(token, TRUE);
|
|
isotope_alpha_ptr->name = string_hsave(token);
|
|
if (copy_token(token, &next_char, &l) != EMPTY)
|
|
{
|
|
isotope_alpha_ptr->named_logk = string_hsave(token);
|
|
}
|
|
|
|
|
|
opt_save = OPTION_DEFAULT;
|
|
break;
|
|
}
|
|
if (return_value == EOF || return_value == KEYWORD)
|
|
break;
|
|
}
|
|
return (return_value);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
add_isotopes(cxxSolution &solution_ref)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
int i;
|
|
class master_isotope *master_isotope_ptr;
|
|
LDBLE total_moles;
|
|
/*
|
|
* zero out isotopes
|
|
*/
|
|
for (i = 0; i < (int)master_isotope.size(); i++)
|
|
{
|
|
master_isotope[i]->moles = 0;
|
|
}
|
|
master_isotope_ptr = master_isotope_search("H");
|
|
if (master_isotope_ptr != NULL)
|
|
{
|
|
total_moles = total_h_x;
|
|
calculate_isotope_moles(master_isotope_ptr->elt, &solution_ref,
|
|
total_moles);
|
|
}
|
|
master_isotope_ptr = master_isotope_search("O");
|
|
if (master_isotope_ptr != NULL)
|
|
{
|
|
total_moles = total_o_x;
|
|
calculate_isotope_moles(master_isotope_ptr->elt, &solution_ref,
|
|
total_moles);
|
|
}
|
|
cxxNameDouble::iterator it = solution_ref.Get_totals().begin();
|
|
for ( ; it != solution_ref.Get_totals().end(); it++)
|
|
{
|
|
master_isotope_ptr = master_isotope_search(it->first.c_str());
|
|
if (master_isotope_ptr == NULL)
|
|
continue;
|
|
if (master_isotope_ptr->minor_isotope == FALSE)
|
|
{
|
|
total_moles = total(master_isotope_ptr->name) * mass_water_aq_x;
|
|
calculate_isotope_moles(master_isotope_ptr->elt, &solution_ref,
|
|
total_moles);
|
|
}
|
|
}
|
|
/*
|
|
* Set isotopes flag
|
|
*/
|
|
initial_solution_isotopes = FALSE;
|
|
for (i = 0; i < (int)master_isotope.size(); i++)
|
|
{
|
|
if (master_isotope[i]->minor_isotope == TRUE
|
|
&& master_isotope[i]->moles > 0)
|
|
{
|
|
initial_solution_isotopes = TRUE;
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
calculate_isotope_moles(class element *elt_ptr,
|
|
cxxSolution *solution_ptr, LDBLE total_moles)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
int i, j, l_iter;
|
|
int count_isotopes, total_is_major;
|
|
class master_isotope *master_isotope_ptr, *master_isotope_ptr1;
|
|
class master_isotope list[MAX_ELTS];
|
|
LDBLE m_major, tot;
|
|
/*
|
|
* Get total concentration of elt_ptr
|
|
*/
|
|
if (total_moles <= 0)
|
|
{
|
|
error_string = sformatf(
|
|
"Cannot calculate molality of isotopes, molality of element is zero, %s",
|
|
elt_ptr->name);
|
|
warning_msg(error_string);
|
|
return (ERROR);
|
|
}
|
|
m_major = total_moles;
|
|
/*
|
|
* Make a list of isotopes
|
|
*/
|
|
count_isotopes = 0;
|
|
total_is_major = FALSE;
|
|
master_isotope_ptr = master_isotope_search("H");
|
|
if ((master_isotope_ptr != NULL) && (master_isotope_ptr->elt == elt_ptr))
|
|
{
|
|
// memcpy(&(list[count_isotopes]), master_isotope_ptr,
|
|
// sizeof(class master_isotope));
|
|
list[count_isotopes] = *master_isotope_ptr;
|
|
list[count_isotopes].ratio = 1.0;
|
|
if (list[count_isotopes].minor_isotope == FALSE)
|
|
{
|
|
total_is_major = list[count_isotopes].total_is_major;
|
|
}
|
|
count_isotopes++;
|
|
}
|
|
master_isotope_ptr = master_isotope_search("O");
|
|
if ((master_isotope_ptr != NULL) && (master_isotope_ptr->elt == elt_ptr))
|
|
{
|
|
// memcpy(&(list[count_isotopes]), master_isotope_ptr,
|
|
// sizeof(class master_isotope));
|
|
list[count_isotopes] = *master_isotope_ptr;
|
|
list[count_isotopes].ratio = 1.0;
|
|
if (list[count_isotopes].minor_isotope == FALSE)
|
|
{
|
|
total_is_major = list[count_isotopes].total_is_major;
|
|
}
|
|
count_isotopes++;
|
|
}
|
|
if (solution_ptr->Get_initial_data() != NULL)
|
|
{
|
|
std::map<std::string, cxxISolutionComp>::iterator it = solution_ptr->Get_initial_data()->Get_comps().begin();
|
|
for ( ; it != solution_ptr->Get_initial_data()->Get_comps().end(); it++)
|
|
{
|
|
master_isotope_ptr = master_isotope_search(it->first.c_str());
|
|
if (master_isotope_ptr == NULL)
|
|
continue;
|
|
if (master_isotope_ptr->elt != elt_ptr)
|
|
continue;
|
|
// memcpy(&(list[count_isotopes]), master_isotope_ptr,
|
|
// sizeof(class master_isotope));
|
|
list[count_isotopes] = *master_isotope_ptr;
|
|
if (list[count_isotopes].minor_isotope == FALSE)
|
|
{
|
|
total_is_major = list[count_isotopes].total_is_major;
|
|
}
|
|
count_isotopes++;
|
|
}
|
|
}
|
|
/*
|
|
* Loop to calculate isotope molalities
|
|
*/
|
|
for (l_iter = 0; l_iter < itmax; l_iter++)
|
|
{
|
|
tot = 0;
|
|
for (i = 0; i < count_isotopes; i++)
|
|
{
|
|
if (list[i].minor_isotope == FALSE)
|
|
{
|
|
list[i].moles = m_major;
|
|
tot += m_major;
|
|
continue;
|
|
}
|
|
if (strcmp_nocase(list[i].units, "permil") == 0)
|
|
{
|
|
from_permil(&(list[i]), m_major);
|
|
tot += list[i].moles;
|
|
continue;
|
|
}
|
|
if (strcmp_nocase(list[i].units, "pct") == 0)
|
|
{
|
|
from_pct(&(list[i]), total_moles);
|
|
tot += list[i].moles;
|
|
continue;
|
|
}
|
|
if (strcmp_nocase(list[i].units, "pmc") == 0)
|
|
{
|
|
from_pct(&(list[i]), total_moles);
|
|
tot += list[i].moles;
|
|
continue;
|
|
}
|
|
if (strcmp_nocase(list[i].units, "tu") == 0)
|
|
{
|
|
from_tu(&(list[i]));
|
|
tot += list[i].moles;
|
|
continue;
|
|
}
|
|
if (strcmp_nocase(list[i].units, "pci/l") == 0)
|
|
{
|
|
from_pcil(&(list[i]));
|
|
tot += list[i].moles;
|
|
continue;
|
|
}
|
|
error_string = sformatf( "Isotope units not recognized, %s",
|
|
list[i].units);
|
|
input_error++;
|
|
error_msg(error_string, CONTINUE);
|
|
}
|
|
if (total_is_major == TRUE)
|
|
break;
|
|
if (fabs(total_moles - tot) < convergence_tolerance * total_moles)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
m_major = m_major * total_moles / tot;
|
|
}
|
|
}
|
|
if (l_iter >= itmax)
|
|
{
|
|
error_msg("Failed to converge in CALCULATE_ISOTOPE_MOLES.", STOP);
|
|
}
|
|
/*
|
|
* Update master_isotope
|
|
*/
|
|
for (j = 0; j < (int)master_isotope.size(); j++)
|
|
{
|
|
for (i = 0; i < count_isotopes; i++)
|
|
{
|
|
if (list[i].name == master_isotope[j]->name)
|
|
{
|
|
// memcpy(master_isotope[j], &(list[i]),
|
|
// sizeof(class master_isotope));
|
|
*master_isotope[j] = list[i];
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
* Update solution
|
|
*/
|
|
master_isotope_ptr1 = master_isotope_search("H");
|
|
if (master_isotope_ptr1 != NULL && master_isotope_ptr1->elt == elt_ptr)
|
|
{
|
|
total_h_x = m_major;
|
|
}
|
|
master_isotope_ptr1 = master_isotope_search("O");
|
|
if (master_isotope_ptr1 != NULL && master_isotope_ptr1->elt == elt_ptr)
|
|
{
|
|
total_o_x = m_major;
|
|
}
|
|
//cxxNameDouble nd(solution_ptr->Get_totals());
|
|
//cxxNameDouble::iterator iit = solution_ptr->Get_totals().begin();
|
|
//for ( ; iit != solution_ptr->Get_totals().end(); iit++)
|
|
//{
|
|
// master_isotope_ptr = master_isotope_search(iit->first.c_str());
|
|
// if (master_isotope_ptr == NULL)
|
|
// continue;
|
|
// if (master_isotope_ptr->elt != elt_ptr)
|
|
// continue;
|
|
// nd[iit->first] = master_isotope_ptr->moles;
|
|
//}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
from_permil(class master_isotope *master_isotope_ptr, LDBLE major_total)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
LDBLE r;
|
|
|
|
r = (master_isotope_ptr->ratio / 1000. +
|
|
1.0) * master_isotope_ptr->standard;
|
|
master_isotope_ptr->moles = major_total * r;
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
from_pct(class master_isotope *master_isotope_ptr, LDBLE total_moles)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
master_isotope_ptr->moles =
|
|
master_isotope_ptr->ratio / 100 * master_isotope_ptr->standard *
|
|
total_moles;
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
from_tu(class master_isotope *master_isotope_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
master_isotope_ptr->moles =
|
|
master_isotope_ptr->ratio * master_isotope_ptr->standard *
|
|
mass_water_aq_x / gfw_water;
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
from_pcil(class master_isotope *master_isotope_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
master_isotope_ptr->moles =
|
|
master_isotope_ptr->ratio * master_isotope_ptr->standard *
|
|
mass_water_aq_x / gfw_water;
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
print_initial_solution_isotopes(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Print isotopes for initial solution
|
|
*/
|
|
int i, j;
|
|
int print_isotope;
|
|
|
|
if (pr.initial_isotopes == FALSE || pr.all == FALSE)
|
|
return (OK);
|
|
if (state != INITIAL_SOLUTION)
|
|
return (OK);
|
|
if (initial_solution_isotopes == FALSE)
|
|
return (OK);
|
|
/*
|
|
* Print heading
|
|
*/
|
|
print_centered("Isotopes");
|
|
output_msg(sformatf( "%10s\t%12s\t%12s\t%12s\t%12s\n\n", "Isotope",
|
|
"Molality", "Moles", "Ratio", "Units"));
|
|
for (i = 0; i < (int)master_isotope.size(); i++)
|
|
{
|
|
if (master_isotope[i]->minor_isotope == FALSE)
|
|
{
|
|
print_isotope = FALSE;
|
|
for (j = 0; j < (int)master_isotope.size(); j++)
|
|
{
|
|
if ((master_isotope[j]->elt == master_isotope[i]->elt) &&
|
|
(master_isotope[j]->minor_isotope == TRUE) &&
|
|
(master_isotope[j]->moles > 0))
|
|
{
|
|
print_isotope = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (print_isotope == FALSE)
|
|
continue;
|
|
/*
|
|
* Print isotope values
|
|
*/
|
|
output_msg(sformatf( "%10s\t%12.5e\t%12.5e\n",
|
|
master_isotope[i]->name,
|
|
(double) (master_isotope[i]->moles / mass_water_aq_x),
|
|
(double) master_isotope[i]->moles));
|
|
for (j = 0; j < (int)master_isotope.size(); j++)
|
|
{
|
|
if (i == j)
|
|
continue;
|
|
if ((master_isotope[j]->elt == master_isotope[i]->elt) &&
|
|
(master_isotope[j]->minor_isotope == TRUE))
|
|
{
|
|
output_msg(sformatf(
|
|
"%10s\t%12.5e\t%12.5e\t%12.5e\t%12s\n",
|
|
master_isotope[j]->name,
|
|
(double) (master_isotope[j]->moles /
|
|
mass_water_aq_x),
|
|
(double) master_isotope[j]->moles,
|
|
(double) master_isotope[j]->ratio,
|
|
master_isotope[j]->units));
|
|
}
|
|
}
|
|
output_msg(sformatf( "\n"));
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
punch_isotopes(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Punch isotope ratios relative to standards
|
|
*/
|
|
//int i;
|
|
LDBLE iso;
|
|
class isotope_ratio *isotope_ratio_ptr;
|
|
class master_isotope *master_isotope_ptr;
|
|
|
|
//if (punch.in == FALSE || punch.isotopes == FALSE)
|
|
// return (OK);
|
|
if (current_selected_output->Get_isotopes().size() == 0)
|
|
return(OK);
|
|
//if (punch.count_isotopes == 0)
|
|
// return (OK);
|
|
//for (i = 0; i < punch.count_isotopes; i++)
|
|
for (size_t i = 0; i < current_selected_output->Get_isotopes().size(); i++)
|
|
{
|
|
iso = MISSING;
|
|
if (state == INITIAL_SOLUTION)
|
|
{
|
|
isotope_ratio_ptr = isotope_ratio_search(current_selected_output->Get_isotopes()[i].first.c_str());
|
|
if (isotope_ratio_ptr != NULL)
|
|
{
|
|
master_isotope_ptr =
|
|
master_isotope_search(isotope_ratio_ptr->isotope_name);
|
|
if (master_isotope_ptr != NULL
|
|
&& master_isotope_ptr->minor_isotope == TRUE)
|
|
{
|
|
iso = master_isotope_ptr->ratio;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isotope_ratio_ptr = isotope_ratio_search(current_selected_output->Get_isotopes()[i].first.c_str());
|
|
if (isotope_ratio_ptr != NULL)
|
|
{
|
|
iso = isotope_ratio_ptr->converted_ratio;
|
|
}
|
|
}
|
|
if (!current_selected_output->Get_high_precision())
|
|
{
|
|
fpunchf(sformatf("I_%s", current_selected_output->Get_isotopes()[i].first.c_str()), "%12.4e\t",
|
|
(double) iso);
|
|
}
|
|
else
|
|
{
|
|
fpunchf(sformatf("I_%s", current_selected_output->Get_isotopes()[i].first.c_str()), "%20.12e\t",
|
|
(double) iso);
|
|
}
|
|
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
punch_calculate_values(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Punch calculate values
|
|
*/
|
|
//int i;
|
|
LDBLE result;
|
|
class calculate_value *calculate_value_ptr;
|
|
char l_command[] = "run";
|
|
|
|
if (current_selected_output->Get_calculate_values().size() == 0)
|
|
return OK;
|
|
|
|
for (size_t i = 0; i < current_selected_output->Get_calculate_values().size(); i++)
|
|
{
|
|
result = MISSING;
|
|
calculate_value_ptr =
|
|
calculate_value_search(current_selected_output->Get_calculate_values()[i].first.c_str());
|
|
if (!calculate_value_ptr)
|
|
{
|
|
error_string = sformatf(
|
|
"Definition not found for CALCULATE_VALUES %s.",
|
|
current_selected_output->Get_calculate_values()[i].first.c_str());
|
|
error_msg(error_string, STOP);
|
|
#if !defined(R_SO)
|
|
exit(4);
|
|
#endif
|
|
}
|
|
|
|
if (calculate_value_ptr->calculated == FALSE)
|
|
{
|
|
rate_moles = NAN;
|
|
if (calculate_value_ptr->new_def == TRUE)
|
|
{
|
|
if (basic_compile
|
|
(calculate_value_ptr->commands.c_str(), &calculate_value_ptr->linebase,
|
|
&calculate_value_ptr->varbase,
|
|
&calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf(
|
|
"Fatal Basic error in CALCULATE_VALUES %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
calculate_value_ptr->new_def = FALSE;
|
|
}
|
|
if (basic_run
|
|
(l_command, calculate_value_ptr->linebase,
|
|
calculate_value_ptr->varbase, calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf( "Fatal Basic error in calculate_value %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
if (std::isnan(rate_moles))
|
|
{
|
|
error_string = sformatf( "Calculated value not SAVEed for %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
else
|
|
{
|
|
calculate_value_ptr->calculated = TRUE;
|
|
calculate_value_ptr->value = rate_moles;
|
|
}
|
|
}
|
|
if (calculate_value_ptr != NULL)
|
|
{
|
|
result = calculate_value_ptr->value;
|
|
}
|
|
if (!current_selected_output->Get_high_precision())
|
|
{
|
|
fpunchf(sformatf("V_%s", current_selected_output->Get_calculate_values()[i].first.c_str()),
|
|
"%12.4e\t", (double) result);
|
|
}
|
|
else
|
|
{
|
|
fpunchf(sformatf("V_%s", current_selected_output->Get_calculate_values()[i].first.c_str()),
|
|
"%20.12e\t", (double) result);
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
print_isotope_ratios(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Print isotopes for initial solution
|
|
*/
|
|
int i, j;
|
|
int print_isotope;
|
|
class master *master_ptr;
|
|
class master_isotope *master_isotope_ptr;
|
|
char token[MAX_LENGTH];
|
|
|
|
|
|
if (pr.isotope_ratios == FALSE || pr.all == FALSE)
|
|
return (OK);
|
|
if (state == INITIAL_SOLUTION)
|
|
return (OK);
|
|
/*
|
|
* Print heading
|
|
*/
|
|
print_isotope = FALSE;
|
|
for (i = 0; i < (int)master_isotope.size(); i++)
|
|
{
|
|
if (master_isotope[i]->minor_isotope == FALSE)
|
|
continue;
|
|
master_ptr = master_bsearch(master_isotope[i]->name);
|
|
if (master_ptr == NULL)
|
|
continue;
|
|
if (master_ptr->total > 0 || master_ptr->s->moles > 0)
|
|
{
|
|
print_isotope = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (print_isotope == FALSE)
|
|
return (OK);
|
|
|
|
print_centered("Isotope Ratios");
|
|
output_msg(sformatf( "%25s\t%12s\t%15s\n\n", "Isotope Ratio",
|
|
"Ratio", "Input Units"));
|
|
|
|
for (j = 0; j < (int)isotope_ratio.size(); j++)
|
|
{
|
|
if (isotope_ratio[j]->ratio == MISSING)
|
|
continue;
|
|
master_isotope_ptr =
|
|
master_isotope_search(isotope_ratio[j]->isotope_name);
|
|
/*
|
|
* Print isotope ratio
|
|
*/
|
|
Utilities::strcpy_safe(token, MAX_LENGTH, isotope_ratio[j]->name);
|
|
while (replace("_", " ", token) == TRUE);
|
|
output_msg(sformatf( " %-20s\t%12.5e\t%15.5g %-10s\n",
|
|
token, (double) isotope_ratio[j]->ratio,
|
|
(double) isotope_ratio[j]->converted_ratio,
|
|
master_isotope_ptr->units));
|
|
}
|
|
output_msg(sformatf( "\n"));
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
print_isotope_alphas(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Print isotopes for initial solution
|
|
*/
|
|
int i, j;
|
|
int print_isotope;
|
|
class master *master_ptr;
|
|
char token[MAX_LENGTH];
|
|
LDBLE log_alpha;
|
|
|
|
if (pr.isotope_alphas == FALSE || pr.all == FALSE)
|
|
return (OK);
|
|
if (state == INITIAL_SOLUTION)
|
|
return (OK);
|
|
/*
|
|
* Print heading
|
|
*/
|
|
print_isotope = FALSE;
|
|
for (i = 0; i < (int)master_isotope.size(); i++)
|
|
{
|
|
if (master_isotope[i]->minor_isotope == FALSE)
|
|
continue;
|
|
master_ptr = master_bsearch(master_isotope[i]->name);
|
|
if (master_ptr == NULL)
|
|
continue;
|
|
if (master_ptr->total > 0 || master_ptr->s->moles > 0)
|
|
{
|
|
print_isotope = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (print_isotope == FALSE)
|
|
return (OK);
|
|
|
|
print_centered("Isotope Alphas");
|
|
output_msg(sformatf( "%75s\n", "1000ln(Alpha)"));
|
|
output_msg(sformatf( "%79s\n", "----------------------"));
|
|
output_msg(sformatf( "%-37s%14s%14s%12.1f C\n\n",
|
|
" Isotope Ratio", "Solution alpha", "Solution",
|
|
(double) tc_x));
|
|
|
|
for (j = 0; j < (int)isotope_alpha.size(); j++)
|
|
{
|
|
if (isotope_alpha[j]->value == MISSING)
|
|
continue;
|
|
/*
|
|
* Print isotope ratio
|
|
*/
|
|
Utilities::strcpy_safe(token, MAX_LENGTH, isotope_alpha[j]->name);
|
|
while (replace("_", " ", token) == TRUE);
|
|
if (isotope_alpha[j]->named_logk != NULL)
|
|
{
|
|
if (isotope_alpha[j]->value <= 0)
|
|
{
|
|
log_alpha = -999.999;
|
|
}
|
|
else
|
|
{
|
|
log_alpha = 1000 * log(isotope_alpha[j]->value);
|
|
}
|
|
output_msg(sformatf( "%-37s%14.5g%14.5g%14.5g\n", token,
|
|
(double) isotope_alpha[j]->value, (double) log_alpha,
|
|
(double) (1000 *
|
|
calc_logk_n(isotope_alpha[j]->named_logk) *
|
|
LOG_10)));
|
|
}
|
|
else
|
|
{
|
|
output_msg(sformatf( "%-37s%14.5g%14.5g\n", token,
|
|
(double) isotope_alpha[j]->value,
|
|
(double) (1000 * log(isotope_alpha[j]->value))));
|
|
}
|
|
|
|
}
|
|
output_msg(sformatf( "\n"));
|
|
return (OK);
|
|
}
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
calculate_values(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
int j;
|
|
class calculate_value *calculate_value_ptr;
|
|
class isotope_ratio *isotope_ratio_ptr;
|
|
class isotope_alpha *isotope_alpha_ptr;
|
|
class master_isotope *master_isotope_ptr;
|
|
char l_command[] = "run";
|
|
|
|
|
|
/*
|
|
* initialize ratios as missing
|
|
*/
|
|
for (j = 0; j < calculate_value.size(); j++)
|
|
{
|
|
calculate_value[j]->calculated = FALSE;
|
|
calculate_value[j]->value = MISSING;
|
|
}
|
|
if (pr.isotope_ratios == TRUE)
|
|
{
|
|
for (j = 0; j < (int)isotope_ratio.size(); j++)
|
|
{
|
|
isotope_ratio_ptr = isotope_ratio[j];
|
|
master_isotope_ptr =
|
|
master_isotope_search(isotope_ratio_ptr->isotope_name);
|
|
if (master_isotope_ptr->master->s->in == FALSE) continue;
|
|
calculate_value_ptr = calculate_value_search(isotope_ratio_ptr->name);
|
|
if (calculate_value_ptr->calculated == FALSE)
|
|
{
|
|
rate_moles = NAN;
|
|
if (calculate_value_ptr->new_def == TRUE)
|
|
{
|
|
if (basic_compile
|
|
(calculate_value_ptr->commands.c_str(), &calculate_value_ptr->linebase,
|
|
&calculate_value_ptr->varbase,
|
|
&calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf(
|
|
"Fatal Basic error in CALCULATE_VALUES %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
calculate_value_ptr->new_def = FALSE;
|
|
}
|
|
if (basic_run
|
|
(l_command, calculate_value_ptr->linebase,
|
|
calculate_value_ptr->varbase, calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf( "Fatal Basic error in calculate_value %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
if (std::isnan(rate_moles))
|
|
{
|
|
error_string = sformatf( "Calculated value not SAVEed for %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
else
|
|
{
|
|
calculate_value_ptr->calculated = TRUE;
|
|
calculate_value_ptr->value = rate_moles;
|
|
}
|
|
}
|
|
/*
|
|
* Calculate converted isotope ratio
|
|
*/
|
|
if (calculate_value_ptr->value == MISSING)
|
|
{
|
|
isotope_ratio_ptr->ratio = MISSING;
|
|
isotope_ratio_ptr->converted_ratio = MISSING;
|
|
}
|
|
else
|
|
{
|
|
isotope_ratio_ptr->ratio = calculate_value_ptr->value;
|
|
isotope_ratio_ptr->converted_ratio =
|
|
convert_isotope(master_isotope_ptr,
|
|
calculate_value_ptr->value);
|
|
}
|
|
}
|
|
}
|
|
if (pr.isotope_alphas == TRUE)
|
|
{
|
|
for (j = 0; j < (int)isotope_alpha.size(); j++)
|
|
{
|
|
isotope_alpha_ptr = isotope_alpha[j];
|
|
calculate_value_ptr = calculate_value_search(isotope_alpha_ptr->name);
|
|
/*
|
|
* Calculate converted isotope ratio
|
|
*/
|
|
if (calculate_value_ptr->calculated == FALSE)
|
|
{
|
|
rate_moles = NAN;
|
|
if (calculate_value_ptr->new_def == TRUE)
|
|
{
|
|
if (basic_compile
|
|
(calculate_value_ptr->commands.c_str(), &calculate_value_ptr->linebase,
|
|
&calculate_value_ptr->varbase,
|
|
&calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf(
|
|
"Fatal Basic error in CALCULATE_VALUES %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
calculate_value_ptr->new_def = FALSE;
|
|
}
|
|
if (basic_run
|
|
(l_command, calculate_value_ptr->linebase,
|
|
calculate_value_ptr->varbase, calculate_value_ptr->loopbase) != 0)
|
|
{
|
|
error_string = sformatf( "Fatal Basic error in calculate_value %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
if (std::isnan(rate_moles))
|
|
{
|
|
error_string = sformatf( "Calculated value not SAVEed for %s.",
|
|
calculate_value_ptr->name);
|
|
error_msg(error_string, STOP);
|
|
}
|
|
else
|
|
{
|
|
calculate_value_ptr->calculated = TRUE;
|
|
calculate_value_ptr->value = rate_moles;
|
|
}
|
|
}
|
|
if (calculate_value_ptr->value == MISSING)
|
|
{
|
|
isotope_alpha_ptr->value = MISSING;
|
|
}
|
|
else
|
|
{
|
|
isotope_alpha_ptr->value = calculate_value_ptr->value;
|
|
}
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
/* ---------------------------------------------------------------------- */
|
|
LDBLE Phreeqc::
|
|
convert_isotope(class master_isotope * master_isotope_ptr, LDBLE ratio)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
const char *units;
|
|
units = master_isotope_ptr->units;
|
|
|
|
if (strcmp_nocase(units, "permil") == 0)
|
|
{
|
|
return ((ratio / master_isotope_ptr->standard - 1) * 1000);
|
|
}
|
|
if (strcmp_nocase(units, "pct") == 0)
|
|
{
|
|
return (ratio / master_isotope_ptr->standard * 100.);
|
|
}
|
|
if (strcmp_nocase(units, "pmc") == 0)
|
|
{
|
|
return (ratio / master_isotope_ptr->standard * 100.);
|
|
}
|
|
if (strcmp_nocase(units, "tu") == 0)
|
|
{
|
|
return (ratio / master_isotope_ptr->standard);
|
|
}
|
|
if (strcmp_nocase(units, "pci/l") == 0)
|
|
{
|
|
return (ratio / master_isotope_ptr->standard);
|
|
}
|
|
error_string = sformatf(
|
|
"Did not recognize isotope units in convert_isotope, %s", units);
|
|
error_msg(error_string, STOP);
|
|
return (-99.0);
|
|
}
|
|
|
|
/*
|
|
* Utility routines for master_isotope
|
|
*/
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class master_isotope * Phreeqc::
|
|
master_isotope_store(const char *name, int replace_if_found)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for master_isotope.
|
|
*
|
|
* Pointer to a master_isotope structure is always returned.
|
|
*
|
|
* If the string is not found, a new entry is made in the map. Pointer to
|
|
* the new structure is returned.
|
|
* If "name" is found and replace is true, pointers in old master_isotope structure
|
|
* are freed and replaced with additional input.
|
|
* If "name" is found and replace is false, the old master_isotope structure is not
|
|
* modified and a pointer to it is returned.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "master_isotope".
|
|
* replace_if_found input, TRUE means reinitialize master_isotope structure if found
|
|
* FALSE means just return pointer if found.
|
|
*
|
|
* Returns:
|
|
* pointer to master_isotope structure "master_isotope" where "name" can be found.
|
|
*/
|
|
int n;
|
|
class master_isotope *master_isotope_ptr;
|
|
/*
|
|
* Search list
|
|
*/
|
|
std::map<std::string, class master_isotope*>::iterator mi_it =
|
|
master_isotope_map.find(name);
|
|
if (mi_it != master_isotope_map.end() && replace_if_found == FALSE)
|
|
{
|
|
master_isotope_ptr = mi_it->second;
|
|
return (master_isotope_ptr);
|
|
}
|
|
else if (mi_it != master_isotope_map.end() && replace_if_found == TRUE)
|
|
{
|
|
master_isotope_ptr = mi_it->second;
|
|
master_isotope_init(master_isotope_ptr);
|
|
}
|
|
else
|
|
{
|
|
n = (int)master_isotope.size();
|
|
master_isotope.resize((size_t)n + 1);
|
|
/* Make new master_isotope structure */
|
|
master_isotope[n] = master_isotope_alloc();
|
|
master_isotope_ptr = master_isotope[n];
|
|
}
|
|
/* set name and z in pointer in master_isotope structure */
|
|
master_isotope_ptr->name = string_hsave(name);
|
|
/*
|
|
* Update map
|
|
*/
|
|
master_isotope_map[name] = master_isotope_ptr;
|
|
return (master_isotope_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class master_isotope * Phreeqc::
|
|
master_isotope_alloc(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* Allocates space to a master_isotope structure, initializes
|
|
* arguments: void
|
|
* return: pointer to a master_isotope structure
|
|
*/
|
|
{
|
|
class master_isotope *master_isotope_ptr = new class master_isotope;
|
|
/*
|
|
* set pointers in structure to NULL, variables to zero
|
|
*/
|
|
master_isotope_init(master_isotope_ptr);
|
|
|
|
return (master_isotope_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
master_isotope_init(class master_isotope *master_isotope_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* return: pointer to a master_isotope structure
|
|
*/
|
|
{
|
|
/*
|
|
* set pointers in structure to NULL
|
|
*/
|
|
if (master_isotope_ptr)
|
|
{
|
|
master_isotope_ptr->name = NULL;
|
|
master_isotope_ptr->master = NULL;
|
|
master_isotope_ptr->elt = NULL;
|
|
master_isotope_ptr->units = NULL;
|
|
master_isotope_ptr->standard = 0;
|
|
master_isotope_ptr->ratio = 0;
|
|
master_isotope_ptr->moles = 0;
|
|
master_isotope_ptr->total_is_major = 0;
|
|
master_isotope_ptr->minor_isotope = 1;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class master_isotope * Phreeqc::
|
|
master_isotope_search(const char *name)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for master_isotope.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "master_isotope".
|
|
*
|
|
* Returns:
|
|
* pointer to master_isotope structure "master_isotope" where "name" can be found.
|
|
* or NULL if not found.
|
|
*/
|
|
class master_isotope* master_isotope_ptr = NULL;
|
|
/*
|
|
* Search list
|
|
*/
|
|
std::map<std::string, class master_isotope*>::iterator mi_it =
|
|
master_isotope_map.find(name);
|
|
if (mi_it != master_isotope_map.end())
|
|
{
|
|
master_isotope_ptr = mi_it->second;
|
|
return (master_isotope_ptr);
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* Utility routines for calculate_value
|
|
*/
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class calculate_value * Phreeqc::
|
|
calculate_value_store(const char *name_in, int replace_if_found)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for calculate_value.
|
|
*
|
|
* Pointer to a calculate_value structure is always returned.
|
|
*
|
|
* If the string is not found, a new entry is made in the map. Pointer to
|
|
* the new structure is returned.
|
|
* If "name" is found and replace is true, pointers in old calculate_value structure
|
|
* are freed and replaced with additional input.
|
|
* If "name" is found and replace is false, the old calculate_value structure is not
|
|
* modified and a pointer to it is returned.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "calculate_value".
|
|
* replace_if_found input, TRUE means reinitialize calculate_value structure if found
|
|
* FALSE means just return pointer if found.
|
|
*
|
|
* Returns:
|
|
* pointer to calculate_value structure "calculate_value" where "name" can be found.
|
|
*/
|
|
class calculate_value *calculate_value_ptr=NULL;
|
|
/*
|
|
* Search list
|
|
*/
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class calculate_value*>::iterator cv_it =
|
|
calculate_value_map.find(name);
|
|
if (cv_it != calculate_value_map.end() && replace_if_found == FALSE)
|
|
{
|
|
calculate_value_ptr = cv_it->second;
|
|
return (calculate_value_ptr);
|
|
}
|
|
else if (cv_it != calculate_value_map.end() && replace_if_found == TRUE)
|
|
{
|
|
calculate_value_ptr = cv_it->second;
|
|
calculate_value_free(calculate_value_ptr);
|
|
calculate_value_init(calculate_value_ptr);
|
|
}
|
|
else
|
|
{
|
|
size_t n = calculate_value.size();
|
|
calculate_value.resize(n+1);
|
|
/* Make new calculate_value structure */
|
|
calculate_value[n] = calculate_value_alloc();
|
|
calculate_value_ptr = calculate_value[n];
|
|
}
|
|
/* set name in calculate_value structure */
|
|
calculate_value_ptr->name = string_hsave(name_in);
|
|
/*
|
|
* Update map
|
|
*/
|
|
calculate_value_map[name] = calculate_value_ptr;
|
|
return (calculate_value_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class calculate_value * Phreeqc::
|
|
calculate_value_alloc(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* Allocates space to a calculate_value structure, initializes
|
|
* arguments: void
|
|
* return: pointer to a calculate_value structure
|
|
*/
|
|
{
|
|
class calculate_value *calculate_value_ptr =
|
|
new class calculate_value;
|
|
/*
|
|
* set pointers in structure to NULL, variables to zero
|
|
*/
|
|
calculate_value_init(calculate_value_ptr);
|
|
|
|
return (calculate_value_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
calculate_value_init(class calculate_value *calculate_value_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* return: pointer to a calculate_value structure
|
|
*/
|
|
{
|
|
/*
|
|
* set pointers in structure to NULL
|
|
*/
|
|
if (calculate_value_ptr)
|
|
{
|
|
calculate_value_ptr->name = NULL;
|
|
calculate_value_ptr->value = 0.0;
|
|
calculate_value_ptr->commands.clear();
|
|
calculate_value_ptr->new_def = TRUE;
|
|
calculate_value_ptr->calculated = FALSE;
|
|
calculate_value_ptr->linebase = NULL;
|
|
calculate_value_ptr->varbase = NULL;
|
|
calculate_value_ptr->loopbase = NULL;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class calculate_value * Phreeqc::
|
|
calculate_value_search(const char *name_in)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for calculate_value.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "calculate_value".
|
|
*
|
|
* Returns:
|
|
* pointer to calculate_value structure "calculate_value" where "name" can be found.
|
|
* or NULL if not found.
|
|
*/
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class calculate_value*>::iterator cv_it =
|
|
calculate_value_map.find(name);
|
|
if (cv_it != calculate_value_map.end())
|
|
{
|
|
return (cv_it->second);
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
calculate_value_free(class calculate_value *calculate_value_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Frees memory allocated within calculate_value[i], does not free calculate_value structure
|
|
* Input: i, number of calculate_value
|
|
* Return: OK
|
|
*/
|
|
char cmd[] = "new; quit";
|
|
|
|
if (calculate_value_ptr == NULL)
|
|
return (ERROR);
|
|
calculate_value_ptr->commands.clear();
|
|
basic_run(cmd, calculate_value_ptr->linebase,
|
|
calculate_value_ptr->varbase, calculate_value_ptr->loopbase);
|
|
calculate_value_ptr->linebase = NULL;
|
|
calculate_value_ptr->varbase = NULL;
|
|
calculate_value_ptr->loopbase = NULL;
|
|
return (OK);
|
|
}
|
|
|
|
/*
|
|
* Utility routines for isotope_ratio
|
|
*/
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_ratio * Phreeqc::
|
|
isotope_ratio_store(const char *name_in, int replace_if_found)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for isotope_ratio.
|
|
*
|
|
* Pointer to a isotope_ratio structure is always returned.
|
|
*
|
|
* If the string is not found, a new entry is made in the map. Pointer to
|
|
* the new structure is returned.
|
|
* If "name" is found and replace is true, pointers in old isotope_ratio structure
|
|
* are freed and replaced with additional input.
|
|
* If "name" is found and replace is false, the old isotope_ratio structure is not
|
|
* modified and a pointer to it is returned.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "isotope_ratio".
|
|
* replace_if_found input, TRUE means reinitialize isotope_ratio structure if found
|
|
* FALSE means just return pointer if found.
|
|
*
|
|
* Returns:
|
|
* pointer to isotope_ratio structure "isotope_ratio" where "name" can be found.
|
|
*/
|
|
class isotope_ratio *isotope_ratio_ptr;
|
|
/*
|
|
* Search list
|
|
*/
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class isotope_ratio*>::iterator it =
|
|
isotope_ratio_map.find(name);
|
|
|
|
if (it != isotope_ratio_map.end() && replace_if_found == FALSE)
|
|
{
|
|
isotope_ratio_ptr = it->second;
|
|
return (isotope_ratio_ptr);
|
|
}
|
|
else if (it != isotope_ratio_map.end() && replace_if_found == TRUE)
|
|
{
|
|
isotope_ratio_ptr = it->second;
|
|
isotope_ratio_init(isotope_ratio_ptr);
|
|
}
|
|
else
|
|
{
|
|
size_t n = isotope_ratio.size();
|
|
isotope_ratio.resize(n + 1);
|
|
/* Make new isotope_ratio structure */
|
|
isotope_ratio[n] = isotope_ratio_alloc();
|
|
isotope_ratio_ptr = isotope_ratio[n];
|
|
}
|
|
/* set name and z in pointer in isotope_ratio structure */
|
|
isotope_ratio_ptr->name = string_hsave(name_in);
|
|
/*
|
|
* Update map
|
|
*/
|
|
isotope_ratio_map[name] = isotope_ratio_ptr;
|
|
return (isotope_ratio_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_ratio * Phreeqc::
|
|
isotope_ratio_alloc(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* Allocates space to a isotope_ratio structure, initializes
|
|
* arguments: void
|
|
* return: pointer to a isotope_ratio structure
|
|
*/
|
|
{
|
|
class isotope_ratio* isotope_ratio_ptr =
|
|
new class isotope_ratio;
|
|
/*
|
|
* set pointers in structure to NULL, variables to zero
|
|
*/
|
|
isotope_ratio_init(isotope_ratio_ptr);
|
|
|
|
return (isotope_ratio_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
isotope_ratio_init(class isotope_ratio *isotope_ratio_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* return: pointer to a isotope_ratio structure
|
|
*/
|
|
{
|
|
/*
|
|
* set pointers in structure to NULL
|
|
*/
|
|
if (isotope_ratio_ptr)
|
|
{
|
|
isotope_ratio_ptr->name = NULL;
|
|
isotope_ratio_ptr->isotope_name = NULL;
|
|
isotope_ratio_ptr->ratio = MISSING;
|
|
isotope_ratio_ptr->converted_ratio = MISSING;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_ratio * Phreeqc::
|
|
isotope_ratio_search(const char *name_in)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for isotope_ratio.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "isotope_ratio".
|
|
*
|
|
* Returns:
|
|
* pointer to isotope_ratio structure "isotope_ratio" where "name" can be found.
|
|
* or NULL if not found.
|
|
*/
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class isotope_ratio*>::iterator it =
|
|
isotope_ratio_map.find(name);
|
|
|
|
if (it != isotope_ratio_map.end())
|
|
{
|
|
return (it->second);
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* Utility routines for isotope_alpha
|
|
*/
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_alpha * Phreeqc::
|
|
isotope_alpha_store(const char *name_in, int replace_if_found)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for isotope_alpha.
|
|
*
|
|
* Pointer to a isotope_alpha structure is always returned.
|
|
*
|
|
* If the string is not found, a new entry is made in the map. Pointer to
|
|
* the new structure is returned.
|
|
* If "name" is found and replace is true, pointers in old isotope_alpha structure
|
|
* are freed and replaced with additional input.
|
|
* If "name" is found and replace is false, the old isotope_alpha structure is not
|
|
* modified and a pointer to it is returned.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "isotope_alpha".
|
|
* replace_if_found input, TRUE means reinitialize isotope_alpha structure if found
|
|
* FALSE means just return pointer if found.
|
|
*
|
|
* Returns:
|
|
* pointer to isotope_alpha structure "isotope_alpha" where "name" can be found.
|
|
*/
|
|
class isotope_alpha *isotope_alpha_ptr;
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class isotope_alpha*>::iterator it =
|
|
isotope_alpha_map.find(name);
|
|
|
|
if (it != isotope_alpha_map.end() && replace_if_found == FALSE)
|
|
{
|
|
return (it->second);
|
|
}
|
|
else if (it != isotope_alpha_map.end() && replace_if_found == TRUE)
|
|
{
|
|
isotope_alpha_ptr = it->second;
|
|
isotope_alpha_init(isotope_alpha_ptr);
|
|
}
|
|
else
|
|
{
|
|
size_t n = isotope_alpha.size();
|
|
isotope_alpha.resize(n + 1);
|
|
/* Make new isotope_alpha structure */
|
|
isotope_alpha[n] = isotope_alpha_alloc();
|
|
isotope_alpha_ptr = isotope_alpha[n];
|
|
}
|
|
/* set name and z in pointer in isotope_alpha structure */
|
|
isotope_alpha_ptr->name = string_hsave(name_in);
|
|
/*
|
|
* Update map
|
|
*/
|
|
isotope_alpha_map[name] = isotope_alpha_ptr;
|
|
return (isotope_alpha_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_alpha * Phreeqc::
|
|
isotope_alpha_alloc(void)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* Allocates space to a isotope_alpha structure, initializes
|
|
* arguments: void
|
|
* return: pointer to a isotope_alpha structure
|
|
*/
|
|
{
|
|
class isotope_alpha* isotope_alpha_ptr =
|
|
new class isotope_alpha;
|
|
/*
|
|
* set pointers in structure to NULL, variables to zero
|
|
*/
|
|
isotope_alpha_init(isotope_alpha_ptr);
|
|
|
|
return (isotope_alpha_ptr);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
int Phreeqc::
|
|
isotope_alpha_init(class isotope_alpha *isotope_alpha_ptr)
|
|
/* ---------------------------------------------------------------------- */
|
|
/*
|
|
* return: pointer to a isotope_alpha structure
|
|
*/
|
|
{
|
|
/*
|
|
* set pointers in structure to NULL
|
|
*/
|
|
if (isotope_alpha_ptr)
|
|
{
|
|
isotope_alpha_ptr->name = NULL;
|
|
isotope_alpha_ptr->named_logk = NULL;
|
|
isotope_alpha_ptr->value = MISSING;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
class isotope_alpha * Phreeqc::
|
|
isotope_alpha_search(const char *name_in)
|
|
/* ---------------------------------------------------------------------- */
|
|
{
|
|
/*
|
|
* Function locates the string "name" in the map for isotope_alpha.
|
|
*
|
|
* Arguments:
|
|
* name input, character string to be found in "isotope_alpha".
|
|
*
|
|
* Returns:
|
|
* pointer to isotope_alpha structure "isotope_alpha" where "name" can be found.
|
|
* or NULL if not found.
|
|
*/
|
|
std::string name = name_in;
|
|
str_tolower(name);
|
|
std::map<std::string, class isotope_alpha*>::iterator it =
|
|
isotope_alpha_map.find(name);
|
|
|
|
if (it != isotope_alpha_map.end())
|
|
{
|
|
return (it->second);
|
|
}
|
|
return (NULL);
|
|
}
|