From 60a154401903b338304b368832c6a4c7d1069099 Mon Sep 17 00:00:00 2001 From: David L Parkhurst Date: Thu, 16 Feb 2006 00:21:39 +0000 Subject: [PATCH] Copying new classes (cxx) and cpp files to src Will remove cpp and header files and make phreeqc an external directory. git-svn-id: svn://136.177.114.72/svn_GW/phreeqcpp/trunk@785 1feff8c3-07ed-0310-ac33-dd36852eb9cd --- Conc.cxx | 233 + Conc.h | 70 + ExchComp.cxx | 554 +++ ExchComp.h | 52 + Exchange.cxx | 413 ++ Exchange.h | 47 + GasPhase.cxx | 474 ++ GasPhase.h | 50 + ISolution.cxx | 334 ++ ISolution.h | 56 + Isotope.cxx | 241 + Isotope.h | 56 + KineticsComp.cxx | 504 ++ KineticsComp.h | 44 + KineticsCxx.cxx | 538 +++ KineticsCxx.h | 51 + Makefile | 348 ++ Mix.cxx | 200 + Mix.h | 39 + NameDouble.cxx | 259 + NameDouble.h | 57 + NumKeyword.cxx | 138 + NumKeyword.h | 43 + PPassemblage.cxx | 191 + PPassemblage.h | 43 + PPassemblageComp.cxx | 278 ++ PPassemblageComp.h | 47 + Parser.cxx | 1070 +++++ Parser.h | 205 + Pe_Data.cxx | 45 + Pe_Data.h | 28 + Reaction.cxx | 323 ++ Reaction.h | 45 + ReadClass.cpp | 701 +++ SAXPhreeqc.cpp | 888 ++++ SAXPhreeqc.h | 20 + SSassemblage.cxx | 171 + SSassemblage.h | 42 + SSassemblageSS.cxx | 443 ++ SSassemblageSS.h | 65 + SaxPhreeqcHandlers.h | 154 + Solution.cxx | 1102 +++++ Solution.h | 94 + Sun/examples/ex1.log | 0 Sun/examples/ex1.out | 325 ++ Sun/examples/ex10.log | 0 Sun/examples/ex10.out | 9431 +++++++++++++++++++++++++++++++++++++ Sun/examples/ex10.sel | 701 +++ Sun/examples/ex11.log | 0 Sun/examples/ex11.out | 2858 +++++++++++ Sun/examples/ex11adv.sel | 125 + Sun/examples/ex11trn.sel | 125 + Sun/examples/ex12.log | 0 Sun/examples/ex12.out | 99 + Sun/examples/ex12.sel | 44 + Sun/examples/ex12a.log | 0 Sun/examples/ex12a.out | 188 + Sun/examples/ex12a.sel | 169 + Sun/examples/ex13a.log | 0 Sun/examples/ex13a.out | 310 ++ Sun/examples/ex13a.sel | 42 + Sun/examples/ex13b.log | 0 Sun/examples/ex13b.out | 430 ++ Sun/examples/ex13b.sel | 42 + Sun/examples/ex13c.log | 0 Sun/examples/ex13c.out | 751 +++ Sun/examples/ex13c.sel | 42 + Sun/examples/ex14.log | 0 Sun/examples/ex14.out | 3000 ++++++++++++ Sun/examples/ex14.sel | 202 + Sun/examples/ex15.log | 0 Sun/examples/ex15.out | 2299 +++++++++ Sun/examples/ex15.sel | 78 + Sun/examples/ex16.log | 0 Sun/examples/ex16.out | 435 ++ Sun/examples/ex17.log | 0 Sun/examples/ex17.out | 349 ++ Sun/examples/ex18.log | 0 Sun/examples/ex18.out | 550 +++ Sun/examples/ex2.log | 0 Sun/examples/ex2.out | 4037 ++++++++++++++++ Sun/examples/ex2.sel | 53 + Sun/examples/ex3.log | 0 Sun/examples/ex3.out | 789 ++++ Sun/examples/ex4.log | 0 Sun/examples/ex4.out | 478 ++ Sun/examples/ex5.log | 0 Sun/examples/ex5.out | 942 ++++ Sun/examples/ex5.sel | 7 + Sun/examples/ex6.log | 0 Sun/examples/ex6.out | 3053 ++++++++++++ Sun/examples/ex6A-B.sel | 22 + Sun/examples/ex6C.sel | 9 + Sun/examples/ex7.log | 0 Sun/examples/ex7.out | 2819 +++++++++++ Sun/examples/ex7.sel | 27 + Sun/examples/ex8.log | 0 Sun/examples/ex8.out | 3612 ++++++++++++++ Sun/examples/ex8.sel | 27 + Sun/examples/ex9.log | 0 Sun/examples/ex9.out | 1284 +++++ Sun/examples/ex9.sel | 13 + SurfCharge.cxx | 493 ++ SurfCharge.h | 50 + SurfComp.cxx | 537 +++ SurfComp.h | 52 + Surface.cxx | 557 +++ Surface.h | 56 + Utils.cxx | 79 + Utils.h | 31 + advection.cpp | 103 + basic.cpp | 4400 +++++++++++++++++ basicsubs.cpp | 1774 +++++++ char_star.h | 11 + cl1.cpp | 753 +++ cl1mp.cpp | 974 ++++ classes/Conc.cxx | 188 + classes/Conc.h | 60 + classes/Isotope.cxx | 100 + classes/Isotope.h | 40 + classes/Makefile | 35 + classes/NumKeyword.cxx | 119 + classes/NumKeyword.h | 34 + classes/Parser.cxx | 836 ++++ classes/Parser.h | 196 + classes/Pe_Data.cxx | 45 + classes/Pe_Data.h | 27 + classes/Solution.cxx | 312 ++ classes/Solution.h | 72 + classes/TestCIsotope.cxx | 164 + classes/TestCIsotope.h | 39 + classes/TestCParser.cxx | 192 + classes/TestCParser.h | 48 + classes/TestCSolution.cxx | 124 + classes/TestCSolution.h | 24 + classes/main.cxx | 83 + classes/test.cxx | 23 + classes/utilities.cxx | 68 + classes/utilities.h | 28 + cpp.dsw | 29 + cvdense.cpp | 473 ++ cvdense.h | 224 + cvode.cpp | 3330 +++++++++++++ cvode.h | 882 ++++ dense.cpp | 114 + dense.h | 298 ++ distribution.checklist | 85 + distribution.mk | 368 ++ dw.cpp | 349 ++ ex1 | 77 + global.h | 1638 +++++++ input.cpp | 249 + input.h | 24 + integrate.cpp | 851 ++++ inverse.cpp | 3014 ++++++++++++ isotopes.cpp | 1540 ++++++ kinetics.cpp | 2288 +++++++++ kinetics.h | 21 + main.cpp | 140 + mainsubs.cpp | 2486 ++++++++++ model.cpp | 3102 ++++++++++++ nvector.cpp | 193 + nvector.h | 441 ++ nvector_serial.cpp | 869 ++++ nvector_serial.h | 325 ++ output.cpp | 182 + output.h | 57 + p2c.h | 543 +++ p2clib.cpp | 936 ++++ parse.cpp | 904 ++++ phast.xsd | 98 + phqalloc.cpp | 246 + phqalloc.h | 46 + phreeqc.dat | 1556 ++++++ phreeqc.rev | 4579 ++++++++++++++++++ phreeqc_files.cpp | 524 +++ phrqproto.h | 515 ++ phrqtype.h | 19 + pitzer.cpp | 1587 +++++++ pitzer.h | 50 + pitzer_structures.cpp | 195 + prep.cpp | 4055 ++++++++++++++++ print.cpp | 2259 +++++++++ read.cpp | 7904 +++++++++++++++++++++++++++++++ readtr.cpp | 1121 +++++ revisions | 1401 ++++++ smalldense.cpp | 243 + smalldense.h | 224 + spread.cpp | 1069 +++++ step.cpp | 1028 ++++ structures.cpp | 6059 ++++++++++++++++++++++++ sundialsmath.cpp | 76 + sundialsmath.h | 130 + sundialstypes.h | 144 + tally.cpp | 1006 ++++ test.xml | 70 + tidy.cpp | 3333 +++++++++++++ transport.cpp | 844 ++++ utilities.cpp | 1471 ++++++ 199 files changed, 131134 insertions(+) create mode 100644 Conc.cxx create mode 100644 Conc.h create mode 100644 ExchComp.cxx create mode 100644 ExchComp.h create mode 100644 Exchange.cxx create mode 100644 Exchange.h create mode 100644 GasPhase.cxx create mode 100644 GasPhase.h create mode 100644 ISolution.cxx create mode 100644 ISolution.h create mode 100644 Isotope.cxx create mode 100644 Isotope.h create mode 100644 KineticsComp.cxx create mode 100644 KineticsComp.h create mode 100644 KineticsCxx.cxx create mode 100644 KineticsCxx.h create mode 100644 Makefile create mode 100644 Mix.cxx create mode 100644 Mix.h create mode 100644 NameDouble.cxx create mode 100644 NameDouble.h create mode 100644 NumKeyword.cxx create mode 100644 NumKeyword.h create mode 100644 PPassemblage.cxx create mode 100644 PPassemblage.h create mode 100644 PPassemblageComp.cxx create mode 100644 PPassemblageComp.h create mode 100644 Parser.cxx create mode 100644 Parser.h create mode 100644 Pe_Data.cxx create mode 100644 Pe_Data.h create mode 100644 Reaction.cxx create mode 100644 Reaction.h create mode 100644 ReadClass.cpp create mode 100644 SAXPhreeqc.cpp create mode 100644 SAXPhreeqc.h create mode 100644 SSassemblage.cxx create mode 100644 SSassemblage.h create mode 100644 SSassemblageSS.cxx create mode 100644 SSassemblageSS.h create mode 100644 SaxPhreeqcHandlers.h create mode 100644 Solution.cxx create mode 100644 Solution.h create mode 100644 Sun/examples/ex1.log create mode 100644 Sun/examples/ex1.out create mode 100644 Sun/examples/ex10.log create mode 100644 Sun/examples/ex10.out create mode 100644 Sun/examples/ex10.sel create mode 100644 Sun/examples/ex11.log create mode 100644 Sun/examples/ex11.out create mode 100644 Sun/examples/ex11adv.sel create mode 100644 Sun/examples/ex11trn.sel create mode 100644 Sun/examples/ex12.log create mode 100644 Sun/examples/ex12.out create mode 100644 Sun/examples/ex12.sel create mode 100644 Sun/examples/ex12a.log create mode 100644 Sun/examples/ex12a.out create mode 100644 Sun/examples/ex12a.sel create mode 100644 Sun/examples/ex13a.log create mode 100644 Sun/examples/ex13a.out create mode 100644 Sun/examples/ex13a.sel create mode 100644 Sun/examples/ex13b.log create mode 100644 Sun/examples/ex13b.out create mode 100644 Sun/examples/ex13b.sel create mode 100644 Sun/examples/ex13c.log create mode 100644 Sun/examples/ex13c.out create mode 100644 Sun/examples/ex13c.sel create mode 100644 Sun/examples/ex14.log create mode 100644 Sun/examples/ex14.out create mode 100644 Sun/examples/ex14.sel create mode 100644 Sun/examples/ex15.log create mode 100644 Sun/examples/ex15.out create mode 100644 Sun/examples/ex15.sel create mode 100644 Sun/examples/ex16.log create mode 100644 Sun/examples/ex16.out create mode 100644 Sun/examples/ex17.log create mode 100644 Sun/examples/ex17.out create mode 100644 Sun/examples/ex18.log create mode 100644 Sun/examples/ex18.out create mode 100644 Sun/examples/ex2.log create mode 100644 Sun/examples/ex2.out create mode 100644 Sun/examples/ex2.sel create mode 100644 Sun/examples/ex3.log create mode 100644 Sun/examples/ex3.out create mode 100644 Sun/examples/ex4.log create mode 100644 Sun/examples/ex4.out create mode 100644 Sun/examples/ex5.log create mode 100644 Sun/examples/ex5.out create mode 100644 Sun/examples/ex5.sel create mode 100644 Sun/examples/ex6.log create mode 100644 Sun/examples/ex6.out create mode 100644 Sun/examples/ex6A-B.sel create mode 100644 Sun/examples/ex6C.sel create mode 100644 Sun/examples/ex7.log create mode 100644 Sun/examples/ex7.out create mode 100644 Sun/examples/ex7.sel create mode 100644 Sun/examples/ex8.log create mode 100644 Sun/examples/ex8.out create mode 100644 Sun/examples/ex8.sel create mode 100644 Sun/examples/ex9.log create mode 100644 Sun/examples/ex9.out create mode 100644 Sun/examples/ex9.sel create mode 100644 SurfCharge.cxx create mode 100644 SurfCharge.h create mode 100644 SurfComp.cxx create mode 100644 SurfComp.h create mode 100644 Surface.cxx create mode 100644 Surface.h create mode 100644 Utils.cxx create mode 100644 Utils.h create mode 100644 advection.cpp create mode 100644 basic.cpp create mode 100644 basicsubs.cpp create mode 100644 char_star.h create mode 100644 cl1.cpp create mode 100644 cl1mp.cpp create mode 100644 classes/Conc.cxx create mode 100644 classes/Conc.h create mode 100644 classes/Isotope.cxx create mode 100644 classes/Isotope.h create mode 100644 classes/Makefile create mode 100644 classes/NumKeyword.cxx create mode 100644 classes/NumKeyword.h create mode 100644 classes/Parser.cxx create mode 100644 classes/Parser.h create mode 100644 classes/Pe_Data.cxx create mode 100644 classes/Pe_Data.h create mode 100644 classes/Solution.cxx create mode 100644 classes/Solution.h create mode 100644 classes/TestCIsotope.cxx create mode 100644 classes/TestCIsotope.h create mode 100644 classes/TestCParser.cxx create mode 100644 classes/TestCParser.h create mode 100644 classes/TestCSolution.cxx create mode 100644 classes/TestCSolution.h create mode 100644 classes/main.cxx create mode 100644 classes/test.cxx create mode 100644 classes/utilities.cxx create mode 100644 classes/utilities.h create mode 100644 cpp.dsw create mode 100644 cvdense.cpp create mode 100644 cvdense.h create mode 100644 cvode.cpp create mode 100644 cvode.h create mode 100644 dense.cpp create mode 100644 dense.h create mode 100644 distribution.checklist create mode 100644 distribution.mk create mode 100644 dw.cpp create mode 100644 ex1 create mode 100644 global.h create mode 100644 input.cpp create mode 100644 input.h create mode 100644 integrate.cpp create mode 100644 inverse.cpp create mode 100644 isotopes.cpp create mode 100644 kinetics.cpp create mode 100644 kinetics.h create mode 100644 main.cpp create mode 100644 mainsubs.cpp create mode 100644 model.cpp create mode 100644 nvector.cpp create mode 100644 nvector.h create mode 100644 nvector_serial.cpp create mode 100644 nvector_serial.h create mode 100644 output.cpp create mode 100644 output.h create mode 100644 p2c.h create mode 100644 p2clib.cpp create mode 100644 parse.cpp create mode 100644 phast.xsd create mode 100644 phqalloc.cpp create mode 100644 phqalloc.h create mode 100644 phreeqc.dat create mode 100644 phreeqc.rev create mode 100644 phreeqc_files.cpp create mode 100644 phrqproto.h create mode 100644 phrqtype.h create mode 100644 pitzer.cpp create mode 100644 pitzer.h create mode 100644 pitzer_structures.cpp create mode 100644 prep.cpp create mode 100644 print.cpp create mode 100644 read.cpp create mode 100644 readtr.cpp create mode 100644 revisions create mode 100644 smalldense.cpp create mode 100644 smalldense.h create mode 100644 spread.cpp create mode 100644 step.cpp create mode 100644 structures.cpp create mode 100644 sundialsmath.cpp create mode 100644 sundialsmath.h create mode 100644 sundialstypes.h create mode 100644 tally.cpp create mode 100644 test.xml create mode 100644 tidy.cpp create mode 100644 transport.cpp create mode 100644 utilities.cpp diff --git a/Conc.cxx b/Conc.cxx new file mode 100644 index 00000000..c4e78dbf --- /dev/null +++ b/Conc.cxx @@ -0,0 +1,233 @@ +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Conc.h" +#include "ISolution.h" +#include "Utils.h" +#include +#define EXTERNAL extern +#include "global.h" +#include "phrqproto.h" +#include "phqalloc.h" + +cxxConc::cxxConc(void) +: description(NULL) +, moles(0.0) +, input_conc(0.0) +, units(NULL) +, equation_name(NULL) +, phase_si(0.0) +, n_pe(-1) +, as(NULL) +, gfw(0.0) + //, skip(0); + //, phase(NULL) +{ +} +cxxConc::cxxConc(struct conc *conc_ptr) +{ + description = conc_ptr->description; + moles = conc_ptr->moles; + input_conc = conc_ptr->input_conc; + units = conc_ptr->units; + equation_name = conc_ptr->equation_name; + phase_si = conc_ptr->phase_si; + n_pe = conc_ptr->n_pe; + as = conc_ptr->as; + gfw = conc_ptr->gfw; + //skip = conc_ptr->skip; + //phase = conc_ptr->phase; +} + +cxxConc::~cxxConc(void) +{ +} +/* +struct conc *cxxConc::concarray(std::map &totals) + // for Solutions, not ISolutions + // takes a map of (elt name, moles) + // returns list of conc structures +{ + struct conc *c; + c = (struct conc *) PHRQ_malloc((size_t) ((totals.size() + 1) * sizeof(struct conc))); + if (c == NULL) malloc_error(); + int i = 0; + for (std::map ::const_iterator it = totals.begin(); it != totals.end(); ++it) { + c[i].description = (char *)it->first; + c[i].moles = it->second; + c[i].input_conc = it->second; + c[i].units = NULL; + c[i].equation_name = NULL; + c[i].phase_si = 0.0; + c[i].n_pe = 0; + c[i].as = NULL; + c[i].gfw = 0.0; + //c[i].skip = 0; + c[i].phase = NULL; + i++; + } + c[i].description = NULL; + return(c); +} +*/ +struct conc *cxxConc::cxxConc2conc(const std::set &totals) + // for ISolutions + // takes a std::vector cxxConc structures + // returns list of conc structures +{ + struct conc *c; + c = (struct conc *) PHRQ_malloc((size_t) ((totals.size() + 1) * sizeof(struct conc))); + if (c == NULL) malloc_error(); + int i = 0; + for (std::set::const_iterator it = totals.begin(); it != totals.end(); ++it) { + c[i].description = it->description; + c[i].moles = it->moles; + c[i].input_conc = it->input_conc; + c[i].units = it->units; + c[i].equation_name = it->equation_name; + c[i].phase_si = it->phase_si; + c[i].n_pe = it->n_pe; + c[i].as = it->as; + c[i].gfw = it->gfw; + //c[i].skip = 0; + c[i].phase = NULL; + i++; + } + c[i].description = NULL; + return(c); +} + +#ifdef SKIP +cxxConc::STATUS_TYPE cxxConc::read(CParser& parser, cxxISolution& solution) +{ + // std::string& str = parser.line(); + std::string str = parser.line(); + + // defaults set in ctor + + // Remove space between "kg" and "solution" or "water" in units + Utilities::replace("Kg", "kg", str); + Utilities::replace("KG", "kg", str); + while (Utilities::replace("kg ", "kg", str)); + + std::istream::pos_type ptr = 0; + + // + // Read master species list for mass balance equation + // + std::string token; + std::string token1; + int count_redox_states = 0; + CParser::TOKEN_TYPE j; + while ( ((j = parser.copy_token(token, ptr)) == CParser::TT_UPPER ) || + ( token[0] == '[' ) || + ( Utilities::strcmp_nocase_arg1(token.c_str(), "ph") == 0 ) || + ( Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0 ) ) + { + ++count_redox_states; + Utilities::replace("(+", "(", token); + if (count_redox_states > 1) token1 += " "; + token1 += token; + } + if (count_redox_states == 0) { + parser.incr_input_error(); + parser.error_msg("No element or master species given for concentration input.", CParser::OT_CONTINUE); + return cxxConc::ERROR; + } + description = token1; + + // Determine if reading alkalinity, allow equivalents for units + Utilities::str_tolower(token1); + bool alk = false; + if (token1.find("alk") == 0) { + alk = true; + } + + // Read concentration + if (!(std::istringstream(token) >> this->input_conc)) { + std::ostringstream err; + err << "Concentration data error for " << token1 << " in solution input."; + parser.error_msg(err, CParser::OT_CONTINUE); + return cxxConc::ERROR; + } + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + + // Read optional data + token1 = token; + + // Check for units info + if (parser.check_units(token1, alk, false, solution.get_units(), false) == CParser::OK) { + if (parser.check_units(token1, alk, false, solution.get_units(), true) == CParser::OK) { + this->units = token1; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + } else { + return cxxConc::ERROR; + } + } + + // Check for "as" followed by formula to be used for gfw + token1 = token; + Utilities::str_tolower(token1); + if (token1.compare("as") == 0) + { + parser.copy_token(token, ptr); + this->as = token; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + } + // Check for "gfw" followed by gram formula weight + else if (token1.compare("gfw") == 0) + { + if (parser.copy_token(token, ptr) != CParser::TT_DIGIT) { + parser.error_msg("Expecting gram formula weight.", CParser::OT_CONTINUE); + return cxxConc::ERROR; + } else { + parser.get_iss() >> this->gfw; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + } + } + + // Check for redox couple for pe + if ( Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0 ) { + this->n_pe = cxxPe_Data::store(solution.pe, token); + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + } else if (token.find("/") != std::string::npos) { + if (parser.parse_couple(token) == CParser::OK) { + this->n_pe = cxxPe_Data::store(solution.pe, token); + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + } else { + return cxxConc::ERROR; + } + } + + // Must have phase + this->equation_name = token; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return cxxConc::OK; + + // Check for saturation index + if (!(std::istringstream(token) >> this->phase_si)) + { + parser.error_msg("Expected saturation index.", CParser::OT_CONTINUE); + return cxxConc::ERROR; + } + return cxxConc::OK; +} +#endif + +#ifdef SKIP +void cxxConc::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + unsigned int i; + std::string indent0(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + + s_oss << indent0; + s_oss << "description << "\"" ; + + s_oss << " conc_moles=\"" << this->moles << "\"" ; + + s_oss << "\">" << std::endl; +} +#endif diff --git a/Conc.h b/Conc.h new file mode 100644 index 00000000..a792408c --- /dev/null +++ b/Conc.h @@ -0,0 +1,70 @@ +#if !defined(CONC_H_INCLUDED) +#define CONC_H_INCLUDED + +//#include "Parser.h" +#include "Utils.h" + +#include +#include // std::map +#include +#include +#include "char_star.h" + +// forward declarations +class cxxISolution; // reqd for read and dump_xml + +class cxxConc +{ +public: + cxxConc(void); + cxxConc(struct conc *conc_ptr); + ~cxxConc(void); + + enum STATUS_TYPE { + ERROR = 0, + OK = 1 + }; + +public: + + //STATUS_TYPE read(CParser& parser, CSolution& sol); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + double get_input_conc()const {return this->input_conc;} + void set_input_conc(double input_conc) {this->input_conc = input_conc;} + + std::string get_equation_name()const {return this->equation_name;} + void set_equation_name(char * equation_name) {this->equation_name = equation_name;} + + std::string get_description()const {return this->description;} + void set_description(char * description) {this->description = description;} + + std::string get_units()const {return this->units;} + void set_units(char * units) {this->units = units;} + + int get_n_pe()const {return this->n_pe;} + void set_n_pe(int n_pe) {this->n_pe = n_pe;} + + //bool operator<(const cxxConc& conc)const { return (this->description < conc.description); } + bool operator<(const cxxConc& conc)const { return ::strcmp(this->description, conc.description) < 0; } + + //static struct conc * concarray(std::map &t ); + + static struct conc * cxxConc2conc(const std::set &t ); + +private: + char * description; + double moles; + double input_conc; + char * units; + char * equation_name; + //struct phase *phase; + double phase_si; + int n_pe; + char * as; + double gfw; + //int skip; +}; + +#endif // CONC_H_INCLUDED diff --git a/ExchComp.cxx b/ExchComp.cxx new file mode 100644 index 00000000..e0832c5d --- /dev/null +++ b/ExchComp.cxx @@ -0,0 +1,554 @@ +// ExchComp.cxx: implementation of the cxxExchComp class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "ExchComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include "output.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxExchComp::cxxExchComp() + // + // default constructor for cxxExchComp + // +{ + moles = 0.0; + la = 0.0; + charge_balance = 0.0; + phase_name = NULL; + phase_proportion = 0.0; + rate_name = NULL; + totals.type = cxxNameDouble::ND_ELT_MOLES; + formula_totals.type = cxxNameDouble::ND_ELT_MOLES; +} + +cxxExchComp::cxxExchComp(struct exch_comp *exch_comp_ptr) + // + // constructor for cxxExchComp from struct exch_comp + // +: +formula_totals(exch_comp_ptr->formula_totals), +totals(exch_comp_ptr->totals) +{ + formula = exch_comp_ptr->formula; + moles = exch_comp_ptr->moles; + // totals in constructor + //formula_totals in constructor + la = exch_comp_ptr->la; + charge_balance = exch_comp_ptr->charge_balance; + phase_name = exch_comp_ptr->phase_name; + phase_proportion = exch_comp_ptr->phase_proportion; + rate_name = exch_comp_ptr->rate_name; + formula_z = exch_comp_ptr->formula_z; +} + +cxxExchComp::~cxxExchComp() +{ +} + +struct master *cxxExchComp::get_master() +{ + struct master *master_ptr = NULL; + for (std::map ::iterator it = totals.begin(); it != totals.end(); it++) { + + /* Find master species */ + char *eltName = it->first; + struct element *elt_ptr = element_store(eltName); + if (elt_ptr->master == NULL) { + std::ostringstream error_oss; + error_oss << "Master species not in data base for " << elt_ptr->name << std::endl; + //Utilities::error_msg(error_oss.str(), STOP); + error_msg(error_oss.str().c_str(), CONTINUE); + return(NULL); + } + if (elt_ptr->master->type != EX) continue; + master_ptr = elt_ptr->master; + break; + } + if (master_ptr == NULL) { + std::ostringstream error_oss; + error_oss << "Exchange formula does not contain an exchange master species, " << this->formula << std::endl; + //Utilities::error_msg(error_oss.str(), CONTINUE); + error_msg(error_oss.str().c_str(), CONTINUE); + } + return(master_ptr); +} + +struct exch_comp *cxxExchComp::cxxExchComp2exch_comp(std::list& el) + // + // Builds exch_comp structure from of cxxExchComp + // +{ + struct exch_comp *exch_comp_ptr = (struct exch_comp *) PHRQ_malloc((size_t) (el.size() * sizeof(struct exch_comp))); + if (exch_comp_ptr == NULL) malloc_error(); + + int i = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + exch_comp_ptr[i].formula = it->formula; + exch_comp_ptr[i].formula_z = it->formula_z; + exch_comp_ptr[i].totals = it->totals.elt_list(); + exch_comp_ptr[i].moles = it->moles; + exch_comp_ptr[i].formula_totals = it->formula_totals.elt_list(); + exch_comp_ptr[i].la = it->la; + exch_comp_ptr[i].charge_balance = it->charge_balance; + exch_comp_ptr[i].phase_name = it->phase_name; + exch_comp_ptr[i].phase_proportion = it->phase_proportion; + exch_comp_ptr[i].rate_name = it->rate_name; + exch_comp_ptr[i].master = it->get_master(); + i++; + } + return(exch_comp_ptr); +} + +void cxxExchComp::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exch_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Exch_Comp element and attributes + + s_oss << indent0 << "formula=\"" << this->formula << "\"" << std::endl; + s_oss << indent0 << "moles=\"" << this->moles << "\"" << std::endl; + s_oss << indent0 << "la=\"" << this->la << "\"" << std::endl; + s_oss << indent0 << "charge_balance=\"" << this->charge_balance << "\"" << std::endl; + if (this->phase_name != NULL) { + s_oss << indent0 << "phase_name=\"" << this->phase_name << "\"" << std::endl; + } + if (this->rate_name != NULL) { + s_oss << indent0 << "rate_name=\"" << this->rate_name << "\"" << std::endl; + } + s_oss << indent0 << "phase_proportion=\"" << this->phase_proportion << "\"" << std::endl; + + // totals + s_oss << indent0; + s_oss << "totals.dump_xml(s_oss, indent + 1); + + // formula_totals + s_oss << indent0; + s_oss << "formula_totals.dump_xml(s_oss, indent + 1); +} + +void cxxExchComp::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exch_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Exch_Comp element and attributes + + s_oss << indent0 << "-formula " << this->formula << std::endl; + s_oss << indent0 << "-moles " << this->moles << std::endl; + s_oss << indent0 << "-la " << this->la << std::endl; + s_oss << indent0 << "-charge_balance " << this->charge_balance << std::endl; + if (this->phase_name != NULL) { + s_oss << indent0 << "-phase_name " << this->phase_name << std::endl; + } + if (this->rate_name != NULL) { + s_oss << indent0 << "-rate_name " << this->rate_name << std::endl; + } + s_oss << indent0 << "-phase_proportion " << this->phase_proportion << std::endl; + s_oss << indent0 << "-formula_z " << this->formula_z << std::endl; + + // totals + s_oss << indent0; + s_oss << "-totals" << std::endl; + this->totals.dump_raw(s_oss, indent + 1); + + // formula_totals + s_oss << indent0; + s_oss << "-formula_totals" << std::endl; + this->formula_totals.dump_raw(s_oss, indent + 1); +} + +void cxxExchComp::read_raw(CParser& parser) +{ + std::string str; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("formula"); // 0 + vopts.push_back("moles"); // 1 + vopts.push_back("la"); // 2 + vopts.push_back("charge_balance"); // 3 + vopts.push_back("phase_name"); // 4 + vopts.push_back("rate_name"); // 5 + vopts.push_back("formula_z"); // 6 + vopts.push_back("phase_proportion"); // 7 + vopts.push_back("totals"); // 8 + vopts.push_back("formula_totals"); // 9 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool formula_defined(false); + bool moles_defined(false); + bool la_defined(false); + bool charge_balance_defined(false); + bool formula_z_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Exchange for more processing + //parser.error_msg("Unknown input in EXCH_COMP read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // formula + if (!(parser.get_iss() >> str)) + { + this->formula = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for formula.", CParser::OT_CONTINUE); + } else { + this->formula = string_hsave(str.c_str()); + } + formula_defined = true; + break; + + case 1: // moles + if (!(parser.get_iss() >> this->moles)) + { + this->moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for moles.", CParser::OT_CONTINUE); + } + moles_defined = true; + break; + + case 2: // la + if (!(parser.get_iss() >> this->la)) + { + this->la = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for la.", CParser::OT_CONTINUE); + } + la_defined = true; + break; + + case 3: // charge_balance + if (!(parser.get_iss() >> this->charge_balance)) + { + this->charge_balance = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for charge_balance.", CParser::OT_CONTINUE); + } + charge_balance_defined = true; + break; + + case 4: // phase_name + if (!(parser.get_iss() >> str)) + { + this->phase_name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for phase_name.", CParser::OT_CONTINUE); + } else { + this->phase_name = string_hsave(str.c_str()); + } + break; + + case 5: // rate_name + if (!(parser.get_iss() >> str)) + { + this->rate_name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for rate_name.", CParser::OT_CONTINUE); + } else { + this->rate_name = string_hsave(str.c_str()); + } + break; + + case 6: // formula_z + if (!(parser.get_iss() >> this->formula_z)) + { + this->formula_z = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for formula_z.", CParser::OT_CONTINUE); + } + formula_z_defined = true; + break; + + case 7: // phase_proportion + if (!(parser.get_iss() >> this->phase_proportion)) + { + this->phase_proportion = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for phase_proportion.", CParser::OT_CONTINUE); + } + break; + + case 8: // totals + if ( this->totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for ExchComp totals.", CParser::OT_CONTINUE); + } + opt_save = 8; + break; + + case 9: // formula_totals + if ( this->formula_totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for ExchComp formula totals.", CParser::OT_CONTINUE); + } + opt_save = 9; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (formula_defined == false) { + parser.incr_input_error(); + parser.error_msg("Formula not defined for ExchComp input.", CParser::OT_CONTINUE); + } + if (moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Moles not defined for ExchComp input.", CParser::OT_CONTINUE); + } + if (la_defined == false) { + parser.incr_input_error(); + parser.error_msg("La not defined for ExchComp input.", CParser::OT_CONTINUE); + } + if (charge_balance_defined == false) { + parser.incr_input_error(); + parser.error_msg("Charge_balance not defined for ExchComp input.", CParser::OT_CONTINUE); + } + if (formula_z_defined == false) { + parser.incr_input_error(); + parser.error_msg("Formula_z not defined for ExchComp input.", CParser::OT_CONTINUE); + } +} + +#ifdef SKIP +cxxExchComp& cxxExchComp::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxExchComp numkey; + + // Read exch_comp number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxExchComp& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in EXCH_COMP keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.exch_comp_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in exch_comp.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif + diff --git a/ExchComp.h b/ExchComp.h new file mode 100644 index 00000000..1684c9ab --- /dev/null +++ b/ExchComp.h @@ -0,0 +1,52 @@ +#if !defined(EXCHCOMP_H_INCLUDED) +#define EXCHCOMP_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxExchComp +{ + +public: + cxxExchComp(); + cxxExchComp(struct exch_comp *); + ~cxxExchComp(); + + + struct master *get_master(); + char *get_phase_name()const {return this->phase_name;} + char *get_rate_name()const {return this->rate_name;} + + static struct exch_comp *cxxExchComp2exch_comp(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + char * formula; + double moles; + cxxNameDouble formula_totals; + cxxNameDouble totals; + double la; + double charge_balance; + char *phase_name; + double phase_proportion; + char *rate_name; + double formula_z; // charge on formula + +public: + +}; + +#endif // !defined(EXCHCOMP_H_INCLUDED) diff --git a/Exchange.cxx b/Exchange.cxx new file mode 100644 index 00000000..146c2c38 --- /dev/null +++ b/Exchange.cxx @@ -0,0 +1,413 @@ +// Exchange.cxx: implementation of the cxxExchange class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Exchange.h" +#include "ExchComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxExchange::cxxExchange() + // + // default constructor for cxxExchange + // +: cxxNumKeyword() +{ + pitzer_exchange_gammas = false; +} + +cxxExchange::cxxExchange(struct exchange *exchange_ptr) + // + // constructor for cxxExchange from struct exchange + // +: +cxxNumKeyword() + +{ + int i; + + this->set_description(exchange_ptr->description); + n_user = exchange_ptr->n_user; + n_user_end = exchange_ptr->n_user_end; + pitzer_exchange_gammas = (exchange_ptr->pitzer_exchange_gammas == TRUE); + for (i = 0; i < exchange_ptr->count_comps; i++) { + cxxExchComp ec(&(exchange_ptr->comps[i])); + exchComps.push_back(ec); + } + + + + +} + +cxxExchange::~cxxExchange() +{ +} + +bool cxxExchange::get_related_phases() +{ + for (std::list::const_iterator it = this->exchComps.begin(); it != this->exchComps.end(); ++it) { + if (it->get_phase_name() == NULL) continue; + return(true); + } + return(false); +} + +bool cxxExchange::get_related_rate() +{ + for (std::list::const_iterator it = this->exchComps.begin(); it != this->exchComps.end(); ++it) { + if (it->get_rate_name() == NULL) continue; + return(true); + } + return(false); +} + +struct exchange *cxxExchange::cxxExchange2exchange() + // + // Builds a exchange structure from instance of cxxExchange + // +{ + struct exchange *exchange_ptr = exchange_alloc(); + + exchange_ptr->description = this->get_description(); + exchange_ptr->n_user = this->n_user; + exchange_ptr->n_user_end = this->n_user_end; + exchange_ptr->new_def = FALSE; + exchange_ptr->solution_equilibria = FALSE; + exchange_ptr->n_solution = -2; + exchange_ptr->related_phases = (int) this->get_related_phases(); + exchange_ptr->related_rate = (int) this->get_related_rate(); + exchange_ptr->pitzer_exchange_gammas = (int) this->pitzer_exchange_gammas; + exchange_ptr->count_comps = this->exchComps.size(); + exchange_ptr->comps = (struct exch_comp *) free_check_null(exchange_ptr->comps); + exchange_ptr->comps = cxxExchComp::cxxExchComp2exch_comp(this->exchComps); + return(exchange_ptr); +} + +void cxxExchange::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exchange message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Exchange element and attributes + s_oss << indent0; + s_oss << "pitzer_exchange_gammas << "\"" << std::endl; + + // components + s_oss << indent1; + s_oss << "::const_iterator it = exchComps.begin(); it != exchComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} + +void cxxExchange::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exchange message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Exchange element and attributes + s_oss << indent0; + s_oss << "EXCHANGE_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-pitzer_exchange_gammas " << this->pitzer_exchange_gammas << std::endl; + + // exchComps structures + for (std::list::const_iterator it = exchComps.begin(); it != exchComps.end(); ++it) { + s_oss << indent1; + s_oss << "-component" << std::endl; + it->dump_raw(s_oss, indent + 2); + } + + return; +} + +void cxxExchange::read_raw(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("pitzer_exchange_gammas"); // 0 + vopts.push_back("component"); // 1 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read exchange number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool pitzer_exchange_gammas_defined(false); + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in EXCH_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // pitzer_exchange_gammas + if (!(parser.get_iss() >> this->pitzer_exchange_gammas)) + { + this->pitzer_exchange_gammas = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for pitzer_exchange_gammas.", CParser::OT_CONTINUE); + } + pitzer_exchange_gammas_defined = true; + useLastLine = false; + break; + case 1: // component + { + cxxExchComp ec; + ec.read_raw(parser); + this->exchComps.push_back(ec); + } + useLastLine = true; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (pitzer_exchange_gammas_defined == false) { + parser.incr_input_error(); + parser.error_msg("Pitzer_exchange_gammsa not defined for EXCHANGE_RAW input.", CParser::OT_CONTINUE); + } +} +#ifdef SKIP +cxxExchange& cxxExchange::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxExchange numkey; + + // Read exchange number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxExchange& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in EXCHANGE keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.exchange_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in exchange.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif diff --git a/Exchange.h b/Exchange.h new file mode 100644 index 00000000..08c06fee --- /dev/null +++ b/Exchange.h @@ -0,0 +1,47 @@ +#if !defined(EXCHANGE_H_INCLUDED) +#define EXCHANGE_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "ExchComp.h" + +class cxxExchange : public cxxNumKeyword +{ + +public: + cxxExchange(); + cxxExchange(struct exchange *); + ~cxxExchange(); + + struct exchange *cxxExchange2exchange(); + + struct exch_comp *cxxExchComp2exch_comp(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + + bool get_related_phases(void); + + bool get_related_rate(void); + +protected: + std::list exchComps; + bool pitzer_exchange_gammas; + +public: + //static std::map& map; + +}; + +#endif // !defined(EXCHANGE_H_INCLUDED) diff --git a/GasPhase.cxx b/GasPhase.cxx new file mode 100644 index 00000000..aef606b3 --- /dev/null +++ b/GasPhase.cxx @@ -0,0 +1,474 @@ +// GasPhase.cxx: implementation of the cxxGasPhase class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "GasPhase.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxGasPhase::cxxGasPhase() + // + // default constructor for cxxGasPhase + // +: cxxNumKeyword() +{ + total_p = 0; + volume = 0; + gasPhaseComps.type = cxxNameDouble::ND_NAME_COEF; +} + +cxxGasPhase::cxxGasPhase(struct gas_phase *gas_phase_ptr) + // + // constructor for cxxGasPhase from struct gas_phase + // +: +cxxNumKeyword() +{ + int i; + + this->set_description(gas_phase_ptr->description); + n_user = gas_phase_ptr->n_user; + n_user_end = gas_phase_ptr->n_user_end; + if (gas_phase_ptr->type == PRESSURE) { + type = cxxGasPhase::GP_PRESSURE; + } else { + type = cxxGasPhase::GP_VOLUME; + } + total_p = gas_phase_ptr->total_p; + volume = gas_phase_ptr->volume; + + // gas_phase components + for (i = 0; i < gas_phase_ptr->count_comps; i++) { + gasPhaseComps[gas_phase_ptr->comps[i].name] = gas_phase_ptr->comps[i].moles; + } +} + +cxxGasPhase::~cxxGasPhase() +{ +} + +struct gas_comp * cxxGasPhase::cxxGasPhaseComp2gas_comp() +{ + struct gas_comp *gas_comp_ptr(NULL); + if (this->gasPhaseComps.size() > 0) { + int i = 0; + int n; + gas_comp_ptr = (struct gas_comp *) PHRQ_malloc((size_t) (this->gasPhaseComps.size() * sizeof(struct gas_comp))); + if (gas_comp_ptr == NULL) malloc_error(); + for (cxxNameDouble::iterator it = this->gasPhaseComps.begin(); it != this->gasPhaseComps.end(); it++) { + gas_comp_ptr[i].name = it->first; + gas_comp_ptr[i].phase = phase_bsearch(it->first, &n, TRUE); + gas_comp_ptr[i].p_read = 0; + gas_comp_ptr[i].moles = it->second; + gas_comp_ptr[i].initial_moles = 0; + i++; + } + } + return(gas_comp_ptr); +} + +struct gas_phase *cxxGasPhase::cxxGasPhase2gas_phase() + // + // Builds a gas_phase structure from instance of cxxGasPhase + // +{ + struct gas_phase *gas_phase_ptr = gas_phase_alloc(); + + gas_phase_ptr->description = this->get_description(); + gas_phase_ptr->n_user = this->n_user; + gas_phase_ptr->n_user_end = this->n_user_end; + gas_phase_ptr->new_def = FALSE; + gas_phase_ptr->solution_equilibria = FALSE; + gas_phase_ptr->n_solution = -2; + if (this->type == cxxGasPhase::GP_PRESSURE) { + gas_phase_ptr->type = PRESSURE; + } else { + gas_phase_ptr->type = VOLUME; + } + gas_phase_ptr->total_p = this->total_p; + gas_phase_ptr->volume = this->volume; + gas_phase_ptr->temperature = 273.15; + + // comps + gas_phase_ptr->count_comps = this->gasPhaseComps.size(); + gas_phase_ptr->comps = (struct gas_comp *) free_check_null(gas_phase_ptr->comps); + gas_phase_ptr->comps = this->cxxGasPhaseComp2gas_comp(); + + return(gas_phase_ptr); +} + +#ifdef SKIP +void cxxGasPhase::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing gas_phase message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // GasPhase element and attributes + s_oss << indent0; + s_oss << "pitzer_gas_phase_gammas << "\"" << std::endl; + + // components + s_oss << indent1; + s_oss << "::const_iterator it = gas_phaseComps.begin(); it != gas_phaseComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} +#endif + +void cxxGasPhase::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing gas_phase message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // GasPhase element and attributes + s_oss << indent0; + s_oss << "GAS_PHASE_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-type " << this->type << std::endl; + + s_oss << indent1; + s_oss << "-total_p " << this->total_p << std::endl; + + s_oss << indent1; + s_oss << "-volume " << this->volume << std::endl; + + // gasPhaseComps + s_oss << indent1; + s_oss << "-component" << std::endl; + this->gasPhaseComps.dump_raw(s_oss, indent + 2); +} + +void cxxGasPhase::read_raw(CParser& parser) +{ + + int i; + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("type"); //0 + vopts.push_back("total_p"); //1 + vopts.push_back("volume"); //2 + vopts.push_back("component"); //3 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read gas_phase number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool type_defined(false); + bool total_p_defined(false); + bool volume_defined(false); + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in GAS_PHASE_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // type + if (!(parser.get_iss() >> i)) + //if (!(parser.get_iss() >> (cxxGasPhase::GP_TYPE) this->type)) + { + this->type = cxxGasPhase::GP_PRESSURE; + parser.incr_input_error(); + parser.error_msg("Expected enum for type.", CParser::OT_CONTINUE); + } else { + this->type = (cxxGasPhase::GP_TYPE) i; + } + type_defined = true; + useLastLine = false; + break; + + case 1: // total_p + if (!(parser.get_iss() >> this->total_p)) + { + this->total_p = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for total_p.", CParser::OT_CONTINUE); + } + total_p_defined = true; + useLastLine = false; + break; + + case 2: // volume + if (!(parser.get_iss() >> this->volume)) + { + this->volume = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for volume.", CParser::OT_CONTINUE); + } + volume_defined = true; + useLastLine = false; + break; + + case 3: // component + if ( this->gasPhaseComps.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected gas component name and moles for gasPhaseComps.", CParser::OT_CONTINUE); + } + opt_save = 3; + useLastLine = false; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (type_defined == false) { + parser.incr_input_error(); + parser.error_msg("Type not defined for GAS_PHASE_RAW input.", CParser::OT_CONTINUE); + } + if (total_p_defined == false) { + parser.incr_input_error(); + parser.error_msg("Total_p not defined for GAS_PHASE_RAW input.", CParser::OT_CONTINUE); + } + if (volume_defined == false) { + parser.incr_input_error(); + parser.error_msg("Volume not defined for GAS_PHASE_RAW input.", CParser::OT_CONTINUE); + } +} +#ifdef SKIP +cxxGasPhase& cxxGasPhase::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxGasPhase numkey; + + // Read gas_phase number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxGasPhase& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in GAS_PHASE keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.gas_phase_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in gas_phase.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif diff --git a/GasPhase.h b/GasPhase.h new file mode 100644 index 00000000..b0bb7c63 --- /dev/null +++ b/GasPhase.h @@ -0,0 +1,50 @@ +#if !defined(GASPHASE_H_INCLUDED) +#define GASPHASE_H_INCLUDED + +#include "NumKeyword.h" +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxGasPhase : public cxxNumKeyword +{ + +public: + cxxGasPhase(); + cxxGasPhase(struct gas_phase *); + ~cxxGasPhase(); + + enum GP_TYPE { + GP_PRESSURE = 0, + GP_VOLUME = 1 + }; + + struct gas_phase *cxxGasPhase2gas_phase(); + + struct gas_comp *cxxGasPhaseComp2gas_comp(); + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + + +protected: + cxxNameDouble gasPhaseComps; + GP_TYPE type; + double total_p; + double volume; +public: + //static std::map& map; + +}; + +#endif // !defined(GASPHASE_H_INCLUDED) diff --git a/ISolution.cxx b/ISolution.cxx new file mode 100644 index 00000000..a8ea03bb --- /dev/null +++ b/ISolution.cxx @@ -0,0 +1,334 @@ +// ISolution.cxx: implementation of the cxxSolutionxx class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "ISolution.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" + +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +//static std::map ss_map; +//std::map& cxxISolution::s_map = ss_map; + +cxxISolution::cxxISolution() +: +units("mMol/kgw") +{ + density = 1.0; + default_pe = -1; +} + +cxxISolution::cxxISolution(struct solution *solution_ptr) +: cxxSolution(solution_ptr) + //, pe(cxxPe_Data::alloc()) +{ + density = solution_ptr->density; + units = solution_ptr->units; + // totals + for (int i = 0; solution_ptr->totals[i].description != NULL; i++) { + cxxConc c(&(solution_ptr->totals[i])); + concs.insert(c); + } + default_pe = solution_ptr->default_pe; + // pe_data + pes = pe_data_dup(solution_ptr->pe); +} + +cxxISolution::~cxxISolution() +{ + pe_data_free(this->pes); +} + +struct solution *cxxISolution::cxxISolution2solution() + // + // Builds a solution structure from instance of cxxISolution + // +{ + struct solution *soln_ptr = this->cxxSolution2solution(); + soln_ptr->new_def = TRUE; + soln_ptr->density = this->density; + soln_ptr->units = string_hsave(this->units.c_str()); + soln_ptr->default_pe = this->default_pe; + // pe + soln_ptr->pe = (struct pe_data *) pe_data_free(soln_ptr->pe); + soln_ptr->pe = pe_data_dup(this->pes); + // totals + soln_ptr->totals = (struct conc *) free_check_null(soln_ptr->totals); + soln_ptr->totals = cxxConc::cxxConc2conc(this->concs); + return(soln_ptr); +} +#ifdef SKIP +cxxISolution& cxxISolution::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxISolution numkey; + + // Read solution number and description + numkey.read_number_description(parser); + + // Malloc space for solution data + //// g_solution_map[numkey.n_user()] = numkey; + s_map[numkey.n_user()] = numkey; + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + cxxISolution& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SOLUTION keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.solution_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in solution.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif +#ifdef SKIP +void cxxISolution::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "\n"; + + cxxNumKeyword::dump_xml(os, indent); + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_tc() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_ph() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_solution_pe() << "" << "\n"; + + assert(this->pe.size() > 0); + assert(this->default_pe >= 0); + assert(this->pe.size() > (unsigned int) this->default_pe); + //this->pe[this->default_pe].dump_xml(os, indent + 1); + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_units() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_density() << "" << "\n"; + + // foreach conc + if (!this->totals.empty()) + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + + std::vector::const_iterator iter = this->totals.begin(); + for(; iter != this->totals.end(); ++iter) + { + (*iter).dump_xml(*this, os, indent + 2); + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + } + + // foreach isotope + if (!this->isotopes.empty()) + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + + std::list::const_iterator iter = this->isotopes.begin(); + for(; iter != this->isotopes.end(); ++iter) + { + (*iter).dump_xml(os, indent + 2); + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_mass_water() << "" << "\n"; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "" << "\n"; +} +#endif diff --git a/ISolution.h b/ISolution.h new file mode 100644 index 00000000..c80d7925 --- /dev/null +++ b/ISolution.h @@ -0,0 +1,56 @@ +#if !defined(ISOLUTION_H_INCLUDED) +#define ISOLUTION_H_INCLUDED + +//#include "Parser.h" +#include "NumKeyword.h" +#include "Solution.h" +#include "Conc.h" +//#include "Isotope.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector +#include // std::set + + +class cxxISolution : public cxxSolution +{ + +public: + cxxISolution(); + cxxISolution(struct solution *); + //cxxISolution(const cxxISolution&); + ~cxxISolution(); + + //static cxxISolution& read(CParser& parser); + + //void add(cxxConc conc) { this->concs.push_back(conc); } + + struct solution *cxxISolution2solution(); + + double get_density()const {return this->density;} + void set_density(double density) {this->density = density;} + + std::string get_units()const {return units;} + void set_units(std::string units) {units = units;} + + //char * get_redox()const {return this->pe[this->default_pe].get_name();} + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + +protected: + friend class cxxConc; // for this->pe access + double density; + std::string units; + std::set concs; + //std::map pe; + struct pe_data *pes; + int default_pe; + +public: + //static std::map& map; + +}; + +#endif // !defined(ISOLUTION_H_INCLUDED) diff --git a/Isotope.cxx b/Isotope.cxx new file mode 100644 index 00000000..244d71fe --- /dev/null +++ b/Isotope.cxx @@ -0,0 +1,241 @@ +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif +#include "Isotope.h" +#include "Utils.h" +#include "Parser.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include +#include // std::ostrstream + +cxxIsotope::cxxIsotope(void) +: isotope_number(0.0) +{ +} + +cxxIsotope::cxxIsotope(struct isotope *isotope_ptr) +{ + isotope_number = isotope_ptr->isotope_number; + elt_name = isotope_ptr->elt_name; + isotope_name = isotope_ptr->isotope_name; + total = isotope_ptr->total; + ratio = isotope_ptr->ratio; + ratio_uncertainty = isotope_ptr->ratio_uncertainty; +} + +cxxIsotope::~cxxIsotope(void) +{ +} + +struct isotope *cxxIsotope::list2isotope(std::list &isolist) + // takes a std::list of cxxIsotope structures + // returns array of isotope structures +{ + struct isotope *iso; + if (isolist.size() <= 0) { + return NULL; + } else { + iso = (struct isotope *) PHRQ_malloc((size_t) ((isolist.size()) * sizeof(struct isotope))); + if (iso == NULL) malloc_error(); + int i = 0; + for (std::list ::iterator it = isolist.begin(); it != isolist.end(); ++it) { + iso[i].isotope_number = it->isotope_number; + iso[i].elt_name = it->elt_name; + iso[i].total = it->total; + iso[i].ratio = it->ratio; + iso[i].ratio_uncertainty = it->ratio_uncertainty; + iso[i].master = it->master(); + iso[i].primary = it->primary(); + i++; + } + } + return(iso); +} + +#ifdef SKIP +std::string cxxIsotope::get_name()const +{ + std::ostringstream oss; + //std::ostrstream oss; + oss << this->isotope_number << this->elt_name; + return oss.str(); +} +#endif + +void cxxIsotope::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + unsigned int i; + + std::string indent0(""), indent1(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + + s_oss << indent0; + s_oss << "isotope_number << "\"" << std::endl; + + s_oss << indent1; + s_oss << "iso_elt_name=\"" << this->elt_name << "\"" << std::endl; + + s_oss << indent1; + s_oss << "iso_isotope_name=\"" << this->isotope_name << "\"" << std::endl; + + s_oss << indent1; + s_oss << "iso_total=\"" << this->total << "\"" << std::endl; + + s_oss << indent1; + s_oss << "iso_ratio=\"" << this->ratio << "\"" << std::endl; + + if (this->ratio_uncertainty != NAN) { + s_oss << indent1; + s_oss << "iso_ratio_uncertainty=\"" << this->ratio_uncertainty << "\"" << std::endl; + } + s_oss << indent0; + s_oss << "\">" << std::endl; +} + +void cxxIsotope::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + unsigned int i; + + std::string indent0(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + + s_oss << indent0; + s_oss << this->isotope_name << " "; + s_oss << this->isotope_number << " "; + s_oss << this->elt_name << " "; + s_oss << this->total << " "; + s_oss << this->ratio << " "; + if (this->ratio_uncertainty != NAN) { + s_oss << this->ratio_uncertainty << " "; + } + s_oss << std::endl; +} + +CParser::STATUS_TYPE cxxIsotope::read_raw(CParser& parser) +{ + std::string token; + std::istream::pos_type next_char; + CParser::TOKEN_TYPE j; + + // isotope_name + j = parser.copy_token(token, next_char); + + if (j == CParser::TT_EMPTY) { + this->isotope_name = NULL; + return(CParser::PARSER_OK); + } + this->isotope_name = string_hsave(token.c_str()); + + // isotope_number + if( !(parser.get_iss() >> isotope_number)) { + return CParser::PARSER_ERROR; + } + + // elt_name + if( !(parser.get_iss() >> token)) { + return CParser::PARSER_ERROR; + } + this->elt_name = string_hsave(token.c_str()); + + // total + if( !(parser.get_iss() >> this->total)) { + return CParser::PARSER_ERROR; + } + + // ratio + if( !(parser.get_iss() >> this->ratio)) { + return CParser::PARSER_ERROR; + } + + // ratio_uncertainty + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + this->ratio_uncertainty = NAN; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in solution.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> this->ratio_uncertainty; + } + + return CParser::PARSER_OK; +} + +bool cxxIsotope::operator<(const cxxIsotope& isotope)const +{ + int i = Utilities::strcmp_nocase(this->elt_name, isotope.elt_name); + if (i != 0) return (i < 0); + return ( this->isotope_number < isotope.isotope_number ); +} + +struct master *cxxIsotope::master(void) +{ + return (master_bsearch(this->elt_name)); +} + +struct master *cxxIsotope::primary(void) +{ + return (master_bsearch_primary(this->elt_name)); +} + +#ifdef SKIP +cxxIsotope::STATUS cxxIsotope::read(CParser& parser) +{ + if ( !(parser.get_iss() >> this->isotope_number) ) { + assert(parser.get_iss().fail()); + parser.incr_input_error(); + parser.error_msg("Expected isotope name to" + " begin with an isotopic number.", CParser::OT_CONTINUE); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + + // read and save element name + std::istringstream::int_type c = parser.get_iss().peek(); + if ( c == std::char_traits::eof() || !(::isupper(c)) ) { + parser.error_msg("Expecting element name.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + parser.incr_input_error(); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + if ( !(parser.get_iss() >> this->elt_name) ) { + // should never get here + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + assert(!this->elt_name.empty() && ::isupper(this->elt_name[0])); + + // read and store isotope ratio + if ( !(parser.get_iss() >> this->ratio) ) { + assert(parser.get_iss().fail()); + parser.incr_input_error(); + parser.error_msg("Expected numeric value for isotope ratio.", CParser::OT_CONTINUE); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + + // read and store isotope ratio + this->ratio_uncertainty_defined = false; + if ( !(parser.get_iss() >> this->ratio_uncertainty)) { + if ( !parser.get_iss().eof() ) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for uncertainty in isotope ratio.", CParser::OT_CONTINUE); + return ERROR; + } + } else { + this->ratio_uncertainty_defined = true; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + return OK; +} + + +#endif diff --git a/Isotope.h b/Isotope.h new file mode 100644 index 00000000..0da740a8 --- /dev/null +++ b/Isotope.h @@ -0,0 +1,56 @@ +#if !defined(ISOTOPE_H_INCLUDED) +#define ISOTOPE_H_INCLUDED + +#include "Parser.h" +#include // std::ostream +#include // std::string +#include // std::list + +class cxxIsotope +{ +public: + cxxIsotope(void); + cxxIsotope(struct isotope *isotope_ptr); + ~cxxIsotope(void); + + enum STATUS { + ERROR = 0, + OK = 1 + }; + + //cxxIsotope::STATUS read(CParser& parser); + static struct isotope * list2isotope(std::list &t); + + void dump_xml(std::ostream& os, unsigned int indent)const; + void dump_raw(std::ostream& os, unsigned int indent)const; + + CParser::STATUS_TYPE cxxIsotope::read_raw(CParser& parser); + + char * get_isotope_name()const { return this->isotope_name;} + void set_isotope_name(char * cstring) { this->isotope_name = cstring;} + char * get_elt_name()const { return this->elt_name;} + void set_elt_name(char * cstring) { this->elt_name = cstring;} + + double get_ratio()const { return this->ratio; } + + double get_ratio_uncertainty()const { return this->ratio_uncertainty; } + + bool get_ratio_uncertainty_defined()const { return this->ratio_uncertainty_defined; } + + bool operator<(const cxxIsotope& conc)const; + + struct master *master(void); + struct master *primary(void); + +private: + double isotope_number; + char * elt_name; + char * isotope_name; + double total; + double ratio; + double ratio_uncertainty; + //struct master *master; + //struct master *primary; + bool ratio_uncertainty_defined; +}; +#endif // ISOTOPE_H_INCLUDED diff --git a/KineticsComp.cxx b/KineticsComp.cxx new file mode 100644 index 00000000..ab9b374e --- /dev/null +++ b/KineticsComp.cxx @@ -0,0 +1,504 @@ +// KineticsComp.cxx: implementation of the cxxKineticsComp class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "KineticsComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxKineticsComp::cxxKineticsComp() + // + // default constructor for cxxKineticsComp + // +{ + rate_name = NULL; + tol = 1e-8; + m = 0.0; + m0 = 0.0; + moles = 0.0; + namecoef.type = cxxNameDouble::ND_NAME_COEF; +} + +cxxKineticsComp::cxxKineticsComp(struct kinetics_comp *kinetics_comp_ptr) + // + // constructor for cxxKineticsComp from struct kinetics_comp + // +: +namecoef(kinetics_comp_ptr->list, kinetics_comp_ptr->count_list, cxxNameDouble::ND_NAME_COEF) +{ + rate_name = kinetics_comp_ptr->rate_name; + tol = kinetics_comp_ptr->tol; + m = kinetics_comp_ptr->m; + m0 = kinetics_comp_ptr->m0; + moles = kinetics_comp_ptr->moles; + for (int i = 0; i < kinetics_comp_ptr->count_d_params; i++) { + this->d_params.push_back(kinetics_comp_ptr->d_params[i]); + } +} + +cxxKineticsComp::~cxxKineticsComp() +{ +} + +struct kinetics_comp *cxxKineticsComp::cxxKineticsComp2kinetics_comp(std::list& el) + // + // Builds kinetics_comp structure from of cxxKineticsComp + // +{ + struct kinetics_comp *kinetics_comp_ptr = (struct kinetics_comp *) PHRQ_malloc((size_t) (el.size() * sizeof(struct kinetics_comp))); + if (kinetics_comp_ptr == NULL) malloc_error(); + + int i = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + kinetics_comp_ptr[i].rate_name = it->rate_name; + kinetics_comp_ptr[i].list = it->namecoef.name_coef(); + kinetics_comp_ptr[i].count_list = it->namecoef.size(); + kinetics_comp_ptr[i].tol = it->tol; + kinetics_comp_ptr[i].m = it->m; + kinetics_comp_ptr[i].initial_moles = 0.; + kinetics_comp_ptr[i].m0 = it->m0; + kinetics_comp_ptr[i].moles = it->moles; + kinetics_comp_ptr[i].count_c_params = 0; + kinetics_comp_ptr[i].c_params = NULL; +/* + kinetics_comp_ptr[i].count_d_params = 0; + kinetics_comp_ptr[i].d_params = NULL; +*/ + + kinetics_comp_ptr[i].count_d_params = it->d_params.size(); + kinetics_comp_ptr[i].d_params = NULL; + if (it->d_params.size() > 0) { + kinetics_comp_ptr[i].d_params = (double *) PHRQ_malloc((size_t) (it->d_params.size() * sizeof(double))); + if (kinetics_comp_ptr[i].d_params == NULL) malloc_error(); + std::copy(it->d_params.begin(), it->d_params.end(), kinetics_comp_ptr[i].d_params); + } + i++; + } + return(kinetics_comp_ptr); +} +#ifdef SKIP +void cxxKineticsComp::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing kinetics_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Kinetics_Comp element and attributes + + s_oss << indent0 << "formula=\"" << this->formula << "\"" << std::endl; + s_oss << indent0 << "moles=\"" << this->moles << "\"" << std::endl; + s_oss << indent0 << "la=\"" << this->la << "\"" << std::endl; + s_oss << indent0 << "charge_balance=\"" << this->charge_balance << "\"" << std::endl; + if (this->phase_name != NULL) { + s_oss << indent0 << "phase_name=\"" << this->phase_name << "\"" << std::endl; + } + if (this->rate_name != NULL) { + s_oss << indent0 << "rate_name=\"" << this->rate_name << "\"" << std::endl; + } + s_oss << indent0 << "phase_proportion=\"" << this->phase_proportion << "\"" << std::endl; + + // totals + s_oss << indent0; + s_oss << "totals.dump_xml(s_oss, indent + 1); + + // formula_totals + s_oss << indent0; + s_oss << "formula_totals.dump_xml(s_oss, indent + 1); +} +#endif +void cxxKineticsComp::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing kinetics_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Kinetics_Comp element and attributes + + s_oss << indent0 << "-rate_name " << this->rate_name << std::endl; + s_oss << indent0 << "-tol " << this->tol << std::endl; + s_oss << indent0 << "-m " << this->m << std::endl; + s_oss << indent0 << "-m0 " << this->m0 << std::endl; + s_oss << indent0 << "-moles " << this->moles << std::endl; + + // namecoef + s_oss << indent0; + s_oss << "-namecoef" << std::endl; + this->namecoef.dump_raw(s_oss, indent + 1); + + // d_params + s_oss << indent0; + s_oss << "-d_params" << std::endl; + { + int i = 0; + s_oss << indent1; + for (std::vector::const_iterator it = d_params.begin(); it != d_params.end(); it++) { + if (i++ == 5) { + s_oss << std::endl; + s_oss << indent1; + i = 0; + } + s_oss << *it << " "; + } + s_oss << std::endl; + } +} + +void cxxKineticsComp::read_raw(CParser& parser) +{ + std::string str; + double d; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("rate_name"); // 0 + vopts.push_back("tol"); // 1 + vopts.push_back("m"); // 2 + vopts.push_back("m0"); // 3 + vopts.push_back("moles"); // 4 + vopts.push_back("namecoef"); // 5 + vopts.push_back("d_params"); // 6 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool rate_name_defined(false); + bool tol_defined(false); + bool m_defined(false); + bool m0_defined(false); + bool moles_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Kinetics for more processing + //parser.error_msg("Unknown input in KINETICS_COMP read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // rate_name + if (!(parser.get_iss() >> str)) + { + this->rate_name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for rate_name.", CParser::OT_CONTINUE); + } else { + this->rate_name = string_hsave(str.c_str()); + } + rate_name_defined = true; + break; + + case 1: // tol + if (!(parser.get_iss() >> this->tol)) + { + this->tol = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for tol.", CParser::OT_CONTINUE); + } + tol_defined = true; + break; + + case 2: // m + if (!(parser.get_iss() >> this->m)) + { + this->m = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for m.", CParser::OT_CONTINUE); + } + m_defined = true; + break; + + case 3: // m0 + if (!(parser.get_iss() >> this->m0)) + { + this->m0 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for m0.", CParser::OT_CONTINUE); + } + m0_defined = true; + break; + + + case 4: // moles + if (!(parser.get_iss() >> this->moles)) + { + this->moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for moles.", CParser::OT_CONTINUE); + } + moles_defined = true; + break; + + + case 5: // namecoef + if ( this->namecoef.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for namecoef.", CParser::OT_CONTINUE); + } + opt_save = 5; + break; + + case 6: // d_params + while (parser.copy_token(token, next_char) == CParser::TT_DIGIT) { + sscanf(token.c_str(), "%lf", &d); + this->d_params.push_back(d); + } + opt_save = 6; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (rate_name_defined == false) { + parser.incr_input_error(); + parser.error_msg("Rate_name not defined for KineticsComp input.", CParser::OT_CONTINUE); + } + if (tol_defined == false) { + parser.incr_input_error(); + parser.error_msg("Tol not defined for KineticsComp input.", CParser::OT_CONTINUE); + } + if (m_defined == false) { + parser.incr_input_error(); + parser.error_msg("M not defined for KineticsComp input.", CParser::OT_CONTINUE); + } + if (m0_defined == false) { + parser.incr_input_error(); + parser.error_msg("M0 not defined for KineticsComp input.", CParser::OT_CONTINUE); + } + if (moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Moles not defined for KineticsComp input.", CParser::OT_CONTINUE); + } +} + +#ifdef SKIP +cxxKineticsComp& cxxKineticsComp::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxKineticsComp numkey; + + // Read kinetics_comp number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxKineticsComp& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in KINETICS_COMP keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.kinetics_comp_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in kinetics_comp.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif + diff --git a/KineticsComp.h b/KineticsComp.h new file mode 100644 index 00000000..899e114e --- /dev/null +++ b/KineticsComp.h @@ -0,0 +1,44 @@ +#if !defined(KINETICSCOMP_H_INCLUDED) +#define KINETICSCOMP_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxKineticsComp +{ + +public: + cxxKineticsComp(); + cxxKineticsComp(struct kinetics_comp *); + ~cxxKineticsComp(); + + static struct kinetics_comp *cxxKineticsComp2kinetics_comp(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + char * rate_name; + cxxNameDouble namecoef; + double tol; + double m; + double m0; + double moles; + std::vector d_params; + +public: + +}; + +#endif // !defined(KINETICSCOMP_H_INCLUDED) diff --git a/KineticsCxx.cxx b/KineticsCxx.cxx new file mode 100644 index 00000000..d440bbda --- /dev/null +++ b/KineticsCxx.cxx @@ -0,0 +1,538 @@ +// Kinetics.cxx: implementation of the cxxKinetics class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "KineticsCxx.h" +#include "KineticsComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxKinetics::cxxKinetics() + // + // default constructor for cxxKinetics + // +: cxxNumKeyword() +{ + step_divide = 1.0; + rk = 3; + bad_step_max = 500; + use_cvode = false; + totals.type = cxxNameDouble::ND_ELT_MOLES; +} + +cxxKinetics::cxxKinetics(struct kinetics *kinetics_ptr) + // + // constructor for cxxKinetics from struct kinetics + // +: +cxxNumKeyword(), +totals(kinetics_ptr->totals) +{ + int i; + + this->set_description(kinetics_ptr->description); + n_user = kinetics_ptr->n_user; + n_user_end = kinetics_ptr->n_user_end; + step_divide = kinetics_ptr->step_divide; + rk = kinetics_ptr->rk; + bad_step_max = kinetics_ptr->bad_step_max; + use_cvode = (kinetics_ptr->use_cvode == TRUE); + + // kinetics components + for (i = 0; i < kinetics_ptr->count_comps; i++) { + cxxKineticsComp ec(&(kinetics_ptr->comps[i])); + this->kineticsComps.push_back(ec); + } + + // steps + for (i = 0; i < kinetics_ptr->count_steps; i++) { + this->steps.push_back(kinetics_ptr->steps[i]); + } +} + +cxxKinetics::~cxxKinetics() +{ +} + +struct kinetics *cxxKinetics::cxxKinetics2kinetics() + // + // Builds a kinetics structure from instance of cxxKinetics + // +{ + struct kinetics *kinetics_ptr = kinetics_alloc(); + + kinetics_ptr->description = this->get_description(); + kinetics_ptr->n_user = this->n_user; + kinetics_ptr->n_user_end = this->n_user_end; + kinetics_ptr->step_divide = this->step_divide; + kinetics_ptr->rk = this->rk; + kinetics_ptr->bad_step_max = this->bad_step_max; + kinetics_ptr->use_cvode = (int) this->use_cvode; + + // totals + kinetics_ptr->totals = this->totals.elt_list(); + + // comps + kinetics_ptr->count_comps = this->kineticsComps.size(); + kinetics_ptr->comps = (struct kinetics_comp *) free_check_null(kinetics_ptr->comps); + kinetics_ptr->comps = cxxKineticsComp::cxxKineticsComp2kinetics_comp(this->kineticsComps); + + // steps + kinetics_ptr->count_steps = this->steps.size(); + kinetics_ptr->steps = (double *) free_check_null(kinetics_ptr->steps); + if (this->steps.size() > 0) { + kinetics_ptr->steps = (double *) PHRQ_malloc((size_t) (this->steps.size() * sizeof(double))); + if (kinetics_ptr->steps == NULL) malloc_error(); + std::copy(this->steps.begin(), this->steps.end(), kinetics_ptr->steps); + /* + int i = 0; + for (std::vector::iterator it = this->steps.begin(); it != this->steps.end(); it++) { + kinetics_ptr->steps[i] = *it; + } + */ + } + return(kinetics_ptr); +} + +#ifdef SKIP +void cxxKinetics::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing kinetics message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Kinetics element and attributes + s_oss << indent0; + s_oss << "pitzer_kinetics_gammas << "\"" << std::endl; + + // components + s_oss << indent1; + s_oss << "::const_iterator it = kineticsComps.begin(); it != kineticsComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} +#endif + +void cxxKinetics::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing kinetics message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Kinetics element and attributes + s_oss << indent0; + s_oss << "KINETICS_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-step_divide " << this->step_divide << std::endl; + + s_oss << indent1; + s_oss << "-rk " << this->rk << std::endl; + + s_oss << indent1; + s_oss << "-bad_step_max " << this->bad_step_max << std::endl; + + s_oss << indent1; + s_oss << "-use_cvode " << this->use_cvode << std::endl; + + // kineticsComps structures + for (std::list::const_iterator it = kineticsComps.begin(); it != kineticsComps.end(); ++it) { + s_oss << indent1; + s_oss << "-component" << std::endl; + it->dump_raw(s_oss, indent + 2); + } + + // totals + s_oss << indent1; + s_oss << "-totals " << std::endl; + this->totals.dump_raw(s_oss, indent + 2); + + // steps + s_oss << indent1; + s_oss << "-steps " << std::endl; + { + int i = 0; + s_oss << indent2; + for (std::vector::const_iterator it = this->steps.begin(); it != this->steps.end(); it++) { + if (i++ == 5) { + s_oss << std::endl; + s_oss << indent2; + i = 0; + } + s_oss << *it << " "; + } + s_oss << std::endl; + } + return; +} + +void cxxKinetics::read_raw(CParser& parser) +{ + + double d; + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("step_divide"); + vopts.push_back("rk"); + vopts.push_back("bad_step_max"); + vopts.push_back("use_cvode"); + vopts.push_back("component"); + vopts.push_back("totals"); + vopts.push_back("steps"); + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read kinetics number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool step_divide_defined(false); + bool rk_defined(false); + bool bad_step_max_defined(false); + bool use_cvode_defined(false); + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in KINETICS_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // step_divide + if (!(parser.get_iss() >> this->step_divide)) + { + this->step_divide = 1.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for step_divide.", CParser::OT_CONTINUE); + } + step_divide_defined = true; + useLastLine = false; + break; + + case 1: // rk + if (!(parser.get_iss() >> this->rk)) + { + this->rk = 3; + parser.incr_input_error(); + parser.error_msg("Expected integer value for rk.", CParser::OT_CONTINUE); + } + rk_defined = true; + useLastLine = false; + break; + + case 2: // bad_step_max + if (!(parser.get_iss() >> this->bad_step_max)) + { + this->bad_step_max = 500; + parser.incr_input_error(); + parser.error_msg("Expected integer value for bad_step_max.", CParser::OT_CONTINUE); + } + bad_step_max_defined = true; + useLastLine = false; + break; + + case 3: // use_cvode + if (!(parser.get_iss() >> this->use_cvode)) + { + this->use_cvode = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for use_cvode.", CParser::OT_CONTINUE); + } + use_cvode_defined = true; + useLastLine = false; + break; + + case 4: // component + { + cxxKineticsComp kc; + kc.read_raw(parser); + this->kineticsComps.push_back(kc); + } + useLastLine = true; + break; + + case 5: // totals + if ( this->totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for KineticsComp totals.", CParser::OT_CONTINUE); + } + opt_save = 5; + useLastLine = false; + + case 6: // steps + while (parser.copy_token(token, next_char) == CParser::TT_DIGIT) { + //sscanf(token.c_str(), "%lf", &d); + //this->steps.push_back(d); + std::istringstream iss(token); + if (!(iss >> d)) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for steps.", CParser::OT_CONTINUE); + } else { + this->steps.push_back(d); + } + } + opt_save = 6; + useLastLine = false; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (step_divide_defined == false) { + parser.incr_input_error(); + parser.error_msg("Step_divide not defined for KINETICS_RAW input.", CParser::OT_CONTINUE); + } + if (rk_defined == false) { + parser.incr_input_error(); + parser.error_msg("Rk not defined for KINETICS_RAW input.", CParser::OT_CONTINUE); + } + if (bad_step_max_defined == false) { + parser.incr_input_error(); + parser.error_msg("Bad_step_max not defined for KINETICS_RAW input.", CParser::OT_CONTINUE); + } + if (use_cvode_defined == false) { + parser.incr_input_error(); + parser.error_msg("Use_cvode not defined for KINETICS_RAW input.", CParser::OT_CONTINUE); + } +} +#ifdef SKIP +cxxKinetics& cxxKinetics::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxKinetics numkey; + + // Read kinetics number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxKinetics& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in KINETICS keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.kinetics_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in kinetics.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif diff --git a/KineticsCxx.h b/KineticsCxx.h new file mode 100644 index 00000000..ec218cfa --- /dev/null +++ b/KineticsCxx.h @@ -0,0 +1,51 @@ +#if !defined(KINETICS_H_INCLUDED) +#define KINETICS_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "KineticsComp.h" + +class cxxKinetics : public cxxNumKeyword +{ + +public: + cxxKinetics(); + cxxKinetics(struct kinetics *); + ~cxxKinetics(); + + struct kinetics *cxxKinetics2kinetics(); + + struct kinetics_comp *cxxKineticsComp2kinetics_comp(); + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + + bool get_related_phases(void); + + bool get_related_rate(void); + +protected: + std::list kineticsComps; + std::vector steps; + cxxNameDouble totals; + double step_divide; + int rk; + int bad_step_max; + bool use_cvode; +public: + //static std::map& map; + +}; + +#endif // !defined(KINETICS_H_INCLUDED) diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..293b837f --- /dev/null +++ b/Makefile @@ -0,0 +1,348 @@ +# +# Make file for PHREEQC +# +# $(CURDIR) is current directory +TOPDIR:=$(CURDIR)/.. +PROGRAM=phreeqcsax +EXE=$(TOPDIR)/bin/$(PROGRAM) +EXE=$(PROGRAM) +SRC:=$(CURDIR) + +# Do not print commands before executing +#.SILENT: + +# Provides compatibility with GNU make +#.SUFFIXES: + +# Change to pawd if using automounter +PWD=pwd + +# Change to C compiler on your system +CC=gcc + +USE_XML=TRUE +XERCESCROOT=/z/parkplace/home/dlpark/packages/xerces-c-src_2_7_0 + +# Change to C compiler options on your system +ifdef OPTIMIZE + CCFLAGS=-O3 -Wall -ansi -pedantic -I${XERCESCROOT}/include # -frounding-math # -pg + CCFLAGS_MODEL=-O2 -Wall -ansi -pedantic # -pg +else + CCFLAGS=-g -Wall -ansi -pedantic -I${XERCESCROOT}/include # -frounding-math # -pg + CCFLAGS_MODEL=-g -Wall -ansi -pedantic # -pg +endif +# Remove the following definition if you do not have +# gmp (Gnu Multiple Precision) package on your system +INVERSE_CL1MP=TRUE + +LOADFLAGS= -lm -lxerces-c # -pg + +PLATFORM= LINUX +CXX= g++ -c -D${PLATFORM} -D_REENTRANT -fpic +ifdef OPTIMIZE + CXXFLAGS= -O3 +else + CXXFLAGS= -Wall -g +endif +LINK= g++ -D${PLATFORM} -fpic +PLATFORM_LIB_LINK_OPTIONS=-L/usr/lib -L/usr/local/lib +EXTRA_LINK_OPTIONS=-lc +LIBRARY_NAMES= -lxerces-c +LIBRARY_SEARCH_PATHS= -L${XERCESCROOT}/lib # -L/home/dlpark/lib # +INCLUDES= -I${XERCESCROOT}/include + +#.c.o : +# ${CC} ${CCFLAGS} -c -o $@ $< +#%.o : $(SRC)/%.c +# ${CC} ${CCFLAGS} -c -o $@ $< +%.o : $(SRC)/%.cpp + ${CXX} ${CXXFLAGS} $(INCLUDES) -c -o $@ $< +%.o : $(SRC)/%.cxx + ${CXX} ${CXXFLAGS} $(INCLUDES) -c -o $@ $< + +# Location to copy scripts on installation +BINDIR=$(HOME)/bin + +OBJECTS= main.o \ + advection.o \ + basic.o \ + basicsubs.o \ + cl1.o \ + input.o \ + integrate.o \ + inverse.o \ + isotopes.o \ + kinetics.o \ + mainsubs.o \ + output.o \ + model.o \ + p2clib.o \ + parse.o \ + phreeqc_files.o \ + phqalloc.o \ + prep.o \ + print.o \ + read.o \ + readtr.o \ + spread.o \ + step.o \ + structures.o \ + tally.o \ + tidy.o \ + transport.o \ + utilities.o \ + cvdense.o \ + cvode.o \ + dense.o \ + nvector.o \ + nvector_serial.o \ + smalldense.o \ + sundialsmath.o \ + dw.o \ + pitzer.o \ + pitzer_structures.o \ + +CLASS_OBJECTS= Conc.o \ + Exchange.o \ + ExchComp.o \ + GasPhase.o \ + ISolution.o \ + Isotope.o \ + KineticsCxx.o \ + KineticsComp.o \ + Mix.o \ + NameDouble.o \ + NumKeyword.o \ + Parser.o \ + PPassemblage.o \ + PPassemblageComp.o \ + Reaction.o \ + ReadClass.o \ + Solution.o \ + SSassemblage.o \ + SSassemblageSS.o \ + Surface.o \ + SurfComp.o \ + SurfCharge.o \ + Temperature.o \ + Utils.o + +OBJECTS += $(CLASS_OBJECTS) + +ifdef USE_XML + OBJECTS += SAXPhreeqc.o +endif + +ifdef INVERSE_CL1MP + LOADFLAGS += /z/parkplace/usr/lib/libgmp.a + CCFLAGS += -DINVERSE_CL1MP + CXXFLAGS += -DINVERSE_CL1MP + OBJECTS += cl1mp.o +endif + +all: $(EXE) + +install: +# +# Create directory for binary and scripts if necessary +# + if [ ! -d $(BINDIR) ]; \ + then \ + mkdir $(BINDIR); \ + echo Created directory $(BINDIR); \ + fi +# +# Put path name of current directory into script for +# locating data files, put script in top directory, +# put symbolic link in BINDIR +# + cd $(TOPDIR); dir1=`$(PWD)`/bin; cd $(BINDIR); if [ `$(PWD)` = $$dir1 ]; \ + then \ + echo "Can not install to $(BINDIR). Choose another directory."; \ + exit 4 ; \ + fi + cd $(TOPDIR); \ + rm -f $(BINDIR)/$(PROGRAM); \ + rm -f $(PROGRAM); \ + sed "s?TOPDIR=.\{0,80\}?TOPDIR=`$(PWD)`?" bin/$(PROGRAM).orig > $(PROGRAM); \ + chmod 755 $(PROGRAM) + cd $(TOPDIR); dir1=`$(PWD)`; cd $(BINDIR); if [ `$(PWD)` != $$dir1 ]; then \ + ln -s $$dir1/$(PROGRAM) $(BINDIR); \ + echo Symbolic link for $(PROGRAM) has been placed in $(BINDIR). ; \ + fi +# +# Check that all necessary files are in place. +# + if [ -f $(BINDIR)/$(PROGRAM) -a \ + -f $(TOPDIR)/bin/$(PROGRAM) -a \ + -f $(TOPDIR)/$(PROGRAM) ]; \ + then echo "Installation complete."; \ + else echo "Installation incomplete."; \ + for FILE in $(BINDIR)/$(PROGRAM) \ + $(TOPDIR)/bin/$(PROGRAM) $(TOPDIR)/$(PROGRAM) ; \ + do \ + if [ ! -f $$FILE ]; then echo $$FILE is missing.; fi; \ + done; \ + fi + echo "Add directory $(BINDIR) to PATH." + +clean: + rm -f $(BINDIR)/$(PROGRAM) + rm -f $(TOPDIR)/bin/$(PROGRAM) + rm -f $(TOPDIR)/src/*.o + rm -f $(SUN_DIR)/bin/$(PROGRAM) + rm -f $(SUN_DIR)/src/*.o + rm -f $(TOPDIR)/src/$(PROGRAM) + rm -f $(DEBUG_DIR)/src/*.o + echo Removed object and executable files generated by make. + +$(EXE): $(OBJECTS) + echo $(TOPDIR) +ifdef USE_XML + ${LINK} ${PLATFORM_LIB_LINK_OPTIONS} ${OBJECTS} -o $(EXE) ${LIBRARY_SEARCH_PATHS} ${LIBRARY_NAMES} ${EXTRA_LINK_OPTIONS} ${LOADFLAGS} +else + $(CC) -o $(EXE) $(OBJECTS) $(LOADFLAGS) # -L/z/estespark/home/dlpark/packages/efence -lefence +endif + echo Compilation complete, $(EXE). + +advection.o: $(SRC)/advection.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +basic.o: $(SRC)/basic.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/p2c.h + +basicsubs.o: $(SRC)/basicsubs.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +cl1.o: $(SRC)/cl1.cpp $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqtype.h + +cl1mp.o: $(SRC)/cl1mp.cpp $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqtype.h + +cvdense.o: $(SRC)/cvdense.cpp $(SRC)/cvdense.h $(SRC)/cvode.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/nvector.h $(SRC)/dense.h $(SRC)/smalldense.h $(SRC)/sundialsmath.h $(SRC)/output.h $(SRC)/phqalloc.h + +cvode.o: $(SRC)/cvode.cpp $(SRC)/cvode.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/nvector.h $(SRC)/sundialsmath.h $(SRC)/output.h $(SRC)/kinetics.h $(SRC)/phqalloc.h + +dense.o: $(SRC)/dense.cpp $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/sundialsmath.h $(SRC)/dense.h $(SRC)/smalldense.h $(SRC)/output.h $(SRC)/phqalloc.h + +input.o: $(SRC)/input.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/input.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/phqalloc.h + +integrate.o: $(SRC)/integrate.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +inverse.o: $(SRC)/inverse.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +isotopes.o: $(SRC)/isotopes.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +kinetics.o: $(SRC)/kinetics.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/sundialstypes.h $(SRC)/cvode.h $(SRC)/nvector.h $(SRC)/cvdense.h $(SRC)/dense.h $(SRC)/smalldense.h $(SRC)/nvector_serial.h $(SRC)/kinetics.h + +main.o: $(SRC)/main.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/input.h + +mainsubs.o: $(SRC)/mainsubs.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/input.h + +model.o: $(SRC)/model.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + ${CC} $(SRC)/model.cpp ${CCFLAGS_MODEL} -c -o model.o #-ffloat-store + +nvector.o: $(SRC)/nvector.cpp $(SRC)/nvector.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/output.h + +nvector_serial.o: $(SRC)/nvector_serial.cpp $(SRC)/nvector_serial.h $(SRC)/nvector.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/sundialsmath.h $(SRC)/output.h $(SRC)/phqalloc.h + +output.o: $(SRC)/output.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/phqalloc.h + +p2clib.o: $(SRC)/p2clib.cpp $(SRC)/p2c.h $(SRC)/output.h + +parse.o: $(SRC)/parse.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +phqalloc.o: $(SRC)/phqalloc.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/output.h + +phreeqc_files.o: $(SRC)/phreeqc_files.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/input.h + +pitzer.o: $(SRC)/pitzer.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/pitzer.h + +dw.o: $(SRC)/dw.cpp $(SRC)/pitzer.h + +pitzer_structures.o: $(SRC)/pitzer_structures.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h $(SRC)/pitzer.h + +prep.o: $(SRC)/prep.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +prep.o: $(SRC)/prep.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +print.o: $(SRC)/print.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +read.o: $(SRC)/read.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +readtr.o: $(SRC)/readtr.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +SAXPhreeqc.o: $(SRC)/SAXPhreeqc.cpp $(SRC)/SAXPhreeqc.h $(SRC)/SaxPhreeqcHandlers.h + ${CXX} ${CXXFLAGS} $(INCLUDES) -o SAXPhreeqc.o $(SRC)/SAXPhreeqc.cpp + +smalldense.o: $(SRC)/smalldense.cpp $(SRC)/smalldense.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/sundialsmath.h $(SRC)/output.h $(SRC)/phqalloc.h + +spread.o: $(SRC)/spread.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +step.o: $(SRC)/step.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +structures.o: $(SRC)/structures.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +sundialsmath.o: $(SRC)/sundialsmath.cpp $(SRC)/sundialsmath.h $(SRC)/sundialstypes.h $(SRC)/phrqtype.h $(SRC)/output.h + +tally.o: $(SRC)/tally.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +tidy.o: $(SRC)/tidy.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +transport.o: $(SRC)/transport.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +utilities.o: $(SRC)/utilities.cpp $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/output.h $(SRC)/phrqproto.h + +Conc.o: $(SRC)/Conc.cxx $(SRC)/Conc.h $(SRC)/Utils.h $(SRC)/char_star.h $(SRC)/ISolution.h $(SRC)/NumKeyword.h \ + $(SRC)/Parser.h $(SRC)/Solution.h $(SRC)/Isotope.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h \ + $(SRC)/phrqproto.h $(SRC)/phqalloc.h +Exchange.o: $(SRC)/Exchange.cxx $(SRC)/Utils.h $(SRC)/Exchange.h $(SRC)/NumKeyword.h Parser.h \ + $(SRC)/char_star.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/ExchComp.h $(SRC)/NameDouble.h $(SRC)/phqalloc.h \ + $(SRC)/phrqproto.h +ExchComp.o: $(SRC)/ExchComp.cxx $(SRC)/Utils.h $(SRC)/ExchComp.h $(SRC)/NameDouble.h $(SRC)/global.h \ + $(SRC)/phrqtype.h $(SRC)/char_star.h $(SRC)/Parser.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +GasPhase.o: $(SRC)/GasPhase.cxx $(SRC)/Utils.h $(SRC)/GasPhase.h $(SRC)/NumKeyword.h $(SRC)/Parser.h \ + $(SRC)/char_star.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +ISolution.o: $(SRC)/ISolution.cxx $(SRC)/ISolution.h $(SRC)/NumKeyword.h $(SRC)/Parser.h $(SRC)/char_star.h \ + $(SRC)/Solution.h $(SRC)/Isotope.h $(SRC)/Conc.h $(SRC)/Utils.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h \ + $(SRC)/phqalloc.h $(SRC)/phrqproto.h +Isotope.o: $(SRC)/Isotope.cxx $(SRC)/Isotope.h $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/Utils.h $(SRC)/global.h \ + $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +KineticsComp.o: $(SRC)/KineticsComp.cxx $(SRC)/Utils.h $(SRC)/KineticsComp.h $(SRC)/NameDouble.h \ + $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/char_star.h $(SRC)/Parser.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +KineticsCxx.o: $(SRC)/KineticsCxx.cxx $(SRC)/Utils.h $(SRC)/KineticsCxx.h $(SRC)/NumKeyword.h $(SRC)/Parser.h \ + $(SRC)/char_star.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/KineticsComp.h $(SRC)/NameDouble.h $(SRC)/phqalloc.h \ + $(SRC)/phrqproto.h +Mix.o: $(SRC)/Mix.cxx $(SRC)/Utils.h $(SRC)/Mix.h $(SRC)/NumKeyword.h $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/global.h \ + $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +NameDouble.o: $(SRC)/NameDouble.cxx $(SRC)/Utils.h $(SRC)/Conc.h $(SRC)/char_star.h $(SRC)/NameDouble.h \ + $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/Parser.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +NumKeyword.o: $(SRC)/NumKeyword.cxx $(SRC)/NumKeyword.h $(SRC)/Parser.h $(SRC)/char_star.h +Reaction.o: $(SRC)/Reaction.cxx $(SRC)/Utils.h $(SRC)/Reaction.h $(SRC)/NumKeyword.h $(SRC)/Parser.h \ + $(SRC)/char_star.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +ReadClass.o: $(SRC)/ReadClass.cpp +Parser.o: $(SRC)/Parser.cxx $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/Utils.h +PPassemblageComp.o: $(SRC)/PPassemblageComp.cxx $(SRC)/Utils.h $(SRC)/NameDouble.h \ + $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/char_star.h $(SRC)/Parser.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +PPassemblage.o: $(SRC)/PPassemblage.cxx $(SRC)/Utils.h $(SRC)/PPassemblage.h $(SRC)/NumKeyword.h \ + $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/PPassemblageComp.h \ + $(SRC)/NameDouble.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +Solution.o: $(SRC)/Solution.cxx $(SRC)/Utils.h $(SRC)/Solution.h $(SRC)/NumKeyword.h $(SRC)/Parser.h \ + $(SRC)/char_star.h $(SRC)/Isotope.h $(SRC)/Conc.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h \ + $(SRC)/phqalloc.h $(SRC)/phrqproto.h $(SRC)/ISolution.h +SSassemblage.o: $(SRC)/SSassemblage.cxx $(SRC)/Utils.h $(SRC)/SSassemblage.h $(SRC)/NumKeyword.h \ + $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/SSassemblageSS.h \ + $(SRC)/NameDouble.h $(SRC)/SSassemblageSS.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h +SSassemblageSS.o: $(SRC)/SSassemblageSS.cxx $(SRC)/Utils.h $(SRC)/SSassemblageSS.h \ + $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/char_star.h $(SRC)/Parser.h $(SRC)/phqalloc.h \ + $(SRC)/phrqproto.h +Surface.o: $(SRC)/Surface.cxx $(SRC)/Utils.h $(SRC)/Surface.h $(SRC)/NumKeyword.h $(SRC)/Parser.h \ + $(SRC)/char_star.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/SurfComp.h $(SRC)/NameDouble.h $(SRC)/phqalloc.h \ + $(SRC)/phrqproto.h +SurfComp.o: $(SRC)/SurfComp.cxx $(SRC)/Utils.h $(SRC)/SurfComp.h $(SRC)/NameDouble.h $(SRC)/global.h \ + $(SRC)/phrqtype.h $(SRC)/char_star.h $(SRC)/Parser.h $(SRC)/phqalloc.h $(SRC)/phrqproto.h + +Temperature.o: $(SRC)/Temperature.cxx $(SRC)/Utils.h $(SRC)/Temperature.h $(SRC)/NumKeyword.h \ + $(SRC)/Parser.h $(SRC)/char_star.h $(SRC)/NameDouble.h $(SRC)/global.h $(SRC)/phrqtype.h $(SRC)/phqalloc.h \ + $(SRC)/phrqproto.h +Utils.o: $(SRC)/Utils.cxx $(SRC)/Utils.h $(SRC)/Parser.h $(SRC)/char_star.h + +-include $(SRC)/distribution.mk + + diff --git a/Mix.cxx b/Mix.cxx new file mode 100644 index 00000000..bc65783f --- /dev/null +++ b/Mix.cxx @@ -0,0 +1,200 @@ +// Mix.cxx: implementation of the cxxMix class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Mix.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxMix::cxxMix() + // + // default constructor for cxxMix + // +: cxxNumKeyword() +{ +} + +cxxMix::cxxMix(struct mix *mix_ptr) + // + // constructor for cxxMix from struct mix + // +: +cxxNumKeyword() +{ + int i; + + this->set_description(mix_ptr->description); + this->n_user = mix_ptr->n_user; + this->n_user_end = mix_ptr->n_user_end; + // comps + if (mix_ptr->count_comps > 0) { + for (i = 0; i < mix_ptr->count_comps; i++) { + this->mixComps[mix_ptr->comps[i].n_solution] = mix_ptr->comps[i].fraction; + } + } +} + +cxxMix::~cxxMix() +{ +} + + +struct mix *cxxMix::cxxMix2mix() + // + // Builds a mix structure from instance of cxxMix + // +{ + struct mix *mix_ptr; + mix_ptr = (struct mix *) PHRQ_malloc(sizeof (struct mix)); + if (mix_ptr == NULL) malloc_error(); + + mix_ptr->description = this->get_description(); + mix_ptr->n_user = this->n_user; + mix_ptr->n_user_end = this->n_user_end; + + // comps + mix_ptr->comps = NULL; + if (this->mixComps.size() > 0) { + int i = 0; + mix_ptr->comps = (struct mix_comp *) PHRQ_malloc((size_t) (this->mixComps.size() * sizeof(struct mix_comp))); + if (mix_ptr->comps == NULL) malloc_error(); + for (std::map::iterator it = mixComps.begin(); it != mixComps.end(); it++) { + mix_ptr->comps[i].n_solution = it->first; + mix_ptr->comps[i].fraction = it->second; + i++; + } + } + mix_ptr->count_comps = this->mixComps.size(); + return(mix_ptr); +} + +#ifdef SKIP +void cxxMix::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing mix message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Mix element and attributes + s_oss << indent0; + s_oss << "pitzer_mix_gammas << "\"" << std::endl; + + // components + s_oss << indent1; + s_oss << "::const_iterator it = mixComps.begin(); it != mixComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} +#endif + +void cxxMix::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing mix message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Mix element and attributes + s_oss << indent0; + s_oss << "MIX " << this->n_user << " " << this->description << std::endl; + + for (std::map::const_iterator it = this->mixComps.begin(); it != this->mixComps.end(); it++) { + s_oss << indent1 << it->first << " " << it->second << std::endl; + } +} + +void cxxMix::read_raw(CParser& parser) +{ + + int i; + double d; + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read mix number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_DEFAULT; + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in MIX_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case CParser::OPT_DEFAULT: // solution number, mix fraction + if (parser.copy_token(token, next_char) != CParser::TT_EMPTY) { + std::istringstream iss(token); + if (!(iss >> i)) + { + parser.incr_input_error(); + parser.error_msg("Expected integer value for solution number.", CParser::OT_CONTINUE); + break; + } + if (!(parser.get_iss() >> d)) + { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for solution fraction.", CParser::OT_CONTINUE); + break; + } + this->mixComps[i] = d; + } + opt_save = CParser::OPT_DEFAULT; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined +} diff --git a/Mix.h b/Mix.h new file mode 100644 index 00000000..9180c5b6 --- /dev/null +++ b/Mix.h @@ -0,0 +1,39 @@ +#if !defined(MIX_H_INCLUDED) +#define MIX_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxMix : public cxxNumKeyword +{ + +public: + cxxMix(); + cxxMix(struct mix *); + ~cxxMix(); + + struct mix *cxxMix2mix(); + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + std::map mixComps; + +public: + //static std::map& map; + +}; + +#endif // !defined(MIX_H_INCLUDED) diff --git a/NameDouble.cxx b/NameDouble.cxx new file mode 100644 index 00000000..b4385bf8 --- /dev/null +++ b/NameDouble.cxx @@ -0,0 +1,259 @@ +// NameDouble.cxx: implementation of the cxxNameDouble class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Conc.h" +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxNameDouble::cxxNameDouble() + // + // default constructor for cxxNameDouble + // +{ +} + +cxxNameDouble::cxxNameDouble(struct elt_list *elt_list_ptr) + // + // constructor for cxxNameDouble from list of elt_list + // +{ + int i; + if (elt_list_ptr != NULL) { + for (i = 0; elt_list_ptr[i].elt != NULL; i++) { + (*this)[elt_list_ptr[i].elt->name] = elt_list_ptr[i].coef; + } + } + this->type = ND_ELT_MOLES; +} +cxxNameDouble::cxxNameDouble(struct conc *tots) + // + // constructor for cxxNameDouble from list of elt_list + // +{ + int i; + for (i = 0; tots[i].description != NULL; i++) { + (*this)[tots[i].description] = tots[i].moles; + } + this->type = ND_ELT_MOLES; +} +cxxNameDouble::cxxNameDouble(struct master_activity *ma, int count, cxxNameDouble::ND_TYPE) + // + // constructor for cxxNameDouble from list of elt_list + // +{ + int i; + for (i = 0; i < count; i++) { + if (ma[i].description == NULL) continue; + (*this)[ma[i].description] = ma[i].la; + } + this->type = ND_SPECIES_LA; +} +cxxNameDouble::cxxNameDouble(struct name_coef *nc, int count, cxxNameDouble::ND_TYPE) + // + // constructor for cxxNameDouble from list of elt_list + // +{ + int i; + for (i = 0; i < count; i++) { + if (nc[i].name == NULL) continue; + (*this)[nc[i].name] = nc[i].coef; + } + this->type = ND_NAME_COEF; +} +cxxNameDouble::~cxxNameDouble() +{ +} + +struct elt_list *cxxNameDouble::elt_list() + // + // Builds a exch_comp structure from instance of cxxNameDouble + // +{ + assert (this->type == cxxNameDouble::ND_ELT_MOLES); + struct elt_list *elt_list_ptr = (struct elt_list *) PHRQ_malloc((size_t)((this->size() + 1) *sizeof(struct elt_list))); + if (elt_list_ptr == NULL) malloc_error(); + int i = 0; + for (iterator it = this->begin(); it != this->end(); ++it) { + elt_list_ptr[i].elt = element_store(it->first); + elt_list_ptr[i].coef = it->second; + i++; + } + elt_list_ptr[i].elt = NULL; + elt_list_ptr[i].coef = 0; + return(elt_list_ptr); +} + +struct master_activity *cxxNameDouble::master_activity()const + // + // Builds a list of master_activity structures from instance of cxxNameDouble + // +{ + int i = 0; + assert (this->type == cxxNameDouble::ND_SPECIES_LA || this->type == cxxNameDouble::ND_SPECIES_GAMMA); + struct master_activity *master_activity_ptr = NULL; + switch ((*this).type) { + case cxxNameDouble::ND_SPECIES_LA: + { + master_activity_ptr= (struct master_activity *) PHRQ_malloc((size_t) (((*this).size() + 1) * sizeof(struct master_activity))); + if (master_activity_ptr == NULL) malloc_error(); + for (const_iterator it = (*this).begin(); it != (*this).end(); it++) { + master_activity_ptr[i].description = (char *)it->first; + master_activity_ptr[i].la = it->second; + i++; + } + } + master_activity_ptr[i].description = NULL; + break; + case cxxNameDouble::ND_SPECIES_GAMMA: + { + if ((*this).size() > 0) { + master_activity_ptr = (struct master_activity *) PHRQ_malloc((size_t) (((*this).size()) * sizeof(struct master_activity))); + if (master_activity_ptr == NULL) malloc_error(); + for (const_iterator it = (*this).begin(); it != (*this).end(); it++) { + master_activity_ptr[i].description = (char *)it->first; + master_activity_ptr[i].la = it->second; + i++; + } + } + } + break; + case cxxNameDouble::ND_ELT_MOLES: + case cxxNameDouble::ND_NAME_COEF: + break; + } + return(master_activity_ptr); +} + +struct conc *cxxNameDouble::conc()const + // for Solutions, not ISolutions + // takes a map of (elt name, moles) + // returns list of conc structures +{ + struct conc *c; + assert (this->type == cxxNameDouble::ND_ELT_MOLES); + c = (struct conc *) PHRQ_malloc((size_t) (((*this).size() + 1) * sizeof(struct conc))); + if (c == NULL) malloc_error(); + int i = 0; + for (const_iterator it = (*this).begin(); it != (*this).end(); ++it) { + c[i].description = (char *)it->first; + c[i].moles = it->second; + c[i].input_conc = it->second; + c[i].units = NULL; + c[i].equation_name = NULL; + c[i].phase_si = 0.0; + c[i].n_pe = 0; + c[i].as = NULL; + c[i].gfw = 0.0; + //c[i].skip = 0; + c[i].phase = NULL; + i++; + } + c[i].description = NULL; + return(c); +} + +struct name_coef *cxxNameDouble::name_coef()const + // + // Builds a name_coef structure from instance of cxxNameDouble + // +{ + assert (this->type == cxxNameDouble::ND_NAME_COEF); + struct name_coef *name_coef_ptr = (struct name_coef *) PHRQ_malloc((size_t)((this->size()) *sizeof(struct name_coef))); + if (name_coef_ptr == NULL) malloc_error(); + int i = 0; + for (const_iterator it = (*this).begin(); it != (*this).end(); ++it) { + name_coef_ptr[i].name = it->first; + name_coef_ptr[i].coef = it->second; + i++; + } + return(name_coef_ptr); +} + +void cxxNameDouble::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exch_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + std::string xmlElement, xmlAtt1, xmlAtt2; + + switch ((*this).type) { + case cxxNameDouble::ND_SPECIES_LA: + xmlElement = "first << xmlAtt2 << it->second << "/>" << std::endl; + } +} + +void cxxNameDouble::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing exch_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + + for (const_iterator it = (*this).begin(); it != (*this).end(); it++) { + s_oss << indent0; + s_oss << it->first << " " << it->second << std::endl; + } +} +CParser::STATUS_TYPE cxxNameDouble::read_raw(CParser& parser, std::istream::pos_type& pos) +{ + std::string token; + char * ctoken; + double d; + + CParser::TOKEN_TYPE j; + + //m_line_iss.seekg(pos); + + j = parser.copy_token(token, pos); + + if (j == CParser::TT_EMPTY) return CParser::PARSER_OK; + + if( !(parser.get_iss() >> d)) { + return CParser::PARSER_ERROR; + } + ctoken = string_hsave(token.c_str()); + (*this)[ctoken] = d; + return CParser::PARSER_OK; +} diff --git a/NameDouble.h b/NameDouble.h new file mode 100644 index 00000000..0977d958 --- /dev/null +++ b/NameDouble.h @@ -0,0 +1,57 @@ +#if !defined(NAMEDOUBLE_H_INCLUDED) +#define NAMEDOUBLE_H_INCLUDED + +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "Parser.h" +class cxxNameDouble : public std::map +{ + +public: + enum ND_TYPE { + ND_ELT_MOLES = 1, + ND_SPECIES_LA = 2, + ND_SPECIES_GAMMA = 3, + ND_NAME_COEF = 4 + }; + + cxxNameDouble(); + cxxNameDouble(struct elt_list *); + cxxNameDouble(struct conc *); + cxxNameDouble(struct master_activity *ma, int count, ND_TYPE); + cxxNameDouble(struct name_coef *nc, int count, ND_TYPE); + ~cxxNameDouble(); + + struct elt_list *elt_list(); + + struct master_activity *master_activity()const; + + struct conc *conc()const; + + struct name_coef *name_coef()const; + + void cxxNameDouble::dump_xml(std::ostream& s_oss, unsigned int indent)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + CParser::STATUS_TYPE read_raw(CParser& parser, std::istream::pos_type& pos); + + enum ND_TYPE type; + +protected: + //std::map totals; + + +public: + //static std::map& map; + +}; + +#endif // !defined(NAMEDOUBLE_H_INCLUDED) diff --git a/NumKeyword.cxx b/NumKeyword.cxx new file mode 100644 index 00000000..c0d3e64d --- /dev/null +++ b/NumKeyword.cxx @@ -0,0 +1,138 @@ +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif +// NumKeyword.cxx: implementation of the cxxNumKeyword class. +// +////////////////////////////////////////////////////////////////////// + +#include "NumKeyword.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxNumKeyword::cxxNumKeyword() +{ +} + +cxxNumKeyword::~cxxNumKeyword() +{ +} + +void cxxNumKeyword::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->n_user << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->n_user_end << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->description << "" << "\n"; +} + +void cxxNumKeyword::read_number_description(CParser& parser) +{ + std::string keyword; + std::istream::pos_type ptr; + + // skip keyword + parser.copy_token(keyword, ptr); + + std::istream::pos_type ptr1 = ptr; + std::string::size_type pos; + std::string token; + if (parser.copy_token(token, ptr) != CParser::TT_DIGIT) + { + this->n_user = 1; + this->n_user_end = 1; + } else { + std::istringstream iss(token); + iss >> this->n_user; + this->n_user_end = this->n_user; + std::string token1; + iss >> token1; + if ( (pos = token1.find_first_of("-")) != std::string::npos ) { + token1.replace(pos, 1, " "); + std::istringstream iss1(token1); + iss1 >> this->n_user_end; + // ptr1 = ptr; + } + } + /* + else if ( (pos = token.find_first_of("-")) != std::string::npos ) + { + token.replace(pos, 1, " "); + std::istringstream iss(token); + if (!(iss >> this->n_user >> this->n_user_end)) + { + std::ostringstream err_oss; + if (parser.next_keyword() >= 0) + { + err_oss << "Reading number range for " << keyword << "."; + } + else + { + err_oss << "Reading number range for keyword."; + } + parser.error_msg(err_oss, CParser::OT_CONTINUE); + parser.incr_input_error(); + } + ptr1 = ptr; + } + else + { + std::istringstream iss(token); + iss >> this->n_user; + this->n_user_end = this->n_user; + ptr1 = ptr; + } + */ + // reset get position + //parser.get_iss().seekg(ptr1); + + // skip whitespace + while (::isspace(parser.get_iss().peek())) parser.get_iss().ignore(); + + // copy description + std::getline(parser.get_iss(), this->description); +} + + +void cxxNumKeyword::read_number_description(std::istream& is) +{ + // KEYWORD [[1[-20]] [This is the description]] + + // eat keyword + std::string token; + is >> token; + + // skip whitespace + while (::isspace(is.peek())) is.ignore(); + + if (::isdigit(is.peek())) + { + is >> this->n_user; + char ch = is.peek(); + if (ch == '-') + { + is >> ch; // eat '-' + is >> this->n_user_end; + } + else + { + this->n_user_end = this->n_user; + } + } + else + { + this->n_user = this->n_user_end = 1; + } + + while (::isspace(is.peek())) is.ignore(); + + std::getline(is, this->description); +} + diff --git a/NumKeyword.h b/NumKeyword.h new file mode 100644 index 00000000..55298566 --- /dev/null +++ b/NumKeyword.h @@ -0,0 +1,43 @@ +#if !defined(NUMKEYWORD_H_INCLUDED) +#define NUMKEYWORD_H_INCLUDED + +#include "Parser.h" +#include // std::ostream +#include // std::string +//#define EXTERNAL extern +//#include "global.h" +//#include "phrqproto.h" +extern char *string_duplicate(const char *); + +class cxxNumKeyword +{ +public: + cxxNumKeyword(); + virtual ~cxxNumKeyword(); + + + char * get_description()const { return string_duplicate(this->description.c_str()); } + void set_description(std::string str) { this->description = str; } + void set_description(char * str) { if (str != NULL) this->description = str; } + + int get_n_user()const { return this->n_user; } + void set_n_user(int user) { this->n_user = user; } + + int get_n_user_end()const { return this->n_user_end; } + void set_n_user_end(int user_end) { this->n_user_end = user_end; } + + bool operator<(const cxxNumKeyword& key)const { return (this->n_user < key.n_user); } + + virtual void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void read_number_description(CParser& parser); + +protected: + int n_user; + int n_user_end; + std::string description; + +private: + void read_number_description(std::istream& is); +}; +#endif // !defined(NUMKEYWORD_H_INCLUDED) diff --git a/PPassemblage.cxx b/PPassemblage.cxx new file mode 100644 index 00000000..a258959b --- /dev/null +++ b/PPassemblage.cxx @@ -0,0 +1,191 @@ +// PPassemblage.cxx: implementation of the cxxPPassemblage class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "PPassemblage.h" +#include "PPassemblageComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxPPassemblage::cxxPPassemblage() + // + // default constructor for cxxPPassemblage + // +: cxxNumKeyword() +{ + eltList.type = cxxNameDouble::ND_ELT_MOLES; +} + +cxxPPassemblage::cxxPPassemblage(struct pp_assemblage *pp_assemblage_ptr) + // + // constructor for cxxPPassemblage from struct PPassemblage + // +: +cxxNumKeyword(), +eltList(pp_assemblage_ptr->next_elt) +{ + int i; + + this->set_description(pp_assemblage_ptr->description); + n_user = pp_assemblage_ptr->n_user; + n_user_end = pp_assemblage_ptr->n_user_end; + for (i = 0; i < pp_assemblage_ptr->count_comps; i++) { + cxxPPassemblageComp ppComp(&(pp_assemblage_ptr->pure_phases[i])); + ppAssemblageComps.push_back(ppComp); + } +} + +cxxPPassemblage::~cxxPPassemblage() +{ +} + +struct pp_assemblage *cxxPPassemblage::cxxPPassemblage2pp_assemblage() + // + // Builds a pp_assemblage structure from instance of cxxPPassemblage + // +{ + struct pp_assemblage *pp_assemblage_ptr = pp_assemblage_alloc(); + + pp_assemblage_ptr->description = this->get_description(); + pp_assemblage_ptr->n_user = this->n_user; + pp_assemblage_ptr->n_user_end = this->n_user_end; + pp_assemblage_ptr->new_def = FALSE; + pp_assemblage_ptr->count_comps = this->ppAssemblageComps.size(); + pp_assemblage_ptr->pure_phases = (struct pure_phase *) free_check_null(pp_assemblage_ptr->pure_phases); + pp_assemblage_ptr->pure_phases = cxxPPassemblageComp::cxxPPassemblageComp2pure_phase(this->ppAssemblageComps); + pp_assemblage_ptr->next_elt = this->eltList.elt_list(); + return(pp_assemblage_ptr); +} + +void cxxPPassemblage::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing PPassemblage message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // PPassemblage element and attributes + s_oss << indent0; + s_oss << "eltList.dump_xml(s_oss, indent + 1); + + // ppAssemblageComps + s_oss << indent1; + s_oss << "::const_iterator it = ppAssemblageComps.begin(); it != ppAssemblageComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } +} + +void cxxPPassemblage::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing PPassemblage message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // PPassemblage element and attributes + s_oss << indent0; + s_oss << "EQUILIBRIUM_PHASES_RAW " << this->n_user << " " << this->description << std::endl; + + // eltList + + s_oss << indent1; + s_oss << "-eltList " << std::endl; + this->eltList.dump_raw(s_oss, indent + 2); + + // ppAssemblagComps + for (std::list::const_iterator it = ppAssemblageComps.begin(); it != ppAssemblageComps.end(); ++it) { + s_oss << indent1; + s_oss << "-component" << std::endl; + it->dump_raw(s_oss, indent + 2); + } +} + +void cxxPPassemblage::read_raw(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("eltlist"); // 0 + vopts.push_back("component"); // 1 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read PPassemblage number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in EQUILIBRIUM_PHASES_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // eltList + if ( this->eltList.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and moles for totals.", CParser::OT_CONTINUE); + } + opt_save = 0; + break; + + case 1: // component + { + cxxPPassemblageComp ppComp; + ppComp.read_raw(parser); + this->ppAssemblageComps.push_back(ppComp); + } + useLastLine = true; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined +} diff --git a/PPassemblage.h b/PPassemblage.h new file mode 100644 index 00000000..34af42e8 --- /dev/null +++ b/PPassemblage.h @@ -0,0 +1,43 @@ +#if !defined(PPASSEMBLAGE_H_INCLUDED) +#define PPASSEMBLAGE_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "PPassemblageComp.h" + +class cxxPPassemblage : public cxxNumKeyword +{ + +public: + cxxPPassemblage(); + cxxPPassemblage(struct pp_assemblage *); + ~cxxPPassemblage(); + + struct pp_assemblage *cxxPPassemblage2pp_assemblage(); + + struct pure_phase *cxxPPassemblageComp2pure_phase(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + std::list ppAssemblageComps; + cxxNameDouble eltList; + +public: + //static std::map& map; + +}; + +#endif // !defined(PPASSEMBLAGE_H_INCLUDED) diff --git a/PPassemblageComp.cxx b/PPassemblageComp.cxx new file mode 100644 index 00000000..0ba431f6 --- /dev/null +++ b/PPassemblageComp.cxx @@ -0,0 +1,278 @@ +// PPassemblageComp.cxx: implementation of the cxxPPassemblageComp class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "PPassemblageComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxPPassemblageComp::cxxPPassemblageComp() + // + // default constructor for cxxPPassemblageComp + // +{ + name = NULL; + add_formula = NULL; + si = 0; + moles = 0; + delta = 0; + initial_moles = 0; + dissolve_only = false; +} + +cxxPPassemblageComp::cxxPPassemblageComp(struct pure_phase *pure_phase_ptr) + // + // constructor for cxxPPassemblageComp from struct pure_phase + // + +{ + name = pure_phase_ptr->name; + add_formula = pure_phase_ptr->add_formula; + si = pure_phase_ptr->si; + moles = pure_phase_ptr->moles; + delta = pure_phase_ptr->delta; + initial_moles = pure_phase_ptr->initial_moles; + dissolve_only = ( pure_phase_ptr->dissolve_only == TRUE); +} + +cxxPPassemblageComp::~cxxPPassemblageComp() +{ +} + +struct phase *cxxPPassemblageComp::get_phase() { + int i; + return phase_bsearch(this->name, &i, FALSE); +} + +struct pure_phase *cxxPPassemblageComp::cxxPPassemblageComp2pure_phase(std::list& el) + // + // Builds pure_phase structure from of cxxPPassemblageComp + // +{ + struct pure_phase *pure_phase_ptr = (struct pure_phase *) PHRQ_malloc((size_t) (el.size() * sizeof(struct pure_phase))); + if (pure_phase_ptr == NULL) malloc_error(); + + int i = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + pure_phase_ptr[i].phase = it->get_phase(); + pure_phase_ptr[i].name = it->name; + pure_phase_ptr[i].add_formula = it->add_formula; + pure_phase_ptr[i].si = it->si; + pure_phase_ptr[i].moles = it->moles; + pure_phase_ptr[i].delta = it->delta; + pure_phase_ptr[i].initial_moles = it->initial_moles; + pure_phase_ptr[i].dissolve_only = (int) it->dissolve_only; + i++; + } + return(pure_phase_ptr); +} + +void cxxPPassemblageComp::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing pure_phase message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Pure_Phase element and attributes + + s_oss << indent0 << "name=\"" << this->name << "\"" << std::endl; + s_oss << indent0 << "add_formula=\"" << this->add_formula << "\"" << std::endl; + s_oss << indent0 << "si=\"" << this->si << "\"" << std::endl; + s_oss << indent0 << "moles=\"" << this->moles << "\"" << std::endl; + s_oss << indent0 << "delta=\"" << this->delta << "\"" << std::endl; + s_oss << indent0 << "initial_moles=\"" << this->initial_moles << "\"" << std::endl; + s_oss << indent0 << "dissolve_only=\"" << this->dissolve_only << "\"" << std::endl; + +} + +void cxxPPassemblageComp::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing pure_phase message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Pure_Phase element and attributes + + if (this->name != NULL) s_oss << indent0 << "-name " << this->name << std::endl; + if (this->add_formula != NULL) s_oss << indent0 << "-add_formula " << this->add_formula << std::endl; + s_oss << indent0 << "-si " << this->si << std::endl; + s_oss << indent0 << "-moles " << this->moles << std::endl; + s_oss << indent0 << "-delta " << this->delta << std::endl; + s_oss << indent0 << "-initial_moles " << this->initial_moles << std::endl; + s_oss << indent0 << "-dissolve_only " << this->dissolve_only << std::endl; +} + +void cxxPPassemblageComp::read_raw(CParser& parser) +{ + std::string str; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("name"); // 0 + vopts.push_back("add_formula"); // 1 + vopts.push_back("si"); // 2 + vopts.push_back("moles"); // 3 + vopts.push_back("delta"); // 4 + vopts.push_back("initial_moles"); // 5 + vopts.push_back("dissolve_only"); // 6 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool name_defined(false); + bool si_defined(false); + bool moles_defined(false); + bool delta_defined(false); + bool initial_moles_defined(false); + bool dissolve_only_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Exchange for more processing + //parser.error_msg("Unknown input in PURE_PHASE read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // name + if (!(parser.get_iss() >> str)) + { + this->name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for name.", CParser::OT_CONTINUE); + } else { + this->name = string_hsave(str.c_str()); + } + name_defined = true; + break; + + case 1: // add_formula + if (!(parser.get_iss() >> str)) + { + this->add_formula = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for add_formula.", CParser::OT_CONTINUE); + } else { + this->add_formula = string_hsave(str.c_str()); + } + break; + + case 2: // si + if (!(parser.get_iss() >> this->si)) + { + this->si = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for si.", CParser::OT_CONTINUE); + } + si_defined = true; + break; + + case 3: // moles + if (!(parser.get_iss() >> this->moles)) + { + this->moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for moles.", CParser::OT_CONTINUE); + } + moles_defined = true; + break; + + case 4: // delta + if (!(parser.get_iss() >> this->delta)) + { + this->delta = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for delta.", CParser::OT_CONTINUE); + } + delta_defined = true; + break; + + case 5: // initial_moles + if (!(parser.get_iss() >> this->initial_moles)) + { + this->initial_moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for initial_moles.", CParser::OT_CONTINUE); + } + initial_moles_defined = true; + break; + + + case 6: // dissolve_only + if (!(parser.get_iss() >> this->dissolve_only)) + { + this->dissolve_only = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for dissolve_only.", CParser::OT_CONTINUE); + } + dissolve_only_defined = true; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (name_defined == false) { + parser.incr_input_error(); + parser.error_msg("Name not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } + if (si_defined == false) { + parser.incr_input_error(); + parser.error_msg("Si not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } + if (moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Moles not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } + if (delta_defined == false) { + parser.incr_input_error(); + parser.error_msg("Delta not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } + if (initial_moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Initial_moles not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } + if (dissolve_only_defined == false) { + parser.incr_input_error(); + parser.error_msg("Dissolve_only not defined for PPassemblageComp input.", CParser::OT_CONTINUE); + } +} + diff --git a/PPassemblageComp.h b/PPassemblageComp.h new file mode 100644 index 00000000..7020a055 --- /dev/null +++ b/PPassemblageComp.h @@ -0,0 +1,47 @@ +#if !defined(PPASSEMBLAGECOMP_H_INCLUDED) +#define PPASSEMBLAGECOMP_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxPPassemblageComp +{ + +public: + cxxPPassemblageComp(); + cxxPPassemblageComp(struct pure_phase *); + ~cxxPPassemblageComp(); + + + static struct pure_phase *cxxPPassemblageComp2pure_phase(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + + struct phase *get_phase(); + +protected: + char * name; + char *add_formula; + double si; + double moles; + double delta; + double initial_moles; + bool dissolve_only; + +public: + +}; + +#endif // !defined(PPASSEMBLAGECOMP_H_INCLUDED) diff --git a/Parser.cxx b/Parser.cxx new file mode 100644 index 00000000..48f78c22 --- /dev/null +++ b/Parser.cxx @@ -0,0 +1,1070 @@ +// Parser.cpp: implementation of the CParser class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Parser.h" +#include "Utils.h" +#include // std::transform +#include // std::map +#include // assert +#include // std::cout std::cerr +#include "char_star.h" +extern char *string_hsave (const char *str); + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CParser::CParser(std::istream& input) +: m_input_stream(input), m_output_stream(std::cout), m_error_stream(std::cerr) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::CParser(std::istream& input, std::ostream& output) +: m_input_stream(input), m_output_stream(output), m_error_stream(std::cerr) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::CParser(std::istream& input, std::ostream& output, std::ostream& error) +: m_input_stream(input), m_output_stream(output), m_error_stream(error) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::~CParser() +{ +} + +CParser::LINE_TYPE CParser::check_line(const std::string& str, bool allow_empty, bool allow_eof, bool allow_keyword, bool print) +{ + LINE_TYPE i; + + // Get line + do { + i = get_line(); + // reset iss + m_line_iss.str(m_line); + m_line_iss.seekg(0, std::ios_base::beg); + m_line_iss.clear(); + + + if (true) // pr.echo_input == TRUE + { + if ((print && i != LT_EOF) || i == LT_KEYWORD) + { + get_output() << "\t" << m_line_save << "\n"; + } + } + + } while (i == LT_EMPTY && allow_empty == false); + + // Check eof + if (i == LT_EOF && allow_eof == false) + { + std::ostringstream msg; + msg << "Unexpected eof while reading " << str << "\nExecution terminated.\n"; + error_msg(msg, OT_STOP); + } + + // Check keyword + if (i == LT_KEYWORD && allow_keyword == false) + { + std::ostringstream msg; + msg << "Expected data for " << str << ", but got a keyword ending data block."; + error_msg(msg, OT_CONTINUE); + incr_input_error(); + } + m_line_type = i; + return i; +} + +CParser::LINE_TYPE CParser::get_line() +{ + CParser::LINE_TYPE return_value = LT_EMPTY; + while (return_value == LT_EMPTY) + { + // + // Eliminate all characters after # sign as a comment + // + + // + // Get line, check for eof + // + if (get_logical_line() == LT_EOF) + { + if (!m_input_stream.eof()) + { + error_msg("Reading input file.", OT_CONTINUE); + error_msg("istream::get() returned an error.", OT_STOP); + } + else + { + //{{MOD + m_line.erase(m_line.begin(), m_line.end()); // m_line.clear(); + //}}MOD + m_next_keyword = KT_EOF; + return LT_EOF; + } + } + + // + // Get long lines + // + bool empty = true; + m_line = m_line_save.substr(0, m_line_save.find_first_of('#')); + for (unsigned int i = 0; i < m_line.size(); ++i) + { + if (!::isspace(m_line[i])) + { + empty = false; + break; + } + } + + // + // New line character encountered + // + return_value = (empty ? LT_EMPTY : LT_OK); + } + + // + // Determine return_value + // + if (return_value == LT_OK) + { + if (check_key(m_line.begin(), m_line.end())) + { + return_value = LT_KEYWORD; + } + else + { + std::string::iterator beg = m_line.begin(); + std::string::iterator end = m_line.end(); + std::string token; + copy_token(token, beg, end); + + if (token.size() > 1 && token[0] == '-' && ::isalpha(token[1])) + { + return_value = LT_OPTION; + } + } + } + return return_value; +} + +/** + Reads input stream until end of line, ";", or eof + stores characters in line_save + + returns: + EOF on empty line on end of file or + OK otherwise +*/ +CParser::LINE_TYPE CParser::get_logical_line() +{ + int j; + unsigned int pos; + char c; + + m_line_save.erase(m_line_save.begin(), m_line_save.end()); // m_line_save.clear(); + + while ((j = m_input_stream.get()) != std::char_traits::eof()) { + c = (char) j; + if (c == '#') { + // ignore all chars after # until newline + do { + c = (char) j; + if (c == '\n') { + break; + } + m_line_save += c; + } while ((j = m_input_stream.get()) != std::char_traits::eof()); + } + if (c == ';') break; + if (c == '\n') { + break; + } + if (c == '\\') { + pos = m_line_save.size(); + m_line_save += c; + while ((j = m_input_stream.get()) != std::char_traits::eof()) { + c = (char) j; + if (c == '\\') { + pos = m_line_save.size(); + m_line_save += c; + continue; + } + if (c == '\n') { + // remove '\\' + for (; pos < m_line_save.size(); pos++) { + m_line_save[pos] = m_line_save[pos+1]; + } + m_line_save.erase(m_line_save.size() - 1, 1); + break; + } + m_line_save += c; + if (!::isspace(j)) break; + } + } else { + m_line_save += c; + } + } + if (j == std::char_traits::eof() && m_line_save.size() == 0) { + return(LT_EOF); + } + return(LT_OK); +} + + +//bool CParser::check_key(const std::string::iterator ptr) +bool CParser::check_key(std::string::iterator begin, std::string::iterator end) +{ + static std::map s_keyword_map; + if (s_keyword_map.size() == 0) + { + s_keyword_map.insert(std::map::value_type("solution", KT_SOLUTION)); + s_keyword_map.insert(std::map::value_type("solution_raw", KT_SOLUTION_RAW)); + s_keyword_map.insert(std::map::value_type("end", KT_END)); + } + + std::string lowercase; + copy_token(lowercase, begin, end); + std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(), tolower); + + m_next_keyword = KT_NONE; + std::map::iterator map_iter = s_keyword_map.find(lowercase); + if (map_iter == s_keyword_map.end()) + return false; + m_next_keyword = (*map_iter).second; + return true; +} + +CParser::STATUS_TYPE CParser::check_units(std::string& tot_units, bool alkalinity, bool check_compatibility, + const std::string& default_units, bool print) +{ +/* + * Check if legitimate units + * Input: + * tot_units character string to check, + * alkalinity true if alkalinity, false if any other total, + * check_compatibility true check alk and default units, false otherwise + * default_units character string of default units (check /L, /kg, etc) + * print true print warning messages + * Output: + * tot_units standard form for unit + */ + using Utilities::str_tolower; + using Utilities::replace; + using Utilities::squeeze_white; + + static const char *units[] = { + "Mol/l", /* 0 */ + "mMol/l", /* 1 */ + "uMol/l", /* 2 */ + "g/l", /* 3 */ + "mg/l", /* 4 */ + "ug/l", /* 5 */ + "Mol/kgs", /* 6 */ + "mMol/kgs", /* 7 */ + "uMol/kgs", /* 8 */ + "g/kgs", /* 9 = ppt */ + "mg/kgs", /* 10 = ppm */ + "ug/kgs", /* 11 = ppb */ + "Mol/kgw", /* 12 = mol/kg H2O */ + "mMol/kgw", /* 13 = mmol/kg H2O */ + "uMol/kgw", /* 14 = umol/kg H2O */ + "g/kgw", /* 15 = mol/kg H2O */ + "mg/kgw", /* 16 = mmol/kg H2O */ + "ug/kgw", /* 17 = umol/kg H2O */ + "eq/l", /* 18 */ + "meq/l", /* 19 */ + "ueq/l", /* 20 */ + "eq/kgs", /* 21 */ + "meq/kgs", /* 22 */ + "ueq/kgs", /* 23 */ + "eq/kgw", /* 24 */ + "meq/kgw", /* 25 */ + "ueq/kgw", /* 26 */ + }; + + squeeze_white(tot_units); + str_tolower(tot_units); + replace("milli", "m", tot_units); + replace("micro", "u", tot_units); + replace("grams", "g", tot_units); + replace("gram", "g", tot_units); + replace("moles", "Mol", tot_units); + replace("mole", "Mol", tot_units); + replace("mol", "Mol", tot_units); + replace("liter", "l", tot_units); + replace("kgh", "kgw", tot_units); + replace("ppt", "g/kgs", tot_units); + replace("ppm", "mg/kgs", tot_units); + replace("ppb", "ug/kgs", tot_units); + replace("equivalents", "eq", tot_units); + replace("equivalent", "eq", tot_units); + replace("equiv", "eq", tot_units); + + std::string::size_type end; + if ((end = tot_units.find("/l")) != std::string::npos) { + tot_units.resize(end + 2); + } + if ((end = tot_units.find("/kgs")) != std::string::npos) { + tot_units.resize(end + 4); + } + if ((end = tot_units.find("/kgw")) != std::string::npos) { + tot_units.resize(end + 4); + } + + // + // Check if unit in list + // + bool found = false; + for (unsigned int i = 0; i < sizeof(units) / sizeof(char *); ++i) { + if (tot_units.compare(units[i]) == 0) { + found = true; + break; + } + } + if (!found) { + if (print) { + std::ostringstream err; + err << "Unknown unit, " << tot_units; + error_msg(err, OT_CONTINUE); + } + return PARSER_ERROR; + } + + // + // Check if units are compatible with default_units + // + if (check_compatibility == false) return PARSER_OK; + + // + // Special cases for alkalinity + // + if (alkalinity == true && tot_units.find("Mol") != std::string::npos) { + if (print) { + warning_msg("Alkalinity given in moles, assumed to be equivalents."); + } + replace("Mol", "eq", tot_units); + } + if (alkalinity == false && tot_units.find("eq") != std::string::npos) { + if (print) { + error_msg("Only alkalinity can be entered in equivalents.", OT_CONTINUE); + } + return PARSER_ERROR; + } + + // + // See if default_units are compatible with tot_units + // + if (default_units.find("/l") != std::string::npos && tot_units.find("/l") != std::string::npos) return PARSER_OK; + if (default_units.find("/kgs") != std::string::npos && tot_units.find("/kgs") != std::string::npos) return PARSER_OK; + if (default_units.find("/kgw") != std::string::npos && tot_units.find("/kgw") != std::string::npos) return PARSER_OK; + + std::string str = default_units; + replace("kgs", "kg solution", str); + replace("kgs", "kg solution", tot_units); + replace("kgw", "kg water", str); + replace("kgw", "kg water", tot_units); + replace("/l", "/L", str); + replace("Mol", "mol", str); + replace("/l", "/L", tot_units); + replace("Mol", "mol", tot_units); + + if (print) { + std::ostringstream err; + err << "Units for master species, " << tot_units << ", are not compatible with default units, " << str << "."; + error_msg(err, OT_CONTINUE); + } + return PARSER_ERROR; +} + +CParser::TOKEN_TYPE CParser::token_type(const std::string& token) +{ + if (!token.empty()) { + if (::isupper(token[0])) { + return CParser::TT_UPPER; + } else if (::islower(token[0])) { + return CParser::TT_LOWER; + } else if (::isdigit(token[0]) || token[0] == '.' || token[0] == '-') { + return CParser::TT_DIGIT; + } else { + assert(!::isspace(token[0])); + return CParser::TT_UNKNOWN; + } + } + else { + return CParser::TT_EMPTY; + } +} + +CParser::TOKEN_TYPE CParser::peek_token() +{ + std::istringstream::pos_type pos = m_line_iss.tellg(); + std::string token; + m_line_iss >> token; + m_line_iss.seekg(pos); + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::string::iterator& begin, std::string::iterator& end) +{ + if (begin != end) + { + std::string::iterator b = begin; + for (; b < end && ::isspace(*b); ++b); + + begin = b; + for (; begin < end && !::isspace(*begin); ++begin); + + token.assign(b, begin); + } + else + { + token.resize(0); + } + + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::istream& is) +{ + is >> token; + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::istream::pos_type& pos) +{ + m_line_iss.seekg(pos); + // m_line_iss >> token; + if( !(m_line_iss >> token)) { + token.erase(token.begin(), token.end()); // token.clear(); + } + pos = m_line_iss.tellg(); + return token_type(token); +} + +CParser::FIND_TYPE CParser::find_option(const std::string& item, int *n, const std::vector& list, bool exact) +{ + std::string token(item); + std::transform(token.begin(), token.end(), token.begin(), tolower); + for (unsigned int i = 0; i < list.size(); i++) + { + if (exact == true) + { + if (list[i].compare(token) == 0) + { + *n = i; + return FT_OK; + } + } + else + { + if(list[i].find(token) == 0) + { + *n = i; + return FT_OK; + } + } + } + + *n = -1; + return FT_ERROR; +} + +// OPTION_TYPE get_option(const char **opt_list, int count_opt_list, char **next_char) +// OPTION_TYPE CParser::get_option(const std::vector& opt_list, std::string::iterator& next_char) +int CParser::get_option(const std::vector& opt_list, std::string::iterator& next_char) +{ + // + // Read a line and check for options + // + int j; + int /* opt_l, */ opt; + //char *opt_ptr; + std::string::iterator opt_ptr; + + // char option[MAX_LENGTH]; + std::string option; + + // + // Read line + // + LINE_TYPE lt = check_line("get_option", false, true, true, false); + if (lt == LT_EOF) + { + j = OPT_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPT_KEYWORD; + } + else if (lt == LT_OPTION) + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, false) == CParser::FT_OK) + { + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + next_char = opt_ptr; + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + //////std::istringstream err_msg; + //////err_msg << "Unknown option."; + //////err_msg << line_save; + //////error_msg(const std::string& msg, ONERROR_TYPE); + + // error_msg("Unknown option.", CONTINUE); + // error_msg(line_save, CONTINUE); + // input_error++; + std::cerr << "Unknown option." << "\n"; + std::cerr << m_line_save << "\n"; + + j = OPT_ERROR; + next_char = m_line.begin(); + } + } + else + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_char = opt_ptr; + } + else + { + j = OPT_DEFAULT; + next_char = m_line.begin(); + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + std::cout << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} + +int CParser::get_option(const std::vector& opt_list, std::istream::pos_type& next_pos) +{ + // + // Read a line and check for options + // + int j; + int opt; + std::istream::pos_type pos_ptr; + std::string option; + + // + // Read line + // + LINE_TYPE lt = check_line("get_option", false, true, true, false); + if (lt == LT_EOF) + { + j = OPT_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPT_KEYWORD; + } + else if (lt == LT_OPTION) + { + std::string::iterator opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option.substr(1), &opt, opt_list, false) == FT_OK) + { + // replace -option with option + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + + // reset iss + m_line_iss.str(m_line); + m_line_iss.seekg(0, std::ios_base::beg); + m_line_iss.clear(); + + pos_ptr = 0; + copy_token(option, pos_ptr); + next_pos = pos_ptr; + //{{ + //// m_line_iss.clear(); + //}} + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + //error_msg("Unknown option.", OT_CONTINUE); + //error_msg(m_line_save.c_str(), OT_CONTINUE); + incr_input_error(); + j = OPT_ERROR; + next_pos = pos_ptr; + } + } + else + { + pos_ptr = 0; + copy_token(option, pos_ptr); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_pos = pos_ptr; + } + else + { + j = OPT_DEFAULT; + next_pos = 0; + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} + +int CParser::error_msg(const char *err_str, ONERROR_TYPE ot) +{ + m_error_stream << "ERROR: " << err_str << "\n"; + m_error_stream.flush(); + + m_output_stream << "ERROR: " << err_str << "\n"; + m_output_stream.flush(); + + if (ot == OT_STOP) + { + exit(1); + } + return 0; +} + +int CParser::warning_msg(const char *err_str) +{ + m_error_stream << "WARNING: " << err_str << "\n"; + m_error_stream.flush(); + + m_output_stream << "WARNING: " << err_str << "\n"; + m_output_stream.flush(); + + return 0; +} + +CParser::STATUS_TYPE CParser::get_elt(std::string::iterator& begin, const std::string::iterator end, std::string& element) +{ + element.erase(element.begin(), element.end()); // element.clear(); + + if (begin == end) { + error_msg("Empty string in get_elt. Expected an element name.", OT_CONTINUE); + return PARSER_ERROR; + } + + // + // Load name into char array element + // + char c = *begin; + ++begin; + element.insert(element.end(), c); // element.push_back(c); + if (c == '[') { + while ( (c = *begin) != ']' ) { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if ( (c = *begin) == ']' ) { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + break; + } else if (begin == end) { + error_msg("No ending bracket (]) for element name", OT_CONTINUE); + incr_input_error(); + return PARSER_ERROR; + } + } + while (::islower(c = *begin) || c == '_') { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if (begin == end) break; + } + } else { + while (::islower(c = *begin) || c == '_') { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if (begin == end) break; + } + } + return PARSER_OK; +} + +CParser::STATUS_TYPE CParser::parse_couple(std::string& token) +{ + // Parse couple puts redox couples in standard form + // "+" is removed and couples are rewritten in sort + // order. + + if (Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0) { + Utilities::str_tolower(token); + return PARSER_OK; + } + + while ( Utilities::replace("+", "", token) ); + + std::string::iterator ptr = token.begin(); + std::string elt1; + get_elt(ptr, token.end(), elt1); + + if (*ptr != '(') { + std::ostringstream err_msg; + err_msg << "Element name must be followed by " << + "parentheses in redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + incr_input_error(); + return PARSER_ERROR; + } + + int paren_count = 1; + std::string paren1 = "("; + while ( ptr != token.end() ) { + ++ptr; + if (*ptr == '/' || ptr == token.end()) { + std::ostringstream err_msg; + err_msg << "End of line or ""/"" encountered before end of parentheses, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return PARSER_ERROR; + } + paren1.insert(paren1.end(), *ptr); // element.push_back(c); + if (*ptr == '(') ++paren_count; + if (*ptr == ')') --paren_count; + if (paren_count == 0) break; + } + + ++ptr; + if (ptr == token.end() || *ptr != '/') { + std::ostringstream err_msg; + err_msg << " ""/"" must follow parentheses " << + "ending first half of redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + return PARSER_ERROR; + } + ++ptr; + std::string elt2; + get_elt(ptr, token.end(), elt2); + if (elt1.compare(elt2) != 0) { + std::ostringstream err_msg; + err_msg << "Redox couple must be two redox states " << + "of the same element, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + return PARSER_ERROR; + } + if (*ptr != '(') { + std::ostringstream err_msg; + err_msg << "Element name must be followed by " + "parentheses in redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + incr_input_error(); + return PARSER_ERROR; + } + std::string paren2 = "("; + paren_count = 1; + + while ( ptr != token.end() ) { + ++ptr; + if (*ptr == '/' || ptr == token.end()) { + std::ostringstream err_msg; + err_msg << "End of line or ""/"" encountered before end of parentheses, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return PARSER_ERROR; + } + paren2.insert(paren2.end(), *ptr); // element.push_back(c); + if (*ptr == '(') ++paren_count; + if (*ptr == ')') --paren_count; + if (paren_count == 0) break; + } + if (paren1.compare(paren2) < 0) { + token = elt1 + paren1 + std::string("/") + elt2 + paren2; + } else if (paren1.compare(paren2) > 0) { + token = elt2 + paren2 + std::string("/") + elt1 + paren1; + } else { + std::ostringstream err_msg; + err_msg << "Both parts of redox couple are the same, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return PARSER_ERROR; + } + return PARSER_OK; +} + +CParser::STATUS_TYPE CParser::addPair(std::map &totals, std::istream::pos_type& pos) +{ + std::string token; + char * ctoken; + double d; + + CParser::TOKEN_TYPE j; + + m_line_iss.seekg(pos); + + j = copy_token(token, pos); + + if (j == TT_EMPTY) return PARSER_OK; + + if( !(m_line_iss >> d)) { + return PARSER_ERROR; + } + ctoken = string_hsave(token.c_str()); + totals[ctoken] = d; + return PARSER_OK; +} + +CParser::STATUS_TYPE CParser::addPair(std::map &totals, std::istream::pos_type& pos) +{ + std::string token; + char * ctoken; + double d; + CParser::TOKEN_TYPE j; + + m_line_iss.seekg(pos); + + j = copy_token(token, pos); + + if (j == TT_EMPTY) return PARSER_OK; + + if( !(m_line_iss >> d)) { + return PARSER_ERROR; + } + ctoken = string_hsave(token.c_str()); + totals[ctoken] = d; + return PARSER_OK; +} +int CParser::getOptionFromLastLine(const std::vector& opt_list, std::string::iterator& next_char) +{ + // + // Read a line and check for options + // + int j; + int /* opt_l, */ opt; + //char *opt_ptr; + std::string::iterator opt_ptr; + + // char option[MAX_LENGTH]; + std::string option; + + // + // Read line + // + LINE_TYPE lt = m_line_type; + if (lt == LT_EOF) + { + j = OPT_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPT_KEYWORD; + } + else if (lt == LT_OPTION) + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, false) == CParser::FT_OK) + { + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + next_char = opt_ptr; + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + //////std::istringstream err_msg; + //////err_msg << "Unknown option."; + //////err_msg << line_save; + //////error_msg(const std::string& msg, ONERROR_TYPE); + + // error_msg("Unknown option.", CONTINUE); + // error_msg(line_save, CONTINUE); + // input_error++; + std::cerr << "Unknown option." << "\n"; + std::cerr << m_line_save << "\n"; + + j = OPT_ERROR; + next_char = m_line.begin(); + } + } + else + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_char = opt_ptr; + } + else + { + j = OPT_DEFAULT; + next_char = m_line.begin(); + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + std::cout << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} +int CParser::getOptionFromLastLine(const std::vector& opt_list, std::istream::pos_type& next_pos) +{ + // + // Read a line and check for options + // + int j; + int opt; + std::istream::pos_type pos_ptr; + std::string option; + + // + // Read line + // + //LINE_TYPE lt = check_line("get_option", false, true, true, false); + LINE_TYPE lt = m_line_type; + if (lt == LT_EOF) + { + j = OPT_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPT_KEYWORD; + } + else if (lt == LT_OPTION) + { + std::string::iterator opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option.substr(1), &opt, opt_list, false) == FT_OK) + { + // replace -option with option + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + + // reset iss + m_line_iss.str(m_line); + m_line_iss.seekg(0, std::ios_base::beg); + m_line_iss.clear(); + + pos_ptr = 0; + copy_token(option, pos_ptr); + next_pos = pos_ptr; + //{{ + //// m_line_iss.clear(); + //}} + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + error_msg("Unknown option.", OT_CONTINUE); + error_msg(m_line_save.c_str(), OT_CONTINUE); + incr_input_error(); + j = OPT_ERROR; + next_pos = pos_ptr; + } + } + else + { + pos_ptr = 0; + copy_token(option, pos_ptr); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_pos = pos_ptr; + } + else + { + j = OPT_DEFAULT; + next_pos = 0; + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} diff --git a/Parser.h b/Parser.h new file mode 100644 index 00000000..2ed217a5 --- /dev/null +++ b/Parser.h @@ -0,0 +1,205 @@ +#if !defined(PARSER_H_INCLUDED) +#define PARSER_H_INCLUDED + +#include // std::string +#include // std::map +#include // std::vector +#include // std::istringstream std::ostringstream +#include // std::ostream +#include // std::istream +#include "char_star.h" + +class CParser +{ +public: + CParser(std::istream& input); + CParser(std::istream& input, std::ostream& output); + CParser(std::istream& input, std::ostream& output, std::ostream& error); + + virtual ~CParser(); + + enum LINE_TYPE { + LT_EOF = -1, + LT_OK = 1, + LT_EMPTY = 2, + LT_KEYWORD = 3, + LT_OPTION = 8 + }; + + enum TOKEN_TYPE { + TT_EMPTY = 2, + TT_UPPER = 4, + TT_LOWER = 5, + TT_DIGIT = 6, + TT_UNKNOWN = 7 + }; + + enum FIND_TYPE { + FT_OK = 0, + FT_ERROR = 1 + }; + + enum KEY_TYPE { + KT_NONE = -1, + KT_END = 0, + KT_EOF = 1, + KT_SOLUTION = 4, + KT_SOLUTION_RAW = 5 + }; + + enum OPT_TYPE { + OPT_DEFAULT = -4, + OPT_ERROR = -3, + OPT_KEYWORD = -2, + OPT_EOF = -1 + }; + + enum ONERROR_TYPE { + OT_CONTINUE = 0, + OT_STOP = 1, + }; + + enum STATUS_TYPE { + PARSER_ERROR = 0, + PARSER_OK = 1 + }; + + /** + Function gets a new line and checks for empty, eof, and keywords. + + Arguments: + string Input, character string used in printing error message + allow_empty Input, True or false, if a blank line is accepable + if false, another line is read + allow_eof Input, True or false, if EOF is acceptable + allow_keyword Input, True or false, if a keyword is acceptable + + Returns: + LT_EMPTY if empty line read and allow_empty == true + LT_KEYWORD if line begins with keyword + LT_EOF if eof and allow_eof == true + LT_OK otherwise + LT_OPTION if line begins with -[alpha] + + Terminates if EOF and allow_eof == false. + */ + LINE_TYPE check_line(const std::string& str, bool allow_empty, bool allow_eof, bool allow_keyword, bool print); + + /** + Read a line from input file put in "line". + Copy of input line is stored in "line_save". + Characters after # are discarded in line but retained in "line_save" + + Arguments: + None + Returns: + LT_EMPTY, + LT_EOF, + LT_KEYWORD, + LT_OK, + LT_OPTION + */ + LINE_TYPE get_line(); + + // bool check_key(const std::string::iterator ptr); + bool check_key(std::string::iterator begin, std::string::iterator end); + + STATUS_TYPE check_units(std::string& tot_units, bool alkalinity, bool check_compatibility, + const std::string& default_units, bool print); + + + KEY_TYPE next_keyword()const { return m_next_keyword; } + int get_option(const std::vector& opt_list, std::string::iterator& next_char); + int get_option(const std::vector& opt_list, std::istream::pos_type& next_pos); + int getOptionFromLastLine(const std::vector& opt_list, std::string::iterator& next_char); + int getOptionFromLastLine(const std::vector& opt_list, std::istream::pos_type& next_pos); + + + std::string& line() {return m_line;} + std::istringstream& get_iss() {return m_line_iss;} + int incr_input_error() {return ++m_input_error;} + std::ostream& get_output() {return m_output_stream;} + int get_input_error() {return m_input_error;} + + + /** + Copies from begin to token until first space is encountered. + + Arguments: + token output, the token + begin input, begin iterator + end input, end iterator + + Returns: + TT_EMPTY + TT_UPPER + TT_LOWER + TT_DIGIT + TT_UNKNOWN + */ + static TOKEN_TYPE copy_token(std::string& token, std::string::iterator& begin, std::string::iterator& end); + static TOKEN_TYPE token_type(const std::string& token); + static TOKEN_TYPE copy_token(std::string& token, std::istream& is); + TOKEN_TYPE copy_token(std::string& token, std::istream::pos_type& pos); + CParser::TOKEN_TYPE peek_token(); + + /** + Function reads an element name out of the equation string. + An element name is composed of a capital letter followed by any number + of lower case characters. + + Arguments: + begin input, points to position in the equation to begin + output, points to next character of equation after + element name. + end input, points to last position in the equation + element input pointer to place to return element character string + */ + STATUS_TYPE get_elt(std::string::iterator& begin, const std::string::iterator end, std::string& element); + + + /** + Compares a string value to match beginning letters of a list of options + + Arguments: + item entry: pointer to string to compare + n exit: item in list that was matched + list entry: pointer to list of character values, assumed to + be lower case + count_list entry: number of character values in list + + Returns: + OK item matched + ERROR item not matched + n -1 item not matched + i position of match in list + */ + static FIND_TYPE find_option(const std::string& item, int *n, const std::vector& list, bool exact); + + + int error_msg(const std::ostringstream& err_str, ONERROR_TYPE stop) {return error_msg(err_str.str().c_str(), stop);} + int error_msg(const char *err_str, ONERROR_TYPE stop); + int warning_msg(const char *err_str); + + + STATUS_TYPE parse_couple(std::string& token); + + STATUS_TYPE addPair(std::map &totals, std::istream::pos_type& pos); + STATUS_TYPE addPair(std::map &totals, std::istream::pos_type& pos); + +protected: + LINE_TYPE get_logical_line(); + +private: + std::istream& m_input_stream; + std::ostream& m_output_stream; + std::ostream& m_error_stream; + int m_input_error; + KEY_TYPE m_next_keyword; + std::string m_line; + std::string m_line_save; + std::istringstream m_line_iss; + LINE_TYPE m_line_type; +}; + +#endif // PARSER_H_INCLUDED diff --git a/Pe_Data.cxx b/Pe_Data.cxx new file mode 100644 index 00000000..19070934 --- /dev/null +++ b/Pe_Data.cxx @@ -0,0 +1,45 @@ +#include "Pe_Data.h" +#include "Utilities.h" +#include // std::ostream + +cxxPe_Data::cxxPe_Data() +: name("") +{ +} + +cxxPe_Data::cxxPe_Data(const std::string& name) +: name(name) +{ +} + +cxxPe_Data::~cxxPe_Data() +{ +} + +int cxxPe_Data::store(std::vector& vec_pe_data, const std::string& token) +{ + unsigned int i = 0; + unsigned int size = vec_pe_data.size(); + for (; i < size; ++i) { + if (vec_pe_data[i].name.compare(token) == 0) + return i; + } + vec_pe_data.push_back(token); + return i; +} + +std::vector cxxPe_Data::alloc() +{ + std::vector vec; + vec.push_back(cxxPe_Data("pe")); + // TODO: see pe_data_alloc + return vec; +} + +void cxxPe_Data::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "" << this->name << "\n"; +} + diff --git a/Pe_Data.h b/Pe_Data.h new file mode 100644 index 00000000..b26ff260 --- /dev/null +++ b/Pe_Data.h @@ -0,0 +1,28 @@ +#if !defined(PE_DATA_H_INCLUDED) +#define PE_DATA_H_INCLUDED + +#include +#include + +class cxxPe_Data +{ +public: + cxxPe_Data(); + cxxPe_Data(struct pe *pe_ptr); + cxxPe_Data(const std::string& name); + + ~cxxPe_Data(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + std::string get_name()const {return this->name;}; + void set_name(std::string name) {this->name = name;}; + + static int store(std::vector& vec, const std::string& token); + static std::vector cxxPe_Data::alloc(); + +private: + std::string name; +}; + +#endif // PE_DATA_H_INCLUDED diff --git a/Reaction.cxx b/Reaction.cxx new file mode 100644 index 00000000..6a0af474 --- /dev/null +++ b/Reaction.cxx @@ -0,0 +1,323 @@ +// Reaction.cxx: implementation of the cxxReaction class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Reaction.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxReaction::cxxReaction() + // + // default constructor for cxxReaction + // +: cxxNumKeyword() +{ + units = string_hsave("Mol"); + countSteps = 0; + equalIncrements = false; + reactantList.type = cxxNameDouble::ND_NAME_COEF; + elementList.type = cxxNameDouble::ND_ELT_MOLES; +} + +cxxReaction::cxxReaction(struct irrev *irrev_ptr) + // + // constructor for cxxReaction from struct irrev + // +: +cxxNumKeyword(), +reactantList(irrev_ptr->list, irrev_ptr->count_list, cxxNameDouble::ND_NAME_COEF), +elementList(irrev_ptr->elts) +{ + int i; + + this->set_description(irrev_ptr->description); + this->n_user = irrev_ptr->n_user; + this->n_user_end = irrev_ptr->n_user_end; + this->units = irrev_ptr->units; + // steps + if (irrev_ptr->count_steps < 0) { + for (i = 0; i < 1; i++) { + this->steps.push_back(irrev_ptr->steps[i]); + } + this->countSteps = -irrev_ptr->count_steps; + this->equalIncrements = true; + } else { + for (i = 0; i < irrev_ptr->count_steps; i++) { + this->steps.push_back(irrev_ptr->steps[i]); + } + this->countSteps = irrev_ptr->count_steps; + this->equalIncrements = false; + } +} + +cxxReaction::~cxxReaction() +{ +} + + +struct irrev *cxxReaction::cxxReaction2irrev() + // + // Builds a irrev structure from instance of cxxReaction + // +{ + struct irrev *irrev_ptr; + irrev_ptr = (struct irrev *) PHRQ_malloc(sizeof (struct irrev)); + if (irrev_ptr == NULL) malloc_error(); + + irrev_ptr->description = this->get_description(); + irrev_ptr->n_user = this->n_user; + irrev_ptr->n_user_end = this->n_user_end; + + irrev_ptr->list = this->reactantList.name_coef(); + irrev_ptr->count_list = this->reactantList.size(); + if (this->elementList.size() > 0) { + irrev_ptr->elts = this->elementList.elt_list(); + } else { + // NULL value causes reaction stoichiometry to be calculated + irrev_ptr->elts = NULL; + } + // steps + irrev_ptr->steps = NULL; + if (this->steps.size() > 0) { + irrev_ptr->steps = (double *) PHRQ_malloc((size_t) (this->steps.size() * sizeof(double))); + if (irrev_ptr->steps == NULL) malloc_error(); + std::copy(this->steps.begin(), this->steps.end(), irrev_ptr->steps); + } + if (this->equalIncrements) { + irrev_ptr->count_steps = -this->countSteps; + } else { + irrev_ptr->count_steps = this->steps.size(); + } + irrev_ptr->units = this->units; + return(irrev_ptr); +} + +#ifdef SKIP +void cxxReaction::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing irrev message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Reaction element and attributes + s_oss << indent0; + s_oss << "pitzer_irrev_gammas << "\"" << std::endl; + + // components + s_oss << indent1; + s_oss << "::const_iterator it = irrevComps.begin(); it != irrevComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} +#endif + +void cxxReaction::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing irrev message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Reaction element and attributes + s_oss << indent0; + s_oss << "REACTION_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-units " << this->units << std::endl; + + s_oss << indent1; + s_oss << "-reactant_list " << std::endl; + this->reactantList.dump_raw(s_oss, indent + 2); + + s_oss << indent1; + s_oss << "-element_list " << std::endl; + this->elementList.dump_raw(s_oss, indent + 2); + + s_oss << indent1; + s_oss << "-steps " << std::endl; + { + int i = 0; + s_oss << indent2; + for (std::vector::const_iterator it = this->steps.begin(); it != this->steps.end(); it++) { + if (i++ == 5) { + s_oss << std::endl; + s_oss << indent2; + i = 0; + } + s_oss << *it << " "; + } + s_oss << std::endl; + } + + s_oss << indent1; + s_oss << "-equal_increments " << this->equalIncrements << std::endl; + + s_oss << indent1; + s_oss << "-count_steps " << this->countSteps << std::endl; + + +} + +void cxxReaction::read_raw(CParser& parser) +{ + + int j; + double d; + CParser::TOKEN_TYPE k; + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("units"); //0 + vopts.push_back("reactant_list"); //1 + vopts.push_back("element_list"); //2 + vopts.push_back("steps"); //3 + vopts.push_back("equal_increments"); //4 + vopts.push_back("count_steps"); //5 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read irrev number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool units_defined(false); + bool equalIncrements_defined(false); + bool countSteps_defined(false); + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in IRREV_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // units + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) break; + this->units = string_hsave(token.c_str()); + opt_save = CParser::OPT_DEFAULT; + useLastLine = false; + units_defined = true; + break; + + case 1: // reactant_list + if ( this->reactantList.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected reactant formula and coefficient.", CParser::OT_CONTINUE); + } + opt_save = 1; + useLastLine = false; + break; + + case 2: // element_list + if ( this->elementList.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element formula and coefficient.", CParser::OT_CONTINUE); + } + opt_save = 2; + useLastLine = false; + break; + + case 3: // steps + while ((k = parser.copy_token(token, next_char)) == CParser::TT_DIGIT) { + std::istringstream iss(token); + if (!(iss >> d)) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for steps.", CParser::OT_CONTINUE); + } else { + this->steps.push_back(d); + } + } + opt_save = 3; + useLastLine = false; + break; + + case 4: // equal_increments + if (!(parser.get_iss() >> this->equalIncrements)) + { + this->equalIncrements = 0; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for equalIncrements.", CParser::OT_CONTINUE); + } + opt_save = CParser::OPT_DEFAULT; + useLastLine = false; + equalIncrements_defined = true; + break; + + case 5: // countSteps + if (!(parser.get_iss() >> this->countSteps)) + { + this->countSteps = 0; + parser.incr_input_error(); + parser.error_msg("Expected integer value for countSteps.", CParser::OT_CONTINUE); + } + opt_save = CParser::OPT_DEFAULT; + useLastLine = false; + countSteps_defined = true; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (units_defined == false) { + parser.incr_input_error(); + parser.error_msg("Units not defined for REACTION_RAW input.", CParser::OT_CONTINUE); + } + if (equalIncrements_defined == false) { + parser.incr_input_error(); + parser.error_msg("Equal_increments not defined for REACTION_RAW input.", CParser::OT_CONTINUE); + } + if (countSteps_defined == false) { + parser.incr_input_error(); + parser.error_msg("Count_steps not defined for REACTION_RAW input.", CParser::OT_CONTINUE); + } +} diff --git a/Reaction.h b/Reaction.h new file mode 100644 index 00000000..8c5e6dd0 --- /dev/null +++ b/Reaction.h @@ -0,0 +1,45 @@ +#if !defined(REACTION_H_INCLUDED) +#define REACTION_H_INCLUDED + +#include "NumKeyword.h" +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxReaction : public cxxNumKeyword +{ + +public: + cxxReaction(); + cxxReaction(struct irrev *); + ~cxxReaction(); + + struct irrev *cxxReaction2irrev(); + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + cxxNameDouble reactantList; + cxxNameDouble elementList; + std::vector steps; + int countSteps; + bool equalIncrements; + char *units; + +public: + //static std::map& map; + +}; + +#endif // !defined(REACTION_H_INCLUDED) diff --git a/ReadClass.cpp b/ReadClass.cpp new file mode 100644 index 00000000..188f9881 --- /dev/null +++ b/ReadClass.cpp @@ -0,0 +1,701 @@ +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif +#include "Parser.h" +#include "Solution.h" +#include "Exchange.h" +#include "Surface.h" +#include "PPassemblage.h" +#include "KineticsCxx.h" +#include "SSassemblage.h" +#include "GasPhase.h" +#include "Reaction.h" +#include "Mix.h" +#include "Temperature.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +extern int check_line(const char *string, int allow_empty, int allow_eof, int allow_keyword, + int print); + +/* ---------------------------------------------------------------------- */ +int read_solution_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads SOLUTION_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + + cxxSolution sol; + sol.read_raw(parser); + struct solution *soln_ptr = sol.cxxSolution2solution(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (solution_bsearch(soln_ptr->n_user, &n, FALSE) != NULL) { + solution_free(solution[n]); + } else { + n=count_solution++; + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, sizeof (struct solution *) ); + } + } + solution[n] = soln_ptr; + + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_exchange_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads EXCHANGE_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("exchange_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxExchange ex; + ex.read_raw(parser); + struct exchange *exchange_ptr = ex.cxxExchange2exchange(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (exchange_bsearch(exchange_ptr->n_user, &n) != NULL) { + exchange_free(&exchange[n]); + } else { + n=count_exchange++; + if (count_exchange >= max_exchange) { + space ((void **) ((void *) &(exchange)), count_exchange, &max_exchange, sizeof (struct exchange *) ); + } + } + exchange_copy(exchange_ptr, &exchange[n], exchange_ptr->n_user); + exchange_free(exchange_ptr); + free_check_null(exchange_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_surface_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads SURFACE_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("surface_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxSurface ex; + ex.read_raw(parser); + struct surface *surface_ptr = ex.cxxSurface2surface(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (surface_bsearch(surface_ptr->n_user, &n) != NULL) { + surface_free(&surface[n]); + } else { + n=count_surface++; + if (count_surface >= max_surface) { + space ((void **) ((void *) &(surface)), count_surface, &max_surface, sizeof (struct surface *) ); + } + } + surface_copy(surface_ptr, &surface[n], surface_ptr->n_user); + surface_free(surface_ptr); + free_check_null(surface_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_equilibrium_phases_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads EQUILIBRIUM_PHASES_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("equilibrium_phases_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxPPassemblage ex; + ex.read_raw(parser); + struct pp_assemblage *pp_assemblage_ptr = ex.cxxPPassemblage2pp_assemblage(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (pp_assemblage_bsearch(pp_assemblage_ptr->n_user, &n) != NULL) { + pp_assemblage_free(&pp_assemblage[n]); + } else { + n=count_pp_assemblage++; + if (count_pp_assemblage >= max_pp_assemblage) { + space ((void **) ((void *) &(pp_assemblage)), count_pp_assemblage, &max_pp_assemblage, sizeof (struct pp_assemblage *) ); + } + } + pp_assemblage_copy(pp_assemblage_ptr, &pp_assemblage[n], pp_assemblage_ptr->n_user); + pp_assemblage_free(pp_assemblage_ptr); + free_check_null(pp_assemblage_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_kinetics_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads KINETICS_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("kinetics_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxKinetics ex; + ex.read_raw(parser); + struct kinetics *kinetics_ptr = ex.cxxKinetics2kinetics(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (kinetics_bsearch(kinetics_ptr->n_user, &n) != NULL) { + kinetics_free(&kinetics[n]); + } else { + n=count_kinetics++; + if (count_kinetics >= max_kinetics) { + space ((void **) ((void *) &(kinetics)), count_kinetics, &max_kinetics, sizeof (struct kinetics *) ); + } + } + kinetics_copy(kinetics_ptr, &kinetics[n], kinetics_ptr->n_user); + kinetics_free(kinetics_ptr); + free_check_null(kinetics_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_solid_solutions_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads SOLID_SOLUTION_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solid_solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxSSassemblage ex; + ex.read_raw(parser); + struct s_s_assemblage *s_s_assemblage_ptr = ex.cxxSSassemblage2s_s_assemblage(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (s_s_assemblage_bsearch(s_s_assemblage_ptr->n_user, &n) != NULL) { + s_s_assemblage_free(&s_s_assemblage[n]); + } else { + n=count_s_s_assemblage++; + if (count_s_s_assemblage >= max_s_s_assemblage) { + space ((void **) ((void *) &(s_s_assemblage)), count_s_s_assemblage, &max_s_s_assemblage, sizeof (struct s_s_assemblage *) ); + } + } + s_s_assemblage_copy(s_s_assemblage_ptr, &s_s_assemblage[n], s_s_assemblage_ptr->n_user); + s_s_assemblage_free(s_s_assemblage_ptr); + free_check_null(s_s_assemblage_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_gas_phase_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads GAS_PHASE_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solid_solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxGasPhase ex; + ex.read_raw(parser); + struct gas_phase *gas_phase_ptr = ex.cxxGasPhase2gas_phase(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (gas_phase_bsearch(gas_phase_ptr->n_user, &n) != NULL) { + gas_phase_free(&gas_phase[n]); + } else { + n=count_gas_phase++; + if (count_gas_phase >= max_gas_phase) { + space ((void **) ((void *) &(gas_phase)), count_gas_phase, &max_gas_phase, sizeof (struct gas_phase *) ); + } + } + gas_phase_copy(gas_phase_ptr, &gas_phase[n], gas_phase_ptr->n_user); + gas_phase_free(gas_phase_ptr); + free_check_null(gas_phase_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_reaction_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads REACTION_RAW 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solid_solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxReaction ex; + ex.read_raw(parser); + struct irrev *irrev_ptr = ex.cxxReaction2irrev(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (irrev_bsearch(irrev_ptr->n_user, &n) != NULL) { + irrev_free(&irrev[n]); + } else { + n=count_irrev++; + irrev = (struct irrev *) PHRQ_realloc(irrev, (size_t) count_irrev * sizeof (struct irrev)); + if (irrev == NULL) malloc_error(); + } + irrev_copy(irrev_ptr, &irrev[n], irrev_ptr->n_user); + irrev_free(irrev_ptr); + free_check_null(irrev_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_mix_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads MIX (_RAW) 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solid_solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxMix ex; + ex.read_raw(parser); + struct mix *mix_ptr = ex.cxxMix2mix(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (mix_bsearch(mix_ptr->n_user, &n) != NULL) { + mix_free(&mix[n]); + } else { + n=count_mix++; + mix = (struct mix *) PHRQ_realloc(mix, (size_t) count_mix * sizeof (struct mix)); + if (mix == NULL) malloc_error(); + } + mix_copy(mix_ptr, &mix[n], mix_ptr->n_user); + mix_free(mix_ptr); + free_check_null(mix_ptr); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_temperature_raw (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads TEMPERATURE (_RAW) 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 return_value; + /* + * Accumulate lines in std string + */ + std::string keywordLines(""); + + keywordLines.append(line); + keywordLines.append("\n"); +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("solid_solution_raw",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; + keywordLines.append(line); + keywordLines.append("\n"); + } + + std::istringstream iss_in(keywordLines); + std::ostringstream oss_out; + std::ostringstream oss_err; + + CParser parser(iss_in, oss_out, oss_err); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + parser.get_option(vopts, next_char); + + cxxTemperature ex; + ex.read_raw(parser); + struct temperature *temperature_ptr = ex.cxxTemperature2temperature(); + int n; + + /* + * This is not quite right, may not produce sort order + */ + + if (temperature_bsearch(temperature_ptr->n_user, &n) != NULL) { + temperature_free(&temperature[n]); + } else { + n=count_temperature++; + temperature = (struct temperature *) PHRQ_realloc(temperature, (size_t) count_temperature * sizeof (struct temperature)); + if (temperature == NULL) malloc_error(); + } + temperature_copy(temperature_ptr, &temperature[n], temperature_ptr->n_user); + temperature_free(temperature_ptr); + free_check_null(temperature_ptr); + return(return_value); +} diff --git a/SAXPhreeqc.cpp b/SAXPhreeqc.cpp new file mode 100644 index 00000000..d3010c9d --- /dev/null +++ b/SAXPhreeqc.cpp @@ -0,0 +1,888 @@ +// SAXPhreeqc.cpp +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include // DBL_DIG +#include // sprintf +#include // iswspace + +#include // assert +//#include // std::ostrstream +#include +#include // std::cerr +#ifdef SKIP +#endif +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#endif + + +#include +#include +#include +#include +#include +#include + +//#include // SAXParser +#include // AttributeList +#include // Unicode definitions +#include // MemBufInputSource +#include +#include +#include // XMLPlatformUtils::getCurrentMillis +#include + +#include +#include + +#include "SAXPhreeqc.h" // SAX_ functions +#include "SaxPhreeqcHandlers.h" // SaxPhreeqcHandlers + +//XERCES_CPP_NAMESPACE_USE +#define xns XERCES_CPP_NAMESPACE + +///static char buffer[300000]; +///static std::ostrstream s_oss(buffer, 300000); // must never go out of scope +static std::ostringstream s_oss; // must never go out of scope +static bool s_bSysIsOpen = false; // must never go out of scope + +#include +// extern routines + #include "phqalloc.h" + #include "global.h" +#include "phrqproto.h" +#include "output.h" +#ifdef SKIP + int conc_init(struct conc *conc_ptr); + void *free_check_null(void *ptr); + int pe_data_store (struct pe_data **pe, const char *token); + struct phase *phase_bsearch (char *ptr, int *j, int print); + struct solution *solution_alloc(void); + struct solution *solution_bsearch(int k, int *n, int print); + int solution_free (struct solution *solution_ptr); + void space (void **ptr, int i, int *max, int struct_size); + char * string_duplicate (const char *token); + char *string_hsave (const char *str); + int error_msg (const char *err_str, const int stop); + struct master *master_bsearch (const char *ptr); + void malloc_error(void); +#endif +//} + + +class Initializer +{ +public: + Initializer(){ +#if defined(_DEBUG) + int tmpDbgFlag; + + /* + * Set the debug-heap flag to keep freed blocks in the + * heap's linked list - This will allow us to catch any + * inadvertent use of freed memory + */ + tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + //tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; + tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF; + //tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF; + _CrtSetDbgFlag(tmpDbgFlag); +#endif + + xns::XMLPlatformUtils::Initialize(); + } +}; + +static Initializer sInit; // initialize xerces once +static SaxPhreeqcHandlers s_handler; // one and only instance + +void SAX_StartSystem() +{ + + assert(!s_bSysIsOpen); // system already open and has not been closed + + // init stream + //s_oss.freeze(false); + s_oss.seekp(0); + + // write stream + // s_oss << ""; + s_oss << ""; + s_oss << ""; + s_oss << " "; + s_bSysIsOpen = true; + +} + +char * stringify_null(char * string) { + if (string == NULL) return(string_hsave("")); + return(string); +} +int SAX_AddSolution(struct solution* solution_ptr) +{ + //const char ERR_MESSAGE[] = "Packing solution message: %s, element not found\n"; + int i, newd; + assert(s_bSysIsOpen); // must call SAX_StartSystem first + s_oss.precision(DBL_DIG - 1); + // Solution element and attributes + newd = solution_ptr->new_def; + s_oss << " new_def << "\"" << std::endl; + s_oss << " soln_n_user=\"" << solution_ptr->n_user << "\" " << std::endl; + s_oss << " soln_n_user_end=\"" << solution_ptr->n_user_end << "\"" << std::endl; + s_oss << " soln_description=\"" << solution_ptr->description << "\"" << std::endl; + s_oss << " soln_tc=\"" << solution_ptr->tc << "\"" << std::endl; + s_oss << " soln_ph=\"" << solution_ptr->ph << "\"" << std::endl; + s_oss << " soln_solution_pe=\"" << solution_ptr->solution_pe << "\"" << std::endl; + s_oss << " soln_mu=\"" << solution_ptr->mu << "\"" << std::endl; + s_oss << " soln_ah2o=\"" << solution_ptr->ah2o << "\"" << std::endl; + s_oss << " soln_density=\"" << solution_ptr->density << "\"" << std::endl; + s_oss << " soln_total_h=\"" << solution_ptr->total_h << "\"" << std::endl; + s_oss << " soln_total_o=\"" << solution_ptr->total_o << "\"" << std::endl; + s_oss << " soln_cb=\"" << solution_ptr->cb << "\"" << std::endl; + s_oss << " soln_mass_water=\"" << solution_ptr->mass_water << "\"" << std::endl; + s_oss << " soln_total_alkalinity=\"" << solution_ptr->total_alkalinity << "\"" << std::endl; + //s_oss << " soln_total_co2=\"" << solution_ptr->total_co2 << "\"" << std::endl; + s_oss << " soln_units=\"" << solution_ptr->units << "\"" << std::endl; + s_oss << " soln_default_pe=\"" << solution_ptr->default_pe << "\"" << std::endl; + s_oss << " soln_count_master_activity=\"" << solution_ptr->count_master_activity << "\"" << std::endl; + s_oss << " soln_count_isotopes=\"" << solution_ptr->count_isotopes << "\"" << std::endl; + s_oss << " soln_count_species_gamma=\"" << solution_ptr->count_species_gamma << "\">" << std::endl; + // end of solution attributes + // pe structures + for (i=0; solution_ptr->pe[i].name != NULL; i++) { + s_oss << " pe[i].name << "\"/>"<< std::endl; + } + // soln_total conc structures + for (i=0; solution_ptr->totals[i].description != NULL; i++) { + struct conc *c = &(solution_ptr->totals[i]); + s_oss << " description << "\"" << std::endl; + s_oss << " conc_moles=\"" << c->moles << "\"" << std::endl; + if (newd == TRUE) { + s_oss << " conc_input_conc=\"" << c->input_conc << "\"" << std::endl; + if (c->units != NULL) s_oss << " conc_units=\"" << c->units << "\"" << std::endl; + if (c->equation_name != NULL) { + s_oss << " conc_equation_name=\"" << stringify_null(c->equation_name) << "\"" << std::endl; + s_oss << " conc_phase_si=\"" << c->phase_si << "\"" << std::endl; + } + if (c->as != NULL) s_oss << " conc_as=\"" << stringify_null(c->as) << "\"" << std::endl; + s_oss << " conc_gfw=\"" << c->gfw << "\"" << std::endl; + } + s_oss << " conc_n_pe=\"" << c->n_pe << "\"" << std::endl; + s_oss << " />" << std::endl; + } + // master_activity, master_activity structure + + for (i=0; i < solution_ptr->count_master_activity; i++) { + s_oss << " master_activity[i].description) << "\" m_a_la=\"" << solution_ptr->master_activity[i].la << "\"/>" << std::endl; + } + /* + if (solution_ptr->count_master_activity > 0) { + s_oss << " count_master_activity; i++) { + if (solution_ptr->master_activity[i].description != NULL) { + s_oss << stringify_null(solution_ptr->master_activity[i].description) << " "; + s_oss << solution_ptr->master_activity[i].la << std::endl; + } else { + s_oss << "null 0.0" << std::endl; + } + } + s_oss << "\"/>" << std::endl; + } + */ + // species_gamma, mater_activity structure + for (i=0; i < solution_ptr->count_species_gamma; i++) { + s_oss << " species_gamma[i].description) << "\" m_a_la=\"" << solution_ptr->species_gamma[i].la << "\"/>" << std::endl; + } + // isotopes, isotope structure + for (i=0; solution_ptr->count_isotopes; i++) { + s_oss << " isotopes[i].isotope_number << "\"" << std::endl; + s_oss << " iso_elt_name=\"" << solution_ptr->isotopes[i].elt_name << "\"" << std::endl; + s_oss << " iso_isotope_name=\"" << solution_ptr->isotopes[i].isotope_name << "\"" << std::endl; + s_oss << " iso_total=\"" << solution_ptr->isotopes[i].total << "\"" << std::endl; + s_oss << " iso_ratio=\"" << solution_ptr->isotopes[i].ratio << "\"" << std::endl; + s_oss << " iso_ratio_uncertainty=\"" << solution_ptr->isotopes[i].ratio_uncertainty << "\"" << std::endl; + s_oss << " iso_coef=\"" << solution_ptr->isotopes[i].coef << "\"" << std::endl; + } + // End of solution + s_oss << " " << std::endl; + + return(OK); +} + +void SAX_EndSystem() +{ + assert(s_bSysIsOpen); // must call SAX_StartSystem first + + s_oss << " " << std::endl; + s_oss << "" << std::endl; + s_oss << '\0'; + + s_bSysIsOpen = false; + //delete[] s_handler; + return; +} + +int SAX_GetXMLLength() +{ + assert(!s_bSysIsOpen); // must call SAX_EndSystem first + //return s_oss.pcount(); + return s_oss.str().size(); +} + +const char* SAX_GetXMLStr() +{ + assert(!s_bSysIsOpen); // must call SAX_EndSystem first + return s_oss.str().c_str(); +} + +void SAX_cleanup() +{ + //delete s_handler; + //s_oss.freeze(false); +} + +// utility routines + +int XMLCh2Int(const XMLCh* const attValue) { + char *string = xns::XMLString::transcode(attValue); + int i = strtol(string, NULL, 10); + xns::XMLString::release(&string); + return i; + //return (xns::XMLString::parseInt(attValue)); +} +double XMLCh2Double(const XMLCh* const attValue) { + char *string = xns::XMLString::transcode(attValue); + double d = strtod(string, NULL); + xns::XMLString::release(&string); + return d; +} +char * XMLCh2String(const XMLCh* const attValue) { + char *string = xns::XMLString::transcode(attValue); + char *s = string_duplicate(string); + xns::XMLString::release(&string); + return s; +} +char * XMLCh_hsave(const XMLCh* const attValue, bool allow_null) { + char *string = xns::XMLString::transcode(attValue); + char *s = string_hsave(string); + if (allow_null && strlen(s) == 0) s = NULL; + xns::XMLString::release(&string); + return s; +} + + +int SAX_UnpackSolutions(void* pvBuffer, int buf_size) +{ + // Create MemBufferInputSource from the buffer containing the XML + // statements. + xns::MemBufInputSource memBufIS((const XMLByte*)pvBuffer, buf_size, "solution_id", false); + fprintf(stderr,"%s", (char *) pvBuffer); + return 0; + // + // Create a SAX2 parser object. + // + xns::SAX2XMLReader * parser = xns::XMLReaderFactory::createXMLReader(); + parser->setFeature(xns::XMLUni::fgXercesSchemaFullChecking, false); + parser->setFeature(xns::XMLUni::fgSAX2CoreNameSpaces, false); + parser->setFeature(xns::XMLUni::fgXercesSchema, false); + parser->setFeature(xns::XMLUni::fgXercesIdentityConstraintChecking, false); + // + // Create the handler object and install it as the document and error + // handler for the parser. Then parse the MemBufferInputSource and + // catch any exceptions that propogate out + // + try + { + unsigned long duration = 0; + parser->setContentHandler(&s_handler); + parser->setErrorHandler(&s_handler); + int t = 0; + for (; t < 1000; ++t) + { + const unsigned long startMillis = xns::XMLPlatformUtils::getCurrentMillis(); + parser->parse(memBufIS); + const unsigned long endMillis = xns::XMLPlatformUtils::getCurrentMillis(); + duration += endMillis - startMillis; + } + std::cerr << "\nSaxParse time = " << duration << " millis\n"; + } + catch (const xns::SAXException& toCatch) + { + char* psz = xns::XMLString::transcode(toCatch.getMessage()); + input_error++; + sprintf(error_string, "SAX_UnpackSolutions: %s\n", psz); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&psz); + return ERROR; + } + catch (const xns::XMLException& toCatch) + { + char* psz = xns::XMLString::transcode(toCatch.getMessage()); + input_error++; + sprintf(error_string, "SAX_UnpackSolutions: %s\n", psz); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&psz); + return ERROR; + } + catch (...) + { + input_error++; + sprintf(error_string,"SAX_UnpackSolutions: %s\n", "Unknown error occured."); + error_msg(error_string, CONTINUE); + return ERROR; + } + + return(OK); +} + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +// element names + +SaxPhreeqcHandlers::SaxPhreeqcHandlers() + : eltType(typeNULL), attType(attNULL), totals(), acts(), solution_ptr(NULL) +{ + int i; + + int count_elementInfo, count_attributeInfo; + struct mapElementInfo {char *key; enum elementType type;}; + struct mapAttributeInfo {enum attributeType type; char *key;}; + struct mapElementInfo elementInfo[] = { + {"phast_state", typePHAST_STATE}, + {"system", typeSYSTEM}, + {"solution", typeSOLUTION}, + {"soln_pe", typeSOLN_PE}, + {"soln_total", typeSOLN_TOTAL}, + {"soln_m_a", typeSOLN_MASTER_ACTIVITY}, + {"soln_isotope", typeSOLN_ISOTOPE}, + {"soln_s_g", typeSOLN_SPECIES_GAMMA} + }; + count_elementInfo = sizeof(elementInfo)/sizeof(struct mapElementInfo); + struct mapAttributeInfo attributeInfo[] = { + // Solution structure + {attSOLN_new_def, "soln_new_def"}, + {attSOLN_n_user, "soln_n_user"}, + {attSOLN_n_user_end, "soln_n_user_end"}, + {attSOLN_description, "soln_description"}, + {attSOLN_tc, "soln_tc"}, + {attSOLN_ph, "soln_ph"}, + {attSOLN_solution_pe, "soln_solution_pe"}, + {attSOLN_mu, "soln_mu"}, + {attSOLN_ah2o, "soln_ah2o"}, + {attSOLN_density, "soln_density"}, + {attSOLN_total_h, "soln_total_h"}, + {attSOLN_total_o, "soln_total_o"}, + {attSOLN_cb, "soln_cb"}, + {attSOLN_mass_water, "soln_mass_water"}, + {attSOLN_total_alkalinity, "soln_total_alkalinity"}, + {attSOLN_total_co2, "soln_total_co2"}, + {attSOLN_units, "soln_units"}, + {attSOLN_default_pe, "soln_default_pe"}, + {attSOLN_count_master_activity, "soln_count_master_activity"}, + {attSOLN_count_isotopes, "soln_count_isotopes"}, + {attSOLN_count_species_gamma, "soln_count_species_gamma"}, + {attSOLN_PE_name, "soln_pe_name"}, + // master_activity structure + {attM_A_description, "m_a_desc"}, + {attM_A_la, "m_a_la"}, + {attM_A_list, "m_a_list"}, + // isotope structure + {attISO_isotope_number, "iso_isotope_number"}, + {attISO_elt_name, "iso_elt_name"}, + {attISO_isotope_name, "iso_isotope_name"}, + {attISO_total, "iso_total"}, + {attISO_ratio, "iso_ratio"}, + {attISO_ratio_uncertainty, "iso_ratio_uncertainty"}, + {attISO_x_ratio_uncertainty, "iso_x_ratio_uncertainty"}, + {attISO_coef, "iso_coef"}, + // conc structure + {attCONC_description, "conc_desc"}, + {attCONC_moles, "conc_moles"}, + {attCONC_input_conc, "conc_input_conc"}, + {attCONC_units, "conc_units"}, + {attCONC_equation_name, "conc_equation_name"}, + {attCONC_phase_si, "conc_phase_si"}, + {attCONC_n_pe, "conc_n_pe"}, + {attCONC_as, "conc_as"}, + {attCONC_gfw, "conc_gfw"}, + + }; + + count_attributeInfo = sizeof(attributeInfo)/sizeof(struct mapAttributeInfo); + for (i = 0; i < count_elementInfo; i++) { + // memory freed in destructor + this->mapXMLCh2Type[xns::XMLString::transcode(elementInfo[i].key)] = elementInfo[i].type; + } + for (i = 0; i < count_attributeInfo; i++) { + // memory freed in destructor + this->mapXMLCh2AttType[xns::XMLString::transcode(attributeInfo[i].key)] = attributeInfo[i].type; + } + + this->totals.reserve(50); + this->acts.reserve(50); +} + +SaxPhreeqcHandlers::~SaxPhreeqcHandlers() +{ + std::map::iterator it = this->mapXMLCh2Type.begin(); + for (; it != this->mapXMLCh2Type.end(); ++it) + { + XMLCh* p = (XMLCh*)it->first; + xns::XMLString::release(&p); + } + this->mapXMLCh2Type.clear(); + std::map::iterator ita = this->mapXMLCh2AttType.begin(); + for (; ita != this->mapXMLCh2AttType.end(); ++ita) + { + XMLCh* p = (XMLCh*)ita->first; + xns::XMLString::release(&p); + } + this->mapXMLCh2AttType.clear(); + +} + +// ----------------------------------------------------------------------- +// Implementations of the SAX DocumentHandler interface +// ----------------------------------------------------------------------- + +void SaxPhreeqcHandlers::endDocument() +{ +} + +void SaxPhreeqcHandlers::endElement(const XMLCh* const uri, const XMLCh* const name, const XMLCh* const qname) +{ + switch (this->mapXMLCh2Type[name]) + { + case typeSOLUTION: + // solution is finished now copy into solutions array + { + int n; + // copy vector of conc's to solution + this->solution_ptr->totals = (struct conc*) PHRQ_realloc(this->solution_ptr->totals, (size_t) (this->totals.size() + 1) * sizeof(struct conc)); + std::copy(this->totals.begin(), this->totals.end(), this->solution_ptr->totals); + this->solution_ptr->totals[this->totals.size()].description=NULL; + this->totals.clear(); + assert(this->totals.size() == 0); + + // copy vector of master_activities's to solution + this->solution_ptr->master_activity = (struct master_activity *) free_check_null(this->solution_ptr->master_activity); + if (this->acts.size() > 0) { + this->solution_ptr->master_activity = (struct master_activity *) PHRQ_realloc(this->solution_ptr->master_activity, (size_t) (this->acts.size()) * sizeof(struct master_activity)); + std::copy(this->acts.begin(), this->acts.end(), this->solution_ptr->master_activity); + } + this->solution_ptr->count_master_activity = this->acts.size(); + this->acts.clear(); + assert(this->acts.size() == 0); + + // copy vector of s_gamma's to solution + this->solution_ptr->species_gamma = (struct master_activity *) free_check_null(this->solution_ptr->species_gamma); + if (this->s_gammas.size() > 0) { + this->solution_ptr->species_gamma = (struct master_activity *) PHRQ_realloc(this->solution_ptr->species_gamma, (size_t) (this->s_gammas.size()) * sizeof(struct master_activity)); + std::copy(this->s_gammas.begin(), this->s_gammas.end(), this->solution_ptr->species_gamma); + } + this->solution_ptr->count_species_gamma = this->s_gammas.size(); + this->s_gammas.clear(); + assert(this->s_gammas.size() == 0); + + // copy vector of isotopes's to solution + this->solution_ptr->isotopes = (struct isotope *) free_check_null(this->solution_ptr->isotopes); + if (this->isotopes.size() > 0) { + this->solution_ptr->isotopes = (struct isotope *) PHRQ_realloc(this->solution_ptr->isotopes, (size_t) (this->isotopes.size()) * sizeof(struct isotope)); + std::copy(this->isotopes.begin(), this->isotopes.end(), this->solution_ptr->isotopes); + } + this->solution_ptr->count_isotopes = this->isotopes.size(); + this->isotopes.clear(); + assert(this->isotopes.size() == 0); + + + // store solution for now + if (solution_bsearch(this->solution_ptr->n_user, &n, FALSE) != NULL) { + solution_free(solution[n]); + solution[n] = this->solution_ptr; + } else { + n = count_solution++; + if (count_solution >= max_solution) + { + space ((void **) &(solution), count_solution, &max_solution, sizeof (struct solution *) ); + } + solution[n] = this->solution_ptr; + } + this->solution_ptr = NULL; + } + break; + default: + break; + } +} + +void SaxPhreeqcHandlers::characters(const XMLCh* const chars, const unsigned int length) +{ + // skip whitespace + + //XMLCh* pChar = (XMLCh*)chars; + //while(pChar && iswspace(*pChar)) ++pChar; + //if (*pChar) + // { +/* + switch(this->eltType) + { + case typeSOLN_MASTER_ACTIVITY: + //xns::BaseRefVectorOf *arg = xns::XMLString::tokenizeString(chars); + for ( i = 0; i < arg->size() - 1; i+=2 ) { + struct master_activity *ma = new master_activity(); + ma->description = XMLCh_hsave( arg->elementAt(i), true); + ma->la = XMLCh2Double( arg->elementAt(i + 1)); + this->acts.push_back(*ma); + } + //struct master_activity *ma = new master_activity(); + //ma->description = NULL; + //this->acts.push_back(*ma); + break; + } + */ + +} + +void SaxPhreeqcHandlers::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) +{ +} + +void SaxPhreeqcHandlers::processingInstruction(const XMLCh* const target, const XMLCh* const data) +{ +} + +void SaxPhreeqcHandlers::startDocument() +{ +} + +void SaxPhreeqcHandlers::startElement(const XMLCh* const uri, const XMLCh* const name, const XMLCh* const qname, const xns::Attributes& attributes) +{ + //const char ERR_MSG[] = "Unpacking solution message: %s, element not found\n"; + char *string; + + int i; + + string = xns::XMLString::transcode(name); + this->eltType = this->mapXMLCh2Type[name]; + xns::XMLString::release(&string); + switch (this->eltType) + { + case typePHAST_STATE: + XMLCh *x; + x = xns::XMLString::transcode("nx"); + i = XMLCh2Int(attributes.getValue(x)); + xns::XMLString::release(&x); + break; + case typeSOLUTION: + assert(this->solution_ptr == NULL); + assert(this->totals.size() == 0); + assert(this->acts.size() == 0); + + // allocate space for solution + this->solution_ptr = solution_alloc(); + + // process attributes for solution + processSolutionAttributes(attributes); + break; + case typeSOLN_PE: + assert(this->solution_ptr->pe != NULL); + // store pe, no need to clean up at end of solution + if ((attributes.getLength() >= 1) && (this->mapXMLCh2AttType[attributes.getLocalName(0)] == attSOLN_PE_name)){ + string = xns::XMLString::transcode(attributes.getValue((unsigned int) 0)); + pe_data_store(&(this->solution_ptr->pe), string); + xns::XMLString::release(&string); + } else { + ++input_error; + sprintf(error_string, "No attribute data for SOLN_PE.\n"); + error_msg(error_string, CONTINUE); + } + break; + case typeSOLN_TOTAL: + { + // store in c, push_back on totals + // need to copy and clean up at end of + struct conc c; + processSolutionTotalAttributes(attributes, &c); + this->totals.push_back(c); + } + break; + case typeSOLN_MASTER_ACTIVITY: + { + // store in ma, push_back on acts + // need to copy and clean up at end of + struct master_activity ma; + processMasterActivityAttributes(attributes, &ma); + this->acts.push_back(ma); + //processMasterActivityAttributes(attributes, &this->acts); + } + break; + case typeSOLN_SPECIES_GAMMA: + { + // store in ma, push_back on s_gammas + // need to copy and clean up at end of + struct master_activity ma; + processMasterActivityAttributes(attributes, &ma); + this->s_gammas.push_back(ma); + } + break; + case typeSOLN_ISOTOPE: + { + // store in iso, push_back on isotopes + // need to copy and clean up at end of + struct isotope iso; + processIsotopeAttributes(attributes, &iso); + this->isotopes.push_back(iso); + } + break; + + default: + break; + } +} +int SaxPhreeqcHandlers::processSolutionAttributes(const xns::Attributes& attributes) +{ + const char ERR_MSG[] = "Unpacking solution attributes: %s, attribute not found\n"; + unsigned int i; + char *string; + attributeType attType; + assert(this->eltType == typeSOLUTION); + assert(this->solution_ptr != NULL); + + // Get attribute name, map to attribute type, process + + for (i = 0; i < attributes.getLength(); i++) { + attType = this->mapXMLCh2AttType[attributes.getLocalName(i)]; + switch (attType) { + case attSOLN_new_def: + this->solution_ptr->new_def = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_n_user: + this->solution_ptr->n_user = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_n_user_end: + this->solution_ptr->n_user_end = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_description: + this->solution_ptr->description = XMLCh2String(attributes.getValue(i)); + break; + case attSOLN_tc: + this->solution_ptr->tc = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_ph: + this->solution_ptr->ph = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_solution_pe: + this->solution_ptr->solution_pe = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_mu: + this->solution_ptr->mu = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_ah2o: + this->solution_ptr->ah2o = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_density: + this->solution_ptr->density = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_total_h: + this->solution_ptr->total_h = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_total_o: + this->solution_ptr->total_o = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_cb: + this->solution_ptr->cb = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_mass_water: + this->solution_ptr->mass_water = XMLCh2Double(attributes.getValue(i)); + break; + case attSOLN_total_alkalinity: + this->solution_ptr->total_alkalinity = XMLCh2Double(attributes.getValue(i)); + break; + //case attSOLN_total_co2: + //this->solution_ptr->total_co2 = XMLCh2Double(attributes.getValue(i)); + //break; + case attSOLN_units: + this->solution_ptr->units = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attSOLN_default_pe: + this->solution_ptr->default_pe = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_count_master_activity: + this->solution_ptr->count_master_activity = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_count_isotopes: + this->solution_ptr->count_isotopes = XMLCh2Int(attributes.getValue(i)); + break; + case attSOLN_count_species_gamma: + this->solution_ptr->count_species_gamma = XMLCh2Int(attributes.getValue(i)); + break; + default: + ++input_error; + string = xns::XMLString::transcode(attributes.getLocalName(i)); + sprintf(error_string, ERR_MSG, string); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&string); + break; + } + } + return 0; +} +int SaxPhreeqcHandlers::processSolutionTotalAttributes(const xns::Attributes& attributes, struct conc *c) +{ + const char ERR_MSG[] = "Unpacking solution totals attributes: %s, attribute not found\n"; + unsigned int i; + char *string; + conc_init(c); + attributeType attType; + assert(this->eltType == typeSOLN_TOTAL); + + + // Get attribute name, map to attribute type, process + + for (i = 0; i < attributes.getLength(); i++) { + attType = this->mapXMLCh2AttType[attributes.getLocalName(i)]; + switch (attType) { + case attCONC_description: + c->description = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attCONC_moles: + c->moles = XMLCh2Double(attributes.getValue(i)); + break; + case attCONC_input_conc: + c->input_conc = XMLCh2Double(attributes.getValue(i)); + break; + case attCONC_units: + c->units = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attCONC_equation_name: + c->equation_name = XMLCh_hsave(attributes.getValue(i), TRUE); + c->phase = NULL; + break; + case attCONC_phase_si: + c->phase_si = XMLCh2Double(attributes.getValue(i)); + break; + case attCONC_n_pe: + c->n_pe = XMLCh2Int(attributes.getValue(i)); + break; + case attCONC_as: + c->as = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attCONC_gfw: + c->gfw = XMLCh2Double(attributes.getValue(i)); + break; + + default: + ++input_error; + string = xns::XMLString::transcode(attributes.getLocalName(i)); + sprintf(error_string, ERR_MSG, string); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&string); + break; + } + } + return(OK); +} +int SaxPhreeqcHandlers::processMasterActivityAttributes(const xns::Attributes& attributes, struct master_activity *ma) +//int SaxPhreeqcHandlers::processMasterActivityAttributes(const xns::Attributes& attributes, std::vector *v) +{ + int i; + char *string; + const char ERR_MSG[] = "Unpacking master activity attributes: %s, attribute not found\n"; + ma->description = NULL; + ma->la = 0.0; + attributeType attType; + for (i = 0; i < (int) attributes.getLength(); i++) { + attType = this->mapXMLCh2AttType[attributes.getLocalName(i)]; + + switch (attType) { + + case attM_A_description: + ma->description = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attM_A_la: + ma->la = XMLCh2Double(attributes.getValue(i)); + break; + /* + case attM_A_list: + { + struct master_activity ma; + xns::BaseRefVectorOf *arg = xns::XMLString::tokenizeString(attributes.getValue((unsigned int) 0)); + + for ( i = 0; i < arg->size(); i+=2 ) { + ma.description = XMLCh_hsave( arg->elementAt(i), TRUE); + if (strcmp(ma.description, "null") == 0) { + ma.description = NULL; + } + ma.la = XMLCh2Double( arg->elementAt(i+1)); + //this->acts.push_back(ma); + (*v).push_back(ma); + } + } + break; + */ + default: + ++input_error; + string = xns::XMLString::transcode(attributes.getLocalName(i)); + sprintf(error_string, ERR_MSG, string); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&string); + break; + } + } + return (OK); +} +int SaxPhreeqcHandlers::processIsotopeAttributes(const xns::Attributes& attributes, struct isotope *iso) +{ + int i; + char *string; + const char ERR_MSG[] = "Unpacking isotope attributes: %s, attribute not found\n"; + + iso->primary = iso->master = NULL; + iso->elt_name = iso->isotope_name = NULL; + attributeType attType; + for (i = 0; i < (int) attributes.getLength(); i++) { + attType = this->mapXMLCh2AttType[attributes.getLocalName(i)]; + switch (attType) { + case attISO_isotope_number: + iso->isotope_number = XMLCh2Int(attributes.getValue(i)); + break; + case attISO_elt_name: + iso->elt_name = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attISO_isotope_name: + iso->isotope_name = XMLCh_hsave(attributes.getValue(i), TRUE); + break; + case attISO_total: + iso->total = XMLCh2Double(attributes.getValue(i)); + break; + case attISO_ratio: + iso->ratio = XMLCh2Double(attributes.getValue(i)); + break; + case attISO_ratio_uncertainty: + iso->ratio_uncertainty = XMLCh2Double(attributes.getValue(i)); + break; + case attISO_coef: + iso->coef = XMLCh2Double(attributes.getValue(i)); + break; + + default: + ++input_error; + string = xns::XMLString::transcode(attributes.getLocalName(i)); + sprintf(error_string, ERR_MSG, string); + error_msg(error_string, CONTINUE); + xns::XMLString::release(&string); + break; + } + } + return (OK); +} + diff --git a/SAXPhreeqc.h b/SAXPhreeqc.h new file mode 100644 index 00000000..68a1f587 --- /dev/null +++ b/SAXPhreeqc.h @@ -0,0 +1,20 @@ +#ifndef _INC_SAXPHREEQC_H +#define _INC_SAXPHREEQC_H + +#if defined(__cplusplus) | defined(_CPP) +extern "C" { +#endif + +void SAX_StartSystem (); +int SAX_AddSolution (struct solution* solution_ptr); +void SAX_EndSystem (); +int SAX_GetXMLLength (); +const char* SAX_GetXMLStr (); +int SAX_UnpackSolutions(void* pvBuffer, int buf_size); + + +#if defined(__cplusplus) | defined(_CPP) +} +#endif + +#endif diff --git a/SSassemblage.cxx b/SSassemblage.cxx new file mode 100644 index 00000000..8bc3082e --- /dev/null +++ b/SSassemblage.cxx @@ -0,0 +1,171 @@ +// SSassemblage.cxx: implementation of the cxxSSassemblage class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "SSassemblage.h" +#include "SSassemblageSS.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSSassemblage::cxxSSassemblage() + // + // default constructor for cxxSSassemblage + // +: cxxNumKeyword() +{ +} + +cxxSSassemblage::cxxSSassemblage(struct s_s_assemblage *s_s_assemblage_ptr) + // + // constructor for cxxSSassemblage from struct SSassemblage + // +: +cxxNumKeyword() +{ + int i; + this->set_description(s_s_assemblage_ptr->description); + n_user = s_s_assemblage_ptr->n_user; + n_user_end = s_s_assemblage_ptr->n_user_end; + for (i = 0; i < s_s_assemblage_ptr->count_s_s; i++) { + cxxSSassemblageSS ssSS(&(s_s_assemblage_ptr->s_s[i])); + ssAssemblageSSs.push_back(ssSS); + } +} + +cxxSSassemblage::~cxxSSassemblage() +{ +} + +struct s_s_assemblage *cxxSSassemblage::cxxSSassemblage2s_s_assemblage() + // + // Builds a s_s_assemblage structure from instance of cxxSSassemblage + // +{ + struct s_s_assemblage *s_s_assemblage_ptr = s_s_assemblage_alloc(); + + s_s_assemblage_ptr->description = this->get_description(); + s_s_assemblage_ptr->n_user = this->n_user; + s_s_assemblage_ptr->n_user_end = this->n_user_end; + s_s_assemblage_ptr->new_def = FALSE; + s_s_assemblage_ptr->count_s_s = this->ssAssemblageSSs.size(); + s_s_assemblage_ptr->s_s = cxxSSassemblageSS::cxxSSassemblageSS2s_s(this->ssAssemblageSSs); + return(s_s_assemblage_ptr); +} + +#ifdef SKIP +void cxxSSassemblage::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing SSassemblage message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // SSassemblage element and attributes + s_oss << indent0; + s_oss << "eltList.dump_xml(s_oss, indent + 1); + + // ssAssemblageSSs + s_oss << indent1; + s_oss << "::const_iterator it = ssAssemblageSSs.begin(); it != ssAssemblageSSs.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } +} +#endif +void cxxSSassemblage::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing SSassemblage message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // SSassemblage element and attributes + s_oss << indent0; + s_oss << "SOLID_SOLUTIONS_RAW " << this->n_user << " " << this->description << std::endl; + + // ssAssemblageSSs + for (std::list::const_iterator it = ssAssemblageSSs.begin(); it != ssAssemblageSSs.end(); ++it) { + s_oss << indent1; + s_oss << "-solid_solution" << std::endl; + it->dump_raw(s_oss, indent + 2); + } +} + +void cxxSSassemblage::read_raw(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("solid_solution"); // 0 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read SSassemblage number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in EQUILIBRIUM_PHASES_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // solid_solution + { + cxxSSassemblageSS ssSS; + ssSS.read_raw(parser); + this->ssAssemblageSSs.push_back(ssSS); + } + useLastLine = true; + break; + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } +} diff --git a/SSassemblage.h b/SSassemblage.h new file mode 100644 index 00000000..416c9e34 --- /dev/null +++ b/SSassemblage.h @@ -0,0 +1,42 @@ +#if !defined(SSASSEMBLAGE_H_INCLUDED) +#define SSASSEMBLAGE_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "SSassemblageSS.h" + +class cxxSSassemblage : public cxxNumKeyword +{ + +public: + cxxSSassemblage(); + cxxSSassemblage(struct s_s_assemblage *); + ~cxxSSassemblage(); + + struct s_s_assemblage *cxxSSassemblage2s_s_assemblage(); + + struct s_s *cxxSSassemblageComp2s_s(); + + //void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + std::list ssAssemblageSSs; + +public: + //static std::map& map; + +}; + +#endif // !defined(SSASSEMBLAGE_H_INCLUDED) diff --git a/SSassemblageSS.cxx b/SSassemblageSS.cxx new file mode 100644 index 00000000..2730621a --- /dev/null +++ b/SSassemblageSS.cxx @@ -0,0 +1,443 @@ +// SSassemblageSS.cxx: implementation of the cxxSSassemblageSS class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "SSassemblageSS.h" +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSSassemblageSS::cxxSSassemblageSS() + // + // default constructor for cxxSSassemblageSS + // +{ + name = NULL; + //total_moles = 0; + a0 = 0; + a1 = 0; + ag0 = 0; + ag1 = 0; + miscibility = false; + //spinodal = false; + //tk = 25.; + xb1 = 0; + xb2 = 0; + //SS_PARAMETER_TYPE type = SS_PARM_NONE; + //double p[4]; +} + +cxxSSassemblageSS::cxxSSassemblageSS(struct s_s *s_s_ptr) + // + // constructor for cxxSSassemblageSS from struct s_s + // + +{ + name = s_s_ptr->name; + //total_moles = s_s_ptr->total_moles; + a0 = s_s_ptr->a0; + a1 = s_s_ptr->a1; + ag0 = s_s_ptr->ag0; + ag1 = s_s_ptr->ag1; + miscibility = (s_s_ptr->miscibility == TRUE); + //spinodal = (s_s_ptr->spinodal == TRUE); + //tk = s_s_ptr->tk; + xb1 = s_s_ptr->xb1; + xb2 = s_s_ptr->xb2; + //type = s_s_ptr->input_case; + /* + for (i = 0; i < 4; i++) { + p[i] = s_s_ptr->p[i]; + } + */ + int i; + for (i = 0; i < s_s_ptr->count_comps; i++) { + comps[s_s_ptr->comps[i].name] = s_s_ptr->comps[i].moles; + } +} + +cxxSSassemblageSS::~cxxSSassemblageSS() +{ +} + +struct s_s *cxxSSassemblageSS::cxxSSassemblageSS2s_s(std::list& el) + // + // Builds s_s structure from of cxxSSassemblageSS + // +{ + + // + // generate s_s structures + // + struct s_s *s_s_ptr = (struct s_s *) PHRQ_malloc((size_t) (el.size() * sizeof(struct s_s))); + if (s_s_ptr == NULL) malloc_error(); + int j = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + s_s_ptr[j].name = it->name; + //s_s_ptr[j].total_moles = it->total_moles; + s_s_ptr[j].total_moles = 0; + s_s_ptr[j].dn = 0; + s_s_ptr[j].a0 = it->a0; + s_s_ptr[j].a1 = it->a1; + s_s_ptr[j].ag0 = it->ag0; + s_s_ptr[j].ag1 = it->ag1; + //s_s_ptr[j].ag0 = 0; + //s_s_ptr[j].ag1 = 0; + s_s_ptr[j].s_s_in = TRUE; + s_s_ptr[j].miscibility = it->miscibility; + //s_s_ptr[j].spinodal = it->spinodal; + s_s_ptr[j].spinodal = FALSE; + //s_s_ptr[j].tk = it->tk; + s_s_ptr[j].tk = 273.15; + s_s_ptr[j].xb1 = it->xb1; + s_s_ptr[j].xb2 = it->xb2; + s_s_ptr[j].input_case = 0; + s_s_ptr[j].p[0] = 0; + s_s_ptr[j].p[1] = 0; + s_s_ptr[j].p[2] = 0; + s_s_ptr[j].p[3] = 0; + // + // generate s_s_comp structures + // + s_s_ptr[j].count_comps = it->comps.size(); + s_s_ptr[j].comps = NULL; + if (it->comps.size() > 0) { + int i = 0; + int n; + struct s_s_comp *s_s_comp_ptr = (struct s_s_comp *) PHRQ_malloc((size_t) (it->comps.size() * sizeof(struct s_s_comp))); + if (s_s_comp_ptr == NULL) malloc_error(); + for (cxxNameDouble::iterator itc = it->comps.begin(); itc != it->comps.end(); ++ itc) { + s_s_comp_ptr[i].name = itc->first; + s_s_comp_ptr[i].phase = phase_bsearch(itc->first, &n, TRUE); + s_s_comp_ptr[i].initial_moles = 0; + s_s_comp_ptr[i].moles = itc->second; + s_s_comp_ptr[i].init_moles = 0; + s_s_comp_ptr[i].delta = 0; + s_s_comp_ptr[i].fraction_x = 0; + s_s_comp_ptr[i].log10_lambda = 0; + s_s_comp_ptr[i].log10_fraction_x = 0; + s_s_comp_ptr[i].dn = 0; + s_s_comp_ptr[i].dnc = 0; + s_s_comp_ptr[i].dnb = 0; + i++; + } + s_s_ptr[j].comps = s_s_comp_ptr; + } + j++; + } + return(s_s_ptr); +} + +#ifdef SKIP +void cxxSSassemblageSS::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing s_s message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // S_S element and attributes + + s_oss << indent0 << "name=\"" << this->name << "\"" << std::endl; + s_oss << indent0 << "add_formula=\"" << this->add_formula << "\"" << std::endl; + s_oss << indent0 << "si=\"" << this->si << "\"" << std::endl; + s_oss << indent0 << "moles=\"" << this->moles << "\"" << std::endl; + s_oss << indent0 << "delta=\"" << this->delta << "\"" << std::endl; + s_oss << indent0 << "initial_moles=\"" << this->initial_moles << "\"" << std::endl; + s_oss << indent0 << "dissolve_only=\"" << this->dissolve_only << "\"" << std::endl; + +} +#endif +void cxxSSassemblageSS::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing s_s message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + + // S_S element and attributes + + s_oss << indent0 << "-name " << this->name << std::endl; + //s_oss << indent0 << "-total_moles " << this->total_moles << std::endl; + s_oss << indent0 << "-a0 " << this->a0 << std::endl; + s_oss << indent0 << "-a1 " << this->a1 << std::endl; + s_oss << indent0 << "-ag0 " << this->ag0 << std::endl; + s_oss << indent0 << "-ag1 " << this->ag1 << std::endl; + s_oss << indent0 << "-miscibility " << this->miscibility << std::endl; + //s_oss << indent0 << "-spinodal " << this->spinodal << std::endl; + //s_oss << indent0 << "-tk " << this->tk << std::endl; + s_oss << indent0 << "-xb1 " << this->xb1 << std::endl; + s_oss << indent0 << "-xb2 " << this->xb2 << std::endl; + s_oss << indent0 << "-component " << std::endl; + this->comps.dump_raw(s_oss, indent + 1); +} + +void cxxSSassemblageSS::read_raw(CParser& parser) +{ + std::string str; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("name"); // 0 + vopts.push_back("total_moles"); // 1 + vopts.push_back("a0"); // 2 + vopts.push_back("a1"); // 3 + vopts.push_back("components"); // 4 + vopts.push_back("miscibility"); // 5 + vopts.push_back("spinodal"); // 6 + vopts.push_back("tk"); // 7 + vopts.push_back("xb1"); // 8 + vopts.push_back("xb2"); // 9 + vopts.push_back("ag0"); // 10 + vopts.push_back("ag1"); // 11 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool name_defined(false); + //bool total_moles_defined(false); + bool a0_defined(false); + bool a1_defined(false); + bool ag0_defined(false); + bool ag1_defined(false); + bool miscibility_defined(false); + //bool spinodal_defined(false); + //bool tk_defined(false); + bool xb1_defined(false); + bool xb2_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Exchange for more processing + //parser.error_msg("Unknown input in S_S read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // name + if (!(parser.get_iss() >> str)) + { + this->name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for name.", CParser::OT_CONTINUE); + } else { + this->name = string_hsave(str.c_str()); + } + name_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 1: // total_moles + /* + if (!(parser.get_iss() >> this->total_moles)) + { + this->total_moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for total_moles.", CParser::OT_CONTINUE); + } + total_moles_defined = true; + */ + opt_save = CParser::OPT_DEFAULT; + break; + + case 2: // a0 + if (!(parser.get_iss() >> this->a0)) + { + this->a0 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for a0.", CParser::OT_CONTINUE); + } + a0_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 3: // a1 + if (!(parser.get_iss() >> this->a1)) + { + this->a1 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for a1.", CParser::OT_CONTINUE); + } + a1_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 4: // components + if ( this->comps.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected phase name and moles for comps.", CParser::OT_CONTINUE); + } + opt_save = 4; + break; + + case 5: // miscibility + if (!(parser.get_iss() >> this->miscibility)) + { + this->miscibility = 0; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for miscibility.", CParser::OT_CONTINUE); + } + miscibility_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 6: // spinodal + /* + if (!(parser.get_iss() >> this->spinodal)) + { + this->spinodal = 0; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for spinodal.", CParser::OT_CONTINUE); + } + spinodal_defined = true; + */ + opt_save = CParser::OPT_DEFAULT; + break; + + case 7: // tk + /* + if (!(parser.get_iss() >> this->tk)) + { + this->tk = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for tk.", CParser::OT_CONTINUE); + } + tk_defined = true; + */ + opt_save = CParser::OPT_DEFAULT; + break; + + case 8: // xb1 + if (!(parser.get_iss() >> this->xb1)) + { + this->xb1 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for xb1.", CParser::OT_CONTINUE); + } + xb1_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 9: // xb2 + if (!(parser.get_iss() >> this->xb2)) + { + this->xb2 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for xb2.", CParser::OT_CONTINUE); + } + xb2_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 10: // ag0 + if (!(parser.get_iss() >> this->ag0)) + { + this->ag0 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for ag0.", CParser::OT_CONTINUE); + } + ag0_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 11: // ag1 + if (!(parser.get_iss() >> this->ag1)) + { + this->ag1 = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for ag1.", CParser::OT_CONTINUE); + } + ag1_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (name_defined == false) { + parser.incr_input_error(); + parser.error_msg("Name not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + /* + if (total_moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Total_moles not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + */ + if (a0_defined == false) { + parser.incr_input_error(); + parser.error_msg("A0 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (a1_defined == false) { + parser.incr_input_error(); + parser.error_msg("A1 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (ag0_defined == false) { + parser.incr_input_error(); + parser.error_msg("Ag0 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (ag1_defined == false) { + parser.incr_input_error(); + parser.error_msg("Ag1 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (miscibility_defined == false) { + parser.incr_input_error(); + parser.error_msg("Miscibility not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + /* + if (spinodal_defined == false) { + parser.incr_input_error(); + parser.error_msg("Spinodal not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (tk_defined == false) { + parser.incr_input_error(); + parser.error_msg("Tk not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + */ + if (xb1_defined == false) { + parser.incr_input_error(); + parser.error_msg("Xb1 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } + if (xb2_defined == false) { + parser.incr_input_error(); + parser.error_msg("Xb2 not defined for SSassemblageSS input.", CParser::OT_CONTINUE); + } +} + diff --git a/SSassemblageSS.h b/SSassemblageSS.h new file mode 100644 index 00000000..cf9c5261 --- /dev/null +++ b/SSassemblageSS.h @@ -0,0 +1,65 @@ +#if !defined(SSASSEMBLAGESS_H_INCLUDED) +#define SSASSEMBLAGESS_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxSSassemblageSS +{ + +public: + cxxSSassemblageSS(); + cxxSSassemblageSS(struct s_s *); + ~cxxSSassemblageSS(); + + enum SS_PARAMETER_TYPE { + SS_PARM_NONE = -1, + SS_PARM_A0_A1 = 0, + SS_PARM_GAMMAS = 1, + SS_PARM_DIST_COEF = 2, + SS_PARM_MISCIBILITY = 3, + SS_PARM_SPINODAL = 4, + SS_PARM_CRITICAL = 5, + SS_PARM_ALYOTROPIC = 6, + SS_PARM_DIM_GUGG = 7, + SS_PARM_WALDBAUM = 8, + SS_PARM_MARGULES = 9 + }; + + static struct s_s *cxxSSassemblageSS2s_s(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + char *name; + //std::list ppAssemblageSS; + cxxNameDouble comps; + //double total_moles; + //double dn; + double a0, a1; + double ag0, ag1; + //bool s_s_in; + bool miscibility; + //bool spinodal; + //double tk; + double xb1, xb2; + //SS_PARAMETER_TYPE type; + //double p[4]; + +public: + +}; + +#endif // !defined(SSASSEMBLAGESS_H_INCLUDED) diff --git a/SaxPhreeqcHandlers.h b/SaxPhreeqcHandlers.h new file mode 100644 index 00000000..2eb590a7 --- /dev/null +++ b/SaxPhreeqcHandlers.h @@ -0,0 +1,154 @@ +// SaxPhreeqcHandlers.h: interface for the SaxPhreeqcHandlers class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SAXPHREEQCHANDLERS_H__4A69D5F5_2E57_4001_911D_4ABF6F2C0A0B__INCLUDED_) +#define AFX_SAXPHREEQCHANDLERS_H__4A69D5F5_2E57_4001_911D_4ABF6F2C0A0B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include // iswspace sprintf +#include // SAX2XMLReader +/** +#include +**/ +#include +#include + +#define xns XERCES_CPP_NAMESPACE + +#ifdef USE_LONG_DOUBLE +#define LDBLE long double +#else +#define LDBLE double +#endif + +struct XMLCH_LESS : std::binary_function { +bool operator()(const XMLCh* _X, const XMLCh* _Y) const +{ + return xns::XMLString::compareString( _X, _Y) < 0;} +}; + +#include +//extern "C" { +#define EXTERNAL extern +//#include "phqalloc.h" +#include "global.h" +#include "phrqproto.h" +// int conc_init(struct conc *conc_ptr); +//} + + +class Cconc : public conc +{ +public: + Cconc() { conc_init(this); } + ~Cconc() { ; } +}; + + +class SaxPhreeqcHandlers : public xns::DefaultHandler +{ +public: + SaxPhreeqcHandlers(); + virtual ~SaxPhreeqcHandlers(); + + // ----------------------------------------------------------------------- + // Implementations of the SAX DocumentHandler interface + // ----------------------------------------------------------------------- + void endDocument(); + + void endElement(const XMLCh* const uri, const XMLCh* const name, const XMLCh* const qname); + + void characters(const XMLCh* const chars, const unsigned int length); + + void ignorableWhitespace(const XMLCh* const chars, const unsigned int length); + + void processingInstruction(const XMLCh* const target, const XMLCh* const data); + + void startDocument(); + + void startElement(const XMLCh* const uri, const XMLCh* const name, const XMLCh* const qname, const xns::Attributes& attributes); + + // element types + enum elementType + { + typeNULL, + typePHAST_STATE, + typeSYSTEM, + typeSOLUTION, + typeSOLN_PE, + typeSOLN_TOTAL, + typeSOLN_MASTER_ACTIVITY, + typeSOLN_ISOTOPE, + typeSOLN_SPECIES_GAMMA + } eltType; + // attribute types + enum attributeType + { + attNULL, + attSOLN_new_def, + attSOLN_n_user, + attSOLN_n_user_end, + attSOLN_description, + attSOLN_tc, + attSOLN_ph, + attSOLN_solution_pe, + attSOLN_mu, + attSOLN_ah2o, + attSOLN_density, + attSOLN_total_h, + attSOLN_total_o, + attSOLN_cb, + attSOLN_mass_water, + attSOLN_total_alkalinity, + attSOLN_total_co2, + attSOLN_units, + attSOLN_default_pe, + attSOLN_count_master_activity, + attSOLN_count_isotopes, + attSOLN_count_species_gamma, + attSOLN_PE_name, + attM_A_description, + attM_A_la, + attM_A_list, + attISO_isotope_number, + attISO_elt_name, + attISO_isotope_name, + attISO_total, + attISO_ratio, + attISO_ratio_uncertainty, + attISO_x_ratio_uncertainty, + attISO_coef, + attCONC_description, + attCONC_moles, + attCONC_input_conc, + attCONC_units, + attCONC_equation_name, + attCONC_phase_si, + attCONC_n_pe, + attCONC_as, + attCONC_gfw, + } attType; + + int processSolutionAttributes(const xns::Attributes& attributes); + int processSolutionTotalAttributes(const xns::Attributes& attributes, struct conc *c); + int processMasterActivityAttributes(const xns::Attributes& attributes, struct master_activity *ma); + //int processMasterActivityAttributes(const xns::Attributes& attributes, std::vector *v); + int processIsotopeAttributes(const xns::Attributes& attributes, struct isotope *iso); + +protected: + std::vector totals; + std::vector acts, s_gammas; + std::vector isotopes; + std::map< const XMLCh*, elementType, XMLCH_LESS > mapXMLCh2Type; + std::map< const XMLCh*, attributeType, XMLCH_LESS > mapXMLCh2AttType; + /** + std::hash_map, XMLCH_EQUALS> m_hashmapXMLCh2Type; + **/ + struct solution* solution_ptr; +}; + +#endif // !defined(AFX_SAXPHREEQCHANDLERS_H__4A69D5F5_2E57_4001_911D_4ABF6F2C0A0B__INCLUDED_) diff --git a/Solution.cxx b/Solution.cxx new file mode 100644 index 00000000..9331295c --- /dev/null +++ b/Solution.cxx @@ -0,0 +1,1102 @@ +// Solution.cxx: implementation of the cxxSolution class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Solution.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSolution::cxxSolution() + // + // default constructor for cxxSolution + // +: cxxNumKeyword() +{ + tc = 25.0; + ph = 7.0; + pe = 4.0; + mu = 1e-7; + ah2o = 1.0; + total_h = 111.1; + total_o = 55.55; + cb = 0.0; + mass_water = 1.0; + total_alkalinity = 0.0; + totals.type = cxxNameDouble::ND_ELT_MOLES; + master_activity.type = cxxNameDouble::ND_SPECIES_LA; + species_gamma.type = cxxNameDouble::ND_SPECIES_GAMMA; +} + +cxxSolution::cxxSolution(struct solution *solution_ptr) + // + // constructor for cxxSolution from struct solution + // +: +cxxNumKeyword(), +totals(solution_ptr->totals), +master_activity(solution_ptr->master_activity, solution_ptr->count_master_activity, cxxNameDouble::ND_SPECIES_LA), +species_gamma(solution_ptr->species_gamma, solution_ptr->count_species_gamma, cxxNameDouble::ND_SPECIES_GAMMA) +{ + int i; + + this->set_description(solution_ptr->description); + n_user = solution_ptr->n_user; + n_user_end = solution_ptr->n_user_end; + tc = solution_ptr->tc; + ph = solution_ptr->ph; + pe = solution_ptr->solution_pe; + mu = solution_ptr->mu; + ah2o = solution_ptr->ah2o; + total_h = solution_ptr->total_h; + total_o = solution_ptr->total_o; + cb = solution_ptr->cb; + mass_water = solution_ptr->mass_water; + total_alkalinity = solution_ptr->total_alkalinity; + + // Totals filled in constructor, just save description and moles + + // Isotopes + for (i = 0; i < solution_ptr->count_isotopes; i++) { + cxxIsotope iso(&solution_ptr->isotopes[i]); + isotopes.push_back(iso); + } + + // Master_activity in constructor + // Species_gamma in constructor +} + +cxxSolution::~cxxSolution() +{ +} + +struct solution *cxxSolution::cxxSolution2solution() + // + // Builds a solution structure from instance of cxxSolution + // +{ + + struct solution *solution_ptr = solution_alloc(); + + solution_ptr->description = this->get_description(); + solution_ptr->n_user = this->n_user; + solution_ptr->n_user_end = this->n_user_end; + solution_ptr->new_def = FALSE; + solution_ptr->tc = this->tc; + solution_ptr->ph = this->ph; + solution_ptr->solution_pe = this->pe; + solution_ptr->mu = this->mu; + solution_ptr->ah2o = this->ah2o; + solution_ptr->total_h = this->total_h; + solution_ptr->total_o = this->total_o; + solution_ptr->cb = this->cb; + solution_ptr->mass_water = this->mass_water; + solution_ptr->total_alkalinity = this->total_alkalinity; + solution_ptr->density = 1.0; + solution_ptr->units = moles_per_kilogram_string; + solution_ptr->default_pe = 0; + // pe_data + + // totals + solution_ptr->totals = (struct conc *) free_check_null(solution_ptr->totals); + solution_ptr->totals = this->totals.conc(); + + // master_activity + solution_ptr->master_activity = (struct master_activity *) free_check_null(solution_ptr->master_activity); + solution_ptr->master_activity = this->master_activity.master_activity(); + solution_ptr->count_master_activity = this->master_activity.size() + 1; + + // species_gamma + solution_ptr->species_gamma = this->species_gamma.master_activity(); + solution_ptr->count_species_gamma = this->species_gamma.size(); + + // isotopes + solution_ptr->isotopes = (struct isotope *) free_check_null(solution_ptr->isotopes); + solution_ptr->isotopes = cxxIsotope::list2isotope(this->isotopes); + solution_ptr->count_isotopes = this->isotopes.size(); + + return(solution_ptr); +} +void cxxSolution::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing solution message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + + // Solution element and attributes + s_oss << indent0; + s_oss << "new_def << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_n_user=\"" << this->n_user << "\" " << std::endl; + + s_oss << indent1; + s_oss << "soln_description=\"" << this->description << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_tc=\"" << this->tc << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_ph=\"" << this->ph << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_solution_pe=\"" << this->pe << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_mu=\"" << this->mu << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_ah2o=\"" << this->ah2o << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_total_h=\"" << this->total_h << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_total_o=\"" << this->total_o << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_cb=\"" << this->cb << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_mass_water=\"" << this->mass_water << "\"" << std::endl; + + s_oss << indent1; + s_oss << "soln_total_alkalinity=\"" << this->total_alkalinity << "\"" << std::endl; + + s_oss << indent1; + s_oss << "\">" << std::endl; + + // soln_total conc structures + this->totals.dump_xml(s_oss, indent + 1); + /* + { + for (std::map ::const_iterator it = totals.begin(); it != totals.end(); ++it) { + s_oss << indent1; + s_oss << "first << "\""; + s_oss << " conc_moles=\"" << it->second << "\"" ; + s_oss << "\">" << std::endl; + } + } + */ + // master_activity map + this->master_activity.dump_xml(s_oss, indent + 1); + /* + { + for (std::map ::const_iterator it = master_activity.begin(); it != master_activity.end(); ++it) { + s_oss << indent1; + s_oss << "first << "\"" ; + s_oss << " m_a_la=\"" << it->second << "\"" ; + s_oss << "\">" << std::endl; + } + } + */ + // species_gamma map + this->species_gamma.dump_xml(s_oss, indent + 1); + /* + { + for (std::map ::const_iterator it = species_gamma.begin(); it != species_gamma.end(); ++it) { + s_oss << indent1; + s_oss << "first << "\"" ; + s_oss << " m_a_la=\"" << it->second << "\"" ; + s_oss << "\">" << std::endl; + } + } + */ + + for (std::list::const_iterator it = this->isotopes.begin(); it != isotopes.end(); ++it) { + it->dump_xml(s_oss, indent + 1); + } + + // End of solution + s_oss << indent0; + s_oss << "" << std::endl; + + return; +} + +void cxxSolution::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing solution message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Solution element and attributes + s_oss << indent0; + s_oss << "SOLUTION_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-temp " << this->tc << std::endl; + + s_oss << indent1; + s_oss << "-pH " << this->ph << std::endl; + + s_oss << indent1; + s_oss << "-pe " << this->pe << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-mu " << this->mu << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-ah2o " << this->ah2o << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-total_h " << this->total_h << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-total_o " << this->total_o << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-cb " << this->cb << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-mass_water " << this->mass_water << std::endl; + + // new identifier + s_oss << indent1; + s_oss << "-total_alkalinity " << this->total_alkalinity << std::endl; + + // soln_total conc structures + s_oss << indent1; + s_oss << "-totals" << std::endl; + this->totals.dump_raw(s_oss, indent + 2); + /* + for (std::map ::const_iterator it = totals.begin(); it != totals.end(); ++it) { + s_oss << indent2; + s_oss << it->first << " " << it->second << std::endl; + } + */ + + // master_activity map + s_oss << indent1; + s_oss << "-activities" << std::endl; + this->master_activity.dump_raw(s_oss, indent + 2); + /* + { + for (std::map ::const_iterator it = master_activity.begin(); it != master_activity.end(); ++it) { + s_oss << indent2; + s_oss << it->first << " " << it->second << std::endl; + } + } + */ + // species_gamma map + s_oss << indent1; + s_oss << "-gammas" << std::endl; + this->species_gamma.dump_raw(s_oss, indent + 2); + /* + { + { + for (std::map ::const_iterator it = species_gamma.begin(); it != species_gamma.end(); ++it) { + s_oss << indent2; + s_oss << it->first << " " << it->second << std::endl; + } + } + } + */ + // Isotopes + s_oss << indent1; + s_oss << "-Isotopes" << std::endl; + { + for (std::list::const_iterator it = this->isotopes.begin(); it != isotopes.end(); ++it) { + it->dump_raw(s_oss, indent + 2); + } + } + + return; +} + +void cxxSolution::read_raw(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(21); + vopts.push_back("totals"); // 0 + vopts.push_back("activities"); // 1 + vopts.push_back("gammas"); // 2 + vopts.push_back("isotopes"); // 3 + vopts.push_back("temp"); // 4 + vopts.push_back("tc"); // 5 + vopts.push_back("temperature"); // 6 + vopts.push_back("ph"); // 7 + vopts.push_back("pe"); // 8 + vopts.push_back("mu"); // 9 + vopts.push_back("ionic_strength"); // 10 + vopts.push_back("ah2o"); // 11 + vopts.push_back("activity_water"); // 12 + vopts.push_back("total_h"); // 13 + vopts.push_back("total_o"); // 14 + vopts.push_back("mass_water"); // 15 + vopts.push_back("mass_h2o"); // 16 + vopts.push_back("total_alkalinity"); // 17 + vopts.push_back("total_alk"); // 18 + vopts.push_back("cb"); // 19 + vopts.push_back("charge_balance"); // 20 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + // Read solution number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool tc_defined(false); + bool ph_defined(false); + bool pe_defined(false); + bool mu_defined(false); + bool ah2o_defined(false); + bool total_h_defined(false); + bool total_o_defined(false); + bool cb_defined(false); + bool mass_water_defined(false); + bool total_alkalinity_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in SOLUTION_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // totals + if ( this->totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and moles for totals.", CParser::OT_CONTINUE); + } + opt_save = 0; + break; + + case 1: // activities + if ( this->master_activity.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected species name and log activity for activities.", CParser::OT_CONTINUE); + } + opt_save = 1; + break; + + case 2: // gammas + if ( this->species_gamma.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected species name and activity coefficient for gammas.", CParser::OT_CONTINUE); + } + opt_save = 2; + break; + + case 3: // isotopes + { + cxxIsotope iso; + if ( iso.read_raw(parser) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected data for isotopes.", CParser::OT_CONTINUE); + } else { + if (iso.get_isotope_name() != NULL) { + this->isotopes.push_back(iso); + } + } + } + opt_save = 3; + break; + + case 4: // temp + case 5: // tc + case 6: // temperature + if (!(parser.get_iss() >> this->tc)) + { + this->tc = 25.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for temperature.", CParser::OT_CONTINUE); + } + tc_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 7: // ph + if (!(parser.get_iss() >> this->ph)) + { + this->ph = 7.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for pH.", CParser::OT_CONTINUE); + } + ph_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 8: // pe + if (!(parser.get_iss() >> this->pe)) + { + this->pe = 4.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for pe.", CParser::OT_CONTINUE); + } + pe_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 9: // mu + case 10: // ionic_strength + if (!(parser.get_iss() >> this->mu)) + { + this->mu = 1e-7; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for ionic strength.", CParser::OT_CONTINUE); + } + mu_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 11: // ah2o + case 12: // activity_water + if (!(parser.get_iss() >> this->ah2o)) + { + this->ah2o = 1.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for activity of water.", CParser::OT_CONTINUE); + } + ah2o_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 13: // total_h + if (!(parser.get_iss() >> this->total_h)) + { + this->total_h = 111.1; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for total hydrogen.", CParser::OT_CONTINUE); + } + total_h_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 14: // total_o + if (!(parser.get_iss() >> this->total_o)) + { + this->total_o = 55.55; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for total oxygen.", CParser::OT_CONTINUE); + } + total_o_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 15: // mass_water + case 16: // mass_h2o + if (!(parser.get_iss() >> this->mass_water)) + { + this->mass_water = 1.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water.", CParser::OT_CONTINUE); + } + mass_water_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 17: // total_alkalinity + case 18: // total_alk + if (!(parser.get_iss() >> this->total_alkalinity)) + { + this->total_alkalinity = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for total_alkalinity.", CParser::OT_CONTINUE); + } + total_alkalinity_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + case 19: // cb + case 20: // charge_balance + if (!(parser.get_iss() >> this->cb)) + { + this->cb = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for charge balance.", CParser::OT_CONTINUE); + } + cb_defined = true; + opt_save = CParser::OPT_DEFAULT; + break; + + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // all members must be defined + if (tc_defined == false) { + parser.incr_input_error(); + parser.error_msg("Temp not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (ph_defined == false) { + parser.incr_input_error(); + parser.error_msg("pH not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (pe_defined == false) { + parser.incr_input_error(); + parser.error_msg("pe not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (mu_defined == false) { + parser.incr_input_error(); + parser.error_msg("Ionic strength not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (ah2o_defined == false) { + parser.incr_input_error(); + parser.error_msg("Activity of water not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (total_h_defined == false) { + parser.incr_input_error(); + parser.error_msg("Total hydrogen not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (total_o_defined == false) { + parser.incr_input_error(); + parser.error_msg("Total oxygen not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (cb_defined == false) { + parser.incr_input_error(); + parser.error_msg("Charge balance not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (mass_water_defined == false) { + parser.incr_input_error(); + parser.error_msg("Temp not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + if (total_alkalinity_defined == false) { + parser.incr_input_error(); + parser.error_msg("Total alkalinity not defined for SOLUTION_RAW input.", CParser::OT_CONTINUE); + } + return; +} + +#ifdef SKIP +cxxSolution& cxxSolution::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxSolution numkey; + + // Read solution number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxSolution& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SOLUTION keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.solution_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in solution.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif + + +#include "ISolution.h" +#include "Exchange.h" +#include "Surface.h" +#include "PPassemblage.h" +#include "KineticsCxx.h" +#include "SSassemblage.h" +#include "GasPhase.h" +#include "Reaction.h" +#include "Mix.h" +#include "Temperature.h" +#include // std::cout std::cerr +//#include +#include +#include +void test_classes(void) +{ + int i; + bool b(true); + i = (int) b; + for (i=0; i < count_solution; i++) { + if (solution[i]->new_def == TRUE) { + cxxISolution sol(solution[i]); + solution[i] = (struct solution *) solution_free(solution[i]); + solution[i] = sol.cxxISolution2solution(); + struct solution *soln_ptr; + soln_ptr = solution[i]; + soln_ptr = solution[i]; + } else { + std::ostringstream oss; + cxxSolution sol(solution[i]); + solution[i] = (struct solution *) solution_free(solution[i]); + sol.dump_raw(oss, 0); + + //std::fstream myfile("t"); + //CParser cparser(myfile, std::cout, std::cerr); + cxxSolution sol1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + + sol1.read_raw(cparser); + + solution[i] = sol1.cxxSolution2solution(); + } + } + for (i=0; i < count_exchange; i++) { + if (exchange[i].new_def != TRUE) { + std::ostringstream oss; + cxxExchange ex(&(exchange[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + cxxExchange ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + + struct exchange *exchange_ptr = ex1.cxxExchange2exchange(); + exchange_free(&exchange[i]); + exchange_copy(exchange_ptr, &exchange[i], exchange_ptr->n_user); + exchange_free(exchange_ptr); + free_check_null(exchange_ptr); + } + } + for (i=0; i < count_surface; i++) { + if (surface[i].new_def != TRUE) { + std::ostringstream oss; + cxxSurface ex(&(surface[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxSurface ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + + struct surface *surface_ptr = ex1.cxxSurface2surface(); + surface_free(&surface[i]); + surface_copy(surface_ptr, &surface[i], surface_ptr->n_user); + surface_free(surface_ptr); + free_check_null(surface_ptr); + + } + + } + for (i=0; i < count_pp_assemblage; i++) { + if (pp_assemblage[i].new_def != TRUE) { + std::ostringstream oss; + cxxPPassemblage ex(&(pp_assemblage[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxPPassemblage ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + + struct pp_assemblage *pp_assemblage_ptr = ex1.cxxPPassemblage2pp_assemblage(); + pp_assemblage_free(&pp_assemblage[i]); + pp_assemblage_copy(pp_assemblage_ptr, &pp_assemblage[i], pp_assemblage_ptr->n_user); + pp_assemblage_free(pp_assemblage_ptr); + free_check_null(pp_assemblage_ptr); + + } + + } + for (i=0; i < count_kinetics; i++) { + std::ostringstream oss; + cxxKinetics ex(&(kinetics[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxKinetics ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + + ex1.read_raw(cparser); + + struct kinetics *kinetics_ptr = ex1.cxxKinetics2kinetics(); + kinetics_free(&kinetics[i]); + kinetics_copy(kinetics_ptr, &kinetics[i], kinetics_ptr->n_user); + kinetics_free(kinetics_ptr); + free_check_null(kinetics_ptr); + } + for (i=0; i < count_s_s_assemblage; i++) { + if (s_s_assemblage[i].new_def != TRUE) { + std::ostringstream oss; + cxxSSassemblage ex(&(s_s_assemblage[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxSSassemblage ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + + struct s_s_assemblage *s_s_assemblage_ptr = ex1.cxxSSassemblage2s_s_assemblage(); + s_s_assemblage_free(&s_s_assemblage[i]); + s_s_assemblage_copy(s_s_assemblage_ptr, &s_s_assemblage[i], s_s_assemblage_ptr->n_user); + s_s_assemblage_free(s_s_assemblage_ptr); + free_check_null(s_s_assemblage_ptr); + + } + + } + for (i=0; i < count_gas_phase; i++) { + if (gas_phase[i].new_def != TRUE) { + std::ostringstream oss; + cxxGasPhase ex(&(gas_phase[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxGasPhase ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + + struct gas_phase *gas_phase_ptr = ex1.cxxGasPhase2gas_phase(); + gas_phase_free(&gas_phase[i]); + gas_phase_copy(gas_phase_ptr, &gas_phase[i], gas_phase_ptr->n_user); + gas_phase_free(gas_phase_ptr); + free_check_null(gas_phase_ptr); + + } + + } + for (i=0; i < count_irrev; i++) { + std::ostringstream oss; + cxxReaction ex(&(irrev[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxReaction ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + struct irrev *irrev_ptr = ex1.cxxReaction2irrev(); + + irrev_free(&irrev[i]); + irrev_copy(irrev_ptr, &irrev[i], irrev_ptr->n_user); + + irrev_free(irrev_ptr); + free_check_null(irrev_ptr); + + } + for (i=0; i < count_mix; i++) { + std::ostringstream oss; + cxxMix ex(&(mix[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxMix ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + struct mix *mix_ptr = ex1.cxxMix2mix(); + + mix_free(&mix[i]); + mix_copy(mix_ptr, &mix[i], mix_ptr->n_user); + + mix_free(mix_ptr); + free_check_null(mix_ptr); + + } + for (i=0; i < count_temperature; i++) { + std::ostringstream oss; + cxxTemperature ex(&(temperature[i])); + ex.dump_raw(oss, 0); + std::cerr << oss.str(); + + + cxxTemperature ex1; + std::string keyInput = oss.str(); + std::istringstream iss(keyInput); + + CParser cparser(iss, oss, std::cerr); + //For testing, need to read line to get started + std::vector vopts; + std::istream::pos_type next_char; + cparser.get_option(vopts, next_char); + + ex1.read_raw(cparser); + struct temperature *temperature_ptr = ex1.cxxTemperature2temperature(); + + temperature_free(&temperature[i]); + temperature_copy(temperature_ptr, &temperature[i], temperature_ptr->n_user); + + temperature_free(temperature_ptr); + free_check_null(temperature_ptr); + + } +} diff --git a/Solution.h b/Solution.h new file mode 100644 index 00000000..e9225701 --- /dev/null +++ b/Solution.h @@ -0,0 +1,94 @@ +#if !defined(SOLUTION_H_INCLUDED) +#define SOLUTION_H_INCLUDED + +#include "NumKeyword.h" +#include "Isotope.h" +#include "Conc.h" +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxSolution : public cxxNumKeyword +{ + +public: + cxxSolution(); + cxxSolution(struct solution *); + //cxxSolution(const cxxSolution&); + ~cxxSolution(); + + //static cxxSolution& read(CParser& parser); + + double get_tc()const {return this->tc;} + void set_tc(double tc) {this->tc = tc;} + + double get_ph()const {return this->ph;} + void set_ph(double pH) {this->ph = pH;} + + double get_pe()const {return this->pe;} + void set_pe(double pe) {this->pe =pe;} + + double get_mu()const {return this->mu;} + void set_mu(double mu) {this->pe = mu;} + + double get_ah2o()const {return this->ah2o;} + void set_ah2o(double ah2o) {this->pe = ah2o;} + + double get_total_h()const {return this->total_h;} + void set_total_h(double total_h) {this->pe = mu;} + + double get_total_o()const {return this->total_o;} + void set_total_o(double total_o) {this->pe = mu;} + + double get_mass_water()const {return this->mass_water;}; + void set_mass_water(long double mass_water) {this->mass_water = mass_water;}; + + double get_total_alkalinity()const {return this->total_alkalinity;} + void set_total_alkalinity(double total_alkalinity) {this->pe = total_alkalinity;} + + //char * get_pe_reaction()const {return this->pe_reaction;} + //void set_pe_reaction(char * pe_reaction) {this->pe_reaction = pe_reaction;} + + struct solution *cxxSolution2solution(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void cxxSolution::dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void cxxSolution::read_raw(CParser& parser); + + +protected: + double tc; + double ph; + double pe; + double mu; + double ah2o; + double total_h; + double total_o; + double cb; + double mass_water; + double total_alkalinity; + // maps element name to moles + //std::map totals; + cxxNameDouble totals; + std::list isotopes; + // maps master species name log activity + //std::map master_activity; + cxxNameDouble master_activity; + // maps species name to Pitzer activty coefficient + //std::map species_gamma; + cxxNameDouble species_gamma; +public: + //static std::map& map; + +}; + +#endif // !defined(SOLUTION_H_INCLUDED) diff --git a/Sun/examples/ex1.log b/Sun/examples/ex1.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex1.out b/Sun/examples/ex1.out new file mode 100644 index 00000000..658d1320 --- /dev/null +++ b/Sun/examples/ex1.out @@ -0,0 +1,325 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex1 + Output file: ex1.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 1.--Add uranium and speciate seawater. + SOLUTION 1 SEAWATER FROM NORDSTROM ET AL. (1979) + units ppm + pH 8.22 + pe 8.451 + density 1.023 + temp 25.0 + redox O(0)/O(-2) + Ca 412.3 + Mg 1291.8 + Na 10768.0 + K 399.1 + Fe 0.002 + Mn 0.0002 pe + Si 4.28 + Cl 19353.0 + Alkalinity 141.682 as HCO3 + S(6) 2712.0 + N(5) 0.29 gfw 62.0 + N(-3) 0.03 as NH4 + U 3.3 ppb N(5)/N(-3) + O(0) 1.0 O2(g) -0.7 + SOLUTION_MASTER_SPECIES + U U+4 0.0 238.0290 238.0290 + U(4) U+4 0.0 238.0290 + U(5) UO2+ 0.0 238.0290 + U(6) UO2+2 0.0 238.0290 + SOLUTION_SPECIES + U+4 = U+4 + log_k 0.0 + U+4 + 4 H2O = U(OH)4 + 4 H+ + log_k -8.538 + delta_h 24.760 kcal + U+4 + 5 H2O = U(OH)5- + 5 H+ + log_k -13.147 + delta_h 27.580 kcal + U+4 + 2 H2O = UO2+ + 4 H+ + e- + log_k -6.432 + delta_h 31.130 kcal + U+4 + 2 H2O = UO2+2 + 4 H+ + 2 e- + log_k -9.217 + delta_h 34.430 kcal + UO2+2 + H2O = UO2OH+ + H+ + log_k -5.782 + delta_h 11.015 kcal + 2UO2+2 + 2H2O = (UO2)2(OH)2+2 + 2H+ + log_k -5.626 + delta_h -36.04 kcal + 3UO2+2 + 5H2O = (UO2)3(OH)5+ + 5H+ + log_k -15.641 + delta_h -44.27 kcal + UO2+2 + CO3-2 = UO2CO3 + log_k 10.064 + delta_h 0.84 kcal + UO2+2 + 2CO3-2 = UO2(CO3)2-2 + log_k 16.977 + delta_h 3.48 kcal + UO2+2 + 3CO3-2 = UO2(CO3)3-4 + log_k 21.397 + delta_h -8.78 kcal + PHASES + Uraninite + UO2 + 4 H+ = U+4 + 2 H2O + log_k -3.490 + delta_h -18.630 kcal + END +----- +TITLE +----- + + Example 1.--Add uranium and speciate seawater. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. SEAWATER FROM NORDSTROM ET AL. (1979) + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Alkalinity 2.406e-03 2.406e-03 + Ca 1.066e-02 1.066e-02 + Cl 5.657e-01 5.657e-01 + Fe 3.711e-08 3.711e-08 + K 1.058e-02 1.058e-02 + Mg 5.507e-02 5.507e-02 + Mn 3.773e-09 3.773e-09 + N(-3) 1.724e-06 1.724e-06 + N(5) 4.847e-06 4.847e-06 + Na 4.854e-01 4.854e-01 + O(0) 3.746e-04 3.746e-04 Equilibrium with O2(g) + S(6) 2.926e-02 2.926e-02 + Si 7.382e-05 7.382e-05 + U 1.437e-08 1.437e-08 + +----------------------------Description of solution---------------------------- + + pH = 8.220 + pe = 8.451 + Activity of water = 0.981 + Ionic strength = 6.748e-01 + Mass of water (kg) = 1.000e+00 + Total carbon (mol/kg) = 2.180e-03 + Total CO2 (mol/kg) = 2.180e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.936e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.07 + Iterations = 7 + Total H = 1.110147e+02 + Total O = 5.563047e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + N(-3)/N(5) 4.6750 0.2766 + O(-2)/O(0) 12.3893 0.7329 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.674e-06 1.629e-06 -5.573 -5.788 -0.215 + H+ 7.981e-09 6.026e-09 -8.098 -8.220 -0.122 + H2O 5.551e+01 9.806e-01 1.744 -0.009 0.000 +C(4) 2.180e-03 + HCO3- 1.514e-03 1.023e-03 -2.820 -2.990 -0.170 + MgHCO3+ 2.195e-04 1.640e-04 -3.658 -3.785 -0.127 + NaHCO3 1.667e-04 1.948e-04 -3.778 -3.710 0.067 + MgCO3 8.913e-05 1.041e-04 -4.050 -3.982 0.067 + NaCO3- 6.718e-05 5.020e-05 -4.173 -4.299 -0.127 + CaHCO3+ 4.597e-05 3.106e-05 -4.337 -4.508 -0.170 + CO3-2 3.821e-05 7.959e-06 -4.418 -5.099 -0.681 + CaCO3 2.725e-05 3.183e-05 -4.565 -4.497 0.067 + CO2 1.210e-05 1.413e-05 -4.917 -4.850 0.067 + UO2(CO3)3-4 1.255e-08 1.184e-10 -7.901 -9.927 -2.025 + UO2(CO3)2-2 1.814e-09 5.653e-10 -8.741 -9.248 -0.506 + MnCO3 2.696e-10 3.150e-10 -9.569 -9.502 0.067 + MnHCO3+ 6.077e-11 4.541e-11 -10.216 -10.343 -0.127 + UO2CO3 7.429e-12 8.678e-12 -11.129 -11.062 0.067 + FeCO3 1.952e-20 2.281e-20 -19.709 -19.642 0.067 + FeHCO3+ 1.635e-20 1.222e-20 -19.786 -19.913 -0.127 +Ca 1.066e-02 + Ca+2 9.504e-03 2.380e-03 -2.022 -2.623 -0.601 + CaSO4 1.083e-03 1.266e-03 -2.965 -2.898 0.067 + CaHCO3+ 4.597e-05 3.106e-05 -4.337 -4.508 -0.170 + CaCO3 2.725e-05 3.183e-05 -4.565 -4.497 0.067 + CaOH+ 8.604e-08 6.429e-08 -7.065 -7.192 -0.127 + CaHSO4+ 5.979e-11 4.467e-11 -10.223 -10.350 -0.127 +Cl 5.657e-01 + Cl- 5.657e-01 3.528e-01 -0.247 -0.452 -0.205 + MnCl+ 9.582e-10 7.160e-10 -9.019 -9.145 -0.127 + MnCl2 9.439e-11 1.103e-10 -10.025 -9.958 0.067 + MnCl3- 1.434e-11 1.071e-11 -10.844 -10.970 -0.127 + FeCl+2 9.557e-19 2.978e-19 -18.020 -18.526 -0.506 + FeCl2+ 6.281e-19 4.693e-19 -18.202 -18.329 -0.127 + FeCl+ 7.786e-20 5.817e-20 -19.109 -19.235 -0.127 + FeCl3 1.417e-20 1.656e-20 -19.849 -19.781 0.067 +Fe(2) 6.909e-19 + Fe+2 5.205e-19 1.195e-19 -18.284 -18.923 -0.639 + FeCl+ 7.786e-20 5.817e-20 -19.109 -19.235 -0.127 + FeSO4 4.845e-20 5.660e-20 -19.315 -19.247 0.067 + FeCO3 1.952e-20 2.281e-20 -19.709 -19.642 0.067 + FeHCO3+ 1.635e-20 1.222e-20 -19.786 -19.913 -0.127 + FeOH+ 8.227e-21 6.147e-21 -20.085 -20.211 -0.127 + FeHSO4+ 3.000e-27 2.242e-27 -26.523 -26.649 -0.127 +Fe(3) 3.711e-08 + Fe(OH)3 2.841e-08 3.318e-08 -7.547 -7.479 0.067 + Fe(OH)4- 6.591e-09 4.924e-09 -8.181 -8.308 -0.127 + Fe(OH)2+ 2.118e-09 1.583e-09 -8.674 -8.801 -0.127 + FeOH+2 9.425e-14 2.937e-14 -13.026 -13.532 -0.506 + FeSO4+ 1.093e-18 8.167e-19 -17.961 -18.088 -0.127 + FeCl+2 9.557e-19 2.978e-19 -18.020 -18.526 -0.506 + FeCl2+ 6.281e-19 4.693e-19 -18.202 -18.329 -0.127 + Fe+3 3.509e-19 2.796e-20 -18.455 -19.554 -1.099 + Fe(SO4)2- 6.372e-20 4.761e-20 -19.196 -19.322 -0.127 + FeCl3 1.417e-20 1.656e-20 -19.849 -19.781 0.067 + Fe2(OH)2+4 2.462e-24 2.322e-26 -23.609 -25.634 -2.025 + FeHSO4+2 4.228e-26 1.318e-26 -25.374 -25.880 -0.506 + Fe3(OH)4+5 1.122e-29 7.679e-33 -28.950 -32.115 -3.165 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.436 -44.369 0.067 +K 1.058e-02 + K+ 1.042e-02 6.495e-03 -1.982 -2.187 -0.205 + KSO4- 1.627e-04 1.216e-04 -3.789 -3.915 -0.127 + KOH 3.137e-09 3.665e-09 -8.503 -8.436 0.067 +Mg 5.507e-02 + Mg+2 4.742e-02 1.371e-02 -1.324 -1.863 -0.539 + MgSO4 7.330e-03 8.562e-03 -2.135 -2.067 0.067 + MgHCO3+ 2.195e-04 1.640e-04 -3.658 -3.785 -0.127 + MgCO3 8.913e-05 1.041e-04 -4.050 -3.982 0.067 + MgOH+ 1.084e-05 8.100e-06 -4.965 -5.092 -0.127 +Mn(2) 3.773e-09 + Mn+2 2.171e-09 4.982e-10 -8.663 -9.303 -0.639 + MnCl+ 9.582e-10 7.160e-10 -9.019 -9.145 -0.127 + MnCO3 2.696e-10 3.150e-10 -9.569 -9.502 0.067 + MnSO4 2.021e-10 2.360e-10 -9.695 -9.627 0.067 + MnCl2 9.439e-11 1.103e-10 -10.025 -9.958 0.067 + MnHCO3+ 6.077e-11 4.541e-11 -10.216 -10.343 -0.127 + MnCl3- 1.434e-11 1.071e-11 -10.844 -10.970 -0.127 + MnOH+ 2.789e-12 2.084e-12 -11.555 -11.681 -0.127 + Mn(NO3)2 1.375e-20 1.607e-20 -19.862 -19.794 0.067 +Mn(3) 5.993e-26 + Mn+3 5.993e-26 4.349e-27 -25.222 -26.362 -1.139 +N(-3) 1.724e-06 + NH4+ 1.609e-06 9.049e-07 -5.794 -6.043 -0.250 + NH3 7.326e-08 8.558e-08 -7.135 -7.068 0.067 + NH4SO4- 4.157e-08 3.106e-08 -7.381 -7.508 -0.127 +N(5) 4.847e-06 + NO3- 4.847e-06 2.846e-06 -5.314 -5.546 -0.231 + Mn(NO3)2 1.375e-20 1.607e-20 -19.862 -19.794 0.067 +Na 4.854e-01 + Na+ 4.791e-01 3.387e-01 -0.320 -0.470 -0.151 + NaSO4- 6.053e-03 4.523e-03 -2.218 -2.345 -0.127 + NaHCO3 1.667e-04 1.948e-04 -3.778 -3.710 0.067 + NaCO3- 6.718e-05 5.020e-05 -4.173 -4.299 -0.127 + NaOH 3.117e-07 3.641e-07 -6.506 -6.439 0.067 +O(0) 3.746e-04 + O2 1.873e-04 2.188e-04 -3.727 -3.660 0.067 +S(6) 2.926e-02 + SO4-2 1.463e-02 2.664e-03 -1.835 -2.574 -0.740 + MgSO4 7.330e-03 8.562e-03 -2.135 -2.067 0.067 + NaSO4- 6.053e-03 4.523e-03 -2.218 -2.345 -0.127 + CaSO4 1.083e-03 1.266e-03 -2.965 -2.898 0.067 + KSO4- 1.627e-04 1.216e-04 -3.789 -3.915 -0.127 + NH4SO4- 4.157e-08 3.106e-08 -7.381 -7.508 -0.127 + HSO4- 2.089e-09 1.561e-09 -8.680 -8.807 -0.127 + MnSO4 2.021e-10 2.360e-10 -9.695 -9.627 0.067 + CaHSO4+ 5.979e-11 4.467e-11 -10.223 -10.350 -0.127 + FeSO4+ 1.093e-18 8.167e-19 -17.961 -18.088 -0.127 + Fe(SO4)2- 6.372e-20 4.761e-20 -19.196 -19.322 -0.127 + FeSO4 4.845e-20 5.660e-20 -19.315 -19.247 0.067 + FeHSO4+2 4.228e-26 1.318e-26 -25.374 -25.880 -0.506 + FeHSO4+ 3.000e-27 2.242e-27 -26.523 -26.649 -0.127 +Si 7.382e-05 + H4SiO4 7.110e-05 8.306e-05 -4.148 -4.081 0.067 + H3SiO4- 2.720e-06 2.032e-06 -5.565 -5.692 -0.127 + H2SiO4-2 7.362e-11 2.294e-11 -10.133 -10.639 -0.506 +U(4) 1.034e-21 + U(OH)5- 1.034e-21 7.725e-22 -20.985 -21.112 -0.127 + U(OH)4 1.652e-25 1.930e-25 -24.782 -24.715 0.067 + U+4 0.000e+00 0.000e+00 -46.997 -49.022 -2.025 +U(5) 1.622e-18 + UO2+ 1.622e-18 1.212e-18 -17.790 -17.916 -0.127 +U(6) 1.437e-08 + UO2(CO3)3-4 1.255e-08 1.184e-10 -7.901 -9.927 -2.025 + UO2(CO3)2-2 1.814e-09 5.653e-10 -8.741 -9.248 -0.506 + UO2CO3 7.429e-12 8.678e-12 -11.129 -11.062 0.067 + UO2OH+ 3.385e-14 2.530e-14 -13.470 -13.597 -0.127 + UO2+2 3.019e-16 9.409e-17 -15.520 -16.026 -0.506 + (UO2)2(OH)2+2 1.780e-21 5.547e-22 -20.750 -21.256 -0.506 + (UO2)3(OH)5+ 2.908e-23 2.173e-23 -22.536 -22.663 -0.127 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.84 -5.20 -4.36 CaSO4 + Aragonite 0.61 -7.72 -8.34 CaCO3 + Calcite 0.76 -7.72 -8.48 CaCO3 + Chalcedony -0.51 -4.06 -3.55 SiO2 + Chrysotile 3.36 35.56 32.20 Mg3Si2O5(OH)4 + CO2(g) -3.38 -4.85 -1.47 CO2 + Dolomite 2.41 -14.68 -17.09 CaMg(CO3)2 + Fe(OH)3(a) 0.19 5.08 4.89 Fe(OH)3 + Goethite 6.09 5.09 -1.00 FeOOH + Gypsum -0.63 -5.21 -4.58 CaSO4:2H2O + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.52 -0.01 1.51 H2O + Halite -2.50 -0.92 1.58 NaCl + Hausmannite 1.57 62.60 61.03 Mn3O4 + Hematite 14.20 10.19 -4.01 Fe2O3 + Jarosite-K -7.52 -16.73 -9.21 KFe3(SO4)2(OH)6 + Manganite 2.39 27.73 25.34 MnOOH + Melanterite -19.35 -21.56 -2.21 FeSO4:7H2O + NH3(g) -8.84 -7.07 1.77 NH3 + O2(g) -0.70 -3.66 -2.96 O2 + Pyrochroite -8.08 7.12 15.20 Mn(OH)2 + Pyrolusite 6.96 48.34 41.38 MnO2 + Quartz -0.08 -4.06 -3.98 SiO2 + Rhodochrosite -3.27 -14.40 -11.13 MnCO3 + Sepiolite 1.16 16.92 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -1.74 16.92 18.66 Mg2Si3O7.5OH:3H2O + Siderite -13.13 -24.02 -10.89 FeCO3 + SiO2(a) -1.35 -4.06 -2.71 SiO2 + Talc 6.04 27.44 21.40 Mg3Si4O10(OH)2 + Uraninite -12.67 -16.16 -3.49 UO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex10.log b/Sun/examples/ex10.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex10.out b/Sun/examples/ex10.out new file mode 100644 index 00000000..3b193583 --- /dev/null +++ b/Sun/examples/ex10.out @@ -0,0 +1,9431 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex10 + Output file: ex10.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 10.--Solid solution of strontianite and aragonite. + PHASES + Strontianite + SrCO3 = CO3-2 + Sr+2 + log_k -9.271 + Aragonite + CaCO3 = CO3-2 + Ca+2 + log_k -8.336 + END +----- +TITLE +----- + + Example 10.--Solid solution of strontianite and aragonite. + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLID_SOLUTIONS 1 + Ca(x)Sr(1-x)CO3 + comp1 Aragonite 0 + comp2 Strontianite 0 + gugg_nondimensional 3.43 -1.82 + END +--------------------------------------------- +Description of Solid Solution Ca(x)Sr(1-x)CO3 +--------------------------------------------- + + Temperature: 298.15 kelvin + A0 (dimensionless): 3.43 + A1 (dimensionless): -1.82 + A0 (kJ/mol): 8.50307 + A1 (kJ/mol): -4.51183 + + Critical mole-fraction of component 2: 0.297625 + Critical temperature: 703.036 kelvin + +(The critical temperature calculation assumes that the Guggenheim model +defined at 298.15 kelvin is valid at the critical temperature.) + + + Spinodal-gap mole fractions, component 2: 0.0654427 0.619798 + Miscibility-gap fractions, component 2: 0.0048032 0.857863 + + Eutectic Point Calculations + + Aqueous activity ratio (comp2/comp1): 0.0981043 + Log aqueous activity ratio (comp2/comp1): -1.00831 + Aqueous activity fraction of component 2: 0.0893397 + Log IAP (component 2): -9.34631 + Log IAP (component 1): -8.338 + Log Sum Pi: -8.29736 + +Local minimum in the solidus curve coresponding to a maximum +in the minimum stoichiometric saturation curve. + + Solid mole fraction of component 2: 0.198353 + Log IAP (component 2): -8.91133 + Log IAP (component 1): -8.30479 + Log Sum Pi: -8.20877 +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + SOLUTION 1 + units mmol/kgw + pH 5.93 charge + Ca 3.932 + C 7.864 + EQUILIBRIUM_PHASES 1 + CO2(g) -0.01265 10 + Aragonite + SAVE solution 1 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 7.864e-03 7.864e-03 + Ca 3.932e-03 3.932e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.969 Charge balance + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.105e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 7.864e-03 + Total CO2 (mol/kg) = 7.864e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.985e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 9 + Total H = 1.110200e+02 + Total O = 5.552965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.039e-06 9.312e-07 -5.983 -6.031 -0.048 + H+ 1.181e-08 1.075e-08 -7.928 -7.969 -0.041 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -75.157 -75.156 0.001 +C(4) 7.864e-03 + HCO3- 7.325e-03 6.602e-03 -2.135 -2.180 -0.045 + CaHCO3+ 2.216e-04 1.997e-04 -3.654 -3.700 -0.045 + CO2 1.592e-04 1.596e-04 -3.798 -3.797 0.001 + CaCO3 1.145e-04 1.147e-04 -3.941 -3.940 0.001 + CO3-2 4.365e-05 2.881e-05 -4.360 -4.541 -0.181 +Ca 3.932e-03 + Ca+2 3.596e-03 2.371e-03 -2.444 -2.625 -0.181 + CaHCO3+ 2.216e-04 1.997e-04 -3.654 -3.700 -0.045 + CaCO3 1.145e-04 1.147e-04 -3.941 -3.940 0.001 + CaOH+ 4.077e-08 3.661e-08 -7.390 -7.436 -0.047 +H(0) 1.632e-27 + H2 8.158e-28 8.179e-28 -27.088 -27.087 0.001 +O(0) 1.243e-38 + O2 6.213e-39 6.229e-39 -38.207 -38.206 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 1.17 -7.17 -8.34 CaCO3 + Calcite 1.31 -7.17 -8.48 CaCO3 + CH4(g) -72.30 -75.16 -2.86 CH4 + CO2(g) -2.33 -3.80 -1.47 CO2 + H2(g) -23.94 -27.09 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -35.25 -38.21 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Aragonite 0.00 -8.34 -8.34 1.000e+01 9.993e+00 -6.605e-03 + CO2(g) -0.01 -18.16 -18.15 1.000e+01 9.961e+00 -3.944e-02 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.392e-02 5.391e-02 + Ca 1.054e-02 1.054e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.063 Charge balance + pe = 11.813 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 2.906e-02 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 2.108e-02 + Total CO2 (mol/kg) = 5.392e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.292e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 10 + Total H = 1.110200e+02 + Total O = 5.562835e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.885e-07 8.654e-07 -6.005 -6.063 -0.058 + OH- 1.366e-08 1.155e-08 -7.865 -7.937 -0.073 + H2O 5.551e+01 9.989e-01 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -120.096 -120.093 0.003 +C(4) 5.392e-02 + CO2 3.285e-02 3.307e-02 -1.483 -1.481 0.003 + HCO3- 1.979e-02 1.698e-02 -1.703 -1.770 -0.067 + CaHCO3+ 1.266e-03 1.086e-03 -2.897 -2.964 -0.067 + CaCO3 7.698e-06 7.750e-06 -5.114 -5.111 0.003 + CO3-2 1.700e-06 9.199e-07 -5.770 -6.036 -0.267 +Ca 1.054e-02 + Ca+2 9.265e-03 5.015e-03 -2.033 -2.300 -0.267 + CaHCO3+ 1.266e-03 1.086e-03 -2.897 -2.964 -0.067 + CaCO3 7.698e-06 7.750e-06 -5.114 -5.111 0.003 + CaOH+ 1.128e-09 9.606e-10 -8.948 -9.017 -0.070 +H(0) 2.496e-39 + H2 1.248e-39 1.257e-39 -38.904 -38.901 0.003 +O(0) 5.234e-15 + O2 2.617e-15 2.635e-15 -14.582 -14.579 0.003 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.00 -8.34 -8.34 CaCO3 + Calcite 0.14 -8.34 -8.48 CaCO3 + CH4(g) -117.23 -120.09 -2.86 CH4 + CO2(g) -0.01 -1.48 -1.47 CO2 + H2(g) -35.75 -38.90 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -11.62 -14.58 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + USE solution 1 + USE solid_solution 1 + REACTION 1 + SrCO3 1.0 + .005 in 500 steps + PRINT + reset false + user_print true + USER_PRINT + start + 10 sum = (S_S("Strontianite") + S_S("Aragonite")) + 20 if sum = 0 THEN GOTO 110 + 30 xb = S_S("Strontianite")/sum + 40 xc = S_S("Aragonite")/sum + 50 PRINT "Simulation number: ", SIM_NO + 60 PRINT "Reaction step number: ", STEP_NO + 70 PRINT "SrCO3 added: ", RXN + 80 PRINT "Log Sigma pi: ", LOG10 (ACT("CO3-2") * (ACT("Ca+2") + ACT("Sr+2"))) + 90 PRINT "XAragonite: ", xc + 100 PRINT "XStrontianite: ", xb + 110 PRINT "XCa: ", TOT("Ca")/(TOT("Ca") + TOT("Sr")) + 120 PRINT "XSr: ", TOT("Sr")/(TOT("Ca") + TOT("Sr")) + 130 PRINT "Misc 1: ", MISC1("Ca(x)Sr(1-x)CO3") + 140 PRINT "Misc 2: ", MISC2("Ca(x)Sr(1-x)CO3") + end + SELECTED_OUTPUT + file ex10.sel + reset false + reaction true + USER_PUNCH + heading lg_SigmaPi X_Arag X_Stront X_Ca_aq X_Sr_aq mol_Misc1 mol_Misc2 mol_Arag mol_Stront + start + 10 sum = (S_S("Strontianite") + S_S("Aragonite")) + 20 if sum = 0 THEN GOTO 60 + 30 xb = S_S("Strontianite")/(S_S("Strontianite") + S_S("Aragonite")) + 40 xc = S_S("Aragonite")/(S_S("Strontianite") + S_S("Aragonite")) + 50 REM Sigma Pi + 60 PUNCH LOG10(ACT("CO3-2") * (ACT("Ca+2") + ACT("Sr+2"))) + 70 PUNCH xc # Mole fraction aragonite + 80 PUNCH xb # Mole fraction strontianite + 90 PUNCH TOT("Ca")/(TOT("Ca") + TOT("Sr")) # Mole aqueous calcium + 100 PUNCH TOT("Sr")/(TOT("Ca") + TOT("Sr")) # Mole aqueous strontium + 110 x1 = MISC1("Ca(x)Sr(1-x)CO3") + 120 x2 = MISC2("Ca(x)Sr(1-x)CO3") + 130 if (xb < x1 OR xb > x2) THEN GOTO 250 + 140 nc = S_S("Aragonite") + 150 nb = S_S("Strontianite") + 160 mol2 = ((x1 - 1)/x1)*nb + nc + 170 mol2 = mol2 / ( ((x1 -1)/x1)*x2 + (1 - x2)) + 180 mol1 = (nb - mol2*x2)/x1 + 190 REM # Moles of misc. end members if in gap + 200 PUNCH mol1 + 210 PUNCH mol2 + 220 GOTO 300 + 250 REM # Moles of misc. end members if not in gap + 260 PUNCH 1e-10 + 270 PUNCH 1e-10 + 300 PUNCH S_S("Aragonite") # Moles aragonite + 310 PUNCH S_S("Strontianite") # Moles Strontianite + end + END +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 1 +SrCO3 added: 1.0000e-05 +Log Sigma pi: -8.3356e+00 +XAragonite: 9.9996e-01 +XStrontianite: 4.2096e-05 +XCa: 9.9905e-01 +XSr: 9.4867e-04 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 2 +SrCO3 added: 2.0000e-05 +Log Sigma pi: -8.3352e+00 +XAragonite: 9.9992e-01 +XStrontianite: 8.4301e-05 +XCa: 9.9810e-01 +XSr: 1.8967e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 3 +SrCO3 added: 3.0000e-05 +Log Sigma pi: -8.3348e+00 +XAragonite: 9.9987e-01 +XStrontianite: 1.2662e-04 +XCa: 9.9716e-01 +XSr: 2.8440e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 4 +SrCO3 added: 4.0000e-05 +Log Sigma pi: -8.3345e+00 +XAragonite: 9.9983e-01 +XStrontianite: 1.6904e-04 +XCa: 9.9621e-01 +XSr: 3.7906e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 5 +SrCO3 added: 5.0000e-05 +Log Sigma pi: -8.3341e+00 +XAragonite: 9.9979e-01 +XStrontianite: 2.1158e-04 +XCa: 9.9526e-01 +XSr: 4.7366e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 6 +SrCO3 added: 6.0000e-05 +Log Sigma pi: -8.3337e+00 +XAragonite: 9.9975e-01 +XStrontianite: 2.5422e-04 +XCa: 9.9432e-01 +XSr: 5.6819e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 7 +SrCO3 added: 7.0000e-05 +Log Sigma pi: -8.3333e+00 +XAragonite: 9.9970e-01 +XStrontianite: 2.9698e-04 +XCa: 9.9337e-01 +XSr: 6.6265e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 8 +SrCO3 added: 8.0000e-05 +Log Sigma pi: -8.3329e+00 +XAragonite: 9.9966e-01 +XStrontianite: 3.3985e-04 +XCa: 9.9243e-01 +XSr: 7.5705e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 9 +SrCO3 added: 9.0000e-05 +Log Sigma pi: -8.3325e+00 +XAragonite: 9.9962e-01 +XStrontianite: 3.8284e-04 +XCa: 9.9149e-01 +XSr: 8.5137e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 10 +SrCO3 added: 1.0000e-04 +Log Sigma pi: -8.3321e+00 +XAragonite: 9.9957e-01 +XStrontianite: 4.2593e-04 +XCa: 9.9054e-01 +XSr: 9.4563e-03 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 11 +SrCO3 added: 1.1000e-04 +Log Sigma pi: -8.3318e+00 +XAragonite: 9.9953e-01 +XStrontianite: 4.6914e-04 +XCa: 9.8960e-01 +XSr: 1.0398e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 12 +SrCO3 added: 1.2000e-04 +Log Sigma pi: -8.3314e+00 +XAragonite: 9.9949e-01 +XStrontianite: 5.1247e-04 +XCa: 9.8866e-01 +XSr: 1.1340e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 13 +SrCO3 added: 1.3000e-04 +Log Sigma pi: -8.3310e+00 +XAragonite: 9.9944e-01 +XStrontianite: 5.5591e-04 +XCa: 9.8772e-01 +XSr: 1.2280e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 14 +SrCO3 added: 1.4000e-04 +Log Sigma pi: -8.3306e+00 +XAragonite: 9.9940e-01 +XStrontianite: 5.9946e-04 +XCa: 9.8678e-01 +XSr: 1.3220e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 15 +SrCO3 added: 1.5000e-04 +Log Sigma pi: -8.3302e+00 +XAragonite: 9.9936e-01 +XStrontianite: 6.4313e-04 +XCa: 9.8584e-01 +XSr: 1.4159e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 16 +SrCO3 added: 1.6000e-04 +Log Sigma pi: -8.3298e+00 +XAragonite: 9.9931e-01 +XStrontianite: 6.8692e-04 +XCa: 9.8490e-01 +XSr: 1.5098e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 17 +SrCO3 added: 1.7000e-04 +Log Sigma pi: -8.3294e+00 +XAragonite: 9.9927e-01 +XStrontianite: 7.3082e-04 +XCa: 9.8396e-01 +XSr: 1.6036e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 18 +SrCO3 added: 1.8000e-04 +Log Sigma pi: -8.3290e+00 +XAragonite: 9.9923e-01 +XStrontianite: 7.7484e-04 +XCa: 9.8303e-01 +XSr: 1.6973e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 19 +SrCO3 added: 1.9000e-04 +Log Sigma pi: -8.3287e+00 +XAragonite: 9.9918e-01 +XStrontianite: 8.1897e-04 +XCa: 9.8209e-01 +XSr: 1.7909e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 20 +SrCO3 added: 2.0000e-04 +Log Sigma pi: -8.3283e+00 +XAragonite: 9.9914e-01 +XStrontianite: 8.6323e-04 +XCa: 9.8115e-01 +XSr: 1.8845e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 21 +SrCO3 added: 2.1000e-04 +Log Sigma pi: -8.3279e+00 +XAragonite: 9.9909e-01 +XStrontianite: 9.0760e-04 +XCa: 9.8022e-01 +XSr: 1.9780e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 22 +SrCO3 added: 2.2000e-04 +Log Sigma pi: -8.3275e+00 +XAragonite: 9.9905e-01 +XStrontianite: 9.5209e-04 +XCa: 9.7929e-01 +XSr: 2.0715e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 23 +SrCO3 added: 2.3000e-04 +Log Sigma pi: -8.3271e+00 +XAragonite: 9.9900e-01 +XStrontianite: 9.9670e-04 +XCa: 9.7835e-01 +XSr: 2.1649e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 24 +SrCO3 added: 2.4000e-04 +Log Sigma pi: -8.3267e+00 +XAragonite: 9.9896e-01 +XStrontianite: 1.0414e-03 +XCa: 9.7742e-01 +XSr: 2.2582e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 25 +SrCO3 added: 2.5000e-04 +Log Sigma pi: -8.3263e+00 +XAragonite: 9.9891e-01 +XStrontianite: 1.0863e-03 +XCa: 9.7649e-01 +XSr: 2.3514e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 26 +SrCO3 added: 2.6000e-04 +Log Sigma pi: -8.3259e+00 +XAragonite: 9.9887e-01 +XStrontianite: 1.1313e-03 +XCa: 9.7555e-01 +XSr: 2.4446e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 27 +SrCO3 added: 2.7000e-04 +Log Sigma pi: -8.3256e+00 +XAragonite: 9.9882e-01 +XStrontianite: 1.1764e-03 +XCa: 9.7462e-01 +XSr: 2.5377e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 28 +SrCO3 added: 2.8000e-04 +Log Sigma pi: -8.3252e+00 +XAragonite: 9.9878e-01 +XStrontianite: 1.2216e-03 +XCa: 9.7369e-01 +XSr: 2.6308e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 29 +SrCO3 added: 2.9000e-04 +Log Sigma pi: -8.3248e+00 +XAragonite: 9.9873e-01 +XStrontianite: 1.2669e-03 +XCa: 9.7276e-01 +XSr: 2.7238e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 30 +SrCO3 added: 3.0000e-04 +Log Sigma pi: -8.3244e+00 +XAragonite: 9.9869e-01 +XStrontianite: 1.3124e-03 +XCa: 9.7183e-01 +XSr: 2.8167e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 31 +SrCO3 added: 3.1000e-04 +Log Sigma pi: -8.3240e+00 +XAragonite: 9.9864e-01 +XStrontianite: 1.3580e-03 +XCa: 9.7090e-01 +XSr: 2.9095e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 32 +SrCO3 added: 3.2000e-04 +Log Sigma pi: -8.3236e+00 +XAragonite: 9.9860e-01 +XStrontianite: 1.4037e-03 +XCa: 9.6998e-01 +XSr: 3.0023e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 33 +SrCO3 added: 3.3000e-04 +Log Sigma pi: -8.3232e+00 +XAragonite: 9.9855e-01 +XStrontianite: 1.4495e-03 +XCa: 9.6905e-01 +XSr: 3.0950e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 34 +SrCO3 added: 3.4000e-04 +Log Sigma pi: -8.3228e+00 +XAragonite: 9.9850e-01 +XStrontianite: 1.4955e-03 +XCa: 9.6812e-01 +XSr: 3.1877e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 35 +SrCO3 added: 3.5000e-04 +Log Sigma pi: -8.3225e+00 +XAragonite: 9.9846e-01 +XStrontianite: 1.5416e-03 +XCa: 9.6720e-01 +XSr: 3.2802e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 36 +SrCO3 added: 3.6000e-04 +Log Sigma pi: -8.3221e+00 +XAragonite: 9.9841e-01 +XStrontianite: 1.5878e-03 +XCa: 9.6627e-01 +XSr: 3.3727e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 37 +SrCO3 added: 3.7000e-04 +Log Sigma pi: -8.3217e+00 +XAragonite: 9.9837e-01 +XStrontianite: 1.6341e-03 +XCa: 9.6535e-01 +XSr: 3.4652e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 38 +SrCO3 added: 3.8000e-04 +Log Sigma pi: -8.3213e+00 +XAragonite: 9.9832e-01 +XStrontianite: 1.6806e-03 +XCa: 9.6442e-01 +XSr: 3.5576e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 39 +SrCO3 added: 3.9000e-04 +Log Sigma pi: -8.3209e+00 +XAragonite: 9.9827e-01 +XStrontianite: 1.7272e-03 +XCa: 9.6350e-01 +XSr: 3.6499e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 40 +SrCO3 added: 4.0000e-04 +Log Sigma pi: -8.3205e+00 +XAragonite: 9.9823e-01 +XStrontianite: 1.7739e-03 +XCa: 9.6258e-01 +XSr: 3.7421e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 41 +SrCO3 added: 4.1000e-04 +Log Sigma pi: -8.3201e+00 +XAragonite: 9.9818e-01 +XStrontianite: 1.8208e-03 +XCa: 9.6166e-01 +XSr: 3.8343e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 42 +SrCO3 added: 4.2000e-04 +Log Sigma pi: -8.3197e+00 +XAragonite: 9.9813e-01 +XStrontianite: 1.8677e-03 +XCa: 9.6074e-01 +XSr: 3.9264e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 43 +SrCO3 added: 4.3000e-04 +Log Sigma pi: -8.3193e+00 +XAragonite: 9.9809e-01 +XStrontianite: 1.9149e-03 +XCa: 9.5982e-01 +XSr: 4.0184e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 44 +SrCO3 added: 4.4000e-04 +Log Sigma pi: -8.3190e+00 +XAragonite: 9.9804e-01 +XStrontianite: 1.9621e-03 +XCa: 9.5890e-01 +XSr: 4.1104e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 45 +SrCO3 added: 4.5000e-04 +Log Sigma pi: -8.3186e+00 +XAragonite: 9.9799e-01 +XStrontianite: 2.0095e-03 +XCa: 9.5798e-01 +XSr: 4.2023e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 46 +SrCO3 added: 4.6000e-04 +Log Sigma pi: -8.3182e+00 +XAragonite: 9.9794e-01 +XStrontianite: 2.0570e-03 +XCa: 9.5706e-01 +XSr: 4.2941e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 47 +SrCO3 added: 4.7000e-04 +Log Sigma pi: -8.3178e+00 +XAragonite: 9.9790e-01 +XStrontianite: 2.1046e-03 +XCa: 9.5614e-01 +XSr: 4.3859e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 48 +SrCO3 added: 4.8000e-04 +Log Sigma pi: -8.3174e+00 +XAragonite: 9.9785e-01 +XStrontianite: 2.1524e-03 +XCa: 9.5522e-01 +XSr: 4.4776e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 49 +SrCO3 added: 4.9000e-04 +Log Sigma pi: -8.3170e+00 +XAragonite: 9.9780e-01 +XStrontianite: 2.2003e-03 +XCa: 9.5431e-01 +XSr: 4.5692e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 50 +SrCO3 added: 5.0000e-04 +Log Sigma pi: -8.3166e+00 +XAragonite: 9.9775e-01 +XStrontianite: 2.2484e-03 +XCa: 9.5339e-01 +XSr: 4.6608e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 51 +SrCO3 added: 5.1000e-04 +Log Sigma pi: -8.3162e+00 +XAragonite: 9.9770e-01 +XStrontianite: 2.2966e-03 +XCa: 9.5248e-01 +XSr: 4.7523e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 52 +SrCO3 added: 5.2000e-04 +Log Sigma pi: -8.3159e+00 +XAragonite: 9.9766e-01 +XStrontianite: 2.3449e-03 +XCa: 9.5156e-01 +XSr: 4.8437e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 53 +SrCO3 added: 5.3000e-04 +Log Sigma pi: -8.3155e+00 +XAragonite: 9.9761e-01 +XStrontianite: 2.3933e-03 +XCa: 9.5065e-01 +XSr: 4.9351e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 54 +SrCO3 added: 5.4000e-04 +Log Sigma pi: -8.3151e+00 +XAragonite: 9.9756e-01 +XStrontianite: 2.4419e-03 +XCa: 9.4974e-01 +XSr: 5.0264e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 55 +SrCO3 added: 5.5000e-04 +Log Sigma pi: -8.3147e+00 +XAragonite: 9.9751e-01 +XStrontianite: 2.4907e-03 +XCa: 9.4882e-01 +XSr: 5.1176e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 56 +SrCO3 added: 5.6000e-04 +Log Sigma pi: -8.3143e+00 +XAragonite: 9.9746e-01 +XStrontianite: 2.5395e-03 +XCa: 9.4791e-01 +XSr: 5.2088e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 57 +SrCO3 added: 5.7000e-04 +Log Sigma pi: -8.3139e+00 +XAragonite: 9.9741e-01 +XStrontianite: 2.5885e-03 +XCa: 9.4700e-01 +XSr: 5.2999e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 58 +SrCO3 added: 5.8000e-04 +Log Sigma pi: -8.3135e+00 +XAragonite: 9.9736e-01 +XStrontianite: 2.6377e-03 +XCa: 9.4609e-01 +XSr: 5.3909e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 59 +SrCO3 added: 5.9000e-04 +Log Sigma pi: -8.3131e+00 +XAragonite: 9.9731e-01 +XStrontianite: 2.6870e-03 +XCa: 9.4518e-01 +XSr: 5.4819e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 60 +SrCO3 added: 6.0000e-04 +Log Sigma pi: -8.3127e+00 +XAragonite: 9.9726e-01 +XStrontianite: 2.7364e-03 +XCa: 9.4427e-01 +XSr: 5.5728e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 61 +SrCO3 added: 6.1000e-04 +Log Sigma pi: -8.3123e+00 +XAragonite: 9.9721e-01 +XStrontianite: 2.7860e-03 +XCa: 9.4336e-01 +XSr: 5.6636e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 62 +SrCO3 added: 6.2000e-04 +Log Sigma pi: -8.3120e+00 +XAragonite: 9.9716e-01 +XStrontianite: 2.8357e-03 +XCa: 9.4246e-01 +XSr: 5.7544e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 63 +SrCO3 added: 6.3000e-04 +Log Sigma pi: -8.3116e+00 +XAragonite: 9.9711e-01 +XStrontianite: 2.8856e-03 +XCa: 9.4155e-01 +XSr: 5.8451e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 64 +SrCO3 added: 6.4000e-04 +Log Sigma pi: -8.3112e+00 +XAragonite: 9.9706e-01 +XStrontianite: 2.9356e-03 +XCa: 9.4064e-01 +XSr: 5.9357e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 65 +SrCO3 added: 6.5000e-04 +Log Sigma pi: -8.3108e+00 +XAragonite: 9.9701e-01 +XStrontianite: 2.9857e-03 +XCa: 9.3974e-01 +XSr: 6.0263e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 66 +SrCO3 added: 6.6000e-04 +Log Sigma pi: -8.3104e+00 +XAragonite: 9.9696e-01 +XStrontianite: 3.0360e-03 +XCa: 9.3883e-01 +XSr: 6.1167e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 67 +SrCO3 added: 6.7000e-04 +Log Sigma pi: -8.3100e+00 +XAragonite: 9.9691e-01 +XStrontianite: 3.0864e-03 +XCa: 9.3793e-01 +XSr: 6.2072e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 68 +SrCO3 added: 6.8000e-04 +Log Sigma pi: -8.3096e+00 +XAragonite: 9.9686e-01 +XStrontianite: 3.1370e-03 +XCa: 9.3702e-01 +XSr: 6.2975e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 69 +SrCO3 added: 6.9000e-04 +Log Sigma pi: -8.3092e+00 +XAragonite: 9.9681e-01 +XStrontianite: 3.1878e-03 +XCa: 9.3612e-01 +XSr: 6.3878e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 70 +SrCO3 added: 7.0000e-04 +Log Sigma pi: -8.3088e+00 +XAragonite: 9.9676e-01 +XStrontianite: 3.2386e-03 +XCa: 9.3522e-01 +XSr: 6.4780e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 71 +SrCO3 added: 7.1000e-04 +Log Sigma pi: -8.3084e+00 +XAragonite: 9.9671e-01 +XStrontianite: 3.2897e-03 +XCa: 9.3432e-01 +XSr: 6.5682e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 72 +SrCO3 added: 7.2000e-04 +Log Sigma pi: -8.3081e+00 +XAragonite: 9.9666e-01 +XStrontianite: 3.3409e-03 +XCa: 9.3342e-01 +XSr: 6.6583e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 73 +SrCO3 added: 7.3000e-04 +Log Sigma pi: -8.3077e+00 +XAragonite: 9.9661e-01 +XStrontianite: 3.3922e-03 +XCa: 9.3252e-01 +XSr: 6.7483e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 74 +SrCO3 added: 7.4000e-04 +Log Sigma pi: -8.3073e+00 +XAragonite: 9.9656e-01 +XStrontianite: 3.4437e-03 +XCa: 9.3162e-01 +XSr: 6.8383e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 75 +SrCO3 added: 7.5000e-04 +Log Sigma pi: -8.3069e+00 +XAragonite: 9.9650e-01 +XStrontianite: 3.4953e-03 +XCa: 9.3072e-01 +XSr: 6.9282e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 76 +SrCO3 added: 7.6000e-04 +Log Sigma pi: -8.3065e+00 +XAragonite: 9.9645e-01 +XStrontianite: 3.5471e-03 +XCa: 9.2982e-01 +XSr: 7.0180e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 77 +SrCO3 added: 7.7000e-04 +Log Sigma pi: -8.3061e+00 +XAragonite: 9.9640e-01 +XStrontianite: 3.5990e-03 +XCa: 9.2892e-01 +XSr: 7.1077e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 78 +SrCO3 added: 7.8000e-04 +Log Sigma pi: -8.3057e+00 +XAragonite: 9.9635e-01 +XStrontianite: 3.6511e-03 +XCa: 9.2803e-01 +XSr: 7.1974e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 79 +SrCO3 added: 7.9000e-04 +Log Sigma pi: -8.3053e+00 +XAragonite: 9.9630e-01 +XStrontianite: 3.7034e-03 +XCa: 9.2713e-01 +XSr: 7.2870e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 80 +SrCO3 added: 8.0000e-04 +Log Sigma pi: -8.3049e+00 +XAragonite: 9.9624e-01 +XStrontianite: 3.7558e-03 +XCa: 9.2623e-01 +XSr: 7.3766e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 81 +SrCO3 added: 8.1000e-04 +Log Sigma pi: -8.3045e+00 +XAragonite: 9.9619e-01 +XStrontianite: 3.8083e-03 +XCa: 9.2534e-01 +XSr: 7.4661e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 82 +SrCO3 added: 8.2000e-04 +Log Sigma pi: -8.3042e+00 +XAragonite: 9.9614e-01 +XStrontianite: 3.8611e-03 +XCa: 9.2445e-01 +XSr: 7.5555e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 83 +SrCO3 added: 8.3000e-04 +Log Sigma pi: -8.3038e+00 +XAragonite: 9.9609e-01 +XStrontianite: 3.9139e-03 +XCa: 9.2355e-01 +XSr: 7.6448e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 84 +SrCO3 added: 8.4000e-04 +Log Sigma pi: -8.3034e+00 +XAragonite: 9.9603e-01 +XStrontianite: 3.9670e-03 +XCa: 9.2266e-01 +XSr: 7.7341e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 85 +SrCO3 added: 8.5000e-04 +Log Sigma pi: -8.3030e+00 +XAragonite: 9.9598e-01 +XStrontianite: 4.0202e-03 +XCa: 9.2177e-01 +XSr: 7.8233e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 86 +SrCO3 added: 8.6000e-04 +Log Sigma pi: -8.3026e+00 +XAragonite: 9.9593e-01 +XStrontianite: 4.0735e-03 +XCa: 9.2088e-01 +XSr: 7.9125e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 87 +SrCO3 added: 8.7000e-04 +Log Sigma pi: -8.3022e+00 +XAragonite: 9.9587e-01 +XStrontianite: 4.1270e-03 +XCa: 9.1998e-01 +XSr: 8.0016e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 88 +SrCO3 added: 8.8000e-04 +Log Sigma pi: -8.3018e+00 +XAragonite: 9.9582e-01 +XStrontianite: 4.1807e-03 +XCa: 9.1909e-01 +XSr: 8.0906e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 89 +SrCO3 added: 8.9000e-04 +Log Sigma pi: -8.3014e+00 +XAragonite: 9.9577e-01 +XStrontianite: 4.2346e-03 +XCa: 9.1820e-01 +XSr: 8.1795e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 90 +SrCO3 added: 9.0000e-04 +Log Sigma pi: -8.3010e+00 +XAragonite: 9.9571e-01 +XStrontianite: 4.2886e-03 +XCa: 9.1732e-01 +XSr: 8.2684e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 91 +SrCO3 added: 9.1000e-04 +Log Sigma pi: -8.3006e+00 +XAragonite: 9.9566e-01 +XStrontianite: 4.3427e-03 +XCa: 9.1643e-01 +XSr: 8.3572e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 92 +SrCO3 added: 9.2000e-04 +Log Sigma pi: -8.3002e+00 +XAragonite: 9.9560e-01 +XStrontianite: 4.3971e-03 +XCa: 9.1554e-01 +XSr: 8.4460e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 93 +SrCO3 added: 9.3000e-04 +Log Sigma pi: -8.2999e+00 +XAragonite: 9.9555e-01 +XStrontianite: 4.4516e-03 +XCa: 9.1465e-01 +XSr: 8.5347e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 94 +SrCO3 added: 9.4000e-04 +Log Sigma pi: -8.2995e+00 +XAragonite: 9.9549e-01 +XStrontianite: 4.5062e-03 +XCa: 9.1377e-01 +XSr: 8.6233e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 95 +SrCO3 added: 9.5000e-04 +Log Sigma pi: -8.2991e+00 +XAragonite: 9.9544e-01 +XStrontianite: 4.5611e-03 +XCa: 9.1288e-01 +XSr: 8.7118e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 96 +SrCO3 added: 9.6000e-04 +Log Sigma pi: -8.2987e+00 +XAragonite: 9.9538e-01 +XStrontianite: 4.6161e-03 +XCa: 9.1200e-01 +XSr: 8.8003e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 97 +SrCO3 added: 9.7000e-04 +Log Sigma pi: -8.2983e+00 +XAragonite: 9.9533e-01 +XStrontianite: 4.6713e-03 +XCa: 9.1111e-01 +XSr: 8.8887e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 98 +SrCO3 added: 9.8000e-04 +Log Sigma pi: -8.2979e+00 +XAragonite: 9.9527e-01 +XStrontianite: 4.7266e-03 +XCa: 9.1023e-01 +XSr: 8.9770e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 99 +SrCO3 added: 9.9000e-04 +Log Sigma pi: -8.2975e+00 +XAragonite: 9.9522e-01 +XStrontianite: 4.7821e-03 +XCa: 9.0935e-01 +XSr: 9.0653e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 100 +SrCO3 added: 1.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.8567e-01 +XStrontianite: 1.4329e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 101 +SrCO3 added: 1.0100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.7071e-01 +XStrontianite: 2.9286e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 102 +SrCO3 added: 1.0200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.5620e-01 +XStrontianite: 4.3796e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 103 +SrCO3 added: 1.0300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.4212e-01 +XStrontianite: 5.7879e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 104 +SrCO3 added: 1.0400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.2845e-01 +XStrontianite: 7.1552e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 105 +SrCO3 added: 1.0500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.1516e-01 +XStrontianite: 8.4835e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 106 +SrCO3 added: 1.0600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.0226e-01 +XStrontianite: 9.7743e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 107 +SrCO3 added: 1.0700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.8971e-01 +XStrontianite: 1.1029e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 108 +SrCO3 added: 1.0800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.7750e-01 +XStrontianite: 1.2250e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 109 +SrCO3 added: 1.0900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.6563e-01 +XStrontianite: 1.3437e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 110 +SrCO3 added: 1.1000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.5407e-01 +XStrontianite: 1.4593e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 111 +SrCO3 added: 1.1100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.4282e-01 +XStrontianite: 1.5718e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 112 +SrCO3 added: 1.1200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.3186e-01 +XStrontianite: 1.6814e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 113 +SrCO3 added: 1.1300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.2118e-01 +XStrontianite: 1.7882e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 114 +SrCO3 added: 1.1400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.1077e-01 +XStrontianite: 1.8923e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 115 +SrCO3 added: 1.1500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 8.0063e-01 +XStrontianite: 1.9937e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 116 +SrCO3 added: 1.1600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.9073e-01 +XStrontianite: 2.0927e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 117 +SrCO3 added: 1.1700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.8107e-01 +XStrontianite: 2.1893e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 118 +SrCO3 added: 1.1800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.7165e-01 +XStrontianite: 2.2835e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 119 +SrCO3 added: 1.1900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.6246e-01 +XStrontianite: 2.3754e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 120 +SrCO3 added: 1.2000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.5348e-01 +XStrontianite: 2.4652e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 121 +SrCO3 added: 1.2100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.4470e-01 +XStrontianite: 2.5530e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 122 +SrCO3 added: 1.2200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.3613e-01 +XStrontianite: 2.6387e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 123 +SrCO3 added: 1.2300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.2776e-01 +XStrontianite: 2.7224e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 124 +SrCO3 added: 1.2400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.1957e-01 +XStrontianite: 2.8043e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 125 +SrCO3 added: 1.2500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.1157e-01 +XStrontianite: 2.8843e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 126 +SrCO3 added: 1.2600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 7.0374e-01 +XStrontianite: 2.9626e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 127 +SrCO3 added: 1.2700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.9608e-01 +XStrontianite: 3.0392e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 128 +SrCO3 added: 1.2800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.8859e-01 +XStrontianite: 3.1141e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 129 +SrCO3 added: 1.2900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.8126e-01 +XStrontianite: 3.1874e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 130 +SrCO3 added: 1.3000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.7408e-01 +XStrontianite: 3.2592e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 131 +SrCO3 added: 1.3100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.6705e-01 +XStrontianite: 3.3295e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 132 +SrCO3 added: 1.3200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.6017e-01 +XStrontianite: 3.3983e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 133 +SrCO3 added: 1.3300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.5342e-01 +XStrontianite: 3.4658e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 134 +SrCO3 added: 1.3400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.4682e-01 +XStrontianite: 3.5318e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 135 +SrCO3 added: 1.3500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.4034e-01 +XStrontianite: 3.5966e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 136 +SrCO3 added: 1.3600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.3399e-01 +XStrontianite: 3.6601e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 137 +SrCO3 added: 1.3700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.2777e-01 +XStrontianite: 3.7223e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 138 +SrCO3 added: 1.3800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.2167e-01 +XStrontianite: 3.7833e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 139 +SrCO3 added: 1.3900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.1569e-01 +XStrontianite: 3.8431e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 140 +SrCO3 added: 1.4000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.0982e-01 +XStrontianite: 3.9018e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 141 +SrCO3 added: 1.4100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 6.0406e-01 +XStrontianite: 3.9594e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 142 +SrCO3 added: 1.4200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.9841e-01 +XStrontianite: 4.0159e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 143 +SrCO3 added: 1.4300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.9286e-01 +XStrontianite: 4.0714e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 144 +SrCO3 added: 1.4400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.8742e-01 +XStrontianite: 4.1258e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 145 +SrCO3 added: 1.4500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.8207e-01 +XStrontianite: 4.1793e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 146 +SrCO3 added: 1.4600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.7683e-01 +XStrontianite: 4.2317e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 147 +SrCO3 added: 1.4700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.7167e-01 +XStrontianite: 4.2833e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 148 +SrCO3 added: 1.4800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.6661e-01 +XStrontianite: 4.3339e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 149 +SrCO3 added: 1.4900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.6163e-01 +XStrontianite: 4.3837e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 150 +SrCO3 added: 1.5000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.5675e-01 +XStrontianite: 4.4325e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 151 +SrCO3 added: 1.5100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.5194e-01 +XStrontianite: 4.4806e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 152 +SrCO3 added: 1.5200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.4722e-01 +XStrontianite: 4.5278e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 153 +SrCO3 added: 1.5300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.4258e-01 +XStrontianite: 4.5742e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 154 +SrCO3 added: 1.5400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.3802e-01 +XStrontianite: 4.6198e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 155 +SrCO3 added: 1.5500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.3353e-01 +XStrontianite: 4.6647e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 156 +SrCO3 added: 1.5600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.2912e-01 +XStrontianite: 4.7088e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 157 +SrCO3 added: 1.5700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.2477e-01 +XStrontianite: 4.7523e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 158 +SrCO3 added: 1.5800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.2050e-01 +XStrontianite: 4.7950e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 159 +SrCO3 added: 1.5900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.1630e-01 +XStrontianite: 4.8370e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 160 +SrCO3 added: 1.6000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.1217e-01 +XStrontianite: 4.8783e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 161 +SrCO3 added: 1.6100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.0810e-01 +XStrontianite: 4.9190e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 162 +SrCO3 added: 1.6200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.0410e-01 +XStrontianite: 4.9590e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 163 +SrCO3 added: 1.6300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 5.0016e-01 +XStrontianite: 4.9984e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 164 +SrCO3 added: 1.6400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.9628e-01 +XStrontianite: 5.0372e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 165 +SrCO3 added: 1.6500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.9246e-01 +XStrontianite: 5.0754e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 166 +SrCO3 added: 1.6600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.8869e-01 +XStrontianite: 5.1131e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 167 +SrCO3 added: 1.6700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.8499e-01 +XStrontianite: 5.1501e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 168 +SrCO3 added: 1.6800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.8134e-01 +XStrontianite: 5.1866e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 169 +SrCO3 added: 1.6900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.7774e-01 +XStrontianite: 5.2226e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 170 +SrCO3 added: 1.7000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.7420e-01 +XStrontianite: 5.2580e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 171 +SrCO3 added: 1.7100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.7071e-01 +XStrontianite: 5.2929e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 172 +SrCO3 added: 1.7200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.6728e-01 +XStrontianite: 5.3272e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 173 +SrCO3 added: 1.7300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.6389e-01 +XStrontianite: 5.3611e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 174 +SrCO3 added: 1.7400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.6055e-01 +XStrontianite: 5.3945e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 175 +SrCO3 added: 1.7500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.5726e-01 +XStrontianite: 5.4274e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 176 +SrCO3 added: 1.7600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.5401e-01 +XStrontianite: 5.4599e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 177 +SrCO3 added: 1.7700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.5081e-01 +XStrontianite: 5.4919e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 178 +SrCO3 added: 1.7800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.4766e-01 +XStrontianite: 5.5234e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 179 +SrCO3 added: 1.7900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.4455e-01 +XStrontianite: 5.5545e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 180 +SrCO3 added: 1.8000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.4148e-01 +XStrontianite: 5.5852e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 181 +SrCO3 added: 1.8100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.3845e-01 +XStrontianite: 5.6155e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 182 +SrCO3 added: 1.8200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.3547e-01 +XStrontianite: 5.6453e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 183 +SrCO3 added: 1.8300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.3252e-01 +XStrontianite: 5.6748e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 184 +SrCO3 added: 1.8400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.2962e-01 +XStrontianite: 5.7038e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 185 +SrCO3 added: 1.8500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.2675e-01 +XStrontianite: 5.7325e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 186 +SrCO3 added: 1.8600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.2392e-01 +XStrontianite: 5.7608e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 187 +SrCO3 added: 1.8700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.2113e-01 +XStrontianite: 5.7887e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 188 +SrCO3 added: 1.8800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.1838e-01 +XStrontianite: 5.8162e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 189 +SrCO3 added: 1.8900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.1566e-01 +XStrontianite: 5.8434e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 190 +SrCO3 added: 1.9000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.1298e-01 +XStrontianite: 5.8702e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 191 +SrCO3 added: 1.9100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.1033e-01 +XStrontianite: 5.8967e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 192 +SrCO3 added: 1.9200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.0771e-01 +XStrontianite: 5.9229e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 193 +SrCO3 added: 1.9300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.0513e-01 +XStrontianite: 5.9487e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 194 +SrCO3 added: 1.9400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.0258e-01 +XStrontianite: 5.9742e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 195 +SrCO3 added: 1.9500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 4.0006e-01 +XStrontianite: 5.9994e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 196 +SrCO3 added: 1.9600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.9758e-01 +XStrontianite: 6.0242e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 197 +SrCO3 added: 1.9700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.9512e-01 +XStrontianite: 6.0488e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 198 +SrCO3 added: 1.9800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.9270e-01 +XStrontianite: 6.0730e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 199 +SrCO3 added: 1.9900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.9030e-01 +XStrontianite: 6.0970e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 200 +SrCO3 added: 2.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.8793e-01 +XStrontianite: 6.1207e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 201 +SrCO3 added: 2.0100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.8559e-01 +XStrontianite: 6.1441e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 202 +SrCO3 added: 2.0200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.8328e-01 +XStrontianite: 6.1672e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 203 +SrCO3 added: 2.0300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.8100e-01 +XStrontianite: 6.1900e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 204 +SrCO3 added: 2.0400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.7875e-01 +XStrontianite: 6.2125e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 205 +SrCO3 added: 2.0500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.7652e-01 +XStrontianite: 6.2348e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 206 +SrCO3 added: 2.0600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.7431e-01 +XStrontianite: 6.2569e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 207 +SrCO3 added: 2.0700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.7214e-01 +XStrontianite: 6.2786e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 208 +SrCO3 added: 2.0800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.6998e-01 +XStrontianite: 6.3002e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 209 +SrCO3 added: 2.0900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.6786e-01 +XStrontianite: 6.3214e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 210 +SrCO3 added: 2.1000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.6575e-01 +XStrontianite: 6.3425e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 211 +SrCO3 added: 2.1100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.6367e-01 +XStrontianite: 6.3633e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 212 +SrCO3 added: 2.1200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.6162e-01 +XStrontianite: 6.3838e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 213 +SrCO3 added: 2.1300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.5958e-01 +XStrontianite: 6.4042e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 214 +SrCO3 added: 2.1400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.5757e-01 +XStrontianite: 6.4243e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 215 +SrCO3 added: 2.1500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.5559e-01 +XStrontianite: 6.4441e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 216 +SrCO3 added: 2.1600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.5362e-01 +XStrontianite: 6.4638e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 217 +SrCO3 added: 2.1700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.5168e-01 +XStrontianite: 6.4832e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 218 +SrCO3 added: 2.1800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4975e-01 +XStrontianite: 6.5025e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 219 +SrCO3 added: 2.1900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4785e-01 +XStrontianite: 6.5215e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 220 +SrCO3 added: 2.2000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4597e-01 +XStrontianite: 6.5403e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 221 +SrCO3 added: 2.2100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4411e-01 +XStrontianite: 6.5589e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 222 +SrCO3 added: 2.2200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4227e-01 +XStrontianite: 6.5773e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 223 +SrCO3 added: 2.2300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.4045e-01 +XStrontianite: 6.5955e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 224 +SrCO3 added: 2.2400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.3864e-01 +XStrontianite: 6.6136e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 225 +SrCO3 added: 2.2500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.3686e-01 +XStrontianite: 6.6314e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 226 +SrCO3 added: 2.2600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.3510e-01 +XStrontianite: 6.6490e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 227 +SrCO3 added: 2.2700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.3335e-01 +XStrontianite: 6.6665e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 228 +SrCO3 added: 2.2800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.3162e-01 +XStrontianite: 6.6838e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 229 +SrCO3 added: 2.2900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2991e-01 +XStrontianite: 6.7009e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 230 +SrCO3 added: 2.3000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2822e-01 +XStrontianite: 6.7178e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 231 +SrCO3 added: 2.3100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2654e-01 +XStrontianite: 6.7346e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 232 +SrCO3 added: 2.3200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2489e-01 +XStrontianite: 6.7511e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 233 +SrCO3 added: 2.3300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2324e-01 +XStrontianite: 6.7676e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 234 +SrCO3 added: 2.3400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2162e-01 +XStrontianite: 6.7838e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 235 +SrCO3 added: 2.3500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.2001e-01 +XStrontianite: 6.7999e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 236 +SrCO3 added: 2.3600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1842e-01 +XStrontianite: 6.8158e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 237 +SrCO3 added: 2.3700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1684e-01 +XStrontianite: 6.8316e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 238 +SrCO3 added: 2.3800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1528e-01 +XStrontianite: 6.8472e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 239 +SrCO3 added: 2.3900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1373e-01 +XStrontianite: 6.8627e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 240 +SrCO3 added: 2.4000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1220e-01 +XStrontianite: 6.8780e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 241 +SrCO3 added: 2.4100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.1068e-01 +XStrontianite: 6.8932e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 242 +SrCO3 added: 2.4200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0918e-01 +XStrontianite: 6.9082e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 243 +SrCO3 added: 2.4300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0770e-01 +XStrontianite: 6.9230e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 244 +SrCO3 added: 2.4400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0622e-01 +XStrontianite: 6.9378e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 245 +SrCO3 added: 2.4500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0476e-01 +XStrontianite: 6.9524e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 246 +SrCO3 added: 2.4600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0332e-01 +XStrontianite: 6.9668e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 247 +SrCO3 added: 2.4700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0189e-01 +XStrontianite: 6.9811e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 248 +SrCO3 added: 2.4800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.0047e-01 +XStrontianite: 6.9953e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 249 +SrCO3 added: 2.4900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9907e-01 +XStrontianite: 7.0093e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 250 +SrCO3 added: 2.5000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9767e-01 +XStrontianite: 7.0233e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 251 +SrCO3 added: 2.5100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9629e-01 +XStrontianite: 7.0371e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 252 +SrCO3 added: 2.5200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9493e-01 +XStrontianite: 7.0507e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 253 +SrCO3 added: 2.5300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9358e-01 +XStrontianite: 7.0642e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 254 +SrCO3 added: 2.5400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9223e-01 +XStrontianite: 7.0777e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 255 +SrCO3 added: 2.5500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.9091e-01 +XStrontianite: 7.0909e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 256 +SrCO3 added: 2.5600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8959e-01 +XStrontianite: 7.1041e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 257 +SrCO3 added: 2.5700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8828e-01 +XStrontianite: 7.1172e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 258 +SrCO3 added: 2.5800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8699e-01 +XStrontianite: 7.1301e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 259 +SrCO3 added: 2.5900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8571e-01 +XStrontianite: 7.1429e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 260 +SrCO3 added: 2.6000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8444e-01 +XStrontianite: 7.1556e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 261 +SrCO3 added: 2.6100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8318e-01 +XStrontianite: 7.1682e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 262 +SrCO3 added: 2.6200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8193e-01 +XStrontianite: 7.1807e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 263 +SrCO3 added: 2.6300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.8069e-01 +XStrontianite: 7.1931e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 264 +SrCO3 added: 2.6400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7947e-01 +XStrontianite: 7.2053e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 265 +SrCO3 added: 2.6500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7825e-01 +XStrontianite: 7.2175e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 266 +SrCO3 added: 2.6600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7705e-01 +XStrontianite: 7.2295e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 267 +SrCO3 added: 2.6700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7585e-01 +XStrontianite: 7.2415e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 268 +SrCO3 added: 2.6800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7467e-01 +XStrontianite: 7.2533e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 269 +SrCO3 added: 2.6900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7349e-01 +XStrontianite: 7.2651e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 270 +SrCO3 added: 2.7000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7233e-01 +XStrontianite: 7.2767e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 271 +SrCO3 added: 2.7100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7117e-01 +XStrontianite: 7.2883e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 272 +SrCO3 added: 2.7200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.7003e-01 +XStrontianite: 7.2997e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 273 +SrCO3 added: 2.7300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6889e-01 +XStrontianite: 7.3111e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 274 +SrCO3 added: 2.7400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6777e-01 +XStrontianite: 7.3223e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 275 +SrCO3 added: 2.7500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6665e-01 +XStrontianite: 7.3335e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 276 +SrCO3 added: 2.7600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6555e-01 +XStrontianite: 7.3445e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 277 +SrCO3 added: 2.7700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6445e-01 +XStrontianite: 7.3555e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 278 +SrCO3 added: 2.7800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6336e-01 +XStrontianite: 7.3664e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 279 +SrCO3 added: 2.7900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6228e-01 +XStrontianite: 7.3772e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 280 +SrCO3 added: 2.8000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6121e-01 +XStrontianite: 7.3879e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 281 +SrCO3 added: 2.8100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.6015e-01 +XStrontianite: 7.3985e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 282 +SrCO3 added: 2.8200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5909e-01 +XStrontianite: 7.4091e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 283 +SrCO3 added: 2.8300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5805e-01 +XStrontianite: 7.4195e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 284 +SrCO3 added: 2.8400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5701e-01 +XStrontianite: 7.4299e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 285 +SrCO3 added: 2.8500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5598e-01 +XStrontianite: 7.4402e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 286 +SrCO3 added: 2.8600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5496e-01 +XStrontianite: 7.4504e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 287 +SrCO3 added: 2.8700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5395e-01 +XStrontianite: 7.4605e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 288 +SrCO3 added: 2.8800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5295e-01 +XStrontianite: 7.4705e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 289 +SrCO3 added: 2.8900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5195e-01 +XStrontianite: 7.4805e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 290 +SrCO3 added: 2.9000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.5096e-01 +XStrontianite: 7.4904e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 291 +SrCO3 added: 2.9100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4998e-01 +XStrontianite: 7.5002e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 292 +SrCO3 added: 2.9200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4901e-01 +XStrontianite: 7.5099e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 293 +SrCO3 added: 2.9300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4804e-01 +XStrontianite: 7.5196e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 294 +SrCO3 added: 2.9400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4708e-01 +XStrontianite: 7.5292e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 295 +SrCO3 added: 2.9500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4613e-01 +XStrontianite: 7.5387e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 296 +SrCO3 added: 2.9600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4519e-01 +XStrontianite: 7.5481e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 297 +SrCO3 added: 2.9700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4425e-01 +XStrontianite: 7.5575e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 298 +SrCO3 added: 2.9800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4332e-01 +XStrontianite: 7.5668e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 299 +SrCO3 added: 2.9900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4240e-01 +XStrontianite: 7.5760e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 300 +SrCO3 added: 3.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4149e-01 +XStrontianite: 7.5851e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 301 +SrCO3 added: 3.0100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4058e-01 +XStrontianite: 7.5942e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 302 +SrCO3 added: 3.0200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3968e-01 +XStrontianite: 7.6032e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 303 +SrCO3 added: 3.0300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3878e-01 +XStrontianite: 7.6122e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 304 +SrCO3 added: 3.0400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3790e-01 +XStrontianite: 7.6210e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 305 +SrCO3 added: 3.0500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3701e-01 +XStrontianite: 7.6299e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 306 +SrCO3 added: 3.0600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3614e-01 +XStrontianite: 7.6386e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 307 +SrCO3 added: 3.0700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3527e-01 +XStrontianite: 7.6473e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 308 +SrCO3 added: 3.0800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3441e-01 +XStrontianite: 7.6559e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 309 +SrCO3 added: 3.0900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3355e-01 +XStrontianite: 7.6645e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 310 +SrCO3 added: 3.1000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3270e-01 +XStrontianite: 7.6730e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 311 +SrCO3 added: 3.1100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3186e-01 +XStrontianite: 7.6814e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 312 +SrCO3 added: 3.1200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3102e-01 +XStrontianite: 7.6898e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 313 +SrCO3 added: 3.1300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.3019e-01 +XStrontianite: 7.6981e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 314 +SrCO3 added: 3.1400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2937e-01 +XStrontianite: 7.7063e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 315 +SrCO3 added: 3.1500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2855e-01 +XStrontianite: 7.7145e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 316 +SrCO3 added: 3.1600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2773e-01 +XStrontianite: 7.7227e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 317 +SrCO3 added: 3.1700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2692e-01 +XStrontianite: 7.7308e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 318 +SrCO3 added: 3.1800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2612e-01 +XStrontianite: 7.7388e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 319 +SrCO3 added: 3.1900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2533e-01 +XStrontianite: 7.7467e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 320 +SrCO3 added: 3.2000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2454e-01 +XStrontianite: 7.7546e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 321 +SrCO3 added: 3.2100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2375e-01 +XStrontianite: 7.7625e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 322 +SrCO3 added: 3.2200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2297e-01 +XStrontianite: 7.7703e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 323 +SrCO3 added: 3.2300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2220e-01 +XStrontianite: 7.7780e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 324 +SrCO3 added: 3.2400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2143e-01 +XStrontianite: 7.7857e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 325 +SrCO3 added: 3.2500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.2066e-01 +XStrontianite: 7.7934e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 326 +SrCO3 added: 3.2600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1990e-01 +XStrontianite: 7.8010e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 327 +SrCO3 added: 3.2700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1915e-01 +XStrontianite: 7.8085e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 328 +SrCO3 added: 3.2800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1840e-01 +XStrontianite: 7.8160e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 329 +SrCO3 added: 3.2900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1766e-01 +XStrontianite: 7.8234e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 330 +SrCO3 added: 3.3000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1692e-01 +XStrontianite: 7.8308e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 331 +SrCO3 added: 3.3100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1619e-01 +XStrontianite: 7.8381e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 332 +SrCO3 added: 3.3200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1546e-01 +XStrontianite: 7.8454e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 333 +SrCO3 added: 3.3300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1474e-01 +XStrontianite: 7.8526e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 334 +SrCO3 added: 3.3400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1402e-01 +XStrontianite: 7.8598e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 335 +SrCO3 added: 3.3500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1330e-01 +XStrontianite: 7.8670e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 336 +SrCO3 added: 3.3600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1260e-01 +XStrontianite: 7.8740e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 337 +SrCO3 added: 3.3700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1189e-01 +XStrontianite: 7.8811e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 338 +SrCO3 added: 3.3800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1119e-01 +XStrontianite: 7.8881e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 339 +SrCO3 added: 3.3900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.1050e-01 +XStrontianite: 7.8950e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 340 +SrCO3 added: 3.4000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0981e-01 +XStrontianite: 7.9019e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 341 +SrCO3 added: 3.4100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0912e-01 +XStrontianite: 7.9088e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 342 +SrCO3 added: 3.4200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0844e-01 +XStrontianite: 7.9156e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 343 +SrCO3 added: 3.4300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0776e-01 +XStrontianite: 7.9224e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 344 +SrCO3 added: 3.4400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0709e-01 +XStrontianite: 7.9291e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 345 +SrCO3 added: 3.4500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0642e-01 +XStrontianite: 7.9358e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 346 +SrCO3 added: 3.4600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0576e-01 +XStrontianite: 7.9424e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 347 +SrCO3 added: 3.4700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0510e-01 +XStrontianite: 7.9490e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 348 +SrCO3 added: 3.4800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0444e-01 +XStrontianite: 7.9556e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 349 +SrCO3 added: 3.4900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0379e-01 +XStrontianite: 7.9621e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 350 +SrCO3 added: 3.5000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0314e-01 +XStrontianite: 7.9686e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 351 +SrCO3 added: 3.5100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0250e-01 +XStrontianite: 7.9750e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 352 +SrCO3 added: 3.5200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0186e-01 +XStrontianite: 7.9814e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 353 +SrCO3 added: 3.5300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0123e-01 +XStrontianite: 7.9877e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 354 +SrCO3 added: 3.5400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.0060e-01 +XStrontianite: 7.9940e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 355 +SrCO3 added: 3.5500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9997e-01 +XStrontianite: 8.0003e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 356 +SrCO3 added: 3.5600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9935e-01 +XStrontianite: 8.0065e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 357 +SrCO3 added: 3.5700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9873e-01 +XStrontianite: 8.0127e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 358 +SrCO3 added: 3.5800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9811e-01 +XStrontianite: 8.0189e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 359 +SrCO3 added: 3.5900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9750e-01 +XStrontianite: 8.0250e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 360 +SrCO3 added: 3.6000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9689e-01 +XStrontianite: 8.0311e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 361 +SrCO3 added: 3.6100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9629e-01 +XStrontianite: 8.0371e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 362 +SrCO3 added: 3.6200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9569e-01 +XStrontianite: 8.0431e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 363 +SrCO3 added: 3.6300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9509e-01 +XStrontianite: 8.0491e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 364 +SrCO3 added: 3.6400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9450e-01 +XStrontianite: 8.0550e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 365 +SrCO3 added: 3.6500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9391e-01 +XStrontianite: 8.0609e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 366 +SrCO3 added: 3.6600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9332e-01 +XStrontianite: 8.0668e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 367 +SrCO3 added: 3.6700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9274e-01 +XStrontianite: 8.0726e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 368 +SrCO3 added: 3.6800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9216e-01 +XStrontianite: 8.0784e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 369 +SrCO3 added: 3.6900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9158e-01 +XStrontianite: 8.0842e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 370 +SrCO3 added: 3.7000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9101e-01 +XStrontianite: 8.0899e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 371 +SrCO3 added: 3.7100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.9044e-01 +XStrontianite: 8.0956e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 372 +SrCO3 added: 3.7200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8988e-01 +XStrontianite: 8.1012e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 373 +SrCO3 added: 3.7300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8932e-01 +XStrontianite: 8.1068e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 374 +SrCO3 added: 3.7400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8876e-01 +XStrontianite: 8.1124e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 375 +SrCO3 added: 3.7500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8820e-01 +XStrontianite: 8.1180e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 376 +SrCO3 added: 3.7600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8765e-01 +XStrontianite: 8.1235e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 377 +SrCO3 added: 3.7700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8710e-01 +XStrontianite: 8.1290e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 378 +SrCO3 added: 3.7800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8656e-01 +XStrontianite: 8.1344e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 379 +SrCO3 added: 3.7900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8601e-01 +XStrontianite: 8.1399e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 380 +SrCO3 added: 3.8000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8547e-01 +XStrontianite: 8.1453e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 381 +SrCO3 added: 3.8100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8494e-01 +XStrontianite: 8.1506e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 382 +SrCO3 added: 3.8200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8440e-01 +XStrontianite: 8.1560e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 383 +SrCO3 added: 3.8300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8387e-01 +XStrontianite: 8.1613e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 384 +SrCO3 added: 3.8400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8335e-01 +XStrontianite: 8.1665e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 385 +SrCO3 added: 3.8500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8282e-01 +XStrontianite: 8.1718e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 386 +SrCO3 added: 3.8600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8230e-01 +XStrontianite: 8.1770e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 387 +SrCO3 added: 3.8700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8178e-01 +XStrontianite: 8.1822e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 388 +SrCO3 added: 3.8800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8127e-01 +XStrontianite: 8.1873e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 389 +SrCO3 added: 3.8900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8076e-01 +XStrontianite: 8.1924e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 390 +SrCO3 added: 3.9000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.8025e-01 +XStrontianite: 8.1975e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 391 +SrCO3 added: 3.9100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7974e-01 +XStrontianite: 8.2026e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 392 +SrCO3 added: 3.9200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7924e-01 +XStrontianite: 8.2076e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 393 +SrCO3 added: 3.9300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7874e-01 +XStrontianite: 8.2126e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 394 +SrCO3 added: 3.9400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7824e-01 +XStrontianite: 8.2176e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 395 +SrCO3 added: 3.9500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7774e-01 +XStrontianite: 8.2226e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 396 +SrCO3 added: 3.9600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7725e-01 +XStrontianite: 8.2275e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 397 +SrCO3 added: 3.9700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7676e-01 +XStrontianite: 8.2324e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 398 +SrCO3 added: 3.9800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7627e-01 +XStrontianite: 8.2373e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 399 +SrCO3 added: 3.9900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7579e-01 +XStrontianite: 8.2421e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 400 +SrCO3 added: 4.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7531e-01 +XStrontianite: 8.2469e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 401 +SrCO3 added: 4.0100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7483e-01 +XStrontianite: 8.2517e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 402 +SrCO3 added: 4.0200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7435e-01 +XStrontianite: 8.2565e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 403 +SrCO3 added: 4.0300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7388e-01 +XStrontianite: 8.2612e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 404 +SrCO3 added: 4.0400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7341e-01 +XStrontianite: 8.2659e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 405 +SrCO3 added: 4.0500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7294e-01 +XStrontianite: 8.2706e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 406 +SrCO3 added: 4.0600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7247e-01 +XStrontianite: 8.2753e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 407 +SrCO3 added: 4.0700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7201e-01 +XStrontianite: 8.2799e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 408 +SrCO3 added: 4.0800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7155e-01 +XStrontianite: 8.2845e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 409 +SrCO3 added: 4.0900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7109e-01 +XStrontianite: 8.2891e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 410 +SrCO3 added: 4.1000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7063e-01 +XStrontianite: 8.2937e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 411 +SrCO3 added: 4.1100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7018e-01 +XStrontianite: 8.2982e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 412 +SrCO3 added: 4.1200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6973e-01 +XStrontianite: 8.3027e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 413 +SrCO3 added: 4.1300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6928e-01 +XStrontianite: 8.3072e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 414 +SrCO3 added: 4.1400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6883e-01 +XStrontianite: 8.3117e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 415 +SrCO3 added: 4.1500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6839e-01 +XStrontianite: 8.3161e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 416 +SrCO3 added: 4.1600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6794e-01 +XStrontianite: 8.3206e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 417 +SrCO3 added: 4.1700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6750e-01 +XStrontianite: 8.3250e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 418 +SrCO3 added: 4.1800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6707e-01 +XStrontianite: 8.3293e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 419 +SrCO3 added: 4.1900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6663e-01 +XStrontianite: 8.3337e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 420 +SrCO3 added: 4.2000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6620e-01 +XStrontianite: 8.3380e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 421 +SrCO3 added: 4.2100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6577e-01 +XStrontianite: 8.3423e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 422 +SrCO3 added: 4.2200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6534e-01 +XStrontianite: 8.3466e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 423 +SrCO3 added: 4.2300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6491e-01 +XStrontianite: 8.3509e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 424 +SrCO3 added: 4.2400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6449e-01 +XStrontianite: 8.3551e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 425 +SrCO3 added: 4.2500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6407e-01 +XStrontianite: 8.3593e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 426 +SrCO3 added: 4.2600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6365e-01 +XStrontianite: 8.3635e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 427 +SrCO3 added: 4.2700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6323e-01 +XStrontianite: 8.3677e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 428 +SrCO3 added: 4.2800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6282e-01 +XStrontianite: 8.3718e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 429 +SrCO3 added: 4.2900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6240e-01 +XStrontianite: 8.3760e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 430 +SrCO3 added: 4.3000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6199e-01 +XStrontianite: 8.3801e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 431 +SrCO3 added: 4.3100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6158e-01 +XStrontianite: 8.3842e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 432 +SrCO3 added: 4.3200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6117e-01 +XStrontianite: 8.3883e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 433 +SrCO3 added: 4.3300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6077e-01 +XStrontianite: 8.3923e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 434 +SrCO3 added: 4.3400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.6037e-01 +XStrontianite: 8.3963e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 435 +SrCO3 added: 4.3500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5997e-01 +XStrontianite: 8.4003e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 436 +SrCO3 added: 4.3600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5957e-01 +XStrontianite: 8.4043e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 437 +SrCO3 added: 4.3700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5917e-01 +XStrontianite: 8.4083e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 438 +SrCO3 added: 4.3800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5877e-01 +XStrontianite: 8.4123e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 439 +SrCO3 added: 4.3900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5838e-01 +XStrontianite: 8.4162e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 440 +SrCO3 added: 4.4000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5799e-01 +XStrontianite: 8.4201e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 441 +SrCO3 added: 4.4100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5760e-01 +XStrontianite: 8.4240e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 442 +SrCO3 added: 4.4200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5721e-01 +XStrontianite: 8.4279e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 443 +SrCO3 added: 4.4300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5683e-01 +XStrontianite: 8.4317e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 444 +SrCO3 added: 4.4400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5644e-01 +XStrontianite: 8.4356e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 445 +SrCO3 added: 4.4500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5606e-01 +XStrontianite: 8.4394e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 446 +SrCO3 added: 4.4600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5568e-01 +XStrontianite: 8.4432e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 447 +SrCO3 added: 4.4700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5530e-01 +XStrontianite: 8.4470e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 448 +SrCO3 added: 4.4800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5493e-01 +XStrontianite: 8.4507e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 449 +SrCO3 added: 4.4900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5455e-01 +XStrontianite: 8.4545e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 450 +SrCO3 added: 4.5000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5418e-01 +XStrontianite: 8.4582e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 451 +SrCO3 added: 4.5100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5381e-01 +XStrontianite: 8.4619e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 452 +SrCO3 added: 4.5200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5344e-01 +XStrontianite: 8.4656e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 453 +SrCO3 added: 4.5300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5307e-01 +XStrontianite: 8.4693e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 454 +SrCO3 added: 4.5400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5271e-01 +XStrontianite: 8.4729e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 455 +SrCO3 added: 4.5500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5235e-01 +XStrontianite: 8.4765e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 456 +SrCO3 added: 4.5600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5198e-01 +XStrontianite: 8.4802e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 457 +SrCO3 added: 4.5700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5162e-01 +XStrontianite: 8.4838e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 458 +SrCO3 added: 4.5800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5127e-01 +XStrontianite: 8.4873e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 459 +SrCO3 added: 4.5900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5091e-01 +XStrontianite: 8.4909e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 460 +SrCO3 added: 4.6000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5055e-01 +XStrontianite: 8.4945e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 461 +SrCO3 added: 4.6100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.5020e-01 +XStrontianite: 8.4980e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 462 +SrCO3 added: 4.6200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4985e-01 +XStrontianite: 8.5015e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 463 +SrCO3 added: 4.6300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4950e-01 +XStrontianite: 8.5050e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 464 +SrCO3 added: 4.6400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4915e-01 +XStrontianite: 8.5085e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 465 +SrCO3 added: 4.6500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4880e-01 +XStrontianite: 8.5120e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 466 +SrCO3 added: 4.6600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4846e-01 +XStrontianite: 8.5154e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 467 +SrCO3 added: 4.6700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4811e-01 +XStrontianite: 8.5189e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 468 +SrCO3 added: 4.6800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4777e-01 +XStrontianite: 8.5223e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 469 +SrCO3 added: 4.6900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4743e-01 +XStrontianite: 8.5257e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 470 +SrCO3 added: 4.7000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4709e-01 +XStrontianite: 8.5291e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 471 +SrCO3 added: 4.7100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4675e-01 +XStrontianite: 8.5325e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 472 +SrCO3 added: 4.7200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4642e-01 +XStrontianite: 8.5358e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 473 +SrCO3 added: 4.7300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4608e-01 +XStrontianite: 8.5392e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 474 +SrCO3 added: 4.7400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4575e-01 +XStrontianite: 8.5425e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 475 +SrCO3 added: 4.7500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4542e-01 +XStrontianite: 8.5458e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 476 +SrCO3 added: 4.7600e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4509e-01 +XStrontianite: 8.5491e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 477 +SrCO3 added: 4.7700e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4476e-01 +XStrontianite: 8.5524e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 478 +SrCO3 added: 4.7800e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4443e-01 +XStrontianite: 8.5557e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 479 +SrCO3 added: 4.7900e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4411e-01 +XStrontianite: 8.5589e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 480 +SrCO3 added: 4.8000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4379e-01 +XStrontianite: 8.5621e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 481 +SrCO3 added: 4.8100e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4346e-01 +XStrontianite: 8.5654e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 482 +SrCO3 added: 4.8200e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4314e-01 +XStrontianite: 8.5686e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 483 +SrCO3 added: 4.8300e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4282e-01 +XStrontianite: 8.5718e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 484 +SrCO3 added: 4.8400e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4250e-01 +XStrontianite: 8.5750e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 485 +SrCO3 added: 4.8500e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.4219e-01 +XStrontianite: 8.5781e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 486 +SrCO3 added: 4.8600e-03 +Log Sigma pi: -8.2975e+00 +XAragonite: 1.4210e-01 +XStrontianite: 8.5790e-01 +XCa: 9.0899e-01 +XSr: 9.1014e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 487 +SrCO3 added: 4.8700e-03 +Log Sigma pi: -8.2976e+00 +XAragonite: 1.4206e-01 +XStrontianite: 8.5794e-01 +XCa: 9.0895e-01 +XSr: 9.1046e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 488 +SrCO3 added: 4.8800e-03 +Log Sigma pi: -8.2977e+00 +XAragonite: 1.4202e-01 +XStrontianite: 8.5798e-01 +XCa: 9.0892e-01 +XSr: 9.1078e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 489 +SrCO3 added: 4.8900e-03 +Log Sigma pi: -8.2979e+00 +XAragonite: 1.4197e-01 +XStrontianite: 8.5803e-01 +XCa: 9.0889e-01 +XSr: 9.1110e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 490 +SrCO3 added: 4.9000e-03 +Log Sigma pi: -8.2980e+00 +XAragonite: 1.4193e-01 +XStrontianite: 8.5807e-01 +XCa: 9.0886e-01 +XSr: 9.1142e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 491 +SrCO3 added: 4.9100e-03 +Log Sigma pi: -8.2981e+00 +XAragonite: 1.4189e-01 +XStrontianite: 8.5811e-01 +XCa: 9.0883e-01 +XSr: 9.1174e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 492 +SrCO3 added: 4.9200e-03 +Log Sigma pi: -8.2982e+00 +XAragonite: 1.4185e-01 +XStrontianite: 8.5815e-01 +XCa: 9.0879e-01 +XSr: 9.1206e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 493 +SrCO3 added: 4.9300e-03 +Log Sigma pi: -8.2984e+00 +XAragonite: 1.4181e-01 +XStrontianite: 8.5819e-01 +XCa: 9.0876e-01 +XSr: 9.1238e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 494 +SrCO3 added: 4.9400e-03 +Log Sigma pi: -8.2985e+00 +XAragonite: 1.4176e-01 +XStrontianite: 8.5824e-01 +XCa: 9.0873e-01 +XSr: 9.1270e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 495 +SrCO3 added: 4.9500e-03 +Log Sigma pi: -8.2986e+00 +XAragonite: 1.4172e-01 +XStrontianite: 8.5828e-01 +XCa: 9.0870e-01 +XSr: 9.1302e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 496 +SrCO3 added: 4.9600e-03 +Log Sigma pi: -8.2988e+00 +XAragonite: 1.4168e-01 +XStrontianite: 8.5832e-01 +XCa: 9.0867e-01 +XSr: 9.1334e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 497 +SrCO3 added: 4.9700e-03 +Log Sigma pi: -8.2989e+00 +XAragonite: 1.4164e-01 +XStrontianite: 8.5836e-01 +XCa: 9.0863e-01 +XSr: 9.1366e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 498 +SrCO3 added: 4.9800e-03 +Log Sigma pi: -8.2990e+00 +XAragonite: 1.4160e-01 +XStrontianite: 8.5840e-01 +XCa: 9.0860e-01 +XSr: 9.1398e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 499 +SrCO3 added: 4.9900e-03 +Log Sigma pi: -8.2991e+00 +XAragonite: 1.4155e-01 +XStrontianite: 8.5845e-01 +XCa: 9.0857e-01 +XSr: 9.1429e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 4 +Reaction step number: 500 +SrCO3 added: 5.0000e-03 +Log Sigma pi: -8.2993e+00 +XAragonite: 1.4151e-01 +XStrontianite: 8.5849e-01 +XCa: 9.0854e-01 +XSr: 9.1461e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + + USE solution 1 + USE solid_solution 1 + REACTION 1 + SrCO3 1.0 + .1 in 100 steps + END +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 1 +SrCO3 added: 1.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 9.8567e-01 +XStrontianite: 1.4329e-02 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 2 +SrCO3 added: 2.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 3.8793e-01 +XStrontianite: 6.1207e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 3 +SrCO3 added: 3.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 2.4149e-01 +XStrontianite: 7.5851e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 4 +SrCO3 added: 4.0000e-03 +Log Sigma pi: -8.2974e+00 +XAragonite: 1.7531e-01 +XStrontianite: 8.2469e-01 +XCa: 9.0901e-01 +XSr: 9.0987e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 5 +SrCO3 added: 5.0000e-03 +Log Sigma pi: -8.2993e+00 +XAragonite: 1.4151e-01 +XStrontianite: 8.5849e-01 +XCa: 9.0854e-01 +XSr: 9.1461e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 6 +SrCO3 added: 6.0000e-03 +Log Sigma pi: -8.3118e+00 +XAragonite: 1.3751e-01 +XStrontianite: 8.6249e-01 +XCa: 9.0539e-01 +XSr: 9.4606e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 7 +SrCO3 added: 7.0000e-03 +Log Sigma pi: -8.3236e+00 +XAragonite: 1.3383e-01 +XStrontianite: 8.6617e-01 +XCa: 9.0233e-01 +XSr: 9.7673e-02 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 8 +SrCO3 added: 8.0000e-03 +Log Sigma pi: -8.3349e+00 +XAragonite: 1.3043e-01 +XStrontianite: 8.6957e-01 +XCa: 8.9933e-01 +XSr: 1.0067e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 9 +SrCO3 added: 9.0000e-03 +Log Sigma pi: -8.3456e+00 +XAragonite: 1.2726e-01 +XStrontianite: 8.7274e-01 +XCa: 8.9640e-01 +XSr: 1.0360e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 10 +SrCO3 added: 1.0000e-02 +Log Sigma pi: -8.3559e+00 +XAragonite: 1.2431e-01 +XStrontianite: 8.7569e-01 +XCa: 8.9352e-01 +XSr: 1.0648e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 11 +SrCO3 added: 1.1000e-02 +Log Sigma pi: -8.3658e+00 +XAragonite: 1.2155e-01 +XStrontianite: 8.7845e-01 +XCa: 8.9070e-01 +XSr: 1.0930e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 12 +SrCO3 added: 1.2000e-02 +Log Sigma pi: -8.3752e+00 +XAragonite: 1.1895e-01 +XStrontianite: 8.8105e-01 +XCa: 8.8792e-01 +XSr: 1.1208e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 13 +SrCO3 added: 1.3000e-02 +Log Sigma pi: -8.3843e+00 +XAragonite: 1.1650e-01 +XStrontianite: 8.8350e-01 +XCa: 8.8519e-01 +XSr: 1.1481e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 14 +SrCO3 added: 1.4000e-02 +Log Sigma pi: -8.3931e+00 +XAragonite: 1.1419e-01 +XStrontianite: 8.8581e-01 +XCa: 8.8251e-01 +XSr: 1.1749e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 15 +SrCO3 added: 1.5000e-02 +Log Sigma pi: -8.4016e+00 +XAragonite: 1.1199e-01 +XStrontianite: 8.8801e-01 +XCa: 8.7986e-01 +XSr: 1.2014e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 16 +SrCO3 added: 1.6000e-02 +Log Sigma pi: -8.4098e+00 +XAragonite: 1.0991e-01 +XStrontianite: 8.9009e-01 +XCa: 8.7725e-01 +XSr: 1.2275e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 17 +SrCO3 added: 1.7000e-02 +Log Sigma pi: -8.4178e+00 +XAragonite: 1.0793e-01 +XStrontianite: 8.9207e-01 +XCa: 8.7468e-01 +XSr: 1.2532e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 18 +SrCO3 added: 1.8000e-02 +Log Sigma pi: -8.4254e+00 +XAragonite: 1.0604e-01 +XStrontianite: 8.9396e-01 +XCa: 8.7214e-01 +XSr: 1.2786e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 19 +SrCO3 added: 1.9000e-02 +Log Sigma pi: -8.4329e+00 +XAragonite: 1.0423e-01 +XStrontianite: 8.9577e-01 +XCa: 8.6963e-01 +XSr: 1.3037e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 20 +SrCO3 added: 2.0000e-02 +Log Sigma pi: -8.4401e+00 +XAragonite: 1.0251e-01 +XStrontianite: 8.9749e-01 +XCa: 8.6716e-01 +XSr: 1.3284e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 21 +SrCO3 added: 2.1000e-02 +Log Sigma pi: -8.4472e+00 +XAragonite: 1.0086e-01 +XStrontianite: 8.9914e-01 +XCa: 8.6471e-01 +XSr: 1.3529e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 22 +SrCO3 added: 2.2000e-02 +Log Sigma pi: -8.4540e+00 +XAragonite: 9.9270e-02 +XStrontianite: 9.0073e-01 +XCa: 8.6230e-01 +XSr: 1.3770e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 23 +SrCO3 added: 2.3000e-02 +Log Sigma pi: -8.4607e+00 +XAragonite: 9.7747e-02 +XStrontianite: 9.0225e-01 +XCa: 8.5991e-01 +XSr: 1.4009e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 24 +SrCO3 added: 2.4000e-02 +Log Sigma pi: -8.4672e+00 +XAragonite: 9.6283e-02 +XStrontianite: 9.0372e-01 +XCa: 8.5754e-01 +XSr: 1.4246e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 25 +SrCO3 added: 2.5000e-02 +Log Sigma pi: -8.4735e+00 +XAragonite: 9.4874e-02 +XStrontianite: 9.0513e-01 +XCa: 8.5520e-01 +XSr: 1.4480e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 26 +SrCO3 added: 2.6000e-02 +Log Sigma pi: -8.4797e+00 +XAragonite: 9.3517e-02 +XStrontianite: 9.0648e-01 +XCa: 8.5289e-01 +XSr: 1.4711e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 27 +SrCO3 added: 2.7000e-02 +Log Sigma pi: -8.4857e+00 +XAragonite: 9.2208e-02 +XStrontianite: 9.0779e-01 +XCa: 8.5060e-01 +XSr: 1.4940e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 28 +SrCO3 added: 2.8000e-02 +Log Sigma pi: -8.4915e+00 +XAragonite: 9.0944e-02 +XStrontianite: 9.0906e-01 +XCa: 8.4833e-01 +XSr: 1.5167e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 29 +SrCO3 added: 2.9000e-02 +Log Sigma pi: -8.4973e+00 +XAragonite: 8.9723e-02 +XStrontianite: 9.1028e-01 +XCa: 8.4608e-01 +XSr: 1.5392e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 30 +SrCO3 added: 3.0000e-02 +Log Sigma pi: -8.5029e+00 +XAragonite: 8.8542e-02 +XStrontianite: 9.1146e-01 +XCa: 8.4386e-01 +XSr: 1.5614e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 31 +SrCO3 added: 3.1000e-02 +Log Sigma pi: -8.5084e+00 +XAragonite: 8.7400e-02 +XStrontianite: 9.1260e-01 +XCa: 8.4166e-01 +XSr: 1.5834e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 32 +SrCO3 added: 3.2000e-02 +Log Sigma pi: -8.5137e+00 +XAragonite: 8.6294e-02 +XStrontianite: 9.1371e-01 +XCa: 8.3947e-01 +XSr: 1.6053e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 33 +SrCO3 added: 3.3000e-02 +Log Sigma pi: -8.5190e+00 +XAragonite: 8.5221e-02 +XStrontianite: 9.1478e-01 +XCa: 8.3731e-01 +XSr: 1.6269e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 34 +SrCO3 added: 3.4000e-02 +Log Sigma pi: -8.5241e+00 +XAragonite: 8.4182e-02 +XStrontianite: 9.1582e-01 +XCa: 8.3516e-01 +XSr: 1.6484e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 35 +SrCO3 added: 3.5000e-02 +Log Sigma pi: -8.5292e+00 +XAragonite: 8.3173e-02 +XStrontianite: 9.1683e-01 +XCa: 8.3304e-01 +XSr: 1.6696e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 36 +SrCO3 added: 3.6000e-02 +Log Sigma pi: -8.5341e+00 +XAragonite: 8.2193e-02 +XStrontianite: 9.1781e-01 +XCa: 8.3093e-01 +XSr: 1.6907e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 37 +SrCO3 added: 3.7000e-02 +Log Sigma pi: -8.5390e+00 +XAragonite: 8.1241e-02 +XStrontianite: 9.1876e-01 +XCa: 8.2884e-01 +XSr: 1.7116e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 38 +SrCO3 added: 3.8000e-02 +Log Sigma pi: -8.5437e+00 +XAragonite: 8.0316e-02 +XStrontianite: 9.1968e-01 +XCa: 8.2677e-01 +XSr: 1.7323e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 39 +SrCO3 added: 3.9000e-02 +Log Sigma pi: -8.5484e+00 +XAragonite: 7.9416e-02 +XStrontianite: 9.2058e-01 +XCa: 8.2471e-01 +XSr: 1.7529e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 40 +SrCO3 added: 4.0000e-02 +Log Sigma pi: -8.5529e+00 +XAragonite: 7.8540e-02 +XStrontianite: 9.2146e-01 +XCa: 8.2267e-01 +XSr: 1.7733e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 41 +SrCO3 added: 4.1000e-02 +Log Sigma pi: -8.5574e+00 +XAragonite: 7.7688e-02 +XStrontianite: 9.2231e-01 +XCa: 8.2065e-01 +XSr: 1.7935e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 42 +SrCO3 added: 4.2000e-02 +Log Sigma pi: -8.5618e+00 +XAragonite: 7.6857e-02 +XStrontianite: 9.2314e-01 +XCa: 8.1865e-01 +XSr: 1.8135e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 43 +SrCO3 added: 4.3000e-02 +Log Sigma pi: -8.5662e+00 +XAragonite: 7.6048e-02 +XStrontianite: 9.2395e-01 +XCa: 8.1665e-01 +XSr: 1.8335e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 44 +SrCO3 added: 4.4000e-02 +Log Sigma pi: -8.5704e+00 +XAragonite: 7.5259e-02 +XStrontianite: 9.2474e-01 +XCa: 8.1468e-01 +XSr: 1.8532e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 45 +SrCO3 added: 4.5000e-02 +Log Sigma pi: -8.5746e+00 +XAragonite: 7.4489e-02 +XStrontianite: 9.2551e-01 +XCa: 8.1272e-01 +XSr: 1.8728e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 46 +SrCO3 added: 4.6000e-02 +Log Sigma pi: -8.5787e+00 +XAragonite: 7.3738e-02 +XStrontianite: 9.2626e-01 +XCa: 8.1077e-01 +XSr: 1.8923e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 47 +SrCO3 added: 4.7000e-02 +Log Sigma pi: -8.5827e+00 +XAragonite: 7.3005e-02 +XStrontianite: 9.2699e-01 +XCa: 8.0884e-01 +XSr: 1.9116e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 48 +SrCO3 added: 4.8000e-02 +Log Sigma pi: -8.5867e+00 +XAragonite: 7.2290e-02 +XStrontianite: 9.2771e-01 +XCa: 8.0692e-01 +XSr: 1.9308e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 49 +SrCO3 added: 4.9000e-02 +Log Sigma pi: -8.5906e+00 +XAragonite: 7.1590e-02 +XStrontianite: 9.2841e-01 +XCa: 8.0502e-01 +XSr: 1.9498e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 50 +SrCO3 added: 5.0000e-02 +Log Sigma pi: -8.5945e+00 +XAragonite: 7.0907e-02 +XStrontianite: 9.2909e-01 +XCa: 8.0313e-01 +XSr: 1.9687e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 51 +SrCO3 added: 5.1000e-02 +Log Sigma pi: -8.5982e+00 +XAragonite: 7.0239e-02 +XStrontianite: 9.2976e-01 +XCa: 8.0125e-01 +XSr: 1.9875e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 52 +SrCO3 added: 5.2000e-02 +Log Sigma pi: -8.6020e+00 +XAragonite: 6.9586e-02 +XStrontianite: 9.3041e-01 +XCa: 7.9939e-01 +XSr: 2.0061e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 53 +SrCO3 added: 5.3000e-02 +Log Sigma pi: -8.6056e+00 +XAragonite: 6.8947e-02 +XStrontianite: 9.3105e-01 +XCa: 7.9753e-01 +XSr: 2.0247e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 54 +SrCO3 added: 5.4000e-02 +Log Sigma pi: -8.6092e+00 +XAragonite: 6.8322e-02 +XStrontianite: 9.3168e-01 +XCa: 7.9570e-01 +XSr: 2.0430e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 55 +SrCO3 added: 5.5000e-02 +Log Sigma pi: -8.6128e+00 +XAragonite: 6.7710e-02 +XStrontianite: 9.3229e-01 +XCa: 7.9387e-01 +XSr: 2.0613e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 56 +SrCO3 added: 5.6000e-02 +Log Sigma pi: -8.6163e+00 +XAragonite: 6.7111e-02 +XStrontianite: 9.3289e-01 +XCa: 7.9206e-01 +XSr: 2.0794e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 57 +SrCO3 added: 5.7000e-02 +Log Sigma pi: -8.6198e+00 +XAragonite: 6.6524e-02 +XStrontianite: 9.3348e-01 +XCa: 7.9026e-01 +XSr: 2.0974e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 58 +SrCO3 added: 5.8000e-02 +Log Sigma pi: -8.6232e+00 +XAragonite: 6.5950e-02 +XStrontianite: 9.3405e-01 +XCa: 7.8847e-01 +XSr: 2.1153e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 59 +SrCO3 added: 5.9000e-02 +Log Sigma pi: -8.6265e+00 +XAragonite: 6.5386e-02 +XStrontianite: 9.3461e-01 +XCa: 7.8669e-01 +XSr: 2.1331e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 60 +SrCO3 added: 6.0000e-02 +Log Sigma pi: -8.6298e+00 +XAragonite: 6.4834e-02 +XStrontianite: 9.3517e-01 +XCa: 7.8492e-01 +XSr: 2.1508e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 61 +SrCO3 added: 6.1000e-02 +Log Sigma pi: -8.6331e+00 +XAragonite: 6.4293e-02 +XStrontianite: 9.3571e-01 +XCa: 7.8317e-01 +XSr: 2.1683e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 62 +SrCO3 added: 6.2000e-02 +Log Sigma pi: -8.6363e+00 +XAragonite: 6.3762e-02 +XStrontianite: 9.3624e-01 +XCa: 7.8142e-01 +XSr: 2.1858e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 63 +SrCO3 added: 6.3000e-02 +Log Sigma pi: -8.6395e+00 +XAragonite: 6.3242e-02 +XStrontianite: 9.3676e-01 +XCa: 7.7969e-01 +XSr: 2.2031e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 64 +SrCO3 added: 6.4000e-02 +Log Sigma pi: -8.6426e+00 +XAragonite: 6.2731e-02 +XStrontianite: 9.3727e-01 +XCa: 7.7797e-01 +XSr: 2.2203e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 65 +SrCO3 added: 6.5000e-02 +Log Sigma pi: -8.6457e+00 +XAragonite: 6.2230e-02 +XStrontianite: 9.3777e-01 +XCa: 7.7626e-01 +XSr: 2.2374e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 66 +SrCO3 added: 6.6000e-02 +Log Sigma pi: -8.6487e+00 +XAragonite: 6.1738e-02 +XStrontianite: 9.3826e-01 +XCa: 7.7456e-01 +XSr: 2.2544e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 67 +SrCO3 added: 6.7000e-02 +Log Sigma pi: -8.6517e+00 +XAragonite: 6.1255e-02 +XStrontianite: 9.3875e-01 +XCa: 7.7287e-01 +XSr: 2.2713e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 68 +SrCO3 added: 6.8000e-02 +Log Sigma pi: -8.6547e+00 +XAragonite: 6.0780e-02 +XStrontianite: 9.3922e-01 +XCa: 7.7119e-01 +XSr: 2.2881e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 69 +SrCO3 added: 6.9000e-02 +Log Sigma pi: -8.6576e+00 +XAragonite: 6.0314e-02 +XStrontianite: 9.3969e-01 +XCa: 7.6952e-01 +XSr: 2.3048e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 70 +SrCO3 added: 7.0000e-02 +Log Sigma pi: -8.6605e+00 +XAragonite: 5.9857e-02 +XStrontianite: 9.4014e-01 +XCa: 7.6786e-01 +XSr: 2.3214e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 71 +SrCO3 added: 7.1000e-02 +Log Sigma pi: -8.6634e+00 +XAragonite: 5.9407e-02 +XStrontianite: 9.4059e-01 +XCa: 7.6621e-01 +XSr: 2.3379e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 72 +SrCO3 added: 7.2000e-02 +Log Sigma pi: -8.6662e+00 +XAragonite: 5.8965e-02 +XStrontianite: 9.4103e-01 +XCa: 7.6457e-01 +XSr: 2.3543e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 73 +SrCO3 added: 7.3000e-02 +Log Sigma pi: -8.6690e+00 +XAragonite: 5.8531e-02 +XStrontianite: 9.4147e-01 +XCa: 7.6294e-01 +XSr: 2.3706e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 74 +SrCO3 added: 7.4000e-02 +Log Sigma pi: -8.6718e+00 +XAragonite: 5.8104e-02 +XStrontianite: 9.4190e-01 +XCa: 7.6132e-01 +XSr: 2.3868e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 75 +SrCO3 added: 7.5000e-02 +Log Sigma pi: -8.6745e+00 +XAragonite: 5.7684e-02 +XStrontianite: 9.4232e-01 +XCa: 7.5970e-01 +XSr: 2.4030e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 76 +SrCO3 added: 7.6000e-02 +Log Sigma pi: -8.6772e+00 +XAragonite: 5.7271e-02 +XStrontianite: 9.4273e-01 +XCa: 7.5810e-01 +XSr: 2.4190e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 77 +SrCO3 added: 7.7000e-02 +Log Sigma pi: -8.6798e+00 +XAragonite: 5.6864e-02 +XStrontianite: 9.4314e-01 +XCa: 7.5651e-01 +XSr: 2.4349e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 78 +SrCO3 added: 7.8000e-02 +Log Sigma pi: -8.6824e+00 +XAragonite: 5.6465e-02 +XStrontianite: 9.4354e-01 +XCa: 7.5492e-01 +XSr: 2.4508e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 79 +SrCO3 added: 7.9000e-02 +Log Sigma pi: -8.6850e+00 +XAragonite: 5.6071e-02 +XStrontianite: 9.4393e-01 +XCa: 7.5335e-01 +XSr: 2.4665e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 80 +SrCO3 added: 8.0000e-02 +Log Sigma pi: -8.6876e+00 +XAragonite: 5.5684e-02 +XStrontianite: 9.4432e-01 +XCa: 7.5178e-01 +XSr: 2.4822e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 81 +SrCO3 added: 8.1000e-02 +Log Sigma pi: -8.6901e+00 +XAragonite: 5.5303e-02 +XStrontianite: 9.4470e-01 +XCa: 7.5023e-01 +XSr: 2.4977e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 82 +SrCO3 added: 8.2000e-02 +Log Sigma pi: -8.6926e+00 +XAragonite: 5.4928e-02 +XStrontianite: 9.4507e-01 +XCa: 7.4868e-01 +XSr: 2.5132e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 83 +SrCO3 added: 8.3000e-02 +Log Sigma pi: -8.6951e+00 +XAragonite: 5.4559e-02 +XStrontianite: 9.4544e-01 +XCa: 7.4714e-01 +XSr: 2.5286e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 84 +SrCO3 added: 8.4000e-02 +Log Sigma pi: -8.6976e+00 +XAragonite: 5.4196e-02 +XStrontianite: 9.4580e-01 +XCa: 7.4560e-01 +XSr: 2.5440e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 85 +SrCO3 added: 8.5000e-02 +Log Sigma pi: -8.7000e+00 +XAragonite: 5.3837e-02 +XStrontianite: 9.4616e-01 +XCa: 7.4408e-01 +XSr: 2.5592e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 86 +SrCO3 added: 8.6000e-02 +Log Sigma pi: -8.7024e+00 +XAragonite: 5.3485e-02 +XStrontianite: 9.4652e-01 +XCa: 7.4256e-01 +XSr: 2.5744e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 87 +SrCO3 added: 8.7000e-02 +Log Sigma pi: -8.7047e+00 +XAragonite: 5.3137e-02 +XStrontianite: 9.4686e-01 +XCa: 7.4106e-01 +XSr: 2.5894e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 88 +SrCO3 added: 8.8000e-02 +Log Sigma pi: -8.7071e+00 +XAragonite: 5.2795e-02 +XStrontianite: 9.4721e-01 +XCa: 7.3956e-01 +XSr: 2.6044e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 89 +SrCO3 added: 8.9000e-02 +Log Sigma pi: -8.7094e+00 +XAragonite: 5.2457e-02 +XStrontianite: 9.4754e-01 +XCa: 7.3807e-01 +XSr: 2.6193e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 90 +SrCO3 added: 9.0000e-02 +Log Sigma pi: -8.7117e+00 +XAragonite: 5.2125e-02 +XStrontianite: 9.4788e-01 +XCa: 7.3658e-01 +XSr: 2.6342e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 91 +SrCO3 added: 9.1000e-02 +Log Sigma pi: -8.7140e+00 +XAragonite: 5.1797e-02 +XStrontianite: 9.4820e-01 +XCa: 7.3511e-01 +XSr: 2.6489e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 92 +SrCO3 added: 9.2000e-02 +Log Sigma pi: -8.7162e+00 +XAragonite: 5.1474e-02 +XStrontianite: 9.4853e-01 +XCa: 7.3364e-01 +XSr: 2.6636e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 93 +SrCO3 added: 9.3000e-02 +Log Sigma pi: -8.7185e+00 +XAragonite: 5.1155e-02 +XStrontianite: 9.4884e-01 +XCa: 7.3218e-01 +XSr: 2.6782e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 94 +SrCO3 added: 9.4000e-02 +Log Sigma pi: -8.7207e+00 +XAragonite: 5.0841e-02 +XStrontianite: 9.4916e-01 +XCa: 7.3073e-01 +XSr: 2.6927e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 95 +SrCO3 added: 9.5000e-02 +Log Sigma pi: -8.7228e+00 +XAragonite: 5.0531e-02 +XStrontianite: 9.4947e-01 +XCa: 7.2928e-01 +XSr: 2.7072e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 96 +SrCO3 added: 9.6000e-02 +Log Sigma pi: -8.7250e+00 +XAragonite: 5.0226e-02 +XStrontianite: 9.4977e-01 +XCa: 7.2784e-01 +XSr: 2.7216e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 97 +SrCO3 added: 9.7000e-02 +Log Sigma pi: -8.7271e+00 +XAragonite: 4.9924e-02 +XStrontianite: 9.5008e-01 +XCa: 7.2641e-01 +XSr: 2.7359e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 98 +SrCO3 added: 9.8000e-02 +Log Sigma pi: -8.7292e+00 +XAragonite: 4.9627e-02 +XStrontianite: 9.5037e-01 +XCa: 7.2499e-01 +XSr: 2.7501e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 99 +SrCO3 added: 9.9000e-02 +Log Sigma pi: -8.7313e+00 +XAragonite: 4.9334e-02 +XStrontianite: 9.5067e-01 +XCa: 7.2357e-01 +XSr: 2.7643e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 5 +Reaction step number: 100 +SrCO3 added: 1.0000e-01 +Log Sigma pi: -8.7334e+00 +XAragonite: 4.9044e-02 +XStrontianite: 9.5096e-01 +XCa: 7.2216e-01 +XSr: 2.7784e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + + USE solution 1 + USE solid_solution 1 + REACTION 1 + SrCO3 1.0 + 10.0 in 100 steps + END +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 1 +SrCO3 added: 1.0000e-01 +Log Sigma pi: -8.7334e+00 +XAragonite: 4.9044e-02 +XStrontianite: 9.5096e-01 +XCa: 7.2216e-01 +XSr: 2.7784e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 2 +SrCO3 added: 2.0000e-01 +Log Sigma pi: -8.8746e+00 +XAragonite: 3.1529e-02 +XStrontianite: 9.6847e-01 +XCa: 6.0843e-01 +XSr: 3.9157e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 3 +SrCO3 added: 3.0000e-01 +Log Sigma pi: -8.9515e+00 +XAragonite: 2.3611e-02 +XStrontianite: 9.7639e-01 +XCa: 5.2912e-01 +XSr: 4.7088e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 4 +SrCO3 added: 4.0000e-01 +Log Sigma pi: -9.0015e+00 +XAragonite: 1.8992e-02 +XStrontianite: 9.8101e-01 +XCa: 4.6954e-01 +XSr: 5.3046e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 5 +SrCO3 added: 5.0000e-01 +Log Sigma pi: -9.0371e+00 +XAragonite: 1.5935e-02 +XStrontianite: 9.8407e-01 +XCa: 4.2272e-01 +XSr: 5.7728e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 6 +SrCO3 added: 6.0000e-01 +Log Sigma pi: -9.0640e+00 +XAragonite: 1.3750e-02 +XStrontianite: 9.8625e-01 +XCa: 3.8479e-01 +XSr: 6.1521e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 7 +SrCO3 added: 7.0000e-01 +Log Sigma pi: -9.0851e+00 +XAragonite: 1.2105e-02 +XStrontianite: 9.8790e-01 +XCa: 3.5335e-01 +XSr: 6.4665e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 8 +SrCO3 added: 8.0000e-01 +Log Sigma pi: -9.1022e+00 +XAragonite: 1.0819e-02 +XStrontianite: 9.8918e-01 +XCa: 3.2680e-01 +XSr: 6.7320e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 9 +SrCO3 added: 9.0000e-01 +Log Sigma pi: -9.1162e+00 +XAragonite: 9.7855e-03 +XStrontianite: 9.9021e-01 +XCa: 3.0406e-01 +XSr: 6.9594e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 10 +SrCO3 added: 1 +Log Sigma pi: -9.1281e+00 +XAragonite: 8.9352e-03 +XStrontianite: 9.9106e-01 +XCa: 2.8435e-01 +XSr: 7.1565e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 11 +SrCO3 added: 1.1000e+00 +Log Sigma pi: -9.1382e+00 +XAragonite: 8.2229e-03 +XStrontianite: 9.9178e-01 +XCa: 2.6708e-01 +XSr: 7.3292e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 12 +SrCO3 added: 1.2000e+00 +Log Sigma pi: -9.1470e+00 +XAragonite: 7.6172e-03 +XStrontianite: 9.9238e-01 +XCa: 2.5183e-01 +XSr: 7.4817e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 13 +SrCO3 added: 1.3000e+00 +Log Sigma pi: -9.1547e+00 +XAragonite: 7.0957e-03 +XStrontianite: 9.9290e-01 +XCa: 2.3825e-01 +XSr: 7.6175e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 14 +SrCO3 added: 1.4000e+00 +Log Sigma pi: -9.1614e+00 +XAragonite: 6.6418e-03 +XStrontianite: 9.9336e-01 +XCa: 2.2608e-01 +XSr: 7.7392e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 15 +SrCO3 added: 1.5000e+00 +Log Sigma pi: -9.1674e+00 +XAragonite: 6.2431e-03 +XStrontianite: 9.9376e-01 +XCa: 2.1511e-01 +XSr: 7.8489e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 16 +SrCO3 added: 1.6000e+00 +Log Sigma pi: -9.1728e+00 +XAragonite: 5.8899e-03 +XStrontianite: 9.9411e-01 +XCa: 2.0516e-01 +XSr: 7.9484e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 17 +SrCO3 added: 1.7000e+00 +Log Sigma pi: -9.1776e+00 +XAragonite: 5.5749e-03 +XStrontianite: 9.9443e-01 +XCa: 1.9610e-01 +XSr: 8.0390e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 18 +SrCO3 added: 1.8000e+00 +Log Sigma pi: -9.1820e+00 +XAragonite: 5.2921e-03 +XStrontianite: 9.9471e-01 +XCa: 1.8782e-01 +XSr: 8.1218e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 19 +SrCO3 added: 1.9000e+00 +Log Sigma pi: -9.1860e+00 +XAragonite: 5.0369e-03 +XStrontianite: 9.9496e-01 +XCa: 1.8021e-01 +XSr: 8.1979e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 20 +SrCO3 added: 2 +Log Sigma pi: -9.1896e+00 +XAragonite: 4.8052e-03 +XStrontianite: 9.9519e-01 +XCa: 1.7320e-01 +XSr: 8.2680e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 21 +SrCO3 added: 2.1000e+00 +Log Sigma pi: -9.1929e+00 +XAragonite: 4.5941e-03 +XStrontianite: 9.9541e-01 +XCa: 1.6672e-01 +XSr: 8.3328e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 22 +SrCO3 added: 2.2000e+00 +Log Sigma pi: -9.1960e+00 +XAragonite: 4.4009e-03 +XStrontianite: 9.9560e-01 +XCa: 1.6071e-01 +XSr: 8.3929e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 23 +SrCO3 added: 2.3000e+00 +Log Sigma pi: -9.1988e+00 +XAragonite: 4.2233e-03 +XStrontianite: 9.9578e-01 +XCa: 1.5512e-01 +XSr: 8.4488e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 24 +SrCO3 added: 2.4000e+00 +Log Sigma pi: -9.2015e+00 +XAragonite: 4.0596e-03 +XStrontianite: 9.9594e-01 +XCa: 1.4990e-01 +XSr: 8.5010e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 25 +SrCO3 added: 2.5000e+00 +Log Sigma pi: -9.2039e+00 +XAragonite: 3.9082e-03 +XStrontianite: 9.9609e-01 +XCa: 1.4503e-01 +XSr: 8.5497e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 26 +SrCO3 added: 2.6000e+00 +Log Sigma pi: -9.2062e+00 +XAragonite: 3.7677e-03 +XStrontianite: 9.9623e-01 +XCa: 1.4047e-01 +XSr: 8.5953e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 27 +SrCO3 added: 2.7000e+00 +Log Sigma pi: -9.2083e+00 +XAragonite: 3.6370e-03 +XStrontianite: 9.9636e-01 +XCa: 1.3618e-01 +XSr: 8.6382e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 28 +SrCO3 added: 2.8000e+00 +Log Sigma pi: -9.2103e+00 +XAragonite: 3.5151e-03 +XStrontianite: 9.9648e-01 +XCa: 1.3216e-01 +XSr: 8.6784e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 29 +SrCO3 added: 2.9000e+00 +Log Sigma pi: -9.2122e+00 +XAragonite: 3.4011e-03 +XStrontianite: 9.9660e-01 +XCa: 1.2836e-01 +XSr: 8.7164e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 30 +SrCO3 added: 3 +Log Sigma pi: -9.2139e+00 +XAragonite: 3.2944e-03 +XStrontianite: 9.9671e-01 +XCa: 1.2478e-01 +XSr: 8.7522e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 31 +SrCO3 added: 3.1000e+00 +Log Sigma pi: -9.2156e+00 +XAragonite: 3.1941e-03 +XStrontianite: 9.9681e-01 +XCa: 1.2139e-01 +XSr: 8.7861e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 32 +SrCO3 added: 3.2000e+00 +Log Sigma pi: -9.2171e+00 +XAragonite: 3.0998e-03 +XStrontianite: 9.9690e-01 +XCa: 1.1818e-01 +XSr: 8.8182e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 33 +SrCO3 added: 3.3000e+00 +Log Sigma pi: -9.2186e+00 +XAragonite: 3.0109e-03 +XStrontianite: 9.9699e-01 +XCa: 1.1514e-01 +XSr: 8.8486e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 34 +SrCO3 added: 3.4000e+00 +Log Sigma pi: -9.2200e+00 +XAragonite: 2.9270e-03 +XStrontianite: 9.9707e-01 +XCa: 1.1225e-01 +XSr: 8.8775e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 35 +SrCO3 added: 3.5000e+00 +Log Sigma pi: -9.2213e+00 +XAragonite: 2.8476e-03 +XStrontianite: 9.9715e-01 +XCa: 1.0950e-01 +XSr: 8.9050e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 36 +SrCO3 added: 3.6000e+00 +Log Sigma pi: -9.2226e+00 +XAragonite: 2.7725e-03 +XStrontianite: 9.9723e-01 +XCa: 1.0688e-01 +XSr: 8.9312e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 37 +SrCO3 added: 3.7000e+00 +Log Sigma pi: -9.2238e+00 +XAragonite: 2.7012e-03 +XStrontianite: 9.9730e-01 +XCa: 1.0439e-01 +XSr: 8.9561e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 38 +SrCO3 added: 3.8000e+00 +Log Sigma pi: -9.2249e+00 +XAragonite: 2.6335e-03 +XStrontianite: 9.9737e-01 +XCa: 1.0201e-01 +XSr: 8.9799e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 39 +SrCO3 added: 3.9000e+00 +Log Sigma pi: -9.2260e+00 +XAragonite: 2.5691e-03 +XStrontianite: 9.9743e-01 +XCa: 9.9738e-02 +XSr: 9.0026e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 40 +SrCO3 added: 4 +Log Sigma pi: -9.2270e+00 +XAragonite: 2.5078e-03 +XStrontianite: 9.9749e-01 +XCa: 9.7564e-02 +XSr: 9.0244e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 41 +SrCO3 added: 4.1000e+00 +Log Sigma pi: -9.2280e+00 +XAragonite: 2.4494e-03 +XStrontianite: 9.9755e-01 +XCa: 9.5483e-02 +XSr: 9.0452e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 42 +SrCO3 added: 4.2000e+00 +Log Sigma pi: -9.2289e+00 +XAragonite: 2.3936e-03 +XStrontianite: 9.9761e-01 +XCa: 9.3489e-02 +XSr: 9.0651e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 43 +SrCO3 added: 4.3000e+00 +Log Sigma pi: -9.2298e+00 +XAragonite: 2.3404e-03 +XStrontianite: 9.9766e-01 +XCa: 9.1577e-02 +XSr: 9.0842e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 44 +SrCO3 added: 4.4000e+00 +Log Sigma pi: -9.2307e+00 +XAragonite: 2.2894e-03 +XStrontianite: 9.9771e-01 +XCa: 8.9742e-02 +XSr: 9.1026e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 45 +SrCO3 added: 4.5000e+00 +Log Sigma pi: -9.2315e+00 +XAragonite: 2.2406e-03 +XStrontianite: 9.9776e-01 +XCa: 8.7979e-02 +XSr: 9.1202e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 46 +SrCO3 added: 4.6000e+00 +Log Sigma pi: -9.2323e+00 +XAragonite: 2.1939e-03 +XStrontianite: 9.9781e-01 +XCa: 8.6284e-02 +XSr: 9.1372e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 47 +SrCO3 added: 4.7000e+00 +Log Sigma pi: -9.2331e+00 +XAragonite: 2.1491e-03 +XStrontianite: 9.9785e-01 +XCa: 8.4653e-02 +XSr: 9.1535e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 48 +SrCO3 added: 4.8000e+00 +Log Sigma pi: -9.2338e+00 +XAragonite: 2.1060e-03 +XStrontianite: 9.9789e-01 +XCa: 8.3083e-02 +XSr: 9.1692e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 49 +SrCO3 added: 4.9000e+00 +Log Sigma pi: -9.2345e+00 +XAragonite: 2.0647e-03 +XStrontianite: 9.9794e-01 +XCa: 8.1570e-02 +XSr: 9.1843e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 50 +SrCO3 added: 5 +Log Sigma pi: -9.2352e+00 +XAragonite: 2.0249e-03 +XStrontianite: 9.9798e-01 +XCa: 8.0112e-02 +XSr: 9.1989e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 51 +SrCO3 added: 5.1000e+00 +Log Sigma pi: -9.2359e+00 +XAragonite: 1.9867e-03 +XStrontianite: 9.9801e-01 +XCa: 7.8704e-02 +XSr: 9.2130e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 52 +SrCO3 added: 5.2000e+00 +Log Sigma pi: -9.2365e+00 +XAragonite: 1.9499e-03 +XStrontianite: 9.9805e-01 +XCa: 7.7346e-02 +XSr: 9.2265e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 53 +SrCO3 added: 5.3000e+00 +Log Sigma pi: -9.2371e+00 +XAragonite: 1.9144e-03 +XStrontianite: 9.9809e-01 +XCa: 7.6033e-02 +XSr: 9.2397e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 54 +SrCO3 added: 5.4000e+00 +Log Sigma pi: -9.2377e+00 +XAragonite: 1.8802e-03 +XStrontianite: 9.9812e-01 +XCa: 7.4765e-02 +XSr: 9.2524e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 55 +SrCO3 added: 5.5000e+00 +Log Sigma pi: -9.2383e+00 +XAragonite: 1.8472e-03 +XStrontianite: 9.9815e-01 +XCa: 7.3538e-02 +XSr: 9.2646e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 56 +SrCO3 added: 5.6000e+00 +Log Sigma pi: -9.2388e+00 +XAragonite: 1.8153e-03 +XStrontianite: 9.9818e-01 +XCa: 7.2350e-02 +XSr: 9.2765e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 57 +SrCO3 added: 5.7000e+00 +Log Sigma pi: -9.2393e+00 +XAragonite: 1.7845e-03 +XStrontianite: 9.9822e-01 +XCa: 7.1201e-02 +XSr: 9.2880e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 58 +SrCO3 added: 5.8000e+00 +Log Sigma pi: -9.2398e+00 +XAragonite: 1.7548e-03 +XStrontianite: 9.9825e-01 +XCa: 7.0087e-02 +XSr: 9.2991e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 59 +SrCO3 added: 5.9000e+00 +Log Sigma pi: -9.2403e+00 +XAragonite: 1.7260e-03 +XStrontianite: 9.9827e-01 +XCa: 6.9008e-02 +XSr: 9.3099e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 60 +SrCO3 added: 6 +Log Sigma pi: -9.2408e+00 +XAragonite: 1.6982e-03 +XStrontianite: 9.9830e-01 +XCa: 6.7962e-02 +XSr: 9.3204e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 61 +SrCO3 added: 6.1000e+00 +Log Sigma pi: -9.2413e+00 +XAragonite: 1.6712e-03 +XStrontianite: 9.9833e-01 +XCa: 6.6947e-02 +XSr: 9.3305e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 62 +SrCO3 added: 6.2000e+00 +Log Sigma pi: -9.2417e+00 +XAragonite: 1.6451e-03 +XStrontianite: 9.9835e-01 +XCa: 6.5961e-02 +XSr: 9.3404e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 63 +SrCO3 added: 6.3000e+00 +Log Sigma pi: -9.2422e+00 +XAragonite: 1.6198e-03 +XStrontianite: 9.9838e-01 +XCa: 6.5005e-02 +XSr: 9.3500e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 64 +SrCO3 added: 6.4000e+00 +Log Sigma pi: -9.2426e+00 +XAragonite: 1.5952e-03 +XStrontianite: 9.9840e-01 +XCa: 6.4076e-02 +XSr: 9.3592e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 65 +SrCO3 added: 6.5000e+00 +Log Sigma pi: -9.2430e+00 +XAragonite: 1.5714e-03 +XStrontianite: 9.9843e-01 +XCa: 6.3173e-02 +XSr: 9.3683e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 66 +SrCO3 added: 6.6000e+00 +Log Sigma pi: -9.2434e+00 +XAragonite: 1.5483e-03 +XStrontianite: 9.9845e-01 +XCa: 6.2295e-02 +XSr: 9.3771e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 67 +SrCO3 added: 6.7000e+00 +Log Sigma pi: -9.2438e+00 +XAragonite: 1.5258e-03 +XStrontianite: 9.9847e-01 +XCa: 6.1441e-02 +XSr: 9.3856e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 68 +SrCO3 added: 6.8000e+00 +Log Sigma pi: -9.2442e+00 +XAragonite: 1.5040e-03 +XStrontianite: 9.9850e-01 +XCa: 6.0610e-02 +XSr: 9.3939e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 69 +SrCO3 added: 6.9000e+00 +Log Sigma pi: -9.2446e+00 +XAragonite: 1.4829e-03 +XStrontianite: 9.9852e-01 +XCa: 5.9802e-02 +XSr: 9.4020e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 70 +SrCO3 added: 7 +Log Sigma pi: -9.2449e+00 +XAragonite: 1.4623e-03 +XStrontianite: 9.9854e-01 +XCa: 5.9015e-02 +XSr: 9.4099e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 71 +SrCO3 added: 7.1000e+00 +Log Sigma pi: -9.2453e+00 +XAragonite: 1.4422e-03 +XStrontianite: 9.9856e-01 +XCa: 5.8248e-02 +XSr: 9.4175e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 72 +SrCO3 added: 7.2000e+00 +Log Sigma pi: -9.2456e+00 +XAragonite: 1.4227e-03 +XStrontianite: 9.9858e-01 +XCa: 5.7501e-02 +XSr: 9.4250e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 73 +SrCO3 added: 7.3000e+00 +Log Sigma pi: -9.2459e+00 +XAragonite: 1.4038e-03 +XStrontianite: 9.9860e-01 +XCa: 5.6773e-02 +XSr: 9.4323e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 74 +SrCO3 added: 7.4000e+00 +Log Sigma pi: -9.2463e+00 +XAragonite: 1.3853e-03 +XStrontianite: 9.9861e-01 +XCa: 5.6063e-02 +XSr: 9.4394e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 75 +SrCO3 added: 7.5000e+00 +Log Sigma pi: -9.2466e+00 +XAragonite: 1.3673e-03 +XStrontianite: 9.9863e-01 +XCa: 5.5370e-02 +XSr: 9.4463e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 76 +SrCO3 added: 7.6000e+00 +Log Sigma pi: -9.2469e+00 +XAragonite: 1.3498e-03 +XStrontianite: 9.9865e-01 +XCa: 5.4695e-02 +XSr: 9.4530e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 77 +SrCO3 added: 7.7000e+00 +Log Sigma pi: -9.2472e+00 +XAragonite: 1.3327e-03 +XStrontianite: 9.9867e-01 +XCa: 5.4036e-02 +XSr: 9.4596e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 78 +SrCO3 added: 7.8000e+00 +Log Sigma pi: -9.2475e+00 +XAragonite: 1.3160e-03 +XStrontianite: 9.9868e-01 +XCa: 5.3392e-02 +XSr: 9.4661e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 79 +SrCO3 added: 7.9000e+00 +Log Sigma pi: -9.2478e+00 +XAragonite: 1.2998e-03 +XStrontianite: 9.9870e-01 +XCa: 5.2764e-02 +XSr: 9.4724e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 80 +SrCO3 added: 8 +Log Sigma pi: -9.2480e+00 +XAragonite: 1.2840e-03 +XStrontianite: 9.9872e-01 +XCa: 5.2150e-02 +XSr: 9.4785e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 81 +SrCO3 added: 8.1000e+00 +Log Sigma pi: -9.2483e+00 +XAragonite: 1.2685e-03 +XStrontianite: 9.9873e-01 +XCa: 5.1551e-02 +XSr: 9.4845e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 82 +SrCO3 added: 8.2000e+00 +Log Sigma pi: -9.2486e+00 +XAragonite: 1.2534e-03 +XStrontianite: 9.9875e-01 +XCa: 5.0965e-02 +XSr: 9.4903e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 83 +SrCO3 added: 8.3000e+00 +Log Sigma pi: -9.2488e+00 +XAragonite: 1.2386e-03 +XStrontianite: 9.9876e-01 +XCa: 5.0392e-02 +XSr: 9.4961e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 84 +SrCO3 added: 8.4000e+00 +Log Sigma pi: -9.2491e+00 +XAragonite: 1.2242e-03 +XStrontianite: 9.9878e-01 +XCa: 4.9832e-02 +XSr: 9.5017e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 85 +SrCO3 added: 8.5000e+00 +Log Sigma pi: -9.2493e+00 +XAragonite: 1.2102e-03 +XStrontianite: 9.9879e-01 +XCa: 4.9285e-02 +XSr: 9.5072e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 86 +SrCO3 added: 8.6000e+00 +Log Sigma pi: -9.2496e+00 +XAragonite: 1.1964e-03 +XStrontianite: 9.9880e-01 +XCa: 4.8749e-02 +XSr: 9.5125e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 87 +SrCO3 added: 8.7000e+00 +Log Sigma pi: -9.2498e+00 +XAragonite: 1.1830e-03 +XStrontianite: 9.9882e-01 +XCa: 4.8225e-02 +XSr: 9.5178e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 88 +SrCO3 added: 8.8000e+00 +Log Sigma pi: -9.2500e+00 +XAragonite: 1.1698e-03 +XStrontianite: 9.9883e-01 +XCa: 4.7712e-02 +XSr: 9.5229e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 89 +SrCO3 added: 8.9000e+00 +Log Sigma pi: -9.2503e+00 +XAragonite: 1.1570e-03 +XStrontianite: 9.9884e-01 +XCa: 4.7209e-02 +XSr: 9.5279e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 90 +SrCO3 added: 9 +Log Sigma pi: -9.2505e+00 +XAragonite: 1.1444e-03 +XStrontianite: 9.9886e-01 +XCa: 4.6718e-02 +XSr: 9.5328e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 91 +SrCO3 added: 9.1000e+00 +Log Sigma pi: -9.2507e+00 +XAragonite: 1.1321e-03 +XStrontianite: 9.9887e-01 +XCa: 4.6236e-02 +XSr: 9.5376e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 92 +SrCO3 added: 9.2000e+00 +Log Sigma pi: -9.2509e+00 +XAragonite: 1.1201e-03 +XStrontianite: 9.9888e-01 +XCa: 4.5764e-02 +XSr: 9.5424e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 93 +SrCO3 added: 9.3000e+00 +Log Sigma pi: -9.2511e+00 +XAragonite: 1.1083e-03 +XStrontianite: 9.9889e-01 +XCa: 4.5302e-02 +XSr: 9.5470e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 94 +SrCO3 added: 9.4000e+00 +Log Sigma pi: -9.2513e+00 +XAragonite: 1.0967e-03 +XStrontianite: 9.9890e-01 +XCa: 4.4849e-02 +XSr: 9.5515e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 95 +SrCO3 added: 9.5000e+00 +Log Sigma pi: -9.2515e+00 +XAragonite: 1.0854e-03 +XStrontianite: 9.9891e-01 +XCa: 4.4405e-02 +XSr: 9.5560e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 96 +SrCO3 added: 9.6000e+00 +Log Sigma pi: -9.2517e+00 +XAragonite: 1.0744e-03 +XStrontianite: 9.9893e-01 +XCa: 4.3969e-02 +XSr: 9.5603e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 97 +SrCO3 added: 9.7000e+00 +Log Sigma pi: -9.2519e+00 +XAragonite: 1.0635e-03 +XStrontianite: 9.9894e-01 +XCa: 4.3543e-02 +XSr: 9.5646e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 98 +SrCO3 added: 9.8000e+00 +Log Sigma pi: -9.2521e+00 +XAragonite: 1.0529e-03 +XStrontianite: 9.9895e-01 +XCa: 4.3124e-02 +XSr: 9.5688e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 99 +SrCO3 added: 9.9000e+00 +Log Sigma pi: -9.2523e+00 +XAragonite: 1.0425e-03 +XStrontianite: 9.9896e-01 +XCa: 4.2713e-02 +XSr: 9.5729e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +----------------------------------User print----------------------------------- + +Simulation number: 6 +Reaction step number: 100 +SrCO3 added: 10 +Log Sigma pi: -9.2525e+00 +XAragonite: 1.0323e-03 +XStrontianite: 9.9897e-01 +XCa: 4.2310e-02 +XSr: 9.5769e-01 +Misc 1: 4.8032e-03 +Misc 2: 8.5786e-01 + +No memory leaks diff --git a/Sun/examples/ex10.sel b/Sun/examples/ex10.sel new file mode 100644 index 00000000..a04f5970 --- /dev/null +++ b/Sun/examples/ex10.sel @@ -0,0 +1,701 @@ + reaction lg_SigmaPi X_Arag X_Stront X_Ca_aq X_Sr_aq mol_Misc1 mol_Misc2 mol_Arag mol_Stront + 1.0000e-05 -8.3356e+00 9.9996e-01 4.2096e-05 9.9905e-01 9.4867e-04 1.0000e-10 1.0000e-10 6.5428e-06 2.7544e-10 + 2.0000e-05 -8.3352e+00 9.9992e-01 8.4301e-05 9.9810e-01 1.8967e-03 1.0000e-10 1.0000e-10 1.3083e-05 1.1030e-09 + 3.0000e-05 -8.3348e+00 9.9987e-01 1.2662e-04 9.9716e-01 2.8440e-03 1.0000e-10 1.0000e-10 1.9622e-05 2.4848e-09 + 4.0000e-05 -8.3345e+00 9.9983e-01 1.6904e-04 9.9621e-01 3.7906e-03 1.0000e-10 1.0000e-10 2.6159e-05 4.4226e-09 + 5.0000e-05 -8.3341e+00 9.9979e-01 2.1158e-04 9.9526e-01 4.7366e-03 1.0000e-10 1.0000e-10 3.2693e-05 6.9185e-09 + 6.0000e-05 -8.3337e+00 9.9975e-01 2.5422e-04 9.9432e-01 5.6819e-03 1.0000e-10 1.0000e-10 3.9225e-05 9.9745e-09 + 7.0000e-05 -8.3333e+00 9.9970e-01 2.9698e-04 9.9337e-01 6.6265e-03 1.0000e-10 1.0000e-10 4.5755e-05 1.3593e-08 + 8.0000e-05 -8.3329e+00 9.9966e-01 3.3985e-04 9.9243e-01 7.5705e-03 1.0000e-10 1.0000e-10 5.2283e-05 1.7775e-08 + 9.0000e-05 -8.3325e+00 9.9962e-01 3.8284e-04 9.9149e-01 8.5137e-03 1.0000e-10 1.0000e-10 5.8809e-05 2.2523e-08 + 1.0000e-04 -8.3321e+00 9.9957e-01 4.2593e-04 9.9054e-01 9.4563e-03 1.0000e-10 1.0000e-10 6.5333e-05 2.7839e-08 + 1.1000e-04 -8.3318e+00 9.9953e-01 4.6914e-04 9.8960e-01 1.0398e-02 1.0000e-10 1.0000e-10 7.1855e-05 3.3726e-08 + 1.2000e-04 -8.3314e+00 9.9949e-01 5.1247e-04 9.8866e-01 1.1340e-02 1.0000e-10 1.0000e-10 7.8374e-05 4.0185e-08 + 1.3000e-04 -8.3310e+00 9.9944e-01 5.5591e-04 9.8772e-01 1.2280e-02 1.0000e-10 1.0000e-10 8.4891e-05 4.7218e-08 + 1.4000e-04 -8.3306e+00 9.9940e-01 5.9946e-04 9.8678e-01 1.3220e-02 1.0000e-10 1.0000e-10 9.1407e-05 5.4828e-08 + 1.5000e-04 -8.3302e+00 9.9936e-01 6.4313e-04 9.8584e-01 1.4159e-02 1.0000e-10 1.0000e-10 9.7920e-05 6.3016e-08 + 1.6000e-04 -8.3298e+00 9.9931e-01 6.8692e-04 9.8490e-01 1.5098e-02 1.0000e-10 1.0000e-10 1.0443e-04 7.1784e-08 + 1.7000e-04 -8.3294e+00 9.9927e-01 7.3082e-04 9.8396e-01 1.6036e-02 1.0000e-10 1.0000e-10 1.1094e-04 8.1136e-08 + 1.8000e-04 -8.3290e+00 9.9923e-01 7.7484e-04 9.8303e-01 1.6973e-02 1.0000e-10 1.0000e-10 1.1745e-04 9.1072e-08 + 1.9000e-04 -8.3287e+00 9.9918e-01 8.1897e-04 9.8209e-01 1.7909e-02 1.0000e-10 1.0000e-10 1.2395e-04 1.0160e-07 + 2.0000e-04 -8.3283e+00 9.9914e-01 8.6323e-04 9.8115e-01 1.8845e-02 1.0000e-10 1.0000e-10 1.3045e-04 1.1271e-07 + 2.1000e-04 -8.3279e+00 9.9909e-01 9.0760e-04 9.8022e-01 1.9780e-02 1.0000e-10 1.0000e-10 1.3695e-04 1.2441e-07 + 2.2000e-04 -8.3275e+00 9.9905e-01 9.5209e-04 9.7929e-01 2.0715e-02 1.0000e-10 1.0000e-10 1.4345e-04 1.3671e-07 + 2.3000e-04 -8.3271e+00 9.9900e-01 9.9670e-04 9.7835e-01 2.1649e-02 1.0000e-10 1.0000e-10 1.4995e-04 1.4960e-07 + 2.4000e-04 -8.3267e+00 9.9896e-01 1.0414e-03 9.7742e-01 2.2582e-02 1.0000e-10 1.0000e-10 1.5644e-04 1.6309e-07 + 2.5000e-04 -8.3263e+00 9.9891e-01 1.0863e-03 9.7649e-01 2.3514e-02 1.0000e-10 1.0000e-10 1.6293e-04 1.7719e-07 + 2.6000e-04 -8.3259e+00 9.9887e-01 1.1313e-03 9.7555e-01 2.4446e-02 1.0000e-10 1.0000e-10 1.6942e-04 1.9188e-07 + 2.7000e-04 -8.3256e+00 9.9882e-01 1.1764e-03 9.7462e-01 2.5377e-02 1.0000e-10 1.0000e-10 1.7591e-04 2.0718e-07 + 2.8000e-04 -8.3252e+00 9.9878e-01 1.2216e-03 9.7369e-01 2.6308e-02 1.0000e-10 1.0000e-10 1.8240e-04 2.2308e-07 + 2.9000e-04 -8.3248e+00 9.9873e-01 1.2669e-03 9.7276e-01 2.7238e-02 1.0000e-10 1.0000e-10 1.8888e-04 2.3960e-07 + 3.0000e-04 -8.3244e+00 9.9869e-01 1.3124e-03 9.7183e-01 2.8167e-02 1.0000e-10 1.0000e-10 1.9536e-04 2.5672e-07 + 3.1000e-04 -8.3240e+00 9.9864e-01 1.3580e-03 9.7090e-01 2.9095e-02 1.0000e-10 1.0000e-10 2.0184e-04 2.7446e-07 + 3.2000e-04 -8.3236e+00 9.9860e-01 1.4037e-03 9.6998e-01 3.0023e-02 1.0000e-10 1.0000e-10 2.0832e-04 2.9282e-07 + 3.3000e-04 -8.3232e+00 9.9855e-01 1.4495e-03 9.6905e-01 3.0950e-02 1.0000e-10 1.0000e-10 2.1479e-04 3.1179e-07 + 3.4000e-04 -8.3228e+00 9.9850e-01 1.4955e-03 9.6812e-01 3.1877e-02 1.0000e-10 1.0000e-10 2.2126e-04 3.3139e-07 + 3.5000e-04 -8.3225e+00 9.9846e-01 1.5416e-03 9.6720e-01 3.2802e-02 1.0000e-10 1.0000e-10 2.2773e-04 3.5161e-07 + 3.6000e-04 -8.3221e+00 9.9841e-01 1.5878e-03 9.6627e-01 3.3727e-02 1.0000e-10 1.0000e-10 2.3420e-04 3.7245e-07 + 3.7000e-04 -8.3217e+00 9.9837e-01 1.6341e-03 9.6535e-01 3.4652e-02 1.0000e-10 1.0000e-10 2.4067e-04 3.9392e-07 + 3.8000e-04 -8.3213e+00 9.9832e-01 1.6806e-03 9.6442e-01 3.5576e-02 1.0000e-10 1.0000e-10 2.4713e-04 4.1602e-07 + 3.9000e-04 -8.3209e+00 9.9827e-01 1.7272e-03 9.6350e-01 3.6499e-02 1.0000e-10 1.0000e-10 2.5359e-04 4.3876e-07 + 4.0000e-04 -8.3205e+00 9.9823e-01 1.7739e-03 9.6258e-01 3.7421e-02 1.0000e-10 1.0000e-10 2.6005e-04 4.6213e-07 + 4.1000e-04 -8.3201e+00 9.9818e-01 1.8208e-03 9.6166e-01 3.8343e-02 1.0000e-10 1.0000e-10 2.6651e-04 4.8614e-07 + 4.2000e-04 -8.3197e+00 9.9813e-01 1.8677e-03 9.6074e-01 3.9264e-02 1.0000e-10 1.0000e-10 2.7297e-04 5.1078e-07 + 4.3000e-04 -8.3193e+00 9.9809e-01 1.9149e-03 9.5982e-01 4.0184e-02 1.0000e-10 1.0000e-10 2.7942e-04 5.3607e-07 + 4.4000e-04 -8.3190e+00 9.9804e-01 1.9621e-03 9.5890e-01 4.1104e-02 1.0000e-10 1.0000e-10 2.8587e-04 5.6201e-07 + 4.5000e-04 -8.3186e+00 9.9799e-01 2.0095e-03 9.5798e-01 4.2023e-02 1.0000e-10 1.0000e-10 2.9232e-04 5.8859e-07 + 4.6000e-04 -8.3182e+00 9.9794e-01 2.0570e-03 9.5706e-01 4.2941e-02 1.0000e-10 1.0000e-10 2.9877e-04 6.1583e-07 + 4.7000e-04 -8.3178e+00 9.9790e-01 2.1046e-03 9.5614e-01 4.3859e-02 1.0000e-10 1.0000e-10 3.0521e-04 6.4371e-07 + 4.8000e-04 -8.3174e+00 9.9785e-01 2.1524e-03 9.5522e-01 4.4776e-02 1.0000e-10 1.0000e-10 3.1165e-04 6.7225e-07 + 4.9000e-04 -8.3170e+00 9.9780e-01 2.2003e-03 9.5431e-01 4.5692e-02 1.0000e-10 1.0000e-10 3.1809e-04 7.0145e-07 + 5.0000e-04 -8.3166e+00 9.9775e-01 2.2484e-03 9.5339e-01 4.6608e-02 1.0000e-10 1.0000e-10 3.2453e-04 7.3131e-07 + 5.1000e-04 -8.3162e+00 9.9770e-01 2.2966e-03 9.5248e-01 4.7523e-02 1.0000e-10 1.0000e-10 3.3097e-04 7.6183e-07 + 5.2000e-04 -8.3159e+00 9.9766e-01 2.3449e-03 9.5156e-01 4.8437e-02 1.0000e-10 1.0000e-10 3.3740e-04 7.9302e-07 + 5.3000e-04 -8.3155e+00 9.9761e-01 2.3933e-03 9.5065e-01 4.9351e-02 1.0000e-10 1.0000e-10 3.4383e-04 8.2488e-07 + 5.4000e-04 -8.3151e+00 9.9756e-01 2.4419e-03 9.4974e-01 5.0264e-02 1.0000e-10 1.0000e-10 3.5026e-04 8.5740e-07 + 5.5000e-04 -8.3147e+00 9.9751e-01 2.4907e-03 9.4882e-01 5.1176e-02 1.0000e-10 1.0000e-10 3.5669e-04 8.9060e-07 + 5.6000e-04 -8.3143e+00 9.9746e-01 2.5395e-03 9.4791e-01 5.2088e-02 1.0000e-10 1.0000e-10 3.6311e-04 9.2448e-07 + 5.7000e-04 -8.3139e+00 9.9741e-01 2.5885e-03 9.4700e-01 5.2999e-02 1.0000e-10 1.0000e-10 3.6954e-04 9.5904e-07 + 5.8000e-04 -8.3135e+00 9.9736e-01 2.6377e-03 9.4609e-01 5.3909e-02 1.0000e-10 1.0000e-10 3.7596e-04 9.9428e-07 + 5.9000e-04 -8.3131e+00 9.9731e-01 2.6870e-03 9.4518e-01 5.4819e-02 1.0000e-10 1.0000e-10 3.8237e-04 1.0302e-06 + 6.0000e-04 -8.3127e+00 9.9726e-01 2.7364e-03 9.4427e-01 5.5728e-02 1.0000e-10 1.0000e-10 3.8879e-04 1.0668e-06 + 6.1000e-04 -8.3123e+00 9.9721e-01 2.7860e-03 9.4336e-01 5.6636e-02 1.0000e-10 1.0000e-10 3.9520e-04 1.1041e-06 + 6.2000e-04 -8.3120e+00 9.9716e-01 2.8357e-03 9.4246e-01 5.7544e-02 1.0000e-10 1.0000e-10 4.0162e-04 1.1421e-06 + 6.3000e-04 -8.3116e+00 9.9711e-01 2.8856e-03 9.4155e-01 5.8451e-02 1.0000e-10 1.0000e-10 4.0803e-04 1.1808e-06 + 6.4000e-04 -8.3112e+00 9.9706e-01 2.9356e-03 9.4064e-01 5.9357e-02 1.0000e-10 1.0000e-10 4.1443e-04 1.2202e-06 + 6.5000e-04 -8.3108e+00 9.9701e-01 2.9857e-03 9.3974e-01 6.0263e-02 1.0000e-10 1.0000e-10 4.2084e-04 1.2603e-06 + 6.6000e-04 -8.3104e+00 9.9696e-01 3.0360e-03 9.3883e-01 6.1167e-02 1.0000e-10 1.0000e-10 4.2724e-04 1.3011e-06 + 6.7000e-04 -8.3100e+00 9.9691e-01 3.0864e-03 9.3793e-01 6.2072e-02 1.0000e-10 1.0000e-10 4.3364e-04 1.3426e-06 + 6.8000e-04 -8.3096e+00 9.9686e-01 3.1370e-03 9.3702e-01 6.2975e-02 1.0000e-10 1.0000e-10 4.4004e-04 1.3848e-06 + 6.9000e-04 -8.3092e+00 9.9681e-01 3.1878e-03 9.3612e-01 6.3878e-02 1.0000e-10 1.0000e-10 4.4644e-04 1.4277e-06 + 7.0000e-04 -8.3088e+00 9.9676e-01 3.2386e-03 9.3522e-01 6.4780e-02 1.0000e-10 1.0000e-10 4.5283e-04 1.4713e-06 + 7.1000e-04 -8.3084e+00 9.9671e-01 3.2897e-03 9.3432e-01 6.5682e-02 1.0000e-10 1.0000e-10 4.5922e-04 1.5157e-06 + 7.2000e-04 -8.3081e+00 9.9666e-01 3.3409e-03 9.3342e-01 6.6583e-02 1.0000e-10 1.0000e-10 4.6561e-04 1.5608e-06 + 7.3000e-04 -8.3077e+00 9.9661e-01 3.3922e-03 9.3252e-01 6.7483e-02 1.0000e-10 1.0000e-10 4.7200e-04 1.6066e-06 + 7.4000e-04 -8.3073e+00 9.9656e-01 3.4437e-03 9.3162e-01 6.8383e-02 1.0000e-10 1.0000e-10 4.7839e-04 1.6531e-06 + 7.5000e-04 -8.3069e+00 9.9650e-01 3.4953e-03 9.3072e-01 6.9282e-02 1.0000e-10 1.0000e-10 4.8477e-04 1.7004e-06 + 7.6000e-04 -8.3065e+00 9.9645e-01 3.5471e-03 9.2982e-01 7.0180e-02 1.0000e-10 1.0000e-10 4.9115e-04 1.7484e-06 + 7.7000e-04 -8.3061e+00 9.9640e-01 3.5990e-03 9.2892e-01 7.1077e-02 1.0000e-10 1.0000e-10 4.9753e-04 1.7971e-06 + 7.8000e-04 -8.3057e+00 9.9635e-01 3.6511e-03 9.2803e-01 7.1974e-02 1.0000e-10 1.0000e-10 5.0391e-04 1.8466e-06 + 7.9000e-04 -8.3053e+00 9.9630e-01 3.7034e-03 9.2713e-01 7.2870e-02 1.0000e-10 1.0000e-10 5.1028e-04 1.8968e-06 + 8.0000e-04 -8.3049e+00 9.9624e-01 3.7558e-03 9.2623e-01 7.3766e-02 1.0000e-10 1.0000e-10 5.1665e-04 1.9477e-06 + 8.1000e-04 -8.3045e+00 9.9619e-01 3.8083e-03 9.2534e-01 7.4661e-02 1.0000e-10 1.0000e-10 5.2302e-04 1.9995e-06 + 8.2000e-04 -8.3042e+00 9.9614e-01 3.8611e-03 9.2445e-01 7.5555e-02 1.0000e-10 1.0000e-10 5.2939e-04 2.0519e-06 + 8.3000e-04 -8.3038e+00 9.9609e-01 3.9139e-03 9.2355e-01 7.6448e-02 1.0000e-10 1.0000e-10 5.3576e-04 2.1052e-06 + 8.4000e-04 -8.3034e+00 9.9603e-01 3.9670e-03 9.2266e-01 7.7341e-02 1.0000e-10 1.0000e-10 5.4212e-04 2.1591e-06 + 8.5000e-04 -8.3030e+00 9.9598e-01 4.0202e-03 9.2177e-01 7.8233e-02 1.0000e-10 1.0000e-10 5.4848e-04 2.2139e-06 + 8.6000e-04 -8.3026e+00 9.9593e-01 4.0735e-03 9.2088e-01 7.9125e-02 1.0000e-10 1.0000e-10 5.5484e-04 2.2694e-06 + 8.7000e-04 -8.3022e+00 9.9587e-01 4.1270e-03 9.1998e-01 8.0016e-02 1.0000e-10 1.0000e-10 5.6120e-04 2.3257e-06 + 8.8000e-04 -8.3018e+00 9.9582e-01 4.1807e-03 9.1909e-01 8.0906e-02 1.0000e-10 1.0000e-10 5.6755e-04 2.3827e-06 + 8.9000e-04 -8.3014e+00 9.9577e-01 4.2346e-03 9.1820e-01 8.1795e-02 1.0000e-10 1.0000e-10 5.7390e-04 2.4406e-06 + 9.0000e-04 -8.3010e+00 9.9571e-01 4.2886e-03 9.1732e-01 8.2684e-02 1.0000e-10 1.0000e-10 5.8025e-04 2.4992e-06 + 9.1000e-04 -8.3006e+00 9.9566e-01 4.3427e-03 9.1643e-01 8.3572e-02 1.0000e-10 1.0000e-10 5.8660e-04 2.5586e-06 + 9.2000e-04 -8.3002e+00 9.9560e-01 4.3971e-03 9.1554e-01 8.4460e-02 1.0000e-10 1.0000e-10 5.9295e-04 2.6187e-06 + 9.3000e-04 -8.2999e+00 9.9555e-01 4.4516e-03 9.1465e-01 8.5347e-02 1.0000e-10 1.0000e-10 5.9929e-04 2.6797e-06 + 9.4000e-04 -8.2995e+00 9.9549e-01 4.5062e-03 9.1377e-01 8.6233e-02 1.0000e-10 1.0000e-10 6.0563e-04 2.7415e-06 + 9.5000e-04 -8.2991e+00 9.9544e-01 4.5611e-03 9.1288e-01 8.7118e-02 1.0000e-10 1.0000e-10 6.1197e-04 2.8040e-06 + 9.6000e-04 -8.2987e+00 9.9538e-01 4.6161e-03 9.1200e-01 8.8003e-02 1.0000e-10 1.0000e-10 6.1831e-04 2.8674e-06 + 9.7000e-04 -8.2983e+00 9.9533e-01 4.6713e-03 9.1111e-01 8.8887e-02 1.0000e-10 1.0000e-10 6.2464e-04 2.9316e-06 + 9.8000e-04 -8.2979e+00 9.9527e-01 4.7266e-03 9.1023e-01 8.9770e-02 1.0000e-10 1.0000e-10 6.3097e-04 2.9965e-06 + 9.9000e-04 -8.2975e+00 9.9522e-01 4.7821e-03 9.0935e-01 9.0653e-02 1.0000e-10 1.0000e-10 6.3730e-04 3.0623e-06 + 1.0000e-03 -8.2974e+00 9.8567e-01 1.4329e-02 9.0901e-01 9.0987e-02 6.4175e-04 7.2473e-06 6.3970e-04 9.2997e-06 + 1.0100e-03 -8.2974e+00 9.7071e-01 2.9286e-02 9.0901e-01 9.0987e-02 6.4009e-04 1.8914e-05 6.3970e-04 1.9300e-05 + 1.0200e-03 -8.2974e+00 9.5620e-01 4.3796e-02 9.0901e-01 9.0987e-02 6.3842e-04 3.0580e-05 6.3970e-04 2.9300e-05 + 1.0300e-03 -8.2974e+00 9.4212e-01 5.7879e-02 9.0901e-01 9.0987e-02 6.3675e-04 4.2246e-05 6.3970e-04 3.9300e-05 + 1.0400e-03 -8.2974e+00 9.2845e-01 7.1552e-02 9.0901e-01 9.0987e-02 6.3509e-04 5.3912e-05 6.3970e-04 4.9300e-05 + 1.0500e-03 -8.2974e+00 9.1516e-01 8.4835e-02 9.0901e-01 9.0987e-02 6.3342e-04 6.5578e-05 6.3970e-04 5.9300e-05 + 1.0600e-03 -8.2974e+00 9.0226e-01 9.7743e-02 9.0901e-01 9.0987e-02 6.3176e-04 7.7245e-05 6.3970e-04 6.9300e-05 + 1.0700e-03 -8.2974e+00 8.8971e-01 1.1029e-01 9.0901e-01 9.0987e-02 6.3009e-04 8.8911e-05 6.3970e-04 7.9300e-05 + 1.0800e-03 -8.2974e+00 8.7750e-01 1.2250e-01 9.0901e-01 9.0987e-02 6.2842e-04 1.0058e-04 6.3970e-04 8.9300e-05 + 1.0900e-03 -8.2974e+00 8.6563e-01 1.3437e-01 9.0901e-01 9.0987e-02 6.2676e-04 1.1224e-04 6.3970e-04 9.9300e-05 + 1.1000e-03 -8.2974e+00 8.5407e-01 1.4593e-01 9.0901e-01 9.0987e-02 6.2509e-04 1.2391e-04 6.3970e-04 1.0930e-04 + 1.1100e-03 -8.2974e+00 8.4282e-01 1.5718e-01 9.0901e-01 9.0987e-02 6.2342e-04 1.3558e-04 6.3970e-04 1.1930e-04 + 1.1200e-03 -8.2974e+00 8.3186e-01 1.6814e-01 9.0901e-01 9.0987e-02 6.2176e-04 1.4724e-04 6.3970e-04 1.2930e-04 + 1.1300e-03 -8.2974e+00 8.2118e-01 1.7882e-01 9.0901e-01 9.0987e-02 6.2009e-04 1.5891e-04 6.3970e-04 1.3930e-04 + 1.1400e-03 -8.2974e+00 8.1077e-01 1.8923e-01 9.0901e-01 9.0987e-02 6.1843e-04 1.7057e-04 6.3970e-04 1.4930e-04 + 1.1500e-03 -8.2974e+00 8.0063e-01 1.9937e-01 9.0901e-01 9.0987e-02 6.1676e-04 1.8224e-04 6.3970e-04 1.5930e-04 + 1.1600e-03 -8.2974e+00 7.9073e-01 2.0927e-01 9.0901e-01 9.0987e-02 6.1509e-04 1.9391e-04 6.3970e-04 1.6930e-04 + 1.1700e-03 -8.2974e+00 7.8107e-01 2.1893e-01 9.0901e-01 9.0987e-02 6.1343e-04 2.0557e-04 6.3970e-04 1.7930e-04 + 1.1800e-03 -8.2974e+00 7.7165e-01 2.2835e-01 9.0901e-01 9.0987e-02 6.1176e-04 2.1724e-04 6.3970e-04 1.8930e-04 + 1.1900e-03 -8.2974e+00 7.6246e-01 2.3754e-01 9.0901e-01 9.0987e-02 6.1009e-04 2.2891e-04 6.3970e-04 1.9930e-04 + 1.2000e-03 -8.2974e+00 7.5348e-01 2.4652e-01 9.0901e-01 9.0987e-02 6.0843e-04 2.4057e-04 6.3970e-04 2.0930e-04 + 1.2100e-03 -8.2974e+00 7.4470e-01 2.5530e-01 9.0901e-01 9.0987e-02 6.0676e-04 2.5224e-04 6.3970e-04 2.1930e-04 + 1.2200e-03 -8.2974e+00 7.3613e-01 2.6387e-01 9.0901e-01 9.0987e-02 6.0510e-04 2.6390e-04 6.3970e-04 2.2930e-04 + 1.2300e-03 -8.2974e+00 7.2776e-01 2.7224e-01 9.0901e-01 9.0987e-02 6.0343e-04 2.7557e-04 6.3970e-04 2.3930e-04 + 1.2400e-03 -8.2974e+00 7.1957e-01 2.8043e-01 9.0901e-01 9.0987e-02 6.0176e-04 2.8724e-04 6.3970e-04 2.4930e-04 + 1.2500e-03 -8.2974e+00 7.1157e-01 2.8843e-01 9.0901e-01 9.0987e-02 6.0010e-04 2.9890e-04 6.3970e-04 2.5930e-04 + 1.2600e-03 -8.2974e+00 7.0374e-01 2.9626e-01 9.0901e-01 9.0987e-02 5.9843e-04 3.1057e-04 6.3970e-04 2.6930e-04 + 1.2700e-03 -8.2974e+00 6.9608e-01 3.0392e-01 9.0901e-01 9.0987e-02 5.9677e-04 3.2223e-04 6.3970e-04 2.7930e-04 + 1.2800e-03 -8.2974e+00 6.8859e-01 3.1141e-01 9.0901e-01 9.0987e-02 5.9510e-04 3.3390e-04 6.3970e-04 2.8930e-04 + 1.2900e-03 -8.2974e+00 6.8126e-01 3.1874e-01 9.0901e-01 9.0987e-02 5.9343e-04 3.4557e-04 6.3970e-04 2.9930e-04 + 1.3000e-03 -8.2974e+00 6.7408e-01 3.2592e-01 9.0901e-01 9.0987e-02 5.9177e-04 3.5723e-04 6.3970e-04 3.0930e-04 + 1.3100e-03 -8.2974e+00 6.6705e-01 3.3295e-01 9.0901e-01 9.0987e-02 5.9010e-04 3.6890e-04 6.3970e-04 3.1930e-04 + 1.3200e-03 -8.2974e+00 6.6017e-01 3.3983e-01 9.0901e-01 9.0987e-02 5.8843e-04 3.8057e-04 6.3970e-04 3.2930e-04 + 1.3300e-03 -8.2974e+00 6.5342e-01 3.4658e-01 9.0901e-01 9.0987e-02 5.8677e-04 3.9223e-04 6.3970e-04 3.3930e-04 + 1.3400e-03 -8.2974e+00 6.4682e-01 3.5318e-01 9.0901e-01 9.0987e-02 5.8510e-04 4.0390e-04 6.3970e-04 3.4930e-04 + 1.3500e-03 -8.2974e+00 6.4034e-01 3.5966e-01 9.0901e-01 9.0987e-02 5.8344e-04 4.1556e-04 6.3970e-04 3.5930e-04 + 1.3600e-03 -8.2974e+00 6.3399e-01 3.6601e-01 9.0901e-01 9.0987e-02 5.8177e-04 4.2723e-04 6.3970e-04 3.6930e-04 + 1.3700e-03 -8.2974e+00 6.2777e-01 3.7223e-01 9.0901e-01 9.0987e-02 5.8010e-04 4.3890e-04 6.3970e-04 3.7930e-04 + 1.3800e-03 -8.2974e+00 6.2167e-01 3.7833e-01 9.0901e-01 9.0987e-02 5.7844e-04 4.5056e-04 6.3970e-04 3.8930e-04 + 1.3900e-03 -8.2974e+00 6.1569e-01 3.8431e-01 9.0901e-01 9.0987e-02 5.7677e-04 4.6223e-04 6.3970e-04 3.9930e-04 + 1.4000e-03 -8.2974e+00 6.0982e-01 3.9018e-01 9.0901e-01 9.0987e-02 5.7510e-04 4.7390e-04 6.3970e-04 4.0930e-04 + 1.4100e-03 -8.2974e+00 6.0406e-01 3.9594e-01 9.0901e-01 9.0987e-02 5.7344e-04 4.8556e-04 6.3970e-04 4.1930e-04 + 1.4200e-03 -8.2974e+00 5.9841e-01 4.0159e-01 9.0901e-01 9.0987e-02 5.7177e-04 4.9723e-04 6.3970e-04 4.2930e-04 + 1.4300e-03 -8.2974e+00 5.9286e-01 4.0714e-01 9.0901e-01 9.0987e-02 5.7011e-04 5.0889e-04 6.3970e-04 4.3930e-04 + 1.4400e-03 -8.2974e+00 5.8742e-01 4.1258e-01 9.0901e-01 9.0987e-02 5.6844e-04 5.2056e-04 6.3970e-04 4.4930e-04 + 1.4500e-03 -8.2974e+00 5.8207e-01 4.1793e-01 9.0901e-01 9.0987e-02 5.6677e-04 5.3223e-04 6.3970e-04 4.5930e-04 + 1.4600e-03 -8.2974e+00 5.7683e-01 4.2317e-01 9.0901e-01 9.0987e-02 5.6511e-04 5.4389e-04 6.3970e-04 4.6930e-04 + 1.4700e-03 -8.2974e+00 5.7167e-01 4.2833e-01 9.0901e-01 9.0987e-02 5.6344e-04 5.5556e-04 6.3970e-04 4.7930e-04 + 1.4800e-03 -8.2974e+00 5.6661e-01 4.3339e-01 9.0901e-01 9.0987e-02 5.6178e-04 5.6723e-04 6.3970e-04 4.8930e-04 + 1.4900e-03 -8.2974e+00 5.6163e-01 4.3837e-01 9.0901e-01 9.0987e-02 5.6011e-04 5.7889e-04 6.3970e-04 4.9930e-04 + 1.5000e-03 -8.2974e+00 5.5675e-01 4.4325e-01 9.0901e-01 9.0987e-02 5.5844e-04 5.9056e-04 6.3970e-04 5.0930e-04 + 1.5100e-03 -8.2974e+00 5.5194e-01 4.4806e-01 9.0901e-01 9.0987e-02 5.5678e-04 6.0222e-04 6.3970e-04 5.1930e-04 + 1.5200e-03 -8.2974e+00 5.4722e-01 4.5278e-01 9.0901e-01 9.0987e-02 5.5511e-04 6.1389e-04 6.3970e-04 5.2930e-04 + 1.5300e-03 -8.2974e+00 5.4258e-01 4.5742e-01 9.0901e-01 9.0987e-02 5.5344e-04 6.2556e-04 6.3970e-04 5.3930e-04 + 1.5400e-03 -8.2974e+00 5.3802e-01 4.6198e-01 9.0901e-01 9.0987e-02 5.5178e-04 6.3722e-04 6.3970e-04 5.4930e-04 + 1.5500e-03 -8.2974e+00 5.3353e-01 4.6647e-01 9.0901e-01 9.0987e-02 5.5011e-04 6.4889e-04 6.3970e-04 5.5930e-04 + 1.5600e-03 -8.2974e+00 5.2912e-01 4.7088e-01 9.0901e-01 9.0987e-02 5.4845e-04 6.6055e-04 6.3970e-04 5.6930e-04 + 1.5700e-03 -8.2974e+00 5.2477e-01 4.7523e-01 9.0901e-01 9.0987e-02 5.4678e-04 6.7222e-04 6.3970e-04 5.7930e-04 + 1.5800e-03 -8.2974e+00 5.2050e-01 4.7950e-01 9.0901e-01 9.0987e-02 5.4511e-04 6.8389e-04 6.3970e-04 5.8930e-04 + 1.5900e-03 -8.2974e+00 5.1630e-01 4.8370e-01 9.0901e-01 9.0987e-02 5.4345e-04 6.9555e-04 6.3970e-04 5.9930e-04 + 1.6000e-03 -8.2974e+00 5.1217e-01 4.8783e-01 9.0901e-01 9.0987e-02 5.4178e-04 7.0722e-04 6.3970e-04 6.0930e-04 + 1.6100e-03 -8.2974e+00 5.0810e-01 4.9190e-01 9.0901e-01 9.0987e-02 5.4011e-04 7.1889e-04 6.3970e-04 6.1930e-04 + 1.6200e-03 -8.2974e+00 5.0410e-01 4.9590e-01 9.0901e-01 9.0987e-02 5.3845e-04 7.3055e-04 6.3970e-04 6.2930e-04 + 1.6300e-03 -8.2974e+00 5.0016e-01 4.9984e-01 9.0901e-01 9.0987e-02 5.3678e-04 7.4222e-04 6.3970e-04 6.3930e-04 + 1.6400e-03 -8.2974e+00 4.9628e-01 5.0372e-01 9.0901e-01 9.0987e-02 5.3512e-04 7.5388e-04 6.3970e-04 6.4930e-04 + 1.6500e-03 -8.2974e+00 4.9246e-01 5.0754e-01 9.0901e-01 9.0987e-02 5.3345e-04 7.6555e-04 6.3970e-04 6.5930e-04 + 1.6600e-03 -8.2974e+00 4.8869e-01 5.1131e-01 9.0901e-01 9.0987e-02 5.3178e-04 7.7722e-04 6.3970e-04 6.6930e-04 + 1.6700e-03 -8.2974e+00 4.8499e-01 5.1501e-01 9.0901e-01 9.0987e-02 5.3012e-04 7.8888e-04 6.3970e-04 6.7930e-04 + 1.6800e-03 -8.2974e+00 4.8134e-01 5.1866e-01 9.0901e-01 9.0987e-02 5.2845e-04 8.0055e-04 6.3970e-04 6.8930e-04 + 1.6900e-03 -8.2974e+00 4.7774e-01 5.2226e-01 9.0901e-01 9.0987e-02 5.2678e-04 8.1222e-04 6.3970e-04 6.9930e-04 + 1.7000e-03 -8.2974e+00 4.7420e-01 5.2580e-01 9.0901e-01 9.0987e-02 5.2512e-04 8.2388e-04 6.3970e-04 7.0930e-04 + 1.7100e-03 -8.2974e+00 4.7071e-01 5.2929e-01 9.0901e-01 9.0987e-02 5.2345e-04 8.3555e-04 6.3970e-04 7.1930e-04 + 1.7200e-03 -8.2974e+00 4.6728e-01 5.3272e-01 9.0901e-01 9.0987e-02 5.2179e-04 8.4721e-04 6.3970e-04 7.2930e-04 + 1.7300e-03 -8.2974e+00 4.6389e-01 5.3611e-01 9.0901e-01 9.0987e-02 5.2012e-04 8.5888e-04 6.3970e-04 7.3930e-04 + 1.7400e-03 -8.2974e+00 4.6055e-01 5.3945e-01 9.0901e-01 9.0987e-02 5.1845e-04 8.7055e-04 6.3970e-04 7.4930e-04 + 1.7500e-03 -8.2974e+00 4.5726e-01 5.4274e-01 9.0901e-01 9.0987e-02 5.1679e-04 8.8221e-04 6.3970e-04 7.5930e-04 + 1.7600e-03 -8.2974e+00 4.5401e-01 5.4599e-01 9.0901e-01 9.0987e-02 5.1512e-04 8.9388e-04 6.3970e-04 7.6930e-04 + 1.7700e-03 -8.2974e+00 4.5081e-01 5.4919e-01 9.0901e-01 9.0987e-02 5.1346e-04 9.0554e-04 6.3970e-04 7.7930e-04 + 1.7800e-03 -8.2974e+00 4.4766e-01 5.5234e-01 9.0901e-01 9.0987e-02 5.1179e-04 9.1721e-04 6.3970e-04 7.8930e-04 + 1.7900e-03 -8.2974e+00 4.4455e-01 5.5545e-01 9.0901e-01 9.0987e-02 5.1012e-04 9.2888e-04 6.3970e-04 7.9930e-04 + 1.8000e-03 -8.2974e+00 4.4148e-01 5.5852e-01 9.0901e-01 9.0987e-02 5.0846e-04 9.4054e-04 6.3970e-04 8.0930e-04 + 1.8100e-03 -8.2974e+00 4.3845e-01 5.6155e-01 9.0901e-01 9.0987e-02 5.0679e-04 9.5221e-04 6.3970e-04 8.1930e-04 + 1.8200e-03 -8.2974e+00 4.3547e-01 5.6453e-01 9.0901e-01 9.0987e-02 5.0512e-04 9.6388e-04 6.3970e-04 8.2930e-04 + 1.8300e-03 -8.2974e+00 4.3252e-01 5.6748e-01 9.0901e-01 9.0987e-02 5.0346e-04 9.7554e-04 6.3970e-04 8.3930e-04 + 1.8400e-03 -8.2974e+00 4.2962e-01 5.7038e-01 9.0901e-01 9.0987e-02 5.0179e-04 9.8721e-04 6.3970e-04 8.4930e-04 + 1.8500e-03 -8.2974e+00 4.2675e-01 5.7325e-01 9.0901e-01 9.0987e-02 5.0013e-04 9.9887e-04 6.3970e-04 8.5930e-04 + 1.8600e-03 -8.2974e+00 4.2392e-01 5.7608e-01 9.0901e-01 9.0987e-02 4.9846e-04 1.0105e-03 6.3970e-04 8.6930e-04 + 1.8700e-03 -8.2974e+00 4.2113e-01 5.7887e-01 9.0901e-01 9.0987e-02 4.9679e-04 1.0222e-03 6.3970e-04 8.7930e-04 + 1.8800e-03 -8.2974e+00 4.1838e-01 5.8162e-01 9.0901e-01 9.0987e-02 4.9513e-04 1.0339e-03 6.3970e-04 8.8930e-04 + 1.8900e-03 -8.2974e+00 4.1566e-01 5.8434e-01 9.0901e-01 9.0987e-02 4.9346e-04 1.0455e-03 6.3970e-04 8.9930e-04 + 1.9000e-03 -8.2974e+00 4.1298e-01 5.8702e-01 9.0901e-01 9.0987e-02 4.9179e-04 1.0572e-03 6.3970e-04 9.0930e-04 + 1.9100e-03 -8.2974e+00 4.1033e-01 5.8967e-01 9.0901e-01 9.0987e-02 4.9013e-04 1.0689e-03 6.3970e-04 9.1930e-04 + 1.9200e-03 -8.2974e+00 4.0771e-01 5.9229e-01 9.0901e-01 9.0987e-02 4.8846e-04 1.0805e-03 6.3970e-04 9.2930e-04 + 1.9300e-03 -8.2974e+00 4.0513e-01 5.9487e-01 9.0901e-01 9.0987e-02 4.8680e-04 1.0922e-03 6.3970e-04 9.3930e-04 + 1.9400e-03 -8.2974e+00 4.0258e-01 5.9742e-01 9.0901e-01 9.0987e-02 4.8513e-04 1.1039e-03 6.3970e-04 9.4930e-04 + 1.9500e-03 -8.2974e+00 4.0006e-01 5.9994e-01 9.0901e-01 9.0987e-02 4.8346e-04 1.1155e-03 6.3970e-04 9.5930e-04 + 1.9600e-03 -8.2974e+00 3.9758e-01 6.0242e-01 9.0901e-01 9.0987e-02 4.8180e-04 1.1272e-03 6.3970e-04 9.6930e-04 + 1.9700e-03 -8.2974e+00 3.9512e-01 6.0488e-01 9.0901e-01 9.0987e-02 4.8013e-04 1.1389e-03 6.3970e-04 9.7930e-04 + 1.9800e-03 -8.2974e+00 3.9270e-01 6.0730e-01 9.0901e-01 9.0987e-02 4.7846e-04 1.1505e-03 6.3970e-04 9.8930e-04 + 1.9900e-03 -8.2974e+00 3.9030e-01 6.0970e-01 9.0901e-01 9.0987e-02 4.7680e-04 1.1622e-03 6.3970e-04 9.9930e-04 + 2.0000e-03 -8.2974e+00 3.8793e-01 6.1207e-01 9.0901e-01 9.0987e-02 4.7513e-04 1.1739e-03 6.3970e-04 1.0093e-03 + 2.0100e-03 -8.2974e+00 3.8559e-01 6.1441e-01 9.0901e-01 9.0987e-02 4.7347e-04 1.1855e-03 6.3970e-04 1.0193e-03 + 2.0200e-03 -8.2974e+00 3.8328e-01 6.1672e-01 9.0901e-01 9.0987e-02 4.7180e-04 1.1972e-03 6.3970e-04 1.0293e-03 + 2.0300e-03 -8.2974e+00 3.8100e-01 6.1900e-01 9.0901e-01 9.0987e-02 4.7013e-04 1.2089e-03 6.3970e-04 1.0393e-03 + 2.0400e-03 -8.2974e+00 3.7875e-01 6.2125e-01 9.0901e-01 9.0987e-02 4.6847e-04 1.2205e-03 6.3970e-04 1.0493e-03 + 2.0500e-03 -8.2974e+00 3.7652e-01 6.2348e-01 9.0901e-01 9.0987e-02 4.6680e-04 1.2322e-03 6.3970e-04 1.0593e-03 + 2.0600e-03 -8.2974e+00 3.7431e-01 6.2569e-01 9.0901e-01 9.0987e-02 4.6514e-04 1.2439e-03 6.3970e-04 1.0693e-03 + 2.0700e-03 -8.2974e+00 3.7214e-01 6.2786e-01 9.0901e-01 9.0987e-02 4.6347e-04 1.2555e-03 6.3970e-04 1.0793e-03 + 2.0800e-03 -8.2974e+00 3.6998e-01 6.3002e-01 9.0901e-01 9.0987e-02 4.6180e-04 1.2672e-03 6.3970e-04 1.0893e-03 + 2.0900e-03 -8.2974e+00 3.6786e-01 6.3214e-01 9.0901e-01 9.0987e-02 4.6014e-04 1.2789e-03 6.3970e-04 1.0993e-03 + 2.1000e-03 -8.2974e+00 3.6575e-01 6.3425e-01 9.0901e-01 9.0987e-02 4.5847e-04 1.2905e-03 6.3970e-04 1.1093e-03 + 2.1100e-03 -8.2974e+00 3.6367e-01 6.3633e-01 9.0901e-01 9.0987e-02 4.5680e-04 1.3022e-03 6.3970e-04 1.1193e-03 + 2.1200e-03 -8.2974e+00 3.6162e-01 6.3838e-01 9.0901e-01 9.0987e-02 4.5514e-04 1.3139e-03 6.3970e-04 1.1293e-03 + 2.1300e-03 -8.2974e+00 3.5958e-01 6.4042e-01 9.0901e-01 9.0987e-02 4.5347e-04 1.3255e-03 6.3970e-04 1.1393e-03 + 2.1400e-03 -8.2974e+00 3.5757e-01 6.4243e-01 9.0901e-01 9.0987e-02 4.5181e-04 1.3372e-03 6.3970e-04 1.1493e-03 + 2.1500e-03 -8.2974e+00 3.5559e-01 6.4441e-01 9.0901e-01 9.0987e-02 4.5014e-04 1.3489e-03 6.3970e-04 1.1593e-03 + 2.1600e-03 -8.2974e+00 3.5362e-01 6.4638e-01 9.0901e-01 9.0987e-02 4.4847e-04 1.3605e-03 6.3970e-04 1.1693e-03 + 2.1700e-03 -8.2974e+00 3.5168e-01 6.4832e-01 9.0901e-01 9.0987e-02 4.4681e-04 1.3722e-03 6.3970e-04 1.1793e-03 + 2.1800e-03 -8.2974e+00 3.4975e-01 6.5025e-01 9.0901e-01 9.0987e-02 4.4514e-04 1.3839e-03 6.3970e-04 1.1893e-03 + 2.1900e-03 -8.2974e+00 3.4785e-01 6.5215e-01 9.0901e-01 9.0987e-02 4.4347e-04 1.3955e-03 6.3970e-04 1.1993e-03 + 2.2000e-03 -8.2974e+00 3.4597e-01 6.5403e-01 9.0901e-01 9.0987e-02 4.4181e-04 1.4072e-03 6.3970e-04 1.2093e-03 + 2.2100e-03 -8.2974e+00 3.4411e-01 6.5589e-01 9.0901e-01 9.0987e-02 4.4014e-04 1.4189e-03 6.3970e-04 1.2193e-03 + 2.2200e-03 -8.2974e+00 3.4227e-01 6.5773e-01 9.0901e-01 9.0987e-02 4.3848e-04 1.4305e-03 6.3970e-04 1.2293e-03 + 2.2300e-03 -8.2974e+00 3.4045e-01 6.5955e-01 9.0901e-01 9.0987e-02 4.3681e-04 1.4422e-03 6.3970e-04 1.2393e-03 + 2.2400e-03 -8.2974e+00 3.3864e-01 6.6136e-01 9.0901e-01 9.0987e-02 4.3514e-04 1.4539e-03 6.3970e-04 1.2493e-03 + 2.2500e-03 -8.2974e+00 3.3686e-01 6.6314e-01 9.0901e-01 9.0987e-02 4.3348e-04 1.4655e-03 6.3970e-04 1.2593e-03 + 2.2600e-03 -8.2974e+00 3.3510e-01 6.6490e-01 9.0901e-01 9.0987e-02 4.3181e-04 1.4772e-03 6.3970e-04 1.2693e-03 + 2.2700e-03 -8.2974e+00 3.3335e-01 6.6665e-01 9.0901e-01 9.0987e-02 4.3015e-04 1.4889e-03 6.3970e-04 1.2793e-03 + 2.2800e-03 -8.2974e+00 3.3162e-01 6.6838e-01 9.0901e-01 9.0987e-02 4.2848e-04 1.5005e-03 6.3970e-04 1.2893e-03 + 2.2900e-03 -8.2974e+00 3.2991e-01 6.7009e-01 9.0901e-01 9.0987e-02 4.2681e-04 1.5122e-03 6.3970e-04 1.2993e-03 + 2.3000e-03 -8.2974e+00 3.2822e-01 6.7178e-01 9.0901e-01 9.0987e-02 4.2515e-04 1.5239e-03 6.3970e-04 1.3093e-03 + 2.3100e-03 -8.2974e+00 3.2654e-01 6.7346e-01 9.0901e-01 9.0987e-02 4.2348e-04 1.5355e-03 6.3970e-04 1.3193e-03 + 2.3200e-03 -8.2974e+00 3.2489e-01 6.7511e-01 9.0901e-01 9.0987e-02 4.2181e-04 1.5472e-03 6.3970e-04 1.3293e-03 + 2.3300e-03 -8.2974e+00 3.2324e-01 6.7676e-01 9.0901e-01 9.0987e-02 4.2015e-04 1.5589e-03 6.3970e-04 1.3393e-03 + 2.3400e-03 -8.2974e+00 3.2162e-01 6.7838e-01 9.0901e-01 9.0987e-02 4.1848e-04 1.5705e-03 6.3970e-04 1.3493e-03 + 2.3500e-03 -8.2974e+00 3.2001e-01 6.7999e-01 9.0901e-01 9.0987e-02 4.1682e-04 1.5822e-03 6.3970e-04 1.3593e-03 + 2.3600e-03 -8.2974e+00 3.1842e-01 6.8158e-01 9.0901e-01 9.0987e-02 4.1515e-04 1.5939e-03 6.3970e-04 1.3693e-03 + 2.3700e-03 -8.2974e+00 3.1684e-01 6.8316e-01 9.0901e-01 9.0987e-02 4.1348e-04 1.6055e-03 6.3970e-04 1.3793e-03 + 2.3800e-03 -8.2974e+00 3.1528e-01 6.8472e-01 9.0901e-01 9.0987e-02 4.1182e-04 1.6172e-03 6.3970e-04 1.3893e-03 + 2.3900e-03 -8.2974e+00 3.1373e-01 6.8627e-01 9.0901e-01 9.0987e-02 4.1015e-04 1.6288e-03 6.3970e-04 1.3993e-03 + 2.4000e-03 -8.2974e+00 3.1220e-01 6.8780e-01 9.0901e-01 9.0987e-02 4.0848e-04 1.6405e-03 6.3970e-04 1.4093e-03 + 2.4100e-03 -8.2974e+00 3.1068e-01 6.8932e-01 9.0901e-01 9.0987e-02 4.0682e-04 1.6522e-03 6.3970e-04 1.4193e-03 + 2.4200e-03 -8.2974e+00 3.0918e-01 6.9082e-01 9.0901e-01 9.0987e-02 4.0515e-04 1.6638e-03 6.3970e-04 1.4293e-03 + 2.4300e-03 -8.2974e+00 3.0770e-01 6.9230e-01 9.0901e-01 9.0987e-02 4.0349e-04 1.6755e-03 6.3970e-04 1.4393e-03 + 2.4400e-03 -8.2974e+00 3.0622e-01 6.9378e-01 9.0901e-01 9.0987e-02 4.0182e-04 1.6872e-03 6.3970e-04 1.4493e-03 + 2.4500e-03 -8.2974e+00 3.0476e-01 6.9524e-01 9.0901e-01 9.0987e-02 4.0015e-04 1.6988e-03 6.3970e-04 1.4593e-03 + 2.4600e-03 -8.2974e+00 3.0332e-01 6.9668e-01 9.0901e-01 9.0987e-02 3.9849e-04 1.7105e-03 6.3970e-04 1.4693e-03 + 2.4700e-03 -8.2974e+00 3.0189e-01 6.9811e-01 9.0901e-01 9.0987e-02 3.9682e-04 1.7222e-03 6.3970e-04 1.4793e-03 + 2.4800e-03 -8.2974e+00 3.0047e-01 6.9953e-01 9.0901e-01 9.0987e-02 3.9515e-04 1.7338e-03 6.3970e-04 1.4893e-03 + 2.4900e-03 -8.2974e+00 2.9907e-01 7.0093e-01 9.0901e-01 9.0987e-02 3.9349e-04 1.7455e-03 6.3970e-04 1.4993e-03 + 2.5000e-03 -8.2974e+00 2.9767e-01 7.0233e-01 9.0901e-01 9.0987e-02 3.9182e-04 1.7572e-03 6.3970e-04 1.5093e-03 + 2.5100e-03 -8.2974e+00 2.9629e-01 7.0371e-01 9.0901e-01 9.0987e-02 3.9016e-04 1.7688e-03 6.3970e-04 1.5193e-03 + 2.5200e-03 -8.2974e+00 2.9493e-01 7.0507e-01 9.0901e-01 9.0987e-02 3.8849e-04 1.7805e-03 6.3970e-04 1.5293e-03 + 2.5300e-03 -8.2974e+00 2.9358e-01 7.0642e-01 9.0901e-01 9.0987e-02 3.8682e-04 1.7922e-03 6.3970e-04 1.5393e-03 + 2.5400e-03 -8.2974e+00 2.9223e-01 7.0777e-01 9.0901e-01 9.0987e-02 3.8516e-04 1.8038e-03 6.3970e-04 1.5493e-03 + 2.5500e-03 -8.2974e+00 2.9091e-01 7.0909e-01 9.0901e-01 9.0987e-02 3.8349e-04 1.8155e-03 6.3970e-04 1.5593e-03 + 2.5600e-03 -8.2974e+00 2.8959e-01 7.1041e-01 9.0901e-01 9.0987e-02 3.8183e-04 1.8272e-03 6.3970e-04 1.5693e-03 + 2.5700e-03 -8.2974e+00 2.8828e-01 7.1172e-01 9.0901e-01 9.0987e-02 3.8016e-04 1.8388e-03 6.3970e-04 1.5793e-03 + 2.5800e-03 -8.2974e+00 2.8699e-01 7.1301e-01 9.0901e-01 9.0987e-02 3.7849e-04 1.8505e-03 6.3970e-04 1.5893e-03 + 2.5900e-03 -8.2974e+00 2.8571e-01 7.1429e-01 9.0901e-01 9.0987e-02 3.7683e-04 1.8622e-03 6.3970e-04 1.5993e-03 + 2.6000e-03 -8.2974e+00 2.8444e-01 7.1556e-01 9.0901e-01 9.0987e-02 3.7516e-04 1.8738e-03 6.3970e-04 1.6093e-03 + 2.6100e-03 -8.2974e+00 2.8318e-01 7.1682e-01 9.0901e-01 9.0987e-02 3.7349e-04 1.8855e-03 6.3970e-04 1.6193e-03 + 2.6200e-03 -8.2974e+00 2.8193e-01 7.1807e-01 9.0901e-01 9.0987e-02 3.7183e-04 1.8972e-03 6.3970e-04 1.6293e-03 + 2.6300e-03 -8.2974e+00 2.8069e-01 7.1931e-01 9.0901e-01 9.0987e-02 3.7016e-04 1.9088e-03 6.3970e-04 1.6393e-03 + 2.6400e-03 -8.2974e+00 2.7947e-01 7.2053e-01 9.0901e-01 9.0987e-02 3.6850e-04 1.9205e-03 6.3970e-04 1.6493e-03 + 2.6500e-03 -8.2974e+00 2.7825e-01 7.2175e-01 9.0901e-01 9.0987e-02 3.6683e-04 1.9322e-03 6.3970e-04 1.6593e-03 + 2.6600e-03 -8.2974e+00 2.7705e-01 7.2295e-01 9.0901e-01 9.0987e-02 3.6516e-04 1.9438e-03 6.3970e-04 1.6693e-03 + 2.6700e-03 -8.2974e+00 2.7585e-01 7.2415e-01 9.0901e-01 9.0987e-02 3.6350e-04 1.9555e-03 6.3970e-04 1.6793e-03 + 2.6800e-03 -8.2974e+00 2.7467e-01 7.2533e-01 9.0901e-01 9.0987e-02 3.6183e-04 1.9672e-03 6.3970e-04 1.6893e-03 + 2.6900e-03 -8.2974e+00 2.7349e-01 7.2651e-01 9.0901e-01 9.0987e-02 3.6016e-04 1.9788e-03 6.3970e-04 1.6993e-03 + 2.7000e-03 -8.2974e+00 2.7233e-01 7.2767e-01 9.0901e-01 9.0987e-02 3.5850e-04 1.9905e-03 6.3970e-04 1.7093e-03 + 2.7100e-03 -8.2974e+00 2.7117e-01 7.2883e-01 9.0901e-01 9.0987e-02 3.5683e-04 2.0022e-03 6.3970e-04 1.7193e-03 + 2.7200e-03 -8.2974e+00 2.7003e-01 7.2997e-01 9.0901e-01 9.0987e-02 3.5517e-04 2.0138e-03 6.3970e-04 1.7293e-03 + 2.7300e-03 -8.2974e+00 2.6889e-01 7.3111e-01 9.0901e-01 9.0987e-02 3.5350e-04 2.0255e-03 6.3970e-04 1.7393e-03 + 2.7400e-03 -8.2974e+00 2.6777e-01 7.3223e-01 9.0901e-01 9.0987e-02 3.5183e-04 2.0372e-03 6.3970e-04 1.7493e-03 + 2.7500e-03 -8.2974e+00 2.6665e-01 7.3335e-01 9.0901e-01 9.0987e-02 3.5017e-04 2.0488e-03 6.3970e-04 1.7593e-03 + 2.7600e-03 -8.2974e+00 2.6555e-01 7.3445e-01 9.0901e-01 9.0987e-02 3.4850e-04 2.0605e-03 6.3970e-04 1.7693e-03 + 2.7700e-03 -8.2974e+00 2.6445e-01 7.3555e-01 9.0901e-01 9.0987e-02 3.4683e-04 2.0722e-03 6.3970e-04 1.7793e-03 + 2.7800e-03 -8.2974e+00 2.6336e-01 7.3664e-01 9.0901e-01 9.0987e-02 3.4517e-04 2.0838e-03 6.3970e-04 1.7893e-03 + 2.7900e-03 -8.2974e+00 2.6228e-01 7.3772e-01 9.0901e-01 9.0987e-02 3.4350e-04 2.0955e-03 6.3970e-04 1.7993e-03 + 2.8000e-03 -8.2974e+00 2.6121e-01 7.3879e-01 9.0901e-01 9.0987e-02 3.4184e-04 2.1072e-03 6.3970e-04 1.8093e-03 + 2.8100e-03 -8.2974e+00 2.6015e-01 7.3985e-01 9.0901e-01 9.0987e-02 3.4017e-04 2.1188e-03 6.3970e-04 1.8193e-03 + 2.8200e-03 -8.2974e+00 2.5909e-01 7.4091e-01 9.0901e-01 9.0987e-02 3.3850e-04 2.1305e-03 6.3970e-04 1.8293e-03 + 2.8300e-03 -8.2974e+00 2.5805e-01 7.4195e-01 9.0901e-01 9.0987e-02 3.3684e-04 2.1422e-03 6.3970e-04 1.8393e-03 + 2.8400e-03 -8.2974e+00 2.5701e-01 7.4299e-01 9.0901e-01 9.0987e-02 3.3517e-04 2.1538e-03 6.3970e-04 1.8493e-03 + 2.8500e-03 -8.2974e+00 2.5598e-01 7.4402e-01 9.0901e-01 9.0987e-02 3.3351e-04 2.1655e-03 6.3970e-04 1.8593e-03 + 2.8600e-03 -8.2974e+00 2.5496e-01 7.4504e-01 9.0901e-01 9.0987e-02 3.3184e-04 2.1772e-03 6.3970e-04 1.8693e-03 + 2.8700e-03 -8.2974e+00 2.5395e-01 7.4605e-01 9.0901e-01 9.0987e-02 3.3017e-04 2.1888e-03 6.3970e-04 1.8793e-03 + 2.8800e-03 -8.2974e+00 2.5295e-01 7.4705e-01 9.0901e-01 9.0987e-02 3.2851e-04 2.2005e-03 6.3970e-04 1.8893e-03 + 2.8900e-03 -8.2974e+00 2.5195e-01 7.4805e-01 9.0901e-01 9.0987e-02 3.2684e-04 2.2122e-03 6.3970e-04 1.8993e-03 + 2.9000e-03 -8.2974e+00 2.5096e-01 7.4904e-01 9.0901e-01 9.0987e-02 3.2517e-04 2.2238e-03 6.3970e-04 1.9093e-03 + 2.9100e-03 -8.2974e+00 2.4998e-01 7.5002e-01 9.0901e-01 9.0987e-02 3.2351e-04 2.2355e-03 6.3970e-04 1.9193e-03 + 2.9200e-03 -8.2974e+00 2.4901e-01 7.5099e-01 9.0901e-01 9.0987e-02 3.2184e-04 2.2472e-03 6.3970e-04 1.9293e-03 + 2.9300e-03 -8.2974e+00 2.4804e-01 7.5196e-01 9.0901e-01 9.0987e-02 3.2018e-04 2.2588e-03 6.3970e-04 1.9393e-03 + 2.9400e-03 -8.2974e+00 2.4708e-01 7.5292e-01 9.0901e-01 9.0987e-02 3.1851e-04 2.2705e-03 6.3970e-04 1.9493e-03 + 2.9500e-03 -8.2974e+00 2.4613e-01 7.5387e-01 9.0901e-01 9.0987e-02 3.1684e-04 2.2822e-03 6.3970e-04 1.9593e-03 + 2.9600e-03 -8.2974e+00 2.4519e-01 7.5481e-01 9.0901e-01 9.0987e-02 3.1518e-04 2.2938e-03 6.3970e-04 1.9693e-03 + 2.9700e-03 -8.2974e+00 2.4425e-01 7.5575e-01 9.0901e-01 9.0987e-02 3.1351e-04 2.3055e-03 6.3970e-04 1.9793e-03 + 2.9800e-03 -8.2974e+00 2.4332e-01 7.5668e-01 9.0901e-01 9.0987e-02 3.1184e-04 2.3172e-03 6.3970e-04 1.9893e-03 + 2.9900e-03 -8.2974e+00 2.4240e-01 7.5760e-01 9.0901e-01 9.0987e-02 3.1018e-04 2.3288e-03 6.3970e-04 1.9993e-03 + 3.0000e-03 -8.2974e+00 2.4149e-01 7.5851e-01 9.0901e-01 9.0987e-02 3.0851e-04 2.3405e-03 6.3970e-04 2.0093e-03 + 3.0100e-03 -8.2974e+00 2.4058e-01 7.5942e-01 9.0901e-01 9.0987e-02 3.0685e-04 2.3522e-03 6.3970e-04 2.0193e-03 + 3.0200e-03 -8.2974e+00 2.3968e-01 7.6032e-01 9.0901e-01 9.0987e-02 3.0518e-04 2.3638e-03 6.3970e-04 2.0293e-03 + 3.0300e-03 -8.2974e+00 2.3878e-01 7.6122e-01 9.0901e-01 9.0987e-02 3.0351e-04 2.3755e-03 6.3970e-04 2.0393e-03 + 3.0400e-03 -8.2974e+00 2.3790e-01 7.6210e-01 9.0901e-01 9.0987e-02 3.0185e-04 2.3872e-03 6.3970e-04 2.0493e-03 + 3.0500e-03 -8.2974e+00 2.3701e-01 7.6299e-01 9.0901e-01 9.0987e-02 3.0018e-04 2.3988e-03 6.3970e-04 2.0593e-03 + 3.0600e-03 -8.2974e+00 2.3614e-01 7.6386e-01 9.0901e-01 9.0987e-02 2.9852e-04 2.4105e-03 6.3970e-04 2.0693e-03 + 3.0700e-03 -8.2974e+00 2.3527e-01 7.6473e-01 9.0901e-01 9.0987e-02 2.9685e-04 2.4222e-03 6.3970e-04 2.0793e-03 + 3.0800e-03 -8.2974e+00 2.3441e-01 7.6559e-01 9.0901e-01 9.0987e-02 2.9518e-04 2.4338e-03 6.3970e-04 2.0893e-03 + 3.0900e-03 -8.2974e+00 2.3355e-01 7.6645e-01 9.0901e-01 9.0987e-02 2.9352e-04 2.4455e-03 6.3970e-04 2.0993e-03 + 3.1000e-03 -8.2974e+00 2.3270e-01 7.6730e-01 9.0901e-01 9.0987e-02 2.9185e-04 2.4571e-03 6.3970e-04 2.1093e-03 + 3.1100e-03 -8.2974e+00 2.3186e-01 7.6814e-01 9.0901e-01 9.0987e-02 2.9018e-04 2.4688e-03 6.3970e-04 2.1193e-03 + 3.1200e-03 -8.2974e+00 2.3102e-01 7.6898e-01 9.0901e-01 9.0987e-02 2.8852e-04 2.4805e-03 6.3970e-04 2.1293e-03 + 3.1300e-03 -8.2974e+00 2.3019e-01 7.6981e-01 9.0901e-01 9.0987e-02 2.8685e-04 2.4921e-03 6.3970e-04 2.1393e-03 + 3.1400e-03 -8.2974e+00 2.2937e-01 7.7063e-01 9.0901e-01 9.0987e-02 2.8519e-04 2.5038e-03 6.3970e-04 2.1493e-03 + 3.1500e-03 -8.2974e+00 2.2855e-01 7.7145e-01 9.0901e-01 9.0987e-02 2.8352e-04 2.5155e-03 6.3970e-04 2.1593e-03 + 3.1600e-03 -8.2974e+00 2.2773e-01 7.7227e-01 9.0901e-01 9.0987e-02 2.8185e-04 2.5271e-03 6.3970e-04 2.1693e-03 + 3.1700e-03 -8.2974e+00 2.2692e-01 7.7308e-01 9.0901e-01 9.0987e-02 2.8019e-04 2.5388e-03 6.3970e-04 2.1793e-03 + 3.1800e-03 -8.2974e+00 2.2612e-01 7.7388e-01 9.0901e-01 9.0987e-02 2.7852e-04 2.5505e-03 6.3970e-04 2.1893e-03 + 3.1900e-03 -8.2974e+00 2.2533e-01 7.7467e-01 9.0901e-01 9.0987e-02 2.7685e-04 2.5621e-03 6.3970e-04 2.1993e-03 + 3.2000e-03 -8.2974e+00 2.2454e-01 7.7546e-01 9.0901e-01 9.0987e-02 2.7519e-04 2.5738e-03 6.3970e-04 2.2093e-03 + 3.2100e-03 -8.2974e+00 2.2375e-01 7.7625e-01 9.0901e-01 9.0987e-02 2.7352e-04 2.5855e-03 6.3970e-04 2.2193e-03 + 3.2200e-03 -8.2974e+00 2.2297e-01 7.7703e-01 9.0901e-01 9.0987e-02 2.7186e-04 2.5971e-03 6.3970e-04 2.2293e-03 + 3.2300e-03 -8.2974e+00 2.2220e-01 7.7780e-01 9.0901e-01 9.0987e-02 2.7019e-04 2.6088e-03 6.3970e-04 2.2393e-03 + 3.2400e-03 -8.2974e+00 2.2143e-01 7.7857e-01 9.0901e-01 9.0987e-02 2.6852e-04 2.6205e-03 6.3970e-04 2.2493e-03 + 3.2500e-03 -8.2974e+00 2.2066e-01 7.7934e-01 9.0901e-01 9.0987e-02 2.6686e-04 2.6321e-03 6.3970e-04 2.2593e-03 + 3.2600e-03 -8.2974e+00 2.1990e-01 7.8010e-01 9.0901e-01 9.0987e-02 2.6519e-04 2.6438e-03 6.3970e-04 2.2693e-03 + 3.2700e-03 -8.2974e+00 2.1915e-01 7.8085e-01 9.0901e-01 9.0987e-02 2.6352e-04 2.6555e-03 6.3970e-04 2.2793e-03 + 3.2800e-03 -8.2974e+00 2.1840e-01 7.8160e-01 9.0901e-01 9.0987e-02 2.6186e-04 2.6671e-03 6.3970e-04 2.2893e-03 + 3.2900e-03 -8.2974e+00 2.1766e-01 7.8234e-01 9.0901e-01 9.0987e-02 2.6019e-04 2.6788e-03 6.3970e-04 2.2993e-03 + 3.3000e-03 -8.2974e+00 2.1692e-01 7.8308e-01 9.0901e-01 9.0987e-02 2.5853e-04 2.6905e-03 6.3970e-04 2.3093e-03 + 3.3100e-03 -8.2974e+00 2.1619e-01 7.8381e-01 9.0901e-01 9.0987e-02 2.5686e-04 2.7021e-03 6.3970e-04 2.3193e-03 + 3.3200e-03 -8.2974e+00 2.1546e-01 7.8454e-01 9.0901e-01 9.0987e-02 2.5519e-04 2.7138e-03 6.3970e-04 2.3293e-03 + 3.3300e-03 -8.2974e+00 2.1474e-01 7.8526e-01 9.0901e-01 9.0987e-02 2.5353e-04 2.7255e-03 6.3970e-04 2.3393e-03 + 3.3400e-03 -8.2974e+00 2.1402e-01 7.8598e-01 9.0901e-01 9.0987e-02 2.5186e-04 2.7371e-03 6.3970e-04 2.3493e-03 + 3.3500e-03 -8.2974e+00 2.1330e-01 7.8670e-01 9.0901e-01 9.0987e-02 2.5020e-04 2.7488e-03 6.3970e-04 2.3593e-03 + 3.3600e-03 -8.2974e+00 2.1260e-01 7.8740e-01 9.0901e-01 9.0987e-02 2.4853e-04 2.7605e-03 6.3970e-04 2.3693e-03 + 3.3700e-03 -8.2974e+00 2.1189e-01 7.8811e-01 9.0901e-01 9.0987e-02 2.4686e-04 2.7721e-03 6.3970e-04 2.3793e-03 + 3.3800e-03 -8.2974e+00 2.1119e-01 7.8881e-01 9.0901e-01 9.0987e-02 2.4520e-04 2.7838e-03 6.3970e-04 2.3893e-03 + 3.3900e-03 -8.2974e+00 2.1050e-01 7.8950e-01 9.0901e-01 9.0987e-02 2.4353e-04 2.7955e-03 6.3970e-04 2.3993e-03 + 3.4000e-03 -8.2974e+00 2.0981e-01 7.9019e-01 9.0901e-01 9.0987e-02 2.4186e-04 2.8071e-03 6.3970e-04 2.4093e-03 + 3.4100e-03 -8.2974e+00 2.0912e-01 7.9088e-01 9.0901e-01 9.0987e-02 2.4020e-04 2.8188e-03 6.3970e-04 2.4193e-03 + 3.4200e-03 -8.2974e+00 2.0844e-01 7.9156e-01 9.0901e-01 9.0987e-02 2.3853e-04 2.8305e-03 6.3970e-04 2.4293e-03 + 3.4300e-03 -8.2974e+00 2.0776e-01 7.9224e-01 9.0901e-01 9.0987e-02 2.3687e-04 2.8421e-03 6.3970e-04 2.4393e-03 + 3.4400e-03 -8.2974e+00 2.0709e-01 7.9291e-01 9.0901e-01 9.0987e-02 2.3520e-04 2.8538e-03 6.3970e-04 2.4493e-03 + 3.4500e-03 -8.2974e+00 2.0642e-01 7.9358e-01 9.0901e-01 9.0987e-02 2.3353e-04 2.8655e-03 6.3970e-04 2.4593e-03 + 3.4600e-03 -8.2974e+00 2.0576e-01 7.9424e-01 9.0901e-01 9.0987e-02 2.3187e-04 2.8771e-03 6.3970e-04 2.4693e-03 + 3.4700e-03 -8.2974e+00 2.0510e-01 7.9490e-01 9.0901e-01 9.0987e-02 2.3020e-04 2.8888e-03 6.3970e-04 2.4793e-03 + 3.4800e-03 -8.2974e+00 2.0444e-01 7.9556e-01 9.0901e-01 9.0987e-02 2.2853e-04 2.9005e-03 6.3970e-04 2.4893e-03 + 3.4900e-03 -8.2974e+00 2.0379e-01 7.9621e-01 9.0901e-01 9.0987e-02 2.2687e-04 2.9121e-03 6.3970e-04 2.4993e-03 + 3.5000e-03 -8.2974e+00 2.0314e-01 7.9686e-01 9.0901e-01 9.0987e-02 2.2520e-04 2.9238e-03 6.3970e-04 2.5093e-03 + 3.5100e-03 -8.2974e+00 2.0250e-01 7.9750e-01 9.0901e-01 9.0987e-02 2.2354e-04 2.9355e-03 6.3970e-04 2.5193e-03 + 3.5200e-03 -8.2974e+00 2.0186e-01 7.9814e-01 9.0901e-01 9.0987e-02 2.2187e-04 2.9471e-03 6.3970e-04 2.5293e-03 + 3.5300e-03 -8.2974e+00 2.0123e-01 7.9877e-01 9.0901e-01 9.0987e-02 2.2020e-04 2.9588e-03 6.3970e-04 2.5393e-03 + 3.5400e-03 -8.2974e+00 2.0060e-01 7.9940e-01 9.0901e-01 9.0987e-02 2.1854e-04 2.9705e-03 6.3970e-04 2.5493e-03 + 3.5500e-03 -8.2974e+00 1.9997e-01 8.0003e-01 9.0901e-01 9.0987e-02 2.1687e-04 2.9821e-03 6.3970e-04 2.5593e-03 + 3.5600e-03 -8.2974e+00 1.9935e-01 8.0065e-01 9.0901e-01 9.0987e-02 2.1520e-04 2.9938e-03 6.3970e-04 2.5693e-03 + 3.5700e-03 -8.2974e+00 1.9873e-01 8.0127e-01 9.0901e-01 9.0987e-02 2.1354e-04 3.0055e-03 6.3970e-04 2.5793e-03 + 3.5800e-03 -8.2974e+00 1.9811e-01 8.0189e-01 9.0901e-01 9.0987e-02 2.1187e-04 3.0171e-03 6.3970e-04 2.5893e-03 + 3.5900e-03 -8.2974e+00 1.9750e-01 8.0250e-01 9.0901e-01 9.0987e-02 2.1021e-04 3.0288e-03 6.3970e-04 2.5993e-03 + 3.6000e-03 -8.2974e+00 1.9689e-01 8.0311e-01 9.0901e-01 9.0987e-02 2.0854e-04 3.0405e-03 6.3970e-04 2.6093e-03 + 3.6100e-03 -8.2974e+00 1.9629e-01 8.0371e-01 9.0901e-01 9.0987e-02 2.0687e-04 3.0521e-03 6.3970e-04 2.6193e-03 + 3.6200e-03 -8.2974e+00 1.9569e-01 8.0431e-01 9.0901e-01 9.0987e-02 2.0521e-04 3.0638e-03 6.3970e-04 2.6293e-03 + 3.6300e-03 -8.2974e+00 1.9509e-01 8.0491e-01 9.0901e-01 9.0987e-02 2.0354e-04 3.0755e-03 6.3970e-04 2.6393e-03 + 3.6400e-03 -8.2974e+00 1.9450e-01 8.0550e-01 9.0901e-01 9.0987e-02 2.0188e-04 3.0871e-03 6.3970e-04 2.6493e-03 + 3.6500e-03 -8.2974e+00 1.9391e-01 8.0609e-01 9.0901e-01 9.0987e-02 2.0021e-04 3.0988e-03 6.3970e-04 2.6593e-03 + 3.6600e-03 -8.2974e+00 1.9332e-01 8.0668e-01 9.0901e-01 9.0987e-02 1.9854e-04 3.1105e-03 6.3970e-04 2.6693e-03 + 3.6700e-03 -8.2974e+00 1.9274e-01 8.0726e-01 9.0901e-01 9.0987e-02 1.9688e-04 3.1221e-03 6.3970e-04 2.6793e-03 + 3.6800e-03 -8.2974e+00 1.9216e-01 8.0784e-01 9.0901e-01 9.0987e-02 1.9521e-04 3.1338e-03 6.3970e-04 2.6893e-03 + 3.6900e-03 -8.2974e+00 1.9158e-01 8.0842e-01 9.0901e-01 9.0987e-02 1.9354e-04 3.1455e-03 6.3970e-04 2.6993e-03 + 3.7000e-03 -8.2974e+00 1.9101e-01 8.0899e-01 9.0901e-01 9.0987e-02 1.9188e-04 3.1571e-03 6.3970e-04 2.7093e-03 + 3.7100e-03 -8.2974e+00 1.9044e-01 8.0956e-01 9.0901e-01 9.0987e-02 1.9021e-04 3.1688e-03 6.3970e-04 2.7193e-03 + 3.7200e-03 -8.2974e+00 1.8988e-01 8.1012e-01 9.0901e-01 9.0987e-02 1.8855e-04 3.1805e-03 6.3970e-04 2.7293e-03 + 3.7300e-03 -8.2974e+00 1.8932e-01 8.1068e-01 9.0901e-01 9.0987e-02 1.8688e-04 3.1921e-03 6.3970e-04 2.7393e-03 + 3.7400e-03 -8.2974e+00 1.8876e-01 8.1124e-01 9.0901e-01 9.0987e-02 1.8521e-04 3.2038e-03 6.3970e-04 2.7493e-03 + 3.7500e-03 -8.2974e+00 1.8820e-01 8.1180e-01 9.0901e-01 9.0987e-02 1.8355e-04 3.2155e-03 6.3970e-04 2.7593e-03 + 3.7600e-03 -8.2974e+00 1.8765e-01 8.1235e-01 9.0901e-01 9.0987e-02 1.8188e-04 3.2271e-03 6.3970e-04 2.7693e-03 + 3.7700e-03 -8.2974e+00 1.8710e-01 8.1290e-01 9.0901e-01 9.0987e-02 1.8021e-04 3.2388e-03 6.3970e-04 2.7793e-03 + 3.7800e-03 -8.2974e+00 1.8656e-01 8.1344e-01 9.0901e-01 9.0987e-02 1.7855e-04 3.2505e-03 6.3970e-04 2.7893e-03 + 3.7900e-03 -8.2974e+00 1.8601e-01 8.1399e-01 9.0901e-01 9.0987e-02 1.7688e-04 3.2621e-03 6.3970e-04 2.7993e-03 + 3.8000e-03 -8.2974e+00 1.8547e-01 8.1453e-01 9.0901e-01 9.0987e-02 1.7522e-04 3.2738e-03 6.3970e-04 2.8093e-03 + 3.8100e-03 -8.2974e+00 1.8494e-01 8.1506e-01 9.0901e-01 9.0987e-02 1.7355e-04 3.2855e-03 6.3970e-04 2.8193e-03 + 3.8200e-03 -8.2974e+00 1.8440e-01 8.1560e-01 9.0901e-01 9.0987e-02 1.7188e-04 3.2971e-03 6.3970e-04 2.8293e-03 + 3.8300e-03 -8.2974e+00 1.8387e-01 8.1613e-01 9.0901e-01 9.0987e-02 1.7022e-04 3.3088e-03 6.3970e-04 2.8393e-03 + 3.8400e-03 -8.2974e+00 1.8335e-01 8.1665e-01 9.0901e-01 9.0987e-02 1.6855e-04 3.3204e-03 6.3970e-04 2.8493e-03 + 3.8500e-03 -8.2974e+00 1.8282e-01 8.1718e-01 9.0901e-01 9.0987e-02 1.6689e-04 3.3321e-03 6.3970e-04 2.8593e-03 + 3.8600e-03 -8.2974e+00 1.8230e-01 8.1770e-01 9.0901e-01 9.0987e-02 1.6522e-04 3.3438e-03 6.3970e-04 2.8693e-03 + 3.8700e-03 -8.2974e+00 1.8178e-01 8.1822e-01 9.0901e-01 9.0987e-02 1.6355e-04 3.3554e-03 6.3970e-04 2.8793e-03 + 3.8800e-03 -8.2974e+00 1.8127e-01 8.1873e-01 9.0901e-01 9.0987e-02 1.6189e-04 3.3671e-03 6.3970e-04 2.8893e-03 + 3.8900e-03 -8.2974e+00 1.8076e-01 8.1924e-01 9.0901e-01 9.0987e-02 1.6022e-04 3.3788e-03 6.3970e-04 2.8993e-03 + 3.9000e-03 -8.2974e+00 1.8025e-01 8.1975e-01 9.0901e-01 9.0987e-02 1.5855e-04 3.3904e-03 6.3970e-04 2.9093e-03 + 3.9100e-03 -8.2974e+00 1.7974e-01 8.2026e-01 9.0901e-01 9.0987e-02 1.5689e-04 3.4021e-03 6.3970e-04 2.9193e-03 + 3.9200e-03 -8.2974e+00 1.7924e-01 8.2076e-01 9.0901e-01 9.0987e-02 1.5522e-04 3.4138e-03 6.3970e-04 2.9293e-03 + 3.9300e-03 -8.2974e+00 1.7874e-01 8.2126e-01 9.0901e-01 9.0987e-02 1.5356e-04 3.4254e-03 6.3970e-04 2.9393e-03 + 3.9400e-03 -8.2974e+00 1.7824e-01 8.2176e-01 9.0901e-01 9.0987e-02 1.5189e-04 3.4371e-03 6.3970e-04 2.9493e-03 + 3.9500e-03 -8.2974e+00 1.7774e-01 8.2226e-01 9.0901e-01 9.0987e-02 1.5022e-04 3.4488e-03 6.3970e-04 2.9593e-03 + 3.9600e-03 -8.2974e+00 1.7725e-01 8.2275e-01 9.0901e-01 9.0987e-02 1.4856e-04 3.4604e-03 6.3970e-04 2.9693e-03 + 3.9700e-03 -8.2974e+00 1.7676e-01 8.2324e-01 9.0901e-01 9.0987e-02 1.4689e-04 3.4721e-03 6.3970e-04 2.9793e-03 + 3.9800e-03 -8.2974e+00 1.7627e-01 8.2373e-01 9.0901e-01 9.0987e-02 1.4522e-04 3.4838e-03 6.3970e-04 2.9893e-03 + 3.9900e-03 -8.2974e+00 1.7579e-01 8.2421e-01 9.0901e-01 9.0987e-02 1.4356e-04 3.4954e-03 6.3970e-04 2.9993e-03 + 4.0000e-03 -8.2974e+00 1.7531e-01 8.2469e-01 9.0901e-01 9.0987e-02 1.4189e-04 3.5071e-03 6.3970e-04 3.0093e-03 + 4.0100e-03 -8.2974e+00 1.7483e-01 8.2517e-01 9.0901e-01 9.0987e-02 1.4023e-04 3.5188e-03 6.3970e-04 3.0193e-03 + 4.0200e-03 -8.2974e+00 1.7435e-01 8.2565e-01 9.0901e-01 9.0987e-02 1.3856e-04 3.5304e-03 6.3970e-04 3.0293e-03 + 4.0300e-03 -8.2974e+00 1.7388e-01 8.2612e-01 9.0901e-01 9.0987e-02 1.3689e-04 3.5421e-03 6.3970e-04 3.0393e-03 + 4.0400e-03 -8.2974e+00 1.7341e-01 8.2659e-01 9.0901e-01 9.0987e-02 1.3523e-04 3.5538e-03 6.3970e-04 3.0493e-03 + 4.0500e-03 -8.2974e+00 1.7294e-01 8.2706e-01 9.0901e-01 9.0987e-02 1.3356e-04 3.5654e-03 6.3970e-04 3.0593e-03 + 4.0600e-03 -8.2974e+00 1.7247e-01 8.2753e-01 9.0901e-01 9.0987e-02 1.3189e-04 3.5771e-03 6.3970e-04 3.0693e-03 + 4.0700e-03 -8.2974e+00 1.7201e-01 8.2799e-01 9.0901e-01 9.0987e-02 1.3023e-04 3.5888e-03 6.3970e-04 3.0793e-03 + 4.0800e-03 -8.2974e+00 1.7155e-01 8.2845e-01 9.0901e-01 9.0987e-02 1.2856e-04 3.6004e-03 6.3970e-04 3.0893e-03 + 4.0900e-03 -8.2974e+00 1.7109e-01 8.2891e-01 9.0901e-01 9.0987e-02 1.2690e-04 3.6121e-03 6.3970e-04 3.0993e-03 + 4.1000e-03 -8.2974e+00 1.7063e-01 8.2937e-01 9.0901e-01 9.0987e-02 1.2523e-04 3.6238e-03 6.3970e-04 3.1093e-03 + 4.1100e-03 -8.2974e+00 1.7018e-01 8.2982e-01 9.0901e-01 9.0987e-02 1.2356e-04 3.6354e-03 6.3970e-04 3.1193e-03 + 4.1200e-03 -8.2974e+00 1.6973e-01 8.3027e-01 9.0901e-01 9.0987e-02 1.2190e-04 3.6471e-03 6.3970e-04 3.1293e-03 + 4.1300e-03 -8.2974e+00 1.6928e-01 8.3072e-01 9.0901e-01 9.0987e-02 1.2023e-04 3.6588e-03 6.3970e-04 3.1393e-03 + 4.1400e-03 -8.2974e+00 1.6883e-01 8.3117e-01 9.0901e-01 9.0987e-02 1.1857e-04 3.6704e-03 6.3970e-04 3.1493e-03 + 4.1500e-03 -8.2974e+00 1.6839e-01 8.3161e-01 9.0901e-01 9.0987e-02 1.1690e-04 3.6821e-03 6.3970e-04 3.1593e-03 + 4.1600e-03 -8.2974e+00 1.6794e-01 8.3206e-01 9.0901e-01 9.0987e-02 1.1523e-04 3.6938e-03 6.3970e-04 3.1693e-03 + 4.1700e-03 -8.2974e+00 1.6750e-01 8.3250e-01 9.0901e-01 9.0987e-02 1.1357e-04 3.7054e-03 6.3970e-04 3.1793e-03 + 4.1800e-03 -8.2974e+00 1.6707e-01 8.3293e-01 9.0901e-01 9.0987e-02 1.1190e-04 3.7171e-03 6.3970e-04 3.1893e-03 + 4.1900e-03 -8.2974e+00 1.6663e-01 8.3337e-01 9.0901e-01 9.0987e-02 1.1023e-04 3.7288e-03 6.3970e-04 3.1993e-03 + 4.2000e-03 -8.2974e+00 1.6620e-01 8.3380e-01 9.0901e-01 9.0987e-02 1.0857e-04 3.7404e-03 6.3970e-04 3.2093e-03 + 4.2100e-03 -8.2974e+00 1.6577e-01 8.3423e-01 9.0901e-01 9.0987e-02 1.0690e-04 3.7521e-03 6.3970e-04 3.2193e-03 + 4.2200e-03 -8.2974e+00 1.6534e-01 8.3466e-01 9.0901e-01 9.0987e-02 1.0524e-04 3.7638e-03 6.3970e-04 3.2293e-03 + 4.2300e-03 -8.2974e+00 1.6491e-01 8.3509e-01 9.0901e-01 9.0987e-02 1.0357e-04 3.7754e-03 6.3970e-04 3.2393e-03 + 4.2400e-03 -8.2974e+00 1.6449e-01 8.3551e-01 9.0901e-01 9.0987e-02 1.0190e-04 3.7871e-03 6.3970e-04 3.2493e-03 + 4.2500e-03 -8.2974e+00 1.6407e-01 8.3593e-01 9.0901e-01 9.0987e-02 1.0024e-04 3.7988e-03 6.3970e-04 3.2593e-03 + 4.2600e-03 -8.2974e+00 1.6365e-01 8.3635e-01 9.0901e-01 9.0987e-02 9.8571e-05 3.8104e-03 6.3970e-04 3.2693e-03 + 4.2700e-03 -8.2974e+00 1.6323e-01 8.3677e-01 9.0901e-01 9.0987e-02 9.6905e-05 3.8221e-03 6.3970e-04 3.2793e-03 + 4.2800e-03 -8.2974e+00 1.6282e-01 8.3718e-01 9.0901e-01 9.0987e-02 9.5238e-05 3.8338e-03 6.3970e-04 3.2893e-03 + 4.2900e-03 -8.2974e+00 1.6240e-01 8.3760e-01 9.0901e-01 9.0987e-02 9.3572e-05 3.8454e-03 6.3970e-04 3.2993e-03 + 4.3000e-03 -8.2974e+00 1.6199e-01 8.3801e-01 9.0901e-01 9.0987e-02 9.1906e-05 3.8571e-03 6.3970e-04 3.3093e-03 + 4.3100e-03 -8.2974e+00 1.6158e-01 8.3842e-01 9.0901e-01 9.0987e-02 9.0240e-05 3.8688e-03 6.3970e-04 3.3193e-03 + 4.3200e-03 -8.2974e+00 1.6117e-01 8.3883e-01 9.0901e-01 9.0987e-02 8.8574e-05 3.8804e-03 6.3970e-04 3.3293e-03 + 4.3300e-03 -8.2974e+00 1.6077e-01 8.3923e-01 9.0901e-01 9.0987e-02 8.6907e-05 3.8921e-03 6.3970e-04 3.3393e-03 + 4.3400e-03 -8.2974e+00 1.6037e-01 8.3963e-01 9.0901e-01 9.0987e-02 8.5241e-05 3.9038e-03 6.3970e-04 3.3493e-03 + 4.3500e-03 -8.2974e+00 1.5997e-01 8.4003e-01 9.0901e-01 9.0987e-02 8.3575e-05 3.9154e-03 6.3970e-04 3.3593e-03 + 4.3600e-03 -8.2974e+00 1.5957e-01 8.4043e-01 9.0901e-01 9.0987e-02 8.1909e-05 3.9271e-03 6.3970e-04 3.3693e-03 + 4.3700e-03 -8.2974e+00 1.5917e-01 8.4083e-01 9.0901e-01 9.0987e-02 8.0243e-05 3.9388e-03 6.3970e-04 3.3793e-03 + 4.3800e-03 -8.2974e+00 1.5877e-01 8.4123e-01 9.0901e-01 9.0987e-02 7.8576e-05 3.9504e-03 6.3970e-04 3.3893e-03 + 4.3900e-03 -8.2974e+00 1.5838e-01 8.4162e-01 9.0901e-01 9.0987e-02 7.6910e-05 3.9621e-03 6.3970e-04 3.3993e-03 + 4.4000e-03 -8.2974e+00 1.5799e-01 8.4201e-01 9.0901e-01 9.0987e-02 7.5244e-05 3.9738e-03 6.3970e-04 3.4093e-03 + 4.4100e-03 -8.2974e+00 1.5760e-01 8.4240e-01 9.0901e-01 9.0987e-02 7.3578e-05 3.9854e-03 6.3970e-04 3.4193e-03 + 4.4200e-03 -8.2974e+00 1.5721e-01 8.4279e-01 9.0901e-01 9.0987e-02 7.1912e-05 3.9971e-03 6.3970e-04 3.4293e-03 + 4.4300e-03 -8.2974e+00 1.5683e-01 8.4317e-01 9.0901e-01 9.0987e-02 7.0245e-05 4.0088e-03 6.3970e-04 3.4393e-03 + 4.4400e-03 -8.2974e+00 1.5644e-01 8.4356e-01 9.0901e-01 9.0987e-02 6.8579e-05 4.0204e-03 6.3970e-04 3.4493e-03 + 4.4500e-03 -8.2974e+00 1.5606e-01 8.4394e-01 9.0901e-01 9.0987e-02 6.6913e-05 4.0321e-03 6.3970e-04 3.4593e-03 + 4.4600e-03 -8.2974e+00 1.5568e-01 8.4432e-01 9.0901e-01 9.0987e-02 6.5247e-05 4.0438e-03 6.3970e-04 3.4693e-03 + 4.4700e-03 -8.2974e+00 1.5530e-01 8.4470e-01 9.0901e-01 9.0987e-02 6.3581e-05 4.0554e-03 6.3970e-04 3.4793e-03 + 4.4800e-03 -8.2974e+00 1.5493e-01 8.4507e-01 9.0901e-01 9.0987e-02 6.1914e-05 4.0671e-03 6.3970e-04 3.4893e-03 + 4.4900e-03 -8.2974e+00 1.5455e-01 8.4545e-01 9.0901e-01 9.0987e-02 6.0248e-05 4.0788e-03 6.3970e-04 3.4993e-03 + 4.5000e-03 -8.2974e+00 1.5418e-01 8.4582e-01 9.0901e-01 9.0987e-02 5.8582e-05 4.0904e-03 6.3970e-04 3.5093e-03 + 4.5100e-03 -8.2974e+00 1.5381e-01 8.4619e-01 9.0901e-01 9.0987e-02 5.6916e-05 4.1021e-03 6.3970e-04 3.5193e-03 + 4.5200e-03 -8.2974e+00 1.5344e-01 8.4656e-01 9.0901e-01 9.0987e-02 5.5250e-05 4.1138e-03 6.3970e-04 3.5293e-03 + 4.5300e-03 -8.2974e+00 1.5307e-01 8.4693e-01 9.0901e-01 9.0987e-02 5.3583e-05 4.1254e-03 6.3970e-04 3.5393e-03 + 4.5400e-03 -8.2974e+00 1.5271e-01 8.4729e-01 9.0901e-01 9.0987e-02 5.1917e-05 4.1371e-03 6.3970e-04 3.5493e-03 + 4.5500e-03 -8.2974e+00 1.5235e-01 8.4765e-01 9.0901e-01 9.0987e-02 5.0251e-05 4.1487e-03 6.3970e-04 3.5593e-03 + 4.5600e-03 -8.2974e+00 1.5198e-01 8.4802e-01 9.0901e-01 9.0987e-02 4.8585e-05 4.1604e-03 6.3970e-04 3.5693e-03 + 4.5700e-03 -8.2974e+00 1.5162e-01 8.4838e-01 9.0901e-01 9.0987e-02 4.6919e-05 4.1721e-03 6.3970e-04 3.5793e-03 + 4.5800e-03 -8.2974e+00 1.5127e-01 8.4873e-01 9.0901e-01 9.0987e-02 4.5252e-05 4.1837e-03 6.3970e-04 3.5893e-03 + 4.5900e-03 -8.2974e+00 1.5091e-01 8.4909e-01 9.0901e-01 9.0987e-02 4.3586e-05 4.1954e-03 6.3970e-04 3.5993e-03 + 4.6000e-03 -8.2974e+00 1.5055e-01 8.4945e-01 9.0901e-01 9.0987e-02 4.1920e-05 4.2071e-03 6.3970e-04 3.6093e-03 + 4.6100e-03 -8.2974e+00 1.5020e-01 8.4980e-01 9.0901e-01 9.0987e-02 4.0254e-05 4.2187e-03 6.3970e-04 3.6193e-03 + 4.6200e-03 -8.2974e+00 1.4985e-01 8.5015e-01 9.0901e-01 9.0987e-02 3.8588e-05 4.2304e-03 6.3970e-04 3.6293e-03 + 4.6300e-03 -8.2974e+00 1.4950e-01 8.5050e-01 9.0901e-01 9.0987e-02 3.6921e-05 4.2421e-03 6.3970e-04 3.6393e-03 + 4.6400e-03 -8.2974e+00 1.4915e-01 8.5085e-01 9.0901e-01 9.0987e-02 3.5255e-05 4.2537e-03 6.3970e-04 3.6493e-03 + 4.6500e-03 -8.2974e+00 1.4880e-01 8.5120e-01 9.0901e-01 9.0987e-02 3.3589e-05 4.2654e-03 6.3970e-04 3.6593e-03 + 4.6600e-03 -8.2974e+00 1.4846e-01 8.5154e-01 9.0901e-01 9.0987e-02 3.1923e-05 4.2771e-03 6.3970e-04 3.6693e-03 + 4.6700e-03 -8.2974e+00 1.4811e-01 8.5189e-01 9.0901e-01 9.0987e-02 3.0257e-05 4.2887e-03 6.3970e-04 3.6793e-03 + 4.6800e-03 -8.2974e+00 1.4777e-01 8.5223e-01 9.0901e-01 9.0987e-02 2.8590e-05 4.3004e-03 6.3970e-04 3.6893e-03 + 4.6900e-03 -8.2974e+00 1.4743e-01 8.5257e-01 9.0901e-01 9.0987e-02 2.6924e-05 4.3121e-03 6.3970e-04 3.6993e-03 + 4.7000e-03 -8.2974e+00 1.4709e-01 8.5291e-01 9.0901e-01 9.0987e-02 2.5258e-05 4.3237e-03 6.3970e-04 3.7093e-03 + 4.7100e-03 -8.2974e+00 1.4675e-01 8.5325e-01 9.0901e-01 9.0987e-02 2.3592e-05 4.3354e-03 6.3970e-04 3.7193e-03 + 4.7200e-03 -8.2974e+00 1.4642e-01 8.5358e-01 9.0901e-01 9.0987e-02 2.1926e-05 4.3471e-03 6.3970e-04 3.7293e-03 + 4.7300e-03 -8.2974e+00 1.4608e-01 8.5392e-01 9.0901e-01 9.0987e-02 2.0259e-05 4.3587e-03 6.3970e-04 3.7393e-03 + 4.7400e-03 -8.2974e+00 1.4575e-01 8.5425e-01 9.0901e-01 9.0987e-02 1.8593e-05 4.3704e-03 6.3970e-04 3.7493e-03 + 4.7500e-03 -8.2974e+00 1.4542e-01 8.5458e-01 9.0901e-01 9.0987e-02 1.6927e-05 4.3821e-03 6.3970e-04 3.7593e-03 + 4.7600e-03 -8.2974e+00 1.4509e-01 8.5491e-01 9.0901e-01 9.0987e-02 1.5261e-05 4.3937e-03 6.3970e-04 3.7693e-03 + 4.7700e-03 -8.2974e+00 1.4476e-01 8.5524e-01 9.0901e-01 9.0987e-02 1.3595e-05 4.4054e-03 6.3970e-04 3.7793e-03 + 4.7800e-03 -8.2974e+00 1.4443e-01 8.5557e-01 9.0901e-01 9.0987e-02 1.1928e-05 4.4171e-03 6.3970e-04 3.7893e-03 + 4.7900e-03 -8.2974e+00 1.4411e-01 8.5589e-01 9.0901e-01 9.0987e-02 1.0262e-05 4.4287e-03 6.3970e-04 3.7993e-03 + 4.8000e-03 -8.2974e+00 1.4379e-01 8.5621e-01 9.0901e-01 9.0987e-02 8.5959e-06 4.4404e-03 6.3970e-04 3.8093e-03 + 4.8100e-03 -8.2974e+00 1.4346e-01 8.5654e-01 9.0901e-01 9.0987e-02 6.9297e-06 4.4521e-03 6.3970e-04 3.8193e-03 + 4.8200e-03 -8.2974e+00 1.4314e-01 8.5686e-01 9.0901e-01 9.0987e-02 5.2635e-06 4.4637e-03 6.3970e-04 3.8293e-03 + 4.8300e-03 -8.2974e+00 1.4282e-01 8.5718e-01 9.0901e-01 9.0987e-02 3.5973e-06 4.4754e-03 6.3970e-04 3.8393e-03 + 4.8400e-03 -8.2974e+00 1.4250e-01 8.5750e-01 9.0901e-01 9.0987e-02 1.9311e-06 4.4871e-03 6.3970e-04 3.8493e-03 + 4.8500e-03 -8.2974e+00 1.4219e-01 8.5781e-01 9.0901e-01 9.0987e-02 2.6493e-07 4.4987e-03 6.3970e-04 3.8593e-03 + 4.8600e-03 -8.2975e+00 1.4210e-01 8.5790e-01 9.0899e-01 9.1014e-02 1.0000e-10 1.0000e-10 6.4087e-04 3.8691e-03 + 4.8700e-03 -8.2976e+00 1.4206e-01 8.5794e-01 9.0895e-01 9.1046e-02 1.0000e-10 1.0000e-10 6.4227e-04 3.8789e-03 + 4.8800e-03 -8.2977e+00 1.4202e-01 8.5798e-01 9.0892e-01 9.1078e-02 1.0000e-10 1.0000e-10 6.4366e-04 3.8886e-03 + 4.8900e-03 -8.2979e+00 1.4197e-01 8.5803e-01 9.0889e-01 9.1110e-02 1.0000e-10 1.0000e-10 6.4505e-04 3.8984e-03 + 4.9000e-03 -8.2980e+00 1.4193e-01 8.5807e-01 9.0886e-01 9.1142e-02 1.0000e-10 1.0000e-10 6.4644e-04 3.9081e-03 + 4.9100e-03 -8.2981e+00 1.4189e-01 8.5811e-01 9.0883e-01 9.1174e-02 1.0000e-10 1.0000e-10 6.4783e-04 3.9179e-03 + 4.9200e-03 -8.2982e+00 1.4185e-01 8.5815e-01 9.0879e-01 9.1206e-02 1.0000e-10 1.0000e-10 6.4922e-04 3.9276e-03 + 4.9300e-03 -8.2984e+00 1.4181e-01 8.5819e-01 9.0876e-01 9.1238e-02 1.0000e-10 1.0000e-10 6.5060e-04 3.9374e-03 + 4.9400e-03 -8.2985e+00 1.4176e-01 8.5824e-01 9.0873e-01 9.1270e-02 1.0000e-10 1.0000e-10 6.5199e-04 3.9471e-03 + 4.9500e-03 -8.2986e+00 1.4172e-01 8.5828e-01 9.0870e-01 9.1302e-02 1.0000e-10 1.0000e-10 6.5338e-04 3.9569e-03 + 4.9600e-03 -8.2988e+00 1.4168e-01 8.5832e-01 9.0867e-01 9.1334e-02 1.0000e-10 1.0000e-10 6.5476e-04 3.9667e-03 + 4.9700e-03 -8.2989e+00 1.4164e-01 8.5836e-01 9.0863e-01 9.1366e-02 1.0000e-10 1.0000e-10 6.5615e-04 3.9764e-03 + 4.9800e-03 -8.2990e+00 1.4160e-01 8.5840e-01 9.0860e-01 9.1398e-02 1.0000e-10 1.0000e-10 6.5753e-04 3.9862e-03 + 4.9900e-03 -8.2991e+00 1.4155e-01 8.5845e-01 9.0857e-01 9.1429e-02 1.0000e-10 1.0000e-10 6.5891e-04 3.9959e-03 + 5.0000e-03 -8.2993e+00 1.4151e-01 8.5849e-01 9.0854e-01 9.1461e-02 1.0000e-10 1.0000e-10 6.6029e-04 4.0057e-03 + 1.0000e-03 -8.2974e+00 9.8567e-01 1.4329e-02 9.0901e-01 9.0987e-02 6.4175e-04 7.2473e-06 6.3970e-04 9.2997e-06 + 2.0000e-03 -8.2974e+00 3.8793e-01 6.1207e-01 9.0901e-01 9.0987e-02 4.7513e-04 1.1739e-03 6.3970e-04 1.0093e-03 + 3.0000e-03 -8.2974e+00 2.4149e-01 7.5851e-01 9.0901e-01 9.0987e-02 3.0851e-04 2.3405e-03 6.3970e-04 2.0093e-03 + 4.0000e-03 -8.2974e+00 1.7531e-01 8.2469e-01 9.0901e-01 9.0987e-02 1.4189e-04 3.5071e-03 6.3970e-04 3.0093e-03 + 5.0000e-03 -8.2993e+00 1.4151e-01 8.5849e-01 9.0854e-01 9.1461e-02 1.0000e-10 1.0000e-10 6.6029e-04 4.0057e-03 + 6.0000e-03 -8.3118e+00 1.3751e-01 8.6249e-01 9.0539e-01 9.4606e-02 1.0000e-10 1.0000e-10 7.9428e-04 4.9819e-03 + 7.0000e-03 -8.3236e+00 1.3383e-01 8.6617e-01 9.0233e-01 9.7673e-02 1.0000e-10 1.0000e-10 9.2071e-04 5.9590e-03 + 8.0000e-03 -8.3349e+00 1.3043e-01 8.6957e-01 8.9933e-01 1.0067e-01 1.0000e-10 1.0000e-10 1.0405e-03 6.9369e-03 + 9.0000e-03 -8.3456e+00 1.2726e-01 8.7274e-01 8.9640e-01 1.0360e-01 1.0000e-10 1.0000e-10 1.1543e-03 7.9155e-03 + 1.0000e-02 -8.3559e+00 1.2431e-01 8.7569e-01 8.9352e-01 1.0648e-01 1.0000e-10 1.0000e-10 1.2627e-03 8.8947e-03 + 1.1000e-02 -8.3658e+00 1.2155e-01 8.7845e-01 8.9070e-01 1.0930e-01 1.0000e-10 1.0000e-10 1.3663e-03 9.8746e-03 + 1.2000e-02 -8.3752e+00 1.1895e-01 8.8105e-01 8.8792e-01 1.1208e-01 1.0000e-10 1.0000e-10 1.4655e-03 1.0855e-02 + 1.3000e-02 -8.3843e+00 1.1650e-01 8.8350e-01 8.8519e-01 1.1481e-01 1.0000e-10 1.0000e-10 1.5607e-03 1.1836e-02 + 1.4000e-02 -8.3931e+00 1.1419e-01 8.8581e-01 8.8251e-01 1.1749e-01 1.0000e-10 1.0000e-10 1.6522e-03 1.2817e-02 + 1.5000e-02 -8.4016e+00 1.1199e-01 8.8801e-01 8.7986e-01 1.2014e-01 1.0000e-10 1.0000e-10 1.7403e-03 1.3799e-02 + 1.6000e-02 -8.4098e+00 1.0991e-01 8.9009e-01 8.7725e-01 1.2275e-01 1.0000e-10 1.0000e-10 1.8252e-03 1.4781e-02 + 1.7000e-02 -8.4178e+00 1.0793e-01 8.9207e-01 8.7468e-01 1.2532e-01 1.0000e-10 1.0000e-10 1.9072e-03 1.5764e-02 + 1.8000e-02 -8.4254e+00 1.0604e-01 8.9396e-01 8.7214e-01 1.2786e-01 1.0000e-10 1.0000e-10 1.9864e-03 1.6746e-02 + 1.9000e-02 -8.4329e+00 1.0423e-01 8.9577e-01 8.6963e-01 1.3037e-01 1.0000e-10 1.0000e-10 2.0631e-03 1.7730e-02 + 2.0000e-02 -8.4401e+00 1.0251e-01 8.9749e-01 8.6716e-01 1.3284e-01 1.0000e-10 1.0000e-10 2.1374e-03 1.8713e-02 + 2.1000e-02 -8.4472e+00 1.0086e-01 8.9914e-01 8.6471e-01 1.3529e-01 1.0000e-10 1.0000e-10 2.2094e-03 1.9697e-02 + 2.2000e-02 -8.4540e+00 9.9270e-02 9.0073e-01 8.6230e-01 1.3770e-01 1.0000e-10 1.0000e-10 2.2793e-03 2.0681e-02 + 2.3000e-02 -8.4607e+00 9.7747e-02 9.0225e-01 8.5991e-01 1.4009e-01 1.0000e-10 1.0000e-10 2.3472e-03 2.1666e-02 + 2.4000e-02 -8.4672e+00 9.6283e-02 9.0372e-01 8.5754e-01 1.4246e-01 1.0000e-10 1.0000e-10 2.4132e-03 2.2650e-02 + 2.5000e-02 -8.4735e+00 9.4874e-02 9.0513e-01 8.5520e-01 1.4480e-01 1.0000e-10 1.0000e-10 2.4774e-03 2.3635e-02 + 2.6000e-02 -8.4797e+00 9.3517e-02 9.0648e-01 8.5289e-01 1.4711e-01 1.0000e-10 1.0000e-10 2.5400e-03 2.4621e-02 + 2.7000e-02 -8.4857e+00 9.2208e-02 9.0779e-01 8.5060e-01 1.4940e-01 1.0000e-10 1.0000e-10 2.6009e-03 2.5606e-02 + 2.8000e-02 -8.4915e+00 9.0944e-02 9.0906e-01 8.4833e-01 1.5167e-01 1.0000e-10 1.0000e-10 2.6603e-03 2.6592e-02 + 2.9000e-02 -8.4973e+00 8.9723e-02 9.1028e-01 8.4608e-01 1.5392e-01 1.0000e-10 1.0000e-10 2.7182e-03 2.7578e-02 + 3.0000e-02 -8.5029e+00 8.8542e-02 9.1146e-01 8.4386e-01 1.5614e-01 1.0000e-10 1.0000e-10 2.7748e-03 2.8564e-02 + 3.1000e-02 -8.5084e+00 8.7400e-02 9.1260e-01 8.4166e-01 1.5834e-01 1.0000e-10 1.0000e-10 2.8300e-03 2.9550e-02 + 3.2000e-02 -8.5137e+00 8.6294e-02 9.1371e-01 8.3947e-01 1.6053e-01 1.0000e-10 1.0000e-10 2.8840e-03 3.0536e-02 + 3.3000e-02 -8.5190e+00 8.5221e-02 9.1478e-01 8.3731e-01 1.6269e-01 1.0000e-10 1.0000e-10 2.9367e-03 3.1523e-02 + 3.4000e-02 -8.5241e+00 8.4182e-02 9.1582e-01 8.3516e-01 1.6484e-01 1.0000e-10 1.0000e-10 2.9883e-03 3.2510e-02 + 3.5000e-02 -8.5292e+00 8.3173e-02 9.1683e-01 8.3304e-01 1.6696e-01 1.0000e-10 1.0000e-10 3.0388e-03 3.3497e-02 + 3.6000e-02 -8.5341e+00 8.2193e-02 9.1781e-01 8.3093e-01 1.6907e-01 1.0000e-10 1.0000e-10 3.0882e-03 3.4484e-02 + 3.7000e-02 -8.5390e+00 8.1241e-02 9.1876e-01 8.2884e-01 1.7116e-01 1.0000e-10 1.0000e-10 3.1366e-03 3.5472e-02 + 3.8000e-02 -8.5437e+00 8.0316e-02 9.1968e-01 8.2677e-01 1.7323e-01 1.0000e-10 1.0000e-10 3.1840e-03 3.6459e-02 + 3.9000e-02 -8.5484e+00 7.9416e-02 9.2058e-01 8.2471e-01 1.7529e-01 1.0000e-10 1.0000e-10 3.2304e-03 3.7447e-02 + 4.0000e-02 -8.5529e+00 7.8540e-02 9.2146e-01 8.2267e-01 1.7733e-01 1.0000e-10 1.0000e-10 3.2760e-03 3.8435e-02 + 4.1000e-02 -8.5574e+00 7.7688e-02 9.2231e-01 8.2065e-01 1.7935e-01 1.0000e-10 1.0000e-10 3.3206e-03 3.9423e-02 + 4.2000e-02 -8.5618e+00 7.6857e-02 9.2314e-01 8.1865e-01 1.8135e-01 1.0000e-10 1.0000e-10 3.3645e-03 4.0411e-02 + 4.3000e-02 -8.5662e+00 7.6048e-02 9.2395e-01 8.1665e-01 1.8335e-01 1.0000e-10 1.0000e-10 3.4075e-03 4.1399e-02 + 4.4000e-02 -8.5704e+00 7.5259e-02 9.2474e-01 8.1468e-01 1.8532e-01 1.0000e-10 1.0000e-10 3.4497e-03 4.2388e-02 + 4.5000e-02 -8.5746e+00 7.4489e-02 9.2551e-01 8.1272e-01 1.8728e-01 1.0000e-10 1.0000e-10 3.4911e-03 4.3376e-02 + 4.6000e-02 -8.5787e+00 7.3738e-02 9.2626e-01 8.1077e-01 1.8923e-01 1.0000e-10 1.0000e-10 3.5318e-03 4.4365e-02 + 4.7000e-02 -8.5827e+00 7.3005e-02 9.2699e-01 8.0884e-01 1.9116e-01 1.0000e-10 1.0000e-10 3.5718e-03 4.5354e-02 + 4.8000e-02 -8.5867e+00 7.2290e-02 9.2771e-01 8.0692e-01 1.9308e-01 1.0000e-10 1.0000e-10 3.6111e-03 4.6343e-02 + 4.9000e-02 -8.5906e+00 7.1590e-02 9.2841e-01 8.0502e-01 1.9498e-01 1.0000e-10 1.0000e-10 3.6498e-03 4.7332e-02 + 5.0000e-02 -8.5945e+00 7.0907e-02 9.2909e-01 8.0313e-01 1.9687e-01 1.0000e-10 1.0000e-10 3.6878e-03 4.8321e-02 + 5.1000e-02 -8.5982e+00 7.0239e-02 9.2976e-01 8.0125e-01 1.9875e-01 1.0000e-10 1.0000e-10 3.7252e-03 4.9310e-02 + 5.2000e-02 -8.6020e+00 6.9586e-02 9.3041e-01 7.9939e-01 2.0061e-01 1.0000e-10 1.0000e-10 3.7619e-03 5.0300e-02 + 5.3000e-02 -8.6056e+00 6.8947e-02 9.3105e-01 7.9753e-01 2.0247e-01 1.0000e-10 1.0000e-10 3.7981e-03 5.1289e-02 + 5.4000e-02 -8.6092e+00 6.8322e-02 9.3168e-01 7.9570e-01 2.0430e-01 1.0000e-10 1.0000e-10 3.8337e-03 5.2279e-02 + 5.5000e-02 -8.6128e+00 6.7710e-02 9.3229e-01 7.9387e-01 2.0613e-01 1.0000e-10 1.0000e-10 3.8688e-03 5.3269e-02 + 5.6000e-02 -8.6163e+00 6.7111e-02 9.3289e-01 7.9206e-01 2.0794e-01 1.0000e-10 1.0000e-10 3.9033e-03 5.4258e-02 + 5.7000e-02 -8.6198e+00 6.6524e-02 9.3348e-01 7.9026e-01 2.0974e-01 1.0000e-10 1.0000e-10 3.9373e-03 5.5248e-02 + 5.8000e-02 -8.6232e+00 6.5950e-02 9.3405e-01 7.8847e-01 2.1153e-01 1.0000e-10 1.0000e-10 3.9708e-03 5.6238e-02 + 5.9000e-02 -8.6265e+00 6.5386e-02 9.3461e-01 7.8669e-01 2.1331e-01 1.0000e-10 1.0000e-10 4.0037e-03 5.7228e-02 + 6.0000e-02 -8.6298e+00 6.4834e-02 9.3517e-01 7.8492e-01 2.1508e-01 1.0000e-10 1.0000e-10 4.0362e-03 5.8219e-02 + 6.1000e-02 -8.6331e+00 6.4293e-02 9.3571e-01 7.8317e-01 2.1683e-01 1.0000e-10 1.0000e-10 4.0683e-03 5.9209e-02 + 6.2000e-02 -8.6363e+00 6.3762e-02 9.3624e-01 7.8142e-01 2.1858e-01 1.0000e-10 1.0000e-10 4.0999e-03 6.0199e-02 + 6.3000e-02 -8.6395e+00 6.3242e-02 9.3676e-01 7.7969e-01 2.2031e-01 1.0000e-10 1.0000e-10 4.1310e-03 6.1190e-02 + 6.4000e-02 -8.6426e+00 6.2731e-02 9.3727e-01 7.7797e-01 2.2203e-01 1.0000e-10 1.0000e-10 4.1617e-03 6.2180e-02 + 6.5000e-02 -8.6457e+00 6.2230e-02 9.3777e-01 7.7626e-01 2.2374e-01 1.0000e-10 1.0000e-10 4.1920e-03 6.3171e-02 + 6.6000e-02 -8.6487e+00 6.1738e-02 9.3826e-01 7.7456e-01 2.2544e-01 1.0000e-10 1.0000e-10 4.2218e-03 6.4162e-02 + 6.7000e-02 -8.6517e+00 6.1255e-02 9.3875e-01 7.7287e-01 2.2713e-01 1.0000e-10 1.0000e-10 4.2513e-03 6.5153e-02 + 6.8000e-02 -8.6547e+00 6.0780e-02 9.3922e-01 7.7119e-01 2.2881e-01 1.0000e-10 1.0000e-10 4.2804e-03 6.6144e-02 + 6.9000e-02 -8.6576e+00 6.0314e-02 9.3969e-01 7.6952e-01 2.3048e-01 1.0000e-10 1.0000e-10 4.3091e-03 6.7135e-02 + 7.0000e-02 -8.6605e+00 5.9857e-02 9.4014e-01 7.6786e-01 2.3214e-01 1.0000e-10 1.0000e-10 4.3374e-03 6.8126e-02 + 7.1000e-02 -8.6634e+00 5.9407e-02 9.4059e-01 7.6621e-01 2.3379e-01 1.0000e-10 1.0000e-10 4.3654e-03 6.9117e-02 + 7.2000e-02 -8.6662e+00 5.8965e-02 9.4103e-01 7.6457e-01 2.3543e-01 1.0000e-10 1.0000e-10 4.3930e-03 7.0108e-02 + 7.3000e-02 -8.6690e+00 5.8531e-02 9.4147e-01 7.6294e-01 2.3706e-01 1.0000e-10 1.0000e-10 4.4202e-03 7.1099e-02 + 7.4000e-02 -8.6718e+00 5.8104e-02 9.4190e-01 7.6132e-01 2.3868e-01 1.0000e-10 1.0000e-10 4.4471e-03 7.2091e-02 + 7.5000e-02 -8.6745e+00 5.7684e-02 9.4232e-01 7.5970e-01 2.4030e-01 1.0000e-10 1.0000e-10 4.4737e-03 7.3082e-02 + 7.6000e-02 -8.6772e+00 5.7271e-02 9.4273e-01 7.5810e-01 2.4190e-01 1.0000e-10 1.0000e-10 4.5000e-03 7.4074e-02 + 7.7000e-02 -8.6798e+00 5.6864e-02 9.4314e-01 7.5651e-01 2.4349e-01 1.0000e-10 1.0000e-10 4.5259e-03 7.5065e-02 + 7.8000e-02 -8.6824e+00 5.6465e-02 9.4354e-01 7.5492e-01 2.4508e-01 1.0000e-10 1.0000e-10 4.5515e-03 7.6057e-02 + 7.9000e-02 -8.6850e+00 5.6071e-02 9.4393e-01 7.5335e-01 2.4665e-01 1.0000e-10 1.0000e-10 4.5769e-03 7.7049e-02 + 8.0000e-02 -8.6876e+00 5.5684e-02 9.4432e-01 7.5178e-01 2.4822e-01 1.0000e-10 1.0000e-10 4.6019e-03 7.8040e-02 + 8.1000e-02 -8.6901e+00 5.5303e-02 9.4470e-01 7.5023e-01 2.4977e-01 1.0000e-10 1.0000e-10 4.6266e-03 7.9032e-02 + 8.2000e-02 -8.6926e+00 5.4928e-02 9.4507e-01 7.4868e-01 2.5132e-01 1.0000e-10 1.0000e-10 4.6511e-03 8.0024e-02 + 8.3000e-02 -8.6951e+00 5.4559e-02 9.4544e-01 7.4714e-01 2.5286e-01 1.0000e-10 1.0000e-10 4.6752e-03 8.1016e-02 + 8.4000e-02 -8.6976e+00 5.4196e-02 9.4580e-01 7.4560e-01 2.5440e-01 1.0000e-10 1.0000e-10 4.6991e-03 8.2008e-02 + 8.5000e-02 -8.7000e+00 5.3837e-02 9.4616e-01 7.4408e-01 2.5592e-01 1.0000e-10 1.0000e-10 4.7228e-03 8.3000e-02 + 8.6000e-02 -8.7024e+00 5.3485e-02 9.4652e-01 7.4256e-01 2.5744e-01 1.0000e-10 1.0000e-10 4.7461e-03 8.3992e-02 + 8.7000e-02 -8.7047e+00 5.3137e-02 9.4686e-01 7.4106e-01 2.5894e-01 1.0000e-10 1.0000e-10 4.7693e-03 8.4984e-02 + 8.8000e-02 -8.7071e+00 5.2795e-02 9.4721e-01 7.3956e-01 2.6044e-01 1.0000e-10 1.0000e-10 4.7921e-03 8.5977e-02 + 8.9000e-02 -8.7094e+00 5.2457e-02 9.4754e-01 7.3807e-01 2.6193e-01 1.0000e-10 1.0000e-10 4.8147e-03 8.6969e-02 + 9.0000e-02 -8.7117e+00 5.2125e-02 9.4788e-01 7.3658e-01 2.6342e-01 1.0000e-10 1.0000e-10 4.8371e-03 8.7961e-02 + 9.1000e-02 -8.7140e+00 5.1797e-02 9.4820e-01 7.3511e-01 2.6489e-01 1.0000e-10 1.0000e-10 4.8592e-03 8.8954e-02 + 9.2000e-02 -8.7162e+00 5.1474e-02 9.4853e-01 7.3364e-01 2.6636e-01 1.0000e-10 1.0000e-10 4.8811e-03 8.9946e-02 + 9.3000e-02 -8.7185e+00 5.1155e-02 9.4884e-01 7.3218e-01 2.6782e-01 1.0000e-10 1.0000e-10 4.9028e-03 9.0939e-02 + 9.4000e-02 -8.7207e+00 5.0841e-02 9.4916e-01 7.3073e-01 2.6927e-01 1.0000e-10 1.0000e-10 4.9243e-03 9.1932e-02 + 9.5000e-02 -8.7228e+00 5.0531e-02 9.4947e-01 7.2928e-01 2.7072e-01 1.0000e-10 1.0000e-10 4.9455e-03 9.2924e-02 + 9.6000e-02 -8.7250e+00 5.0226e-02 9.4977e-01 7.2784e-01 2.7216e-01 1.0000e-10 1.0000e-10 4.9665e-03 9.3917e-02 + 9.7000e-02 -8.7271e+00 4.9924e-02 9.5008e-01 7.2641e-01 2.7359e-01 1.0000e-10 1.0000e-10 4.9873e-03 9.4910e-02 + 9.8000e-02 -8.7292e+00 4.9627e-02 9.5037e-01 7.2499e-01 2.7501e-01 1.0000e-10 1.0000e-10 5.0079e-03 9.5903e-02 + 9.9000e-02 -8.7313e+00 4.9334e-02 9.5067e-01 7.2357e-01 2.7643e-01 1.0000e-10 1.0000e-10 5.0283e-03 9.6895e-02 + 1.0000e-01 -8.7334e+00 4.9044e-02 9.5096e-01 7.2216e-01 2.7784e-01 1.0000e-10 1.0000e-10 5.0485e-03 9.7888e-02 + 1.0000e-01 -8.7334e+00 4.9044e-02 9.5096e-01 7.2216e-01 2.7784e-01 1.0000e-10 1.0000e-10 5.0485e-03 9.7888e-02 + 2.0000e-01 -8.8746e+00 3.1529e-02 9.6847e-01 6.0843e-01 3.9157e-01 1.0000e-10 1.0000e-10 6.4250e-03 1.9735e-01 + 3.0000e-01 -8.9515e+00 2.3611e-02 9.7639e-01 5.2912e-01 4.7088e-01 1.0000e-10 1.0000e-10 7.1824e-03 2.9701e-01 + 4.0000e-01 -9.0015e+00 1.8992e-02 9.8101e-01 4.6954e-01 5.3046e-01 1.0000e-10 1.0000e-10 7.6814e-03 3.9677e-01 + 5.0000e-01 -9.0371e+00 1.5935e-02 9.8407e-01 4.2272e-01 5.7728e-01 1.0000e-10 1.0000e-10 8.0411e-03 4.9659e-01 + 6.0000e-01 -9.0640e+00 1.3750e-02 9.8625e-01 3.8479e-01 6.1521e-01 1.0000e-10 1.0000e-10 8.3153e-03 5.9645e-01 + 7.0000e-01 -9.0851e+00 1.2105e-02 9.8790e-01 3.5335e-01 6.4665e-01 1.0000e-10 1.0000e-10 8.5323e-03 6.9633e-01 + 8.0000e-01 -9.1022e+00 1.0819e-02 9.8918e-01 3.2680e-01 6.7320e-01 1.0000e-10 1.0000e-10 8.7090e-03 7.9623e-01 + 9.0000e-01 -9.1162e+00 9.7855e-03 9.9021e-01 3.0406e-01 6.9594e-01 1.0000e-10 1.0000e-10 8.8560e-03 8.9615e-01 + 1.0000e+00 -9.1281e+00 8.9352e-03 9.9106e-01 2.8435e-01 7.1565e-01 1.0000e-10 1.0000e-10 8.9804e-03 9.9608e-01 + 1.1000e+00 -9.1382e+00 8.2229e-03 9.9178e-01 2.6708e-01 7.3292e-01 1.0000e-10 1.0000e-10 9.0872e-03 1.0960e+00 + 1.2000e+00 -9.1470e+00 7.6172e-03 9.9238e-01 2.5183e-01 7.4817e-01 1.0000e-10 1.0000e-10 9.1799e-03 1.1960e+00 + 1.3000e+00 -9.1547e+00 7.0957e-03 9.9290e-01 2.3825e-01 7.6175e-01 1.0000e-10 1.0000e-10 9.2612e-03 1.2959e+00 + 1.4000e+00 -9.1614e+00 6.6418e-03 9.9336e-01 2.2608e-01 7.7392e-01 1.0000e-10 1.0000e-10 9.3332e-03 1.3959e+00 + 1.5000e+00 -9.1674e+00 6.2431e-03 9.9376e-01 2.1511e-01 7.8489e-01 1.0000e-10 1.0000e-10 9.3973e-03 1.4958e+00 + 1.6000e+00 -9.1728e+00 5.8899e-03 9.9411e-01 2.0516e-01 7.9484e-01 1.0000e-10 1.0000e-10 9.4548e-03 1.5958e+00 + 1.7000e+00 -9.1776e+00 5.5749e-03 9.9443e-01 1.9610e-01 8.0390e-01 1.0000e-10 1.0000e-10 9.5068e-03 1.6958e+00 + 1.8000e+00 -9.1820e+00 5.2921e-03 9.9471e-01 1.8782e-01 8.1218e-01 1.0000e-10 1.0000e-10 9.5539e-03 1.7957e+00 + 1.9000e+00 -9.1860e+00 5.0369e-03 9.9496e-01 1.8021e-01 8.1979e-01 1.0000e-10 1.0000e-10 9.5968e-03 1.8957e+00 + 2.0000e+00 -9.1896e+00 4.8052e-03 9.9519e-01 1.7320e-01 8.2680e-01 1.0000e-10 1.0000e-10 9.6361e-03 1.9957e+00 + 2.1000e+00 -9.1929e+00 4.5941e-03 9.9541e-01 1.6672e-01 8.3328e-01 1.0000e-10 1.0000e-10 9.6722e-03 2.0957e+00 + 2.2000e+00 -9.1960e+00 4.4009e-03 9.9560e-01 1.6071e-01 8.3929e-01 1.0000e-10 1.0000e-10 9.7055e-03 2.1957e+00 + 2.3000e+00 -9.1988e+00 4.2233e-03 9.9578e-01 1.5512e-01 8.4488e-01 1.0000e-10 1.0000e-10 9.7364e-03 2.2956e+00 + 2.4000e+00 -9.2015e+00 4.0596e-03 9.9594e-01 1.4990e-01 8.5010e-01 1.0000e-10 1.0000e-10 9.7650e-03 2.3956e+00 + 2.5000e+00 -9.2039e+00 3.9082e-03 9.9609e-01 1.4503e-01 8.5497e-01 1.0000e-10 1.0000e-10 9.7916e-03 2.4956e+00 + 2.6000e+00 -9.2062e+00 3.7677e-03 9.9623e-01 1.4047e-01 8.5953e-01 1.0000e-10 1.0000e-10 9.8164e-03 2.5956e+00 + 2.7000e+00 -9.2083e+00 3.6370e-03 9.9636e-01 1.3618e-01 8.6382e-01 1.0000e-10 1.0000e-10 9.8396e-03 2.6956e+00 + 2.8000e+00 -9.2103e+00 3.5151e-03 9.9648e-01 1.3216e-01 8.6784e-01 1.0000e-10 1.0000e-10 9.8614e-03 2.7956e+00 + 2.9000e+00 -9.2122e+00 3.4011e-03 9.9660e-01 1.2836e-01 8.7164e-01 1.0000e-10 1.0000e-10 9.8818e-03 2.8955e+00 + 3.0000e+00 -9.2139e+00 3.2944e-03 9.9671e-01 1.2478e-01 8.7522e-01 1.0000e-10 1.0000e-10 9.9010e-03 2.9955e+00 + 3.1000e+00 -9.2156e+00 3.1941e-03 9.9681e-01 1.2139e-01 8.7861e-01 1.0000e-10 1.0000e-10 9.9191e-03 3.0955e+00 + 3.2000e+00 -9.2171e+00 3.0998e-03 9.9690e-01 1.1818e-01 8.8182e-01 1.0000e-10 1.0000e-10 9.9363e-03 3.1955e+00 + 3.3000e+00 -9.2186e+00 3.0109e-03 9.9699e-01 1.1514e-01 8.8486e-01 1.0000e-10 1.0000e-10 9.9524e-03 3.2955e+00 + 3.4000e+00 -9.2200e+00 2.9270e-03 9.9707e-01 1.1225e-01 8.8775e-01 1.0000e-10 1.0000e-10 9.9678e-03 3.3955e+00 + 3.5000e+00 -9.2213e+00 2.8476e-03 9.9715e-01 1.0950e-01 8.9050e-01 1.0000e-10 1.0000e-10 9.9823e-03 3.4955e+00 + 3.6000e+00 -9.2226e+00 2.7725e-03 9.9723e-01 1.0688e-01 8.9312e-01 1.0000e-10 1.0000e-10 9.9961e-03 3.5955e+00 + 3.7000e+00 -9.2238e+00 2.7012e-03 9.9730e-01 1.0439e-01 8.9561e-01 1.0000e-10 1.0000e-10 1.0009e-02 3.6955e+00 + 3.8000e+00 -9.2249e+00 2.6335e-03 9.9737e-01 1.0201e-01 8.9799e-01 1.0000e-10 1.0000e-10 1.0022e-02 3.7955e+00 + 3.9000e+00 -9.2260e+00 2.5691e-03 9.9743e-01 9.9738e-02 9.0026e-01 1.0000e-10 1.0000e-10 1.0034e-02 3.8955e+00 + 4.0000e+00 -9.2270e+00 2.5078e-03 9.9749e-01 9.7564e-02 9.0244e-01 1.0000e-10 1.0000e-10 1.0045e-02 3.9954e+00 + 4.1000e+00 -9.2280e+00 2.4494e-03 9.9755e-01 9.5483e-02 9.0452e-01 1.0000e-10 1.0000e-10 1.0056e-02 4.0954e+00 + 4.2000e+00 -9.2289e+00 2.3936e-03 9.9761e-01 9.3489e-02 9.0651e-01 1.0000e-10 1.0000e-10 1.0066e-02 4.1954e+00 + 4.3000e+00 -9.2298e+00 2.3404e-03 9.9766e-01 9.1577e-02 9.0842e-01 1.0000e-10 1.0000e-10 1.0076e-02 4.2954e+00 + 4.4000e+00 -9.2307e+00 2.2894e-03 9.9771e-01 8.9742e-02 9.1026e-01 1.0000e-10 1.0000e-10 1.0086e-02 4.3954e+00 + 4.5000e+00 -9.2315e+00 2.2406e-03 9.9776e-01 8.7979e-02 9.1202e-01 1.0000e-10 1.0000e-10 1.0095e-02 4.4954e+00 + 4.6000e+00 -9.2323e+00 2.1939e-03 9.9781e-01 8.6284e-02 9.1372e-01 1.0000e-10 1.0000e-10 1.0104e-02 4.5954e+00 + 4.7000e+00 -9.2331e+00 2.1491e-03 9.9785e-01 8.4653e-02 9.1535e-01 1.0000e-10 1.0000e-10 1.0112e-02 4.6954e+00 + 4.8000e+00 -9.2338e+00 2.1060e-03 9.9789e-01 8.3083e-02 9.1692e-01 1.0000e-10 1.0000e-10 1.0121e-02 4.7954e+00 + 4.9000e+00 -9.2345e+00 2.0647e-03 9.9794e-01 8.1570e-02 9.1843e-01 1.0000e-10 1.0000e-10 1.0128e-02 4.8954e+00 + 5.0000e+00 -9.2352e+00 2.0249e-03 9.9798e-01 8.0112e-02 9.1989e-01 1.0000e-10 1.0000e-10 1.0136e-02 4.9954e+00 + 5.1000e+00 -9.2359e+00 1.9867e-03 9.9801e-01 7.8704e-02 9.2130e-01 1.0000e-10 1.0000e-10 1.0143e-02 5.0954e+00 + 5.2000e+00 -9.2365e+00 1.9499e-03 9.9805e-01 7.7346e-02 9.2265e-01 1.0000e-10 1.0000e-10 1.0150e-02 5.1954e+00 + 5.3000e+00 -9.2371e+00 1.9144e-03 9.9809e-01 7.6033e-02 9.2397e-01 1.0000e-10 1.0000e-10 1.0157e-02 5.2954e+00 + 5.4000e+00 -9.2377e+00 1.8802e-03 9.9812e-01 7.4765e-02 9.2524e-01 1.0000e-10 1.0000e-10 1.0163e-02 5.3954e+00 + 5.5000e+00 -9.2383e+00 1.8472e-03 9.9815e-01 7.3538e-02 9.2646e-01 1.0000e-10 1.0000e-10 1.0170e-02 5.4954e+00 + 5.6000e+00 -9.2388e+00 1.8153e-03 9.9818e-01 7.2350e-02 9.2765e-01 1.0000e-10 1.0000e-10 1.0176e-02 5.5954e+00 + 5.7000e+00 -9.2393e+00 1.7845e-03 9.9822e-01 7.1201e-02 9.2880e-01 1.0000e-10 1.0000e-10 1.0182e-02 5.6954e+00 + 5.8000e+00 -9.2398e+00 1.7548e-03 9.9825e-01 7.0087e-02 9.2991e-01 1.0000e-10 1.0000e-10 1.0187e-02 5.7954e+00 + 5.9000e+00 -9.2403e+00 1.7260e-03 9.9827e-01 6.9008e-02 9.3099e-01 1.0000e-10 1.0000e-10 1.0193e-02 5.8954e+00 + 6.0000e+00 -9.2408e+00 1.6982e-03 9.9830e-01 6.7962e-02 9.3204e-01 1.0000e-10 1.0000e-10 1.0198e-02 5.9954e+00 + 6.1000e+00 -9.2413e+00 1.6712e-03 9.9833e-01 6.6947e-02 9.3305e-01 1.0000e-10 1.0000e-10 1.0204e-02 6.0953e+00 + 6.2000e+00 -9.2417e+00 1.6451e-03 9.9835e-01 6.5961e-02 9.3404e-01 1.0000e-10 1.0000e-10 1.0209e-02 6.1953e+00 + 6.3000e+00 -9.2422e+00 1.6198e-03 9.9838e-01 6.5005e-02 9.3500e-01 1.0000e-10 1.0000e-10 1.0213e-02 6.2953e+00 + 6.4000e+00 -9.2426e+00 1.5952e-03 9.9840e-01 6.4076e-02 9.3592e-01 1.0000e-10 1.0000e-10 1.0218e-02 6.3953e+00 + 6.5000e+00 -9.2430e+00 1.5714e-03 9.9843e-01 6.3173e-02 9.3683e-01 1.0000e-10 1.0000e-10 1.0223e-02 6.4953e+00 + 6.6000e+00 -9.2434e+00 1.5483e-03 9.9845e-01 6.2295e-02 9.3771e-01 1.0000e-10 1.0000e-10 1.0227e-02 6.5953e+00 + 6.7000e+00 -9.2438e+00 1.5258e-03 9.9847e-01 6.1441e-02 9.3856e-01 1.0000e-10 1.0000e-10 1.0232e-02 6.6953e+00 + 6.8000e+00 -9.2442e+00 1.5040e-03 9.9850e-01 6.0610e-02 9.3939e-01 1.0000e-10 1.0000e-10 1.0236e-02 6.7953e+00 + 6.9000e+00 -9.2446e+00 1.4829e-03 9.9852e-01 5.9802e-02 9.4020e-01 1.0000e-10 1.0000e-10 1.0240e-02 6.8953e+00 + 7.0000e+00 -9.2449e+00 1.4623e-03 9.9854e-01 5.9015e-02 9.4099e-01 1.0000e-10 1.0000e-10 1.0244e-02 6.9953e+00 + 7.1000e+00 -9.2453e+00 1.4422e-03 9.9856e-01 5.8248e-02 9.4175e-01 1.0000e-10 1.0000e-10 1.0248e-02 7.0953e+00 + 7.2000e+00 -9.2456e+00 1.4227e-03 9.9858e-01 5.7501e-02 9.4250e-01 1.0000e-10 1.0000e-10 1.0252e-02 7.1953e+00 + 7.3000e+00 -9.2459e+00 1.4038e-03 9.9860e-01 5.6773e-02 9.4323e-01 1.0000e-10 1.0000e-10 1.0255e-02 7.2953e+00 + 7.4000e+00 -9.2463e+00 1.3853e-03 9.9861e-01 5.6063e-02 9.4394e-01 1.0000e-10 1.0000e-10 1.0259e-02 7.3953e+00 + 7.5000e+00 -9.2466e+00 1.3673e-03 9.9863e-01 5.5370e-02 9.4463e-01 1.0000e-10 1.0000e-10 1.0262e-02 7.4953e+00 + 7.6000e+00 -9.2469e+00 1.3498e-03 9.9865e-01 5.4695e-02 9.4530e-01 1.0000e-10 1.0000e-10 1.0266e-02 7.5953e+00 + 7.7000e+00 -9.2472e+00 1.3327e-03 9.9867e-01 5.4036e-02 9.4596e-01 1.0000e-10 1.0000e-10 1.0269e-02 7.6953e+00 + 7.8000e+00 -9.2475e+00 1.3160e-03 9.9868e-01 5.3392e-02 9.4661e-01 1.0000e-10 1.0000e-10 1.0273e-02 7.7953e+00 + 7.9000e+00 -9.2478e+00 1.2998e-03 9.9870e-01 5.2764e-02 9.4724e-01 1.0000e-10 1.0000e-10 1.0276e-02 7.8953e+00 + 8.0000e+00 -9.2480e+00 1.2840e-03 9.9872e-01 5.2150e-02 9.4785e-01 1.0000e-10 1.0000e-10 1.0279e-02 7.9953e+00 + 8.1000e+00 -9.2483e+00 1.2685e-03 9.9873e-01 5.1551e-02 9.4845e-01 1.0000e-10 1.0000e-10 1.0282e-02 8.0953e+00 + 8.2000e+00 -9.2486e+00 1.2534e-03 9.9875e-01 5.0965e-02 9.4903e-01 1.0000e-10 1.0000e-10 1.0285e-02 8.1953e+00 + 8.3000e+00 -9.2488e+00 1.2386e-03 9.9876e-01 5.0392e-02 9.4961e-01 1.0000e-10 1.0000e-10 1.0288e-02 8.2953e+00 + 8.4000e+00 -9.2491e+00 1.2242e-03 9.9878e-01 4.9832e-02 9.5017e-01 1.0000e-10 1.0000e-10 1.0290e-02 8.3953e+00 + 8.5000e+00 -9.2493e+00 1.2102e-03 9.9879e-01 4.9285e-02 9.5072e-01 1.0000e-10 1.0000e-10 1.0293e-02 8.4953e+00 + 8.6000e+00 -9.2496e+00 1.1964e-03 9.9880e-01 4.8749e-02 9.5125e-01 1.0000e-10 1.0000e-10 1.0296e-02 8.5953e+00 + 8.7000e+00 -9.2498e+00 1.1830e-03 9.9882e-01 4.8225e-02 9.5178e-01 1.0000e-10 1.0000e-10 1.0299e-02 8.6953e+00 + 8.8000e+00 -9.2500e+00 1.1698e-03 9.9883e-01 4.7712e-02 9.5229e-01 1.0000e-10 1.0000e-10 1.0301e-02 8.7953e+00 + 8.9000e+00 -9.2503e+00 1.1570e-03 9.9884e-01 4.7209e-02 9.5279e-01 1.0000e-10 1.0000e-10 1.0304e-02 8.8953e+00 + 9.0000e+00 -9.2505e+00 1.1444e-03 9.9886e-01 4.6718e-02 9.5328e-01 1.0000e-10 1.0000e-10 1.0306e-02 8.9953e+00 + 9.1000e+00 -9.2507e+00 1.1321e-03 9.9887e-01 4.6236e-02 9.5376e-01 1.0000e-10 1.0000e-10 1.0309e-02 9.0953e+00 + 9.2000e+00 -9.2509e+00 1.1201e-03 9.9888e-01 4.5764e-02 9.5424e-01 1.0000e-10 1.0000e-10 1.0311e-02 9.1953e+00 + 9.3000e+00 -9.2511e+00 1.1083e-03 9.9889e-01 4.5302e-02 9.5470e-01 1.0000e-10 1.0000e-10 1.0313e-02 9.2953e+00 + 9.4000e+00 -9.2513e+00 1.0967e-03 9.9890e-01 4.4849e-02 9.5515e-01 1.0000e-10 1.0000e-10 1.0316e-02 9.3953e+00 + 9.5000e+00 -9.2515e+00 1.0854e-03 9.9891e-01 4.4405e-02 9.5560e-01 1.0000e-10 1.0000e-10 1.0318e-02 9.4953e+00 + 9.6000e+00 -9.2517e+00 1.0744e-03 9.9893e-01 4.3969e-02 9.5603e-01 1.0000e-10 1.0000e-10 1.0320e-02 9.5953e+00 + 9.7000e+00 -9.2519e+00 1.0635e-03 9.9894e-01 4.3543e-02 9.5646e-01 1.0000e-10 1.0000e-10 1.0322e-02 9.6953e+00 + 9.8000e+00 -9.2521e+00 1.0529e-03 9.9895e-01 4.3124e-02 9.5688e-01 1.0000e-10 1.0000e-10 1.0324e-02 9.7953e+00 + 9.9000e+00 -9.2523e+00 1.0425e-03 9.9896e-01 4.2713e-02 9.5729e-01 1.0000e-10 1.0000e-10 1.0326e-02 9.8953e+00 + 1.0000e+01 -9.2525e+00 1.0323e-03 9.9897e-01 4.2310e-02 9.5769e-01 1.0000e-10 1.0000e-10 1.0328e-02 9.9953e+00 diff --git a/Sun/examples/ex11.log b/Sun/examples/ex11.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex11.out b/Sun/examples/ex11.out new file mode 100644 index 00000000..fcfa23e9 --- /dev/null +++ b/Sun/examples/ex11.out @@ -0,0 +1,2858 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex11 + Output file: ex11.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + PRINT + TITLE Example 11.--Transport and ion exchange. + SOLUTION 0 CaCl2 + units mmol/kgw + temp 25.0 + pH 7.0 charge + pe 12.5 O2(g) -0.68 + Ca 0.6 + Cl 1.2 + SOLUTION 1-40 Initial solution for column + units mmol/kgw + temp 25.0 + pH 7.0 charge + pe 12.5 O2(g) -0.68 + Na 1.0 + K 0.2 + N(5) 1.2 + EXCHANGE 1-40 + equilibrate 1 + X 0.0011 + ADVECTION + cells 40 + shifts 120 + punch_cells 40 + punch_frequency 1 + print_cells 40 + print_frequency 20 + SELECTED_OUTPUT + file ex11adv.sel + reset false + step + totals Na Cl K Ca + USER_PUNCH + heading Pore_vol + 10 PUNCH (STEP_NO + .5) / 40. + END +----- +TITLE +----- + + Example 11.--Transport and ion exchange. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. CaCl2 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 6.000e-04 6.000e-04 + Cl 1.200e-03 1.200e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.800e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -5.732e-20 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 4.630e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 4 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 6.000e-04 + Ca+2 6.000e-04 4.985e-04 -3.222 -3.302 -0.081 + CaOH+ 8.617e-10 8.221e-10 -9.065 -9.085 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.68 -3.64 -2.96 O2 + +Initial solution 1. Initial solution for column + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 2.000e-04 2.000e-04 + N(5) 1.200e-03 1.200e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.114e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -8.455e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(5) 1.200e-03 + NO3- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.68 -3.64 -2.96 O2 + +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 0. CaCl2 +Using exchange 1. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 4.933e-04 9.866e-04 8.969e-01 -0.069 + KX 9.224e-05 9.224e-05 8.385e-02 -0.018 + NaX 2.120e-05 2.120e-05 1.928e-02 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.067e-04 1.067e-04 + Cl 1.200e-03 1.200e-03 + K 4.584e-04 4.584e-04 + Na 5.281e-04 5.281e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.307e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.215e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 9.601e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 8 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.042e-07 1.003e-07 -6.982 -6.999 -0.017 + OH- 1.040e-07 9.983e-08 -6.983 -7.001 -0.018 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 1.067e-04 + Ca+2 1.067e-04 9.098e-05 -3.972 -4.041 -0.069 + CaOH+ 1.568e-10 1.506e-10 -9.805 -9.822 -0.018 +Cl 1.200e-03 + Cl- 1.200e-03 1.152e-03 -2.921 -2.938 -0.018 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 4.584e-04 + K+ 4.584e-04 4.402e-04 -3.339 -3.356 -0.018 + KOH 1.522e-11 1.522e-11 -10.818 -10.818 0.000 +Na 5.281e-04 + Na+ 5.281e-04 5.073e-04 -3.277 -3.295 -0.017 + NaOH 3.342e-11 3.343e-11 -10.476 -10.476 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.82 -6.23 1.58 NaCl + O2(g) -0.68 -3.64 -2.96 O2 + +------------------------------------ +Beginning of advection calculations. +------------------------------------ + +Beginning of advection time step 1, cumulative pore volumes 0.025000. +Beginning of advection time step 2, cumulative pore volumes 0.050000. +Beginning of advection time step 3, cumulative pore volumes 0.075000. +Beginning of advection time step 4, cumulative pore volumes 0.100000. +Beginning of advection time step 5, cumulative pore volumes 0.125000. +Beginning of advection time step 6, cumulative pore volumes 0.150000. +Beginning of advection time step 7, cumulative pore volumes 0.175000. +Beginning of advection time step 8, cumulative pore volumes 0.200000. +Beginning of advection time step 9, cumulative pore volumes 0.225000. +Beginning of advection time step 10, cumulative pore volumes 0.250000. +Beginning of advection time step 11, cumulative pore volumes 0.275000. +Beginning of advection time step 12, cumulative pore volumes 0.300000. +Beginning of advection time step 13, cumulative pore volumes 0.325000. +Beginning of advection time step 14, cumulative pore volumes 0.350000. +Beginning of advection time step 15, cumulative pore volumes 0.375000. +Beginning of advection time step 16, cumulative pore volumes 0.400000. +Beginning of advection time step 17, cumulative pore volumes 0.425000. +Beginning of advection time step 18, cumulative pore volumes 0.450000. +Beginning of advection time step 19, cumulative pore volumes 0.475000. +Beginning of advection time step 20, cumulative pore volumes 0.500000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + NH4X 4.148e-63 4.148e-63 3.771e-60 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 2.000e-04 2.000e-04 + N 1.200e-03 1.200e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.114e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.539e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.722 -62.739 -0.017 + NH3 0.000e+00 0.000e+00 -64.984 -64.984 0.000 +N(0) 2.552e-19 + N2 1.276e-19 1.276e-19 -18.894 -18.894 0.000 +N(3) 2.686e-16 + NO2- 2.686e-16 2.583e-16 -15.571 -15.588 -0.017 +N(5) 1.200e-03 + NO3- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.63 -18.89 -3.26 N2 + NH3(g) -66.75 -64.98 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Beginning of advection time step 21, cumulative pore volumes 0.525000. +Beginning of advection time step 22, cumulative pore volumes 0.550000. +Beginning of advection time step 23, cumulative pore volumes 0.575000. +Beginning of advection time step 24, cumulative pore volumes 0.600000. +Beginning of advection time step 25, cumulative pore volumes 0.625000. +Beginning of advection time step 26, cumulative pore volumes 0.650000. +Beginning of advection time step 27, cumulative pore volumes 0.675000. +Beginning of advection time step 28, cumulative pore volumes 0.700000. +Beginning of advection time step 29, cumulative pore volumes 0.725000. +Beginning of advection time step 30, cumulative pore volumes 0.750000. +Beginning of advection time step 31, cumulative pore volumes 0.775000. +Beginning of advection time step 32, cumulative pore volumes 0.800000. +Beginning of advection time step 33, cumulative pore volumes 0.825000. +Beginning of advection time step 34, cumulative pore volumes 0.850000. +Beginning of advection time step 35, cumulative pore volumes 0.875000. +Beginning of advection time step 36, cumulative pore volumes 0.900000. +Beginning of advection time step 37, cumulative pore volumes 0.925000. +Beginning of advection time step 38, cumulative pore volumes 0.950000. +Beginning of advection time step 39, cumulative pore volumes 0.975000. +Beginning of advection time step 40, cumulative pore volumes 1.000000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.200e-03 1.200e-03 + K 2.000e-04 2.000e-04 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.450e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.960e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Cl 1.200e-03 + Cl- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.54 -5.95 1.58 NaCl + O2(g) -0.68 -3.64 -2.96 O2 + +Beginning of advection time step 41, cumulative pore volumes 1.025000. +Beginning of advection time step 42, cumulative pore volumes 1.050000. +Beginning of advection time step 43, cumulative pore volumes 1.075000. +Beginning of advection time step 44, cumulative pore volumes 1.100000. +Beginning of advection time step 45, cumulative pore volumes 1.125000. +Beginning of advection time step 46, cumulative pore volumes 1.150000. +Beginning of advection time step 47, cumulative pore volumes 1.175000. +Beginning of advection time step 48, cumulative pore volumes 1.200000. +Beginning of advection time step 49, cumulative pore volumes 1.225000. +Beginning of advection time step 50, cumulative pore volumes 1.250000. +Beginning of advection time step 51, cumulative pore volumes 1.275000. +Beginning of advection time step 52, cumulative pore volumes 1.300000. +Beginning of advection time step 53, cumulative pore volumes 1.325000. +Beginning of advection time step 54, cumulative pore volumes 1.350000. +Beginning of advection time step 55, cumulative pore volumes 1.375000. +Beginning of advection time step 56, cumulative pore volumes 1.400000. +Beginning of advection time step 57, cumulative pore volumes 1.425000. +Beginning of advection time step 58, cumulative pore volumes 1.450000. +Beginning of advection time step 59, cumulative pore volumes 1.475000. +Beginning of advection time step 60, cumulative pore volumes 1.500000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 7.000e-04 7.000e-04 6.363e-01 -0.017 + NaX 4.000e-04 4.000e-04 3.637e-01 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.200e-03 1.200e-03 + K 3.105e-04 3.105e-04 + Na 8.895e-04 8.895e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -2.836e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 3.548e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 4 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Cl 1.200e-03 + Cl- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 3.105e-04 + K+ 3.105e-04 2.986e-04 -3.508 -3.525 -0.017 + KOH 1.033e-11 1.033e-11 -10.986 -10.986 0.000 +Na 8.895e-04 + Na+ 8.895e-04 8.558e-04 -3.051 -3.068 -0.017 + NaOH 5.641e-11 5.643e-11 -10.249 -10.249 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.59 -6.01 1.58 NaCl + O2(g) -0.68 -3.64 -2.96 O2 + +Beginning of advection time step 61, cumulative pore volumes 1.525000. +Beginning of advection time step 62, cumulative pore volumes 1.550000. +Beginning of advection time step 63, cumulative pore volumes 1.575000. +Beginning of advection time step 64, cumulative pore volumes 1.600000. +Beginning of advection time step 65, cumulative pore volumes 1.625000. +Beginning of advection time step 66, cumulative pore volumes 1.650000. +Beginning of advection time step 67, cumulative pore volumes 1.675000. +Beginning of advection time step 68, cumulative pore volumes 1.700000. +Beginning of advection time step 69, cumulative pore volumes 1.725000. +Beginning of advection time step 70, cumulative pore volumes 1.750000. +Beginning of advection time step 71, cumulative pore volumes 1.775000. +Beginning of advection time step 72, cumulative pore volumes 1.800000. +Beginning of advection time step 73, cumulative pore volumes 1.825000. +Beginning of advection time step 74, cumulative pore volumes 1.850000. +Beginning of advection time step 75, cumulative pore volumes 1.875000. +Beginning of advection time step 76, cumulative pore volumes 1.900000. +Beginning of advection time step 77, cumulative pore volumes 1.925000. +Beginning of advection time step 78, cumulative pore volumes 1.950000. +Beginning of advection time step 79, cumulative pore volumes 1.975000. +Beginning of advection time step 80, cumulative pore volumes 2.000000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.500e-04 1.100e-03 1.000e+00 -0.081 + KX 6.870e-09 6.870e-09 6.246e-06 -0.021 + NaX 2.513e-21 2.513e-21 2.285e-18 -0.020 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 6.000e-04 6.000e-04 + Cl 1.200e-03 1.200e-03 + K 7.667e-08 7.667e-08 + Na 1.406e-19 1.406e-19 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.800e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.294e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 3.976e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 6 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 6.000e-04 + Ca+2 6.000e-04 4.984e-04 -3.222 -3.302 -0.081 + CaOH+ 8.617e-10 8.220e-10 -9.065 -9.085 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 7.667e-08 + K+ 7.667e-08 7.312e-08 -7.115 -7.136 -0.021 + KOH 2.519e-15 2.520e-15 -14.599 -14.599 0.000 +Na 1.406e-19 + Na+ 1.406e-19 1.341e-19 -18.852 -18.872 -0.020 + NaOH 8.804e-27 8.807e-27 -26.055 -26.055 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -23.40 -21.81 1.58 NaCl + O2(g) -0.68 -3.64 -2.96 O2 + +Beginning of advection time step 81, cumulative pore volumes 2.025000. +Beginning of advection time step 82, cumulative pore volumes 2.050000. +Beginning of advection time step 83, cumulative pore volumes 2.075000. +Beginning of advection time step 84, cumulative pore volumes 2.100000. +Beginning of advection time step 85, cumulative pore volumes 2.125000. +Beginning of advection time step 86, cumulative pore volumes 2.150000. +Beginning of advection time step 87, cumulative pore volumes 2.175000. +Beginning of advection time step 88, cumulative pore volumes 2.200000. +Beginning of advection time step 89, cumulative pore volumes 2.225000. +Beginning of advection time step 90, cumulative pore volumes 2.250000. +Beginning of advection time step 91, cumulative pore volumes 2.275000. +Beginning of advection time step 92, cumulative pore volumes 2.300000. +Beginning of advection time step 93, cumulative pore volumes 2.325000. +Beginning of advection time step 94, cumulative pore volumes 2.350000. +Beginning of advection time step 95, cumulative pore volumes 2.375000. +Beginning of advection time step 96, cumulative pore volumes 2.400000. +Beginning of advection time step 97, cumulative pore volumes 2.425000. +Beginning of advection time step 98, cumulative pore volumes 2.450000. +Beginning of advection time step 99, cumulative pore volumes 2.475000. +Beginning of advection time step 100, cumulative pore volumes 2.500000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.500e-04 1.100e-03 1.000e+00 -0.081 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 6.000e-04 6.000e-04 + Cl 1.200e-03 1.200e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.800e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -5.732e-20 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 3.546e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 6.000e-04 + Ca+2 6.000e-04 4.985e-04 -3.222 -3.302 -0.081 + CaOH+ 8.617e-10 8.221e-10 -9.065 -9.085 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.68 -3.64 -2.96 O2 + +Beginning of advection time step 101, cumulative pore volumes 2.525000. +Beginning of advection time step 102, cumulative pore volumes 2.550000. +Beginning of advection time step 103, cumulative pore volumes 2.575000. +Beginning of advection time step 104, cumulative pore volumes 2.600000. +Beginning of advection time step 105, cumulative pore volumes 2.625000. +Beginning of advection time step 106, cumulative pore volumes 2.650000. +Beginning of advection time step 107, cumulative pore volumes 2.675000. +Beginning of advection time step 108, cumulative pore volumes 2.700000. +Beginning of advection time step 109, cumulative pore volumes 2.725000. +Beginning of advection time step 110, cumulative pore volumes 2.750000. +Beginning of advection time step 111, cumulative pore volumes 2.775000. +Beginning of advection time step 112, cumulative pore volumes 2.800000. +Beginning of advection time step 113, cumulative pore volumes 2.825000. +Beginning of advection time step 114, cumulative pore volumes 2.850000. +Beginning of advection time step 115, cumulative pore volumes 2.875000. +Beginning of advection time step 116, cumulative pore volumes 2.900000. +Beginning of advection time step 117, cumulative pore volumes 2.925000. +Beginning of advection time step 118, cumulative pore volumes 2.950000. +Beginning of advection time step 119, cumulative pore volumes 2.975000. +Beginning of advection time step 120, cumulative pore volumes 3.000000. + +Cell 40. + +Using solution 40. Solution after simulation 1. +Using exchange 40. Exchange assemblage after simulation 1. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.500e-04 1.100e-03 1.000e+00 -0.081 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 6.000e-04 6.000e-04 + Cl 1.200e-03 1.200e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.800e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -5.732e-20 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 3.546e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 6.000e-04 + Ca+2 6.000e-04 4.985e-04 -3.222 -3.302 -0.081 + CaOH+ 8.617e-10 8.221e-10 -9.065 -9.085 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.68 -3.64 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1-40 Initial solution for column + units mmol/kgw + temp 25.0 + pH 7.0 charge + pe 12.5 O2(g) -0.68 + Na 1.0 + K 0.2 + N(5) 1.2 + EXCHANGE 1-40 + equilibrate 1 + X 0.0011 + TRANSPORT + cells 40 + length 0.002 + shifts 120 + time_step 720.0 + flow_direction forward + boundary_conditions flux flux + diffc 0.0e-9 + dispersivity 0.002 + correct_disp true + punch 40 + punch_frequency 1 + print 40 + print_frequency 20 + SELECTED_OUTPUT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 40. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 40. + file ex11trn.sel + reset false + step + totals Na Cl K Ca + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Initial solution for column + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 2.000e-04 2.000e-04 + N(5) 1.200e-03 1.200e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.114e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -8.455e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(5) 1.200e-03 + NO3- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.68 -3.64 -2.96 O2 + +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Initial solution for column +Using exchange 1. Exchange assemblage after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + NH4X 4.148e-63 4.148e-63 3.771e-60 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 2.000e-04 2.000e-04 + N 1.200e-03 1.200e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.114e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.532e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.722 -62.739 -0.017 + NH3 0.000e+00 0.000e+00 -64.984 -64.984 0.000 +N(0) 2.552e-19 + N2 1.276e-19 1.276e-19 -18.894 -18.894 0.000 +N(3) 2.686e-16 + NO2- 2.686e-16 2.583e-16 -15.571 -15.588 -0.017 +N(5) 1.200e-03 + NO3- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.63 -18.89 -3.26 N2 + NH3(g) -66.75 -64.98 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +------------------------------------ +Beginning of transport calculations. +------------------------------------ + +------------------------------- +Equilibrating initial solutions +------------------------------- + +Using solution 40. Initial solution for column +Using exchange 40. Exchanger defined in simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + NH4X 4.148e-63 4.148e-63 3.771e-60 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 2.000e-04 2.000e-04 + N 1.200e-03 1.200e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.114e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.532e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.722 -62.739 -0.017 + NH3 0.000e+00 0.000e+00 -64.984 -64.984 0.000 +N(0) 2.552e-19 + N2 1.276e-19 1.276e-19 -18.894 -18.894 0.000 +N(3) 2.686e-16 + NO2- 2.686e-16 2.583e-16 -15.571 -15.588 -0.017 +N(5) 1.200e-03 + NO3- 1.200e-03 1.154e-03 -2.921 -2.938 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.63 -18.89 -3.26 N2 + NH3(g) -66.75 -64.98 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 1. + +Transport step 1. Mixrun 1. + +Transport step 1. Mixrun 2. + +Transport step 1. Mixrun 3. + +Transport step 1. Mixrun 4. + +Transport step 2. + +Transport step 2. Mixrun 1. + +Transport step 2. Mixrun 2. + +Transport step 2. Mixrun 3. + +Transport step 2. Mixrun 4. + +Transport step 3. + +Transport step 3. Mixrun 1. + +Transport step 3. Mixrun 2. + +Transport step 3. Mixrun 3. + +Transport step 3. Mixrun 4. + +Transport step 4. + +Transport step 4. Mixrun 1. + +Transport step 4. Mixrun 2. + +Transport step 4. Mixrun 3. + +Transport step 4. Mixrun 4. + +Transport step 5. + +Transport step 5. Mixrun 1. + +Transport step 5. Mixrun 2. + +Transport step 5. Mixrun 3. + +Transport step 5. Mixrun 4. + +Transport step 6. + +Transport step 6. Mixrun 1. + +Transport step 6. Mixrun 2. + +Transport step 6. Mixrun 3. + +Transport step 6. Mixrun 4. + +Transport step 7. + +Transport step 7. Mixrun 1. + +Transport step 7. Mixrun 2. + +Transport step 7. Mixrun 3. + +Transport step 7. Mixrun 4. + +Transport step 8. + +Transport step 8. Mixrun 1. + +Transport step 8. Mixrun 2. + +Transport step 8. Mixrun 3. + +Transport step 8. Mixrun 4. + +Transport step 9. + +Transport step 9. Mixrun 1. + +Transport step 9. Mixrun 2. + +Transport step 9. Mixrun 3. + +Transport step 9. Mixrun 4. + +Transport step 10. + +Transport step 10. Mixrun 1. + +Transport step 10. Mixrun 2. + +Transport step 10. Mixrun 3. + +Transport step 10. Mixrun 4. + +Transport step 11. + +Transport step 11. Mixrun 1. + +Transport step 11. Mixrun 2. + +Transport step 11. Mixrun 3. + +Transport step 11. Mixrun 4. + +Transport step 12. + +Transport step 12. Mixrun 1. + +Transport step 12. Mixrun 2. + +Transport step 12. Mixrun 3. + +Transport step 12. Mixrun 4. + +Transport step 13. + +Transport step 13. Mixrun 1. + +Transport step 13. Mixrun 2. + +Transport step 13. Mixrun 3. + +Transport step 13. Mixrun 4. + +Transport step 14. + +Transport step 14. Mixrun 1. + +Transport step 14. Mixrun 2. + +Transport step 14. Mixrun 3. + +Transport step 14. Mixrun 4. + +Transport step 15. + +Transport step 15. Mixrun 1. + +Transport step 15. Mixrun 2. + +Transport step 15. Mixrun 3. + +Transport step 15. Mixrun 4. + +Transport step 16. + +Transport step 16. Mixrun 1. + +Transport step 16. Mixrun 2. + +Transport step 16. Mixrun 3. + +Transport step 16. Mixrun 4. + +Transport step 17. + +Transport step 17. Mixrun 1. + +Transport step 17. Mixrun 2. + +Transport step 17. Mixrun 3. + +Transport step 17. Mixrun 4. + +Transport step 18. + +Transport step 18. Mixrun 1. + +Transport step 18. Mixrun 2. + +Transport step 18. Mixrun 3. + +Transport step 18. Mixrun 4. + +Transport step 19. + +Transport step 19. Mixrun 1. + +Transport step 19. Mixrun 2. + +Transport step 19. Mixrun 3. + +Transport step 19. Mixrun 4. + +Transport step 20. + +Transport step 20. Mixrun 1. + +Transport step 20. Mixrun 2. + +Transport step 20. Mixrun 3. + +Transport step 20. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.507e-04 5.507e-04 5.006e-01 -0.017 + NaX 5.493e-04 5.493e-04 4.994e-01 -0.017 + NH4X 4.141e-63 4.141e-63 3.765e-60 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.848e-06 1.848e-06 + K 2.000e-04 2.000e-04 + N 1.198e-03 1.198e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.424e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 1.564e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.551027e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Cl 1.848e-06 + Cl- 1.848e-06 1.777e-06 -5.733 -5.750 -0.017 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.000e-04 + K+ 2.000e-04 1.923e-04 -3.699 -3.716 -0.017 + KOH 6.654e-12 6.656e-12 -11.177 -11.177 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.723 -62.740 -0.017 + NH3 0.000e+00 0.000e+00 -64.985 -64.985 0.000 +N(0) 2.544e-19 + N2 1.272e-19 1.272e-19 -18.895 -18.895 0.000 +N(3) 2.682e-16 + NO2- 2.682e-16 2.579e-16 -15.571 -15.589 -0.017 +N(5) 1.198e-03 + NO3- 1.198e-03 1.152e-03 -2.921 -2.939 -0.017 +Na 1.000e-03 + Na+ 1.000e-03 9.621e-04 -3.000 -3.017 -0.017 + NaOH 6.342e-11 6.344e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -10.35 -8.77 1.58 NaCl + N2(g) -15.64 -18.90 -3.26 N2 + NH3(g) -66.75 -64.98 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 21. + +Transport step 21. Mixrun 1. + +Transport step 21. Mixrun 2. + +Transport step 21. Mixrun 3. + +Transport step 21. Mixrun 4. + +Transport step 22. + +Transport step 22. Mixrun 1. + +Transport step 22. Mixrun 2. + +Transport step 22. Mixrun 3. + +Transport step 22. Mixrun 4. + +Transport step 23. + +Transport step 23. Mixrun 1. + +Transport step 23. Mixrun 2. + +Transport step 23. Mixrun 3. + +Transport step 23. Mixrun 4. + +Transport step 24. + +Transport step 24. Mixrun 1. + +Transport step 24. Mixrun 2. + +Transport step 24. Mixrun 3. + +Transport step 24. Mixrun 4. + +Transport step 25. + +Transport step 25. Mixrun 1. + +Transport step 25. Mixrun 2. + +Transport step 25. Mixrun 3. + +Transport step 25. Mixrun 4. + +Transport step 26. + +Transport step 26. Mixrun 1. + +Transport step 26. Mixrun 2. + +Transport step 26. Mixrun 3. + +Transport step 26. Mixrun 4. + +Transport step 27. + +Transport step 27. Mixrun 1. + +Transport step 27. Mixrun 2. + +Transport step 27. Mixrun 3. + +Transport step 27. Mixrun 4. + +Transport step 28. + +Transport step 28. Mixrun 1. + +Transport step 28. Mixrun 2. + +Transport step 28. Mixrun 3. + +Transport step 28. Mixrun 4. + +Transport step 29. + +Transport step 29. Mixrun 1. + +Transport step 29. Mixrun 2. + +Transport step 29. Mixrun 3. + +Transport step 29. Mixrun 4. + +Transport step 30. + +Transport step 30. Mixrun 1. + +Transport step 30. Mixrun 2. + +Transport step 30. Mixrun 3. + +Transport step 30. Mixrun 4. + +Transport step 31. + +Transport step 31. Mixrun 1. + +Transport step 31. Mixrun 2. + +Transport step 31. Mixrun 3. + +Transport step 31. Mixrun 4. + +Transport step 32. + +Transport step 32. Mixrun 1. + +Transport step 32. Mixrun 2. + +Transport step 32. Mixrun 3. + +Transport step 32. Mixrun 4. + +Transport step 33. + +Transport step 33. Mixrun 1. + +Transport step 33. Mixrun 2. + +Transport step 33. Mixrun 3. + +Transport step 33. Mixrun 4. + +Transport step 34. + +Transport step 34. Mixrun 1. + +Transport step 34. Mixrun 2. + +Transport step 34. Mixrun 3. + +Transport step 34. Mixrun 4. + +Transport step 35. + +Transport step 35. Mixrun 1. + +Transport step 35. Mixrun 2. + +Transport step 35. Mixrun 3. + +Transport step 35. Mixrun 4. + +Transport step 36. + +Transport step 36. Mixrun 1. + +Transport step 36. Mixrun 2. + +Transport step 36. Mixrun 3. + +Transport step 36. Mixrun 4. + +Transport step 37. + +Transport step 37. Mixrun 1. + +Transport step 37. Mixrun 2. + +Transport step 37. Mixrun 3. + +Transport step 37. Mixrun 4. + +Transport step 38. + +Transport step 38. Mixrun 1. + +Transport step 38. Mixrun 2. + +Transport step 38. Mixrun 3. + +Transport step 38. Mixrun 4. + +Transport step 39. + +Transport step 39. Mixrun 1. + +Transport step 39. Mixrun 2. + +Transport step 39. Mixrun 3. + +Transport step 39. Mixrun 4. + +Transport step 40. + +Transport step 40. Mixrun 1. + +Transport step 40. Mixrun 2. + +Transport step 40. Mixrun 3. + +Transport step 40. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 5.512e-04 5.512e-04 5.011e-01 -0.017 + NaX 5.488e-04 5.488e-04 4.989e-01 -0.017 + NH4X 1.796e-63 1.796e-63 1.633e-60 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 6.801e-04 6.801e-04 + K 2.004e-04 2.004e-04 + N 5.199e-04 5.199e-04 + Na 9.996e-04 9.996e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.848e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.884e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550823e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Cl 6.801e-04 + Cl- 6.801e-04 6.540e-04 -3.167 -3.184 -0.017 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 2.004e-04 + K+ 2.004e-04 1.927e-04 -3.698 -3.715 -0.017 + KOH 6.666e-12 6.668e-12 -11.176 -11.176 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -63.085 -63.102 -0.017 + NH3 0.000e+00 0.000e+00 -65.348 -65.347 0.000 +N(0) 4.792e-20 + N2 2.396e-20 2.397e-20 -19.621 -19.620 0.000 +N(3) 1.164e-16 + NO2- 1.164e-16 1.119e-16 -15.934 -15.951 -0.017 +N(5) 5.199e-04 + NO3- 5.199e-04 4.999e-04 -3.284 -3.301 -0.017 +Na 9.996e-04 + Na+ 9.996e-04 9.617e-04 -3.000 -3.017 -0.017 + NaOH 6.340e-11 6.341e-11 -10.198 -10.198 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.78 -6.20 1.58 NaCl + N2(g) -16.36 -19.62 -3.26 N2 + NH3(g) -67.12 -65.35 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 41. + +Transport step 41. Mixrun 1. + +Transport step 41. Mixrun 2. + +Transport step 41. Mixrun 3. + +Transport step 41. Mixrun 4. + +Transport step 42. + +Transport step 42. Mixrun 1. + +Transport step 42. Mixrun 2. + +Transport step 42. Mixrun 3. + +Transport step 42. Mixrun 4. + +Transport step 43. + +Transport step 43. Mixrun 1. + +Transport step 43. Mixrun 2. + +Transport step 43. Mixrun 3. + +Transport step 43. Mixrun 4. + +Transport step 44. + +Transport step 44. Mixrun 1. + +Transport step 44. Mixrun 2. + +Transport step 44. Mixrun 3. + +Transport step 44. Mixrun 4. + +Transport step 45. + +Transport step 45. Mixrun 1. + +Transport step 45. Mixrun 2. + +Transport step 45. Mixrun 3. + +Transport step 45. Mixrun 4. + +Transport step 46. + +Transport step 46. Mixrun 1. + +Transport step 46. Mixrun 2. + +Transport step 46. Mixrun 3. + +Transport step 46. Mixrun 4. + +Transport step 47. + +Transport step 47. Mixrun 1. + +Transport step 47. Mixrun 2. + +Transport step 47. Mixrun 3. + +Transport step 47. Mixrun 4. + +Transport step 48. + +Transport step 48. Mixrun 1. + +Transport step 48. Mixrun 2. + +Transport step 48. Mixrun 3. + +Transport step 48. Mixrun 4. + +Transport step 49. + +Transport step 49. Mixrun 1. + +Transport step 49. Mixrun 2. + +Transport step 49. Mixrun 3. + +Transport step 49. Mixrun 4. + +Transport step 50. + +Transport step 50. Mixrun 1. + +Transport step 50. Mixrun 2. + +Transport step 50. Mixrun 3. + +Transport step 50. Mixrun 4. + +Transport step 51. + +Transport step 51. Mixrun 1. + +Transport step 51. Mixrun 2. + +Transport step 51. Mixrun 3. + +Transport step 51. Mixrun 4. + +Transport step 52. + +Transport step 52. Mixrun 1. + +Transport step 52. Mixrun 2. + +Transport step 52. Mixrun 3. + +Transport step 52. Mixrun 4. + +Transport step 53. + +Transport step 53. Mixrun 1. + +Transport step 53. Mixrun 2. + +Transport step 53. Mixrun 3. + +Transport step 53. Mixrun 4. + +Transport step 54. + +Transport step 54. Mixrun 1. + +Transport step 54. Mixrun 2. + +Transport step 54. Mixrun 3. + +Transport step 54. Mixrun 4. + +Transport step 55. + +Transport step 55. Mixrun 1. + +Transport step 55. Mixrun 2. + +Transport step 55. Mixrun 3. + +Transport step 55. Mixrun 4. + +Transport step 56. + +Transport step 56. Mixrun 1. + +Transport step 56. Mixrun 2. + +Transport step 56. Mixrun 3. + +Transport step 56. Mixrun 4. + +Transport step 57. + +Transport step 57. Mixrun 1. + +Transport step 57. Mixrun 2. + +Transport step 57. Mixrun 3. + +Transport step 57. Mixrun 4. + +Transport step 58. + +Transport step 58. Mixrun 1. + +Transport step 58. Mixrun 2. + +Transport step 58. Mixrun 3. + +Transport step 58. Mixrun 4. + +Transport step 59. + +Transport step 59. Mixrun 1. + +Transport step 59. Mixrun 2. + +Transport step 59. Mixrun 3. + +Transport step 59. Mixrun 4. + +Transport step 60. + +Transport step 60. Mixrun 1. + +Transport step 60. Mixrun 2. + +Transport step 60. Mixrun 3. + +Transport step 60. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 9.451e-04 9.451e-04 8.592e-01 -0.017 + NaX 1.549e-04 1.549e-04 1.408e-01 -0.017 + CaX2 2.150e-20 4.300e-20 3.909e-17 -0.067 + NH4X 5.255e-65 5.255e-65 4.777e-62 -0.017 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 9.153e-23 9.153e-23 + Cl 1.171e-03 1.171e-03 + K 6.589e-04 6.589e-04 + N 2.918e-05 2.918e-05 + Na 5.411e-04 5.411e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.999 Charge balance + pe = 13.611 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.200e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.591e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 3.043e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550676e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.040e-07 1.002e-07 -6.983 -6.999 -0.016 + OH- 1.039e-07 9.991e-08 -6.983 -7.000 -0.017 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 9.153e-23 + Ca+2 9.153e-23 7.852e-23 -22.038 -22.105 -0.067 + CaOH+ 1.352e-28 1.301e-28 -27.869 -27.886 -0.017 +Cl 1.171e-03 + Cl- 1.171e-03 1.126e-03 -2.932 -2.948 -0.017 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 6.589e-04 + K+ 6.589e-04 6.337e-04 -3.181 -3.198 -0.017 + KOH 2.192e-11 2.193e-11 -10.659 -10.659 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -64.336 -64.353 -0.017 + NH3 0.000e+00 0.000e+00 -66.598 -66.598 0.000 +N(0) 1.509e-22 + N2 7.545e-23 7.547e-23 -22.122 -22.122 0.000 +N(3) 6.532e-18 + NO2- 6.532e-18 6.281e-18 -17.185 -17.202 -0.017 +N(5) 2.918e-05 + NO3- 2.918e-05 2.805e-05 -4.535 -4.552 -0.017 +Na 5.411e-04 + Na+ 5.411e-04 5.206e-04 -3.267 -3.284 -0.017 + NaOH 3.432e-11 3.433e-11 -10.464 -10.464 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.81 -6.23 1.58 NaCl + N2(g) -18.86 -22.12 -3.26 N2 + NH3(g) -68.37 -66.60 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 61. + +Transport step 61. Mixrun 1. + +Transport step 61. Mixrun 2. + +Transport step 61. Mixrun 3. + +Transport step 61. Mixrun 4. + +Transport step 62. + +Transport step 62. Mixrun 1. + +Transport step 62. Mixrun 2. + +Transport step 62. Mixrun 3. + +Transport step 62. Mixrun 4. + +Transport step 63. + +Transport step 63. Mixrun 1. + +Transport step 63. Mixrun 2. + +Transport step 63. Mixrun 3. + +Transport step 63. Mixrun 4. + +Transport step 64. + +Transport step 64. Mixrun 1. + +Transport step 64. Mixrun 2. + +Transport step 64. Mixrun 3. + +Transport step 64. Mixrun 4. + +Transport step 65. + +Transport step 65. Mixrun 1. + +Transport step 65. Mixrun 2. + +Transport step 65. Mixrun 3. + +Transport step 65. Mixrun 4. + +Transport step 66. + +Transport step 66. Mixrun 1. + +Transport step 66. Mixrun 2. + +Transport step 66. Mixrun 3. + +Transport step 66. Mixrun 4. + +Transport step 67. + +Transport step 67. Mixrun 1. + +Transport step 67. Mixrun 2. + +Transport step 67. Mixrun 3. + +Transport step 67. Mixrun 4. + +Transport step 68. + +Transport step 68. Mixrun 1. + +Transport step 68. Mixrun 2. + +Transport step 68. Mixrun 3. + +Transport step 68. Mixrun 4. + +Transport step 69. + +Transport step 69. Mixrun 1. + +Transport step 69. Mixrun 2. + +Transport step 69. Mixrun 3. + +Transport step 69. Mixrun 4. + +Transport step 70. + +Transport step 70. Mixrun 1. + +Transport step 70. Mixrun 2. + +Transport step 70. Mixrun 3. + +Transport step 70. Mixrun 4. + +Transport step 71. + +Transport step 71. Mixrun 1. + +Transport step 71. Mixrun 2. + +Transport step 71. Mixrun 3. + +Transport step 71. Mixrun 4. + +Transport step 72. + +Transport step 72. Mixrun 1. + +Transport step 72. Mixrun 2. + +Transport step 72. Mixrun 3. + +Transport step 72. Mixrun 4. + +Transport step 73. + +Transport step 73. Mixrun 1. + +Transport step 73. Mixrun 2. + +Transport step 73. Mixrun 3. + +Transport step 73. Mixrun 4. + +Transport step 74. + +Transport step 74. Mixrun 1. + +Transport step 74. Mixrun 2. + +Transport step 74. Mixrun 3. + +Transport step 74. Mixrun 4. + +Transport step 75. + +Transport step 75. Mixrun 1. + +Transport step 75. Mixrun 2. + +Transport step 75. Mixrun 3. + +Transport step 75. Mixrun 4. + +Transport step 76. + +Transport step 76. Mixrun 1. + +Transport step 76. Mixrun 2. + +Transport step 76. Mixrun 3. + +Transport step 76. Mixrun 4. + +Transport step 77. + +Transport step 77. Mixrun 1. + +Transport step 77. Mixrun 2. + +Transport step 77. Mixrun 3. + +Transport step 77. Mixrun 4. + +Transport step 78. + +Transport step 78. Mixrun 1. + +Transport step 78. Mixrun 2. + +Transport step 78. Mixrun 3. + +Transport step 78. Mixrun 4. + +Transport step 79. + +Transport step 79. Mixrun 1. + +Transport step 79. Mixrun 2. + +Transport step 79. Mixrun 3. + +Transport step 79. Mixrun 4. + +Transport step 80. + +Transport step 80. Mixrun 1. + +Transport step 80. Mixrun 2. + +Transport step 80. Mixrun 3. + +Transport step 80. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.430e-04 1.086e-03 9.874e-01 -0.079 + KX 1.370e-05 1.370e-05 1.245e-02 -0.020 + NaX 2.152e-07 2.152e-07 1.956e-04 -0.020 + NH4X 7.135e-68 7.135e-68 6.486e-65 -0.020 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 5.226e-04 5.226e-04 + Cl 1.199e-03 1.199e-03 + K 1.436e-04 1.436e-04 + N 5.912e-07 5.912e-07 + Na 1.130e-05 1.130e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.998 Charge balance + pe = 13.612 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.723e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.957e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 9.758e-12 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550668e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.050e-07 1.006e-07 -6.979 -6.998 -0.019 + OH- 1.043e-07 9.954e-08 -6.982 -7.002 -0.020 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 5.226e-04 + Ca+2 5.226e-04 4.358e-04 -3.282 -3.361 -0.079 + CaOH+ 7.530e-10 7.191e-10 -9.123 -9.143 -0.020 +Cl 1.199e-03 + Cl- 1.199e-03 1.145e-03 -2.921 -2.941 -0.020 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 1.436e-04 + K+ 1.436e-04 1.370e-04 -3.843 -3.863 -0.020 + KOH 4.723e-12 4.725e-12 -11.326 -11.326 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -66.026 -66.047 -0.020 + NH3 0.000e+00 0.000e+00 -68.293 -68.293 0.000 +N(0) 6.148e-26 + N2 3.074e-26 3.075e-26 -25.512 -25.512 0.000 +N(3) 1.324e-19 + NO2- 1.324e-19 1.263e-19 -18.878 -18.899 -0.020 +N(5) 5.912e-07 + NO3- 5.912e-07 5.642e-07 -6.228 -6.249 -0.020 +Na 1.130e-05 + Na+ 1.130e-05 1.080e-05 -4.947 -4.967 -0.020 + NaOH 7.089e-13 7.092e-13 -12.149 -12.149 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -9.49 -7.91 1.58 NaCl + N2(g) -22.25 -25.51 -3.26 N2 + NH3(g) -70.06 -68.29 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 81. + +Transport step 81. Mixrun 1. + +Transport step 81. Mixrun 2. + +Transport step 81. Mixrun 3. + +Transport step 81. Mixrun 4. + +Transport step 82. + +Transport step 82. Mixrun 1. + +Transport step 82. Mixrun 2. + +Transport step 82. Mixrun 3. + +Transport step 82. Mixrun 4. + +Transport step 83. + +Transport step 83. Mixrun 1. + +Transport step 83. Mixrun 2. + +Transport step 83. Mixrun 3. + +Transport step 83. Mixrun 4. + +Transport step 84. + +Transport step 84. Mixrun 1. + +Transport step 84. Mixrun 2. + +Transport step 84. Mixrun 3. + +Transport step 84. Mixrun 4. + +Transport step 85. + +Transport step 85. Mixrun 1. + +Transport step 85. Mixrun 2. + +Transport step 85. Mixrun 3. + +Transport step 85. Mixrun 4. + +Transport step 86. + +Transport step 86. Mixrun 1. + +Transport step 86. Mixrun 2. + +Transport step 86. Mixrun 3. + +Transport step 86. Mixrun 4. + +Transport step 87. + +Transport step 87. Mixrun 1. + +Transport step 87. Mixrun 2. + +Transport step 87. Mixrun 3. + +Transport step 87. Mixrun 4. + +Transport step 88. + +Transport step 88. Mixrun 1. + +Transport step 88. Mixrun 2. + +Transport step 88. Mixrun 3. + +Transport step 88. Mixrun 4. + +Transport step 89. + +Transport step 89. Mixrun 1. + +Transport step 89. Mixrun 2. + +Transport step 89. Mixrun 3. + +Transport step 89. Mixrun 4. + +Transport step 90. + +Transport step 90. Mixrun 1. + +Transport step 90. Mixrun 2. + +Transport step 90. Mixrun 3. + +Transport step 90. Mixrun 4. + +Transport step 91. + +Transport step 91. Mixrun 1. + +Transport step 91. Mixrun 2. + +Transport step 91. Mixrun 3. + +Transport step 91. Mixrun 4. + +Transport step 92. + +Transport step 92. Mixrun 1. + +Transport step 92. Mixrun 2. + +Transport step 92. Mixrun 3. + +Transport step 92. Mixrun 4. + +Transport step 93. + +Transport step 93. Mixrun 1. + +Transport step 93. Mixrun 2. + +Transport step 93. Mixrun 3. + +Transport step 93. Mixrun 4. + +Transport step 94. + +Transport step 94. Mixrun 1. + +Transport step 94. Mixrun 2. + +Transport step 94. Mixrun 3. + +Transport step 94. Mixrun 4. + +Transport step 95. + +Transport step 95. Mixrun 1. + +Transport step 95. Mixrun 2. + +Transport step 95. Mixrun 3. + +Transport step 95. Mixrun 4. + +Transport step 96. + +Transport step 96. Mixrun 1. + +Transport step 96. Mixrun 2. + +Transport step 96. Mixrun 3. + +Transport step 96. Mixrun 4. + +Transport step 97. + +Transport step 97. Mixrun 1. + +Transport step 97. Mixrun 2. + +Transport step 97. Mixrun 3. + +Transport step 97. Mixrun 4. + +Transport step 98. + +Transport step 98. Mixrun 1. + +Transport step 98. Mixrun 2. + +Transport step 98. Mixrun 3. + +Transport step 98. Mixrun 4. + +Transport step 99. + +Transport step 99. Mixrun 1. + +Transport step 99. Mixrun 2. + +Transport step 99. Mixrun 3. + +Transport step 99. Mixrun 4. + +Transport step 100. + +Transport step 100. Mixrun 1. + +Transport step 100. Mixrun 2. + +Transport step 100. Mixrun 3. + +Transport step 100. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.499e-04 1.100e-03 9.999e-01 -0.080 + KX 1.363e-07 1.363e-07 1.239e-04 -0.021 + NaX 1.851e-09 1.851e-09 1.683e-06 -0.020 + NH4X 8.683e-70 8.683e-70 7.894e-67 -0.021 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 5.992e-04 5.992e-04 + Cl 1.200e-03 1.200e-03 + K 1.520e-06 1.520e-06 + N 7.648e-09 7.648e-09 + Na 1.035e-07 1.035e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.799e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 6.006e-20 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.774e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 5.992e-04 + Ca+2 5.992e-04 4.978e-04 -3.222 -3.303 -0.080 + CaOH+ 8.606e-10 8.210e-10 -9.065 -9.086 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 1.520e-06 + K+ 1.520e-06 1.450e-06 -5.818 -5.839 -0.021 + KOH 4.994e-14 4.996e-14 -13.302 -13.301 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -67.914 -67.935 -0.021 + NH3 0.000e+00 0.000e+00 -70.182 -70.182 0.000 +N(0) 1.028e-29 + N2 5.139e-30 5.141e-30 -29.289 -29.289 0.000 +N(3) 1.712e-21 + NO2- 1.712e-21 1.632e-21 -20.766 -20.787 -0.021 +N(5) 7.648e-09 + NO3- 7.648e-09 7.291e-09 -8.116 -8.137 -0.021 +Na 1.035e-07 + Na+ 1.035e-07 9.874e-08 -6.985 -7.006 -0.020 + NaOH 6.480e-15 6.483e-15 -14.188 -14.188 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -11.53 -9.95 1.58 NaCl + N2(g) -26.03 -29.29 -3.26 N2 + NH3(g) -71.95 -70.18 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +Transport step 101. + +Transport step 101. Mixrun 1. + +Transport step 101. Mixrun 2. + +Transport step 101. Mixrun 3. + +Transport step 101. Mixrun 4. + +Transport step 102. + +Transport step 102. Mixrun 1. + +Transport step 102. Mixrun 2. + +Transport step 102. Mixrun 3. + +Transport step 102. Mixrun 4. + +Transport step 103. + +Transport step 103. Mixrun 1. + +Transport step 103. Mixrun 2. + +Transport step 103. Mixrun 3. + +Transport step 103. Mixrun 4. + +Transport step 104. + +Transport step 104. Mixrun 1. + +Transport step 104. Mixrun 2. + +Transport step 104. Mixrun 3. + +Transport step 104. Mixrun 4. + +Transport step 105. + +Transport step 105. Mixrun 1. + +Transport step 105. Mixrun 2. + +Transport step 105. Mixrun 3. + +Transport step 105. Mixrun 4. + +Transport step 106. + +Transport step 106. Mixrun 1. + +Transport step 106. Mixrun 2. + +Transport step 106. Mixrun 3. + +Transport step 106. Mixrun 4. + +Transport step 107. + +Transport step 107. Mixrun 1. + +Transport step 107. Mixrun 2. + +Transport step 107. Mixrun 3. + +Transport step 107. Mixrun 4. + +Transport step 108. + +Transport step 108. Mixrun 1. + +Transport step 108. Mixrun 2. + +Transport step 108. Mixrun 3. + +Transport step 108. Mixrun 4. + +Transport step 109. + +Transport step 109. Mixrun 1. + +Transport step 109. Mixrun 2. + +Transport step 109. Mixrun 3. + +Transport step 109. Mixrun 4. + +Transport step 110. + +Transport step 110. Mixrun 1. + +Transport step 110. Mixrun 2. + +Transport step 110. Mixrun 3. + +Transport step 110. Mixrun 4. + +Transport step 111. + +Transport step 111. Mixrun 1. + +Transport step 111. Mixrun 2. + +Transport step 111. Mixrun 3. + +Transport step 111. Mixrun 4. + +Transport step 112. + +Transport step 112. Mixrun 1. + +Transport step 112. Mixrun 2. + +Transport step 112. Mixrun 3. + +Transport step 112. Mixrun 4. + +Transport step 113. + +Transport step 113. Mixrun 1. + +Transport step 113. Mixrun 2. + +Transport step 113. Mixrun 3. + +Transport step 113. Mixrun 4. + +Transport step 114. + +Transport step 114. Mixrun 1. + +Transport step 114. Mixrun 2. + +Transport step 114. Mixrun 3. + +Transport step 114. Mixrun 4. + +Transport step 115. + +Transport step 115. Mixrun 1. + +Transport step 115. Mixrun 2. + +Transport step 115. Mixrun 3. + +Transport step 115. Mixrun 4. + +Transport step 116. + +Transport step 116. Mixrun 1. + +Transport step 116. Mixrun 2. + +Transport step 116. Mixrun 3. + +Transport step 116. Mixrun 4. + +Transport step 117. + +Transport step 117. Mixrun 1. + +Transport step 117. Mixrun 2. + +Transport step 117. Mixrun 3. + +Transport step 117. Mixrun 4. + +Transport step 118. + +Transport step 118. Mixrun 1. + +Transport step 118. Mixrun 2. + +Transport step 118. Mixrun 3. + +Transport step 118. Mixrun 4. + +Transport step 119. + +Transport step 119. Mixrun 1. + +Transport step 119. Mixrun 2. + +Transport step 119. Mixrun 3. + +Transport step 119. Mixrun 4. + +Transport step 120. + +Transport step 120. Mixrun 1. + +Transport step 120. Mixrun 2. + +Transport step 120. Mixrun 3. + +Transport step 120. Mixrun 4. + +Using mix 40. +Using exchange 40. Exchange assemblage after simulation 2. + +Mixture 40. + + 2.625e-01 Solution 39 Solution after simulation 2. + 0.000e+00 Solution 41 Initial solution for column + 7.375e-01 Solution 40 Solution after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.100e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 5.500e-04 1.100e-03 1.000e+00 -0.081 + KX 1.753e-09 1.753e-09 1.593e-06 -0.021 + NaX 1.743e-11 1.743e-11 1.585e-08 -0.020 + NH4X 8.965e-72 8.965e-72 8.150e-69 -0.021 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 6.000e-04 6.000e-04 + Cl 1.200e-03 1.200e-03 + K 1.956e-08 1.956e-08 + N 7.901e-11 7.901e-11 + Na 9.751e-10 9.751e-10 + +----------------------------Description of solution---------------------------- + + pH = 6.997 Charge balance + pe = 13.613 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.800e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -5.732e-19 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 1.157e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550667e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.052e-07 1.006e-07 -6.978 -6.997 -0.019 + OH- 1.043e-07 9.948e-08 -6.982 -7.002 -0.021 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Ca 6.000e-04 + Ca+2 6.000e-04 4.985e-04 -3.222 -3.302 -0.081 + CaOH+ 8.617e-10 8.221e-10 -9.065 -9.085 -0.020 +Cl 1.200e-03 + Cl- 1.200e-03 1.144e-03 -2.921 -2.941 -0.021 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.370 -44.370 0.000 +K 1.956e-08 + K+ 1.956e-08 1.865e-08 -7.709 -7.729 -0.021 + KOH 6.425e-16 6.428e-16 -15.192 -15.192 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -69.900 -69.921 -0.021 + NH3 0.000e+00 0.000e+00 -72.168 -72.168 0.000 +N(0) 1.097e-33 + N2 5.484e-34 5.487e-34 -33.261 -33.261 0.000 +N(3) 1.769e-23 + NO2- 1.769e-23 1.686e-23 -22.752 -22.773 -0.021 +N(5) 7.901e-11 + NO3- 7.901e-11 7.532e-11 -10.102 -10.123 -0.021 +Na 9.751e-10 + Na+ 9.751e-10 9.305e-10 -9.011 -9.031 -0.020 + NaOH 6.107e-17 6.109e-17 -16.214 -16.214 0.000 +O(0) 4.580e-04 + O2 2.290e-04 2.291e-04 -3.640 -3.640 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.22 -44.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -13.55 -11.97 1.58 NaCl + N2(g) -30.00 -33.26 -3.26 N2 + NH3(g) -73.94 -72.17 1.77 NH3 + O2(g) -0.68 -3.64 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex11adv.sel b/Sun/examples/ex11adv.sel new file mode 100644 index 00000000..1958435f --- /dev/null +++ b/Sun/examples/ex11adv.sel @@ -0,0 +1,125 @@ + step Na Cl K Ca Pore_vol + -99 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 1.2500e-02 + -99 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.2500e-02 + -99 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.2500e-02 + 1 5.2815e-04 1.2000e-03 4.5842e-04 1.0672e-04 3.7500e-02 + 1 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.7500e-02 + 2 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.2500e-02 + 3 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.7500e-02 + 4 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.1250e-01 + 5 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.3750e-01 + 6 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.6250e-01 + 7 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.8750e-01 + 8 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 2.1250e-01 + 9 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 2.3750e-01 + 10 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 2.6250e-01 + 11 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 2.8750e-01 + 12 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.1250e-01 + 13 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.3750e-01 + 14 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.6250e-01 + 15 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.8750e-01 + 16 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 4.1250e-01 + 17 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 4.3750e-01 + 18 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 4.6250e-01 + 19 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 4.8750e-01 + 20 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 5.1250e-01 + 21 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 5.3750e-01 + 22 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 5.6250e-01 + 23 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 5.8750e-01 + 24 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.1250e-01 + 25 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.3750e-01 + 26 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.6250e-01 + 27 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.8750e-01 + 28 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 7.1250e-01 + 29 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 7.3750e-01 + 30 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 7.6250e-01 + 31 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 7.8750e-01 + 32 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.1250e-01 + 33 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.3750e-01 + 34 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.6250e-01 + 35 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.8750e-01 + 36 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 9.1250e-01 + 37 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 9.3750e-01 + 38 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 9.6250e-01 + 39 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 9.8750e-01 + 40 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.0125e+00 + 41 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.0375e+00 + 42 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.0625e+00 + 43 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.0875e+00 + 44 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.1125e+00 + 45 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.1375e+00 + 46 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.1625e+00 + 47 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.1875e+00 + 48 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.2125e+00 + 49 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.2375e+00 + 50 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.2625e+00 + 51 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.2875e+00 + 52 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.3125e+00 + 53 1.0000e-03 1.2000e-03 2.0000e-04 0.0000e+00 1.3375e+00 + 54 9.9998e-04 1.2000e-03 2.0002e-04 0.0000e+00 1.3625e+00 + 55 9.9993e-04 1.2000e-03 2.0007e-04 0.0000e+00 1.3875e+00 + 56 9.9969e-04 1.2000e-03 2.0031e-04 0.0000e+00 1.4125e+00 + 57 9.9860e-04 1.2000e-03 2.0140e-04 0.0000e+00 1.4375e+00 + 58 9.9376e-04 1.2000e-03 2.0624e-04 0.0000e+00 1.4625e+00 + 59 9.7266e-04 1.2000e-03 2.2734e-04 0.0000e+00 1.4875e+00 + 60 8.8947e-04 1.2000e-03 3.1053e-04 0.0000e+00 1.5125e+00 + 61 6.5396e-04 1.2000e-03 5.4604e-04 0.0000e+00 1.5375e+00 + 62 3.1876e-04 1.2000e-03 8.8124e-04 0.0000e+00 1.5625e+00 + 63 1.0663e-04 1.2000e-03 1.0934e-03 0.0000e+00 1.5875e+00 + 64 2.9829e-05 1.2000e-03 1.1702e-03 0.0000e+00 1.6125e+00 + 65 7.8763e-06 1.2000e-03 1.1921e-03 1.2216e-27 1.6375e+00 + 66 2.0460e-06 1.2000e-03 1.1980e-03 1.8112e-25 1.6625e+00 + 67 5.2878e-07 1.2000e-03 1.1995e-03 2.6557e-23 1.6875e+00 + 68 1.3629e-07 1.2000e-03 1.1999e-03 3.9376e-21 1.7125e+00 + 69 3.5021e-08 1.2000e-03 1.2000e-03 5.8912e-19 1.7375e+00 + 70 8.9558e-09 1.2000e-03 1.2000e-03 8.8181e-17 1.7625e+00 + 71 2.2719e-09 1.2000e-03 1.2000e-03 1.3080e-14 1.7875e+00 + 72 5.6835e-10 1.2000e-03 1.2000e-03 1.9126e-12 1.8125e+00 + 73 1.3869e-10 1.2000e-03 1.2000e-03 2.7576e-10 1.8375e+00 + 74 3.2281e-11 1.2000e-03 1.1999e-03 3.9374e-08 1.8625e+00 + 75 6.7673e-12 1.2000e-03 1.1890e-03 5.4946e-06 1.8875e+00 + 76 8.0510e-13 1.2000e-03 7.0494e-04 2.4753e-04 1.9125e+00 + 77 2.1968e-14 1.2000e-03 9.6079e-05 5.5196e-04 1.9375e+00 + 78 4.1771e-16 1.2000e-03 9.1269e-06 5.9544e-04 1.9625e+00 + 79 7.6748e-18 1.2000e-03 8.3782e-07 5.9958e-04 1.9875e+00 + 80 1.4057e-19 1.2000e-03 7.6671e-08 5.9996e-04 2.0125e+00 + 81 2.5740e-21 1.2000e-03 7.0147e-09 6.0000e-04 2.0375e+00 + 82 4.7052e-23 1.2000e-03 6.4179e-10 6.0000e-04 2.0625e+00 + 83 8.2642e-25 1.2000e-03 5.8721e-11 6.0000e-04 2.0875e+00 + 84 0.0000e+00 1.2000e-03 5.3731e-12 6.0000e-04 2.1125e+00 + 85 0.0000e+00 1.2000e-03 4.9168e-13 6.0000e-04 2.1375e+00 + 86 0.0000e+00 1.2000e-03 4.4995e-14 6.0000e-04 2.1625e+00 + 87 0.0000e+00 1.2000e-03 4.1178e-15 6.0000e-04 2.1875e+00 + 88 0.0000e+00 1.2000e-03 3.7688e-16 6.0000e-04 2.2125e+00 + 89 0.0000e+00 1.2000e-03 3.4497e-17 6.0000e-04 2.2375e+00 + 90 0.0000e+00 1.2000e-03 3.1577e-18 6.0000e-04 2.2625e+00 + 91 0.0000e+00 1.2000e-03 2.8907e-19 6.0000e-04 2.2875e+00 + 92 0.0000e+00 1.2000e-03 2.6465e-20 6.0000e-04 2.3125e+00 + 93 0.0000e+00 1.2000e-03 2.4231e-21 6.0000e-04 2.3375e+00 + 94 0.0000e+00 1.2000e-03 2.2183e-22 6.0000e-04 2.3625e+00 + 95 0.0000e+00 1.2000e-03 2.0287e-23 6.0000e-04 2.3875e+00 + 96 0.0000e+00 1.2000e-03 1.8364e-24 6.0000e-04 2.4125e+00 + 97 0.0000e+00 1.2000e-03 1.5102e-25 6.0000e-04 2.4375e+00 + 98 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.4625e+00 + 99 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.4875e+00 + 100 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.5125e+00 + 101 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.5375e+00 + 102 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.5625e+00 + 103 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.5875e+00 + 104 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.6125e+00 + 105 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.6375e+00 + 106 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.6625e+00 + 107 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.6875e+00 + 108 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.7125e+00 + 109 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.7375e+00 + 110 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.7625e+00 + 111 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.7875e+00 + 112 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.8125e+00 + 113 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.8375e+00 + 114 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.8625e+00 + 115 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.8875e+00 + 116 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.9125e+00 + 117 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.9375e+00 + 118 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.9625e+00 + 119 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 2.9875e+00 + 120 0.0000e+00 1.2000e-03 0.0000e+00 6.0000e-04 3.0125e+00 diff --git a/Sun/examples/ex11trn.sel b/Sun/examples/ex11trn.sel new file mode 100644 index 00000000..ca370b4c --- /dev/null +++ b/Sun/examples/ex11trn.sel @@ -0,0 +1,125 @@ + step Na Cl K Ca Pore_vol + -99 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.2500e-02 + -99 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.2500e-02 + 1 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.7500e-02 + 0 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.2500e-02 + 1 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 3.7500e-02 + 2 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 6.2500e-02 + 3 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 8.7500e-02 + 4 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.1250e-01 + 5 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.3750e-01 + 6 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.6250e-01 + 7 1.0000e-03 0.0000e+00 2.0000e-04 0.0000e+00 1.8750e-01 + 8 1.0000e-03 3.0997e-22 2.0000e-04 0.0000e+00 2.1250e-01 + 9 1.0000e-03 1.5009e-17 2.0000e-04 0.0000e+00 2.3750e-01 + 10 1.0000e-03 6.3378e-15 2.0000e-04 0.0000e+00 2.6250e-01 + 11 1.0000e-03 4.4948e-13 2.0000e-04 0.0000e+00 2.8750e-01 + 12 1.0000e-03 1.1487e-11 2.0000e-04 0.0000e+00 3.1250e-01 + 13 1.0000e-03 1.5022e-10 2.0000e-04 0.0000e+00 3.3750e-01 + 14 1.0000e-03 1.2225e-09 2.0000e-04 0.0000e+00 3.6250e-01 + 15 1.0000e-03 6.9925e-09 2.0000e-04 0.0000e+00 3.8750e-01 + 16 1.0000e-03 3.0480e-08 2.0000e-04 0.0000e+00 4.1250e-01 + 17 1.0000e-03 1.0717e-07 2.0000e-04 0.0000e+00 4.3750e-01 + 18 1.0000e-03 3.1679e-07 2.0000e-04 0.0000e+00 4.6250e-01 + 19 1.0000e-03 8.1192e-07 2.0000e-04 0.0000e+00 4.8750e-01 + 20 1.0000e-03 1.8478e-06 2.0000e-04 0.0000e+00 5.1250e-01 + 21 1.0000e-03 3.8042e-06 2.0000e-04 0.0000e+00 5.3750e-01 + 22 1.0000e-03 7.1918e-06 2.0000e-04 0.0000e+00 5.6250e-01 + 23 1.0000e-03 1.2635e-05 2.0000e-04 0.0000e+00 5.8750e-01 + 24 1.0000e-03 2.0834e-05 2.0000e-04 0.0000e+00 6.1250e-01 + 25 1.0000e-03 3.2507e-05 2.0000e-04 0.0000e+00 6.3750e-01 + 26 1.0000e-03 4.8325e-05 2.0000e-04 0.0000e+00 6.6250e-01 + 27 1.0000e-03 6.8844e-05 2.0000e-04 0.0000e+00 6.8750e-01 + 28 1.0000e-03 9.4449e-05 2.0000e-04 0.0000e+00 7.1250e-01 + 29 1.0000e-03 1.2532e-04 2.0000e-04 0.0000e+00 7.3750e-01 + 30 1.0000e-03 1.6140e-04 2.0000e-04 0.0000e+00 7.6250e-01 + 31 1.0000e-03 2.0242e-04 2.0000e-04 0.0000e+00 7.8750e-01 + 32 1.0000e-03 2.4790e-04 2.0000e-04 0.0000e+00 8.1250e-01 + 33 9.9999e-04 2.9719e-04 2.0001e-04 0.0000e+00 8.3750e-01 + 34 9.9999e-04 3.4951e-04 2.0001e-04 0.0000e+00 8.6250e-01 + 35 9.9998e-04 4.0403e-04 2.0002e-04 0.0000e+00 8.8750e-01 + 36 9.9996e-04 4.5987e-04 2.0004e-04 0.0000e+00 9.1250e-01 + 37 9.9993e-04 5.1616e-04 2.0007e-04 0.0000e+00 9.3750e-01 + 38 9.9988e-04 5.7209e-04 2.0012e-04 0.0000e+00 9.6250e-01 + 39 9.9979e-04 6.2694e-04 2.0021e-04 0.0000e+00 9.8750e-01 + 40 9.9964e-04 6.8006e-04 2.0036e-04 0.0000e+00 1.0125e+00 + 41 9.9940e-04 7.3093e-04 2.0060e-04 0.0000e+00 1.0375e+00 + 42 9.9902e-04 7.7913e-04 2.0098e-04 0.0000e+00 1.0625e+00 + 43 9.9842e-04 8.2437e-04 2.0158e-04 0.0000e+00 1.0875e+00 + 44 9.9749e-04 8.6644e-04 2.0251e-04 0.0000e+00 1.1125e+00 + 45 9.9606e-04 9.0523e-04 2.0394e-04 0.0000e+00 1.1375e+00 + 46 9.9390e-04 9.4071e-04 2.0610e-04 0.0000e+00 1.1625e+00 + 47 9.9067e-04 9.7294e-04 2.0933e-04 0.0000e+00 1.1875e+00 + 48 9.8590e-04 1.0020e-03 2.1410e-04 0.0000e+00 1.2125e+00 + 49 9.7896e-04 1.0281e-03 2.2104e-04 0.0000e+00 1.2375e+00 + 50 9.6900e-04 1.0513e-03 2.3100e-04 0.0000e+00 1.2625e+00 + 51 9.5496e-04 1.0718e-03 2.4504e-04 0.0000e+00 1.2875e+00 + 52 9.3563e-04 1.0899e-03 2.6437e-04 0.0000e+00 1.3125e+00 + 53 9.0974e-04 1.1058e-03 2.9026e-04 0.0000e+00 1.3375e+00 + 54 8.7620e-04 1.1196e-03 3.2380e-04 0.0000e+00 1.3625e+00 + 55 8.3445e-04 1.1316e-03 3.6555e-04 0.0000e+00 1.3875e+00 + 56 7.8479e-04 1.1420e-03 4.1521e-04 0.0000e+00 1.4125e+00 + 57 7.2845e-04 1.1510e-03 4.7155e-04 3.5277e-28 1.4375e+00 + 58 6.6747e-04 1.1587e-03 5.3253e-04 4.2108e-26 1.4625e+00 + 59 6.0423e-04 1.1652e-03 5.9577e-04 2.1113e-24 1.4875e+00 + 60 5.4107e-04 1.1708e-03 6.5893e-04 9.1531e-23 1.5125e+00 + 61 4.7992e-04 1.1756e-03 7.2008e-04 3.5143e-21 1.5375e+00 + 62 4.2217e-04 1.1796e-03 7.7783e-04 1.2072e-19 1.5625e+00 + 63 3.6873e-04 1.1830e-03 8.3127e-04 3.6941e-18 1.5875e+00 + 64 3.2004e-04 1.1859e-03 8.7996e-04 1.0357e-16 1.6125e+00 + 65 2.7623e-04 1.1883e-03 9.2377e-04 2.6573e-15 1.6375e+00 + 66 2.3720e-04 1.1903e-03 9.6280e-04 6.2721e-14 1.6625e+00 + 67 2.0268e-04 1.1920e-03 9.9732e-04 1.4041e-12 1.6875e+00 + 68 1.7232e-04 1.1934e-03 1.0277e-03 2.9709e-11 1.7125e+00 + 69 1.4570e-04 1.1945e-03 1.0543e-03 5.8657e-10 1.7375e+00 + 70 1.2238e-04 1.1955e-03 1.0776e-03 1.1507e-08 1.7625e+00 + 71 1.0193e-04 1.1963e-03 1.0977e-03 2.0826e-07 1.7875e+00 + 72 8.3815e-05 1.1970e-03 1.1095e-03 3.3299e-06 1.8125e+00 + 73 6.6682e-05 1.1975e-03 1.0249e-03 5.4190e-05 1.8375e+00 + 74 5.0532e-05 1.1980e-03 7.3505e-04 2.0721e-04 1.8625e+00 + 75 3.8797e-05 1.1983e-03 5.3569e-04 3.1276e-04 1.8875e+00 + 76 3.0077e-05 1.1986e-03 4.0212e-04 3.8390e-04 1.9125e+00 + 77 2.3445e-05 1.1989e-03 3.0685e-04 4.3485e-04 1.9375e+00 + 78 1.8340e-05 1.1991e-03 2.3662e-04 4.7252e-04 1.9625e+00 + 79 1.4384e-05 1.1993e-03 1.8380e-04 5.0091e-04 1.9875e+00 + 80 1.1303e-05 1.1994e-03 1.4355e-04 5.2257e-04 2.0125e+00 + 81 8.8949e-06 1.1995e-03 1.1260e-04 5.3925e-04 2.0375e+00 + 82 7.0081e-06 1.1996e-03 8.8613e-05 5.5219e-04 2.0625e+00 + 83 5.5269e-06 1.1997e-03 6.9934e-05 5.6227e-04 2.0875e+00 + 84 4.3622e-06 1.1997e-03 5.5321e-05 5.7016e-04 2.1125e+00 + 85 3.4452e-06 1.1998e-03 4.3847e-05 5.7635e-04 2.1375e+00 + 86 2.7225e-06 1.1998e-03 3.4813e-05 5.8123e-04 2.1625e+00 + 87 2.1523e-06 1.1999e-03 2.7680e-05 5.8508e-04 2.1875e+00 + 88 1.7023e-06 1.1999e-03 2.2038e-05 5.8813e-04 2.2125e+00 + 89 1.3467e-06 1.1999e-03 1.7565e-05 5.9054e-04 2.2375e+00 + 90 1.0658e-06 1.1999e-03 1.4014e-05 5.9246e-04 2.2625e+00 + 91 8.4359e-07 1.1999e-03 1.1192e-05 5.9398e-04 2.2875e+00 + 92 6.6787e-07 1.2000e-03 8.9443e-06 5.9519e-04 2.3125e+00 + 93 5.2883e-07 1.2000e-03 7.1535e-06 5.9616e-04 2.3375e+00 + 94 4.1880e-07 1.2000e-03 5.7250e-06 5.9693e-04 2.3625e+00 + 95 3.3169e-07 1.2000e-03 4.5844e-06 5.9754e-04 2.3875e+00 + 96 2.6273e-07 1.2000e-03 3.6730e-06 5.9803e-04 2.4125e+00 + 97 2.0811e-07 1.2000e-03 2.9442e-06 5.9842e-04 2.4375e+00 + 98 1.6486e-07 1.2000e-03 2.3611e-06 5.9874e-04 2.4625e+00 + 99 1.3060e-07 1.2000e-03 1.8942e-06 5.9899e-04 2.4875e+00 + 100 1.0347e-07 1.2000e-03 1.5202e-06 5.9919e-04 2.5125e+00 + 101 8.1970e-08 1.2000e-03 1.2205e-06 5.9935e-04 2.5375e+00 + 102 6.4939e-08 1.2000e-03 9.8015e-07 5.9948e-04 2.5625e+00 + 103 5.1446e-08 1.2000e-03 7.8736e-07 5.9958e-04 2.5875e+00 + 104 4.0756e-08 1.2000e-03 6.3266e-07 5.9966e-04 2.6125e+00 + 105 3.2287e-08 1.2000e-03 5.0848e-07 5.9973e-04 2.6375e+00 + 106 2.5577e-08 1.2000e-03 4.0877e-07 5.9978e-04 2.6625e+00 + 107 2.0260e-08 1.2000e-03 3.2868e-07 5.9983e-04 2.6875e+00 + 108 1.6048e-08 1.2000e-03 2.6433e-07 5.9986e-04 2.7125e+00 + 109 1.2712e-08 1.2000e-03 2.1262e-07 5.9989e-04 2.7375e+00 + 110 1.0068e-08 1.2000e-03 1.7105e-07 5.9991e-04 2.7625e+00 + 111 7.9740e-09 1.2000e-03 1.3763e-07 5.9993e-04 2.7875e+00 + 112 6.3151e-09 1.2000e-03 1.1076e-07 5.9994e-04 2.8125e+00 + 113 5.0010e-09 1.2000e-03 8.9141e-08 5.9995e-04 2.8375e+00 + 114 3.9601e-09 1.2000e-03 7.1753e-08 5.9996e-04 2.8625e+00 + 115 3.1357e-09 1.2000e-03 5.7764e-08 5.9997e-04 2.8875e+00 + 116 2.4828e-09 1.2000e-03 4.6507e-08 5.9998e-04 2.9125e+00 + 117 1.9657e-09 1.2000e-03 3.7447e-08 5.9998e-04 2.9375e+00 + 118 1.5562e-09 1.2000e-03 3.0156e-08 5.9998e-04 2.9625e+00 + 119 1.2319e-09 1.2000e-03 2.4286e-08 5.9999e-04 2.9875e+00 + 120 9.7513e-10 1.2000e-03 1.9560e-08 5.9999e-04 3.0125e+00 diff --git a/Sun/examples/ex12.log b/Sun/examples/ex12.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex12.out b/Sun/examples/ex12.out new file mode 100644 index 00000000..8ed928a7 --- /dev/null +++ b/Sun/examples/ex12.out @@ -0,0 +1,99 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex12 + Output file: ex12.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 12.--Advective and diffusive transport of heat and solutes. + Constant boundary condition at one end, closed at other. + The problem is designed so that temperature should equal Na-conc + (in mmol/kgw) after diffusion. + EXCHANGE_SPECIES + Na+ + X- = NaX + log_k 0.0 + gamma 4.0 0.075 + H+ + X- = HX + log_k -99. + gamma 9.0 0.0 + K+ + X- = KX + log_k 0.0 + gamma 3.5 0.015 + SOLUTION 0 24.0 mM KNO3 + units mol/kgw + temp 0 # Incoming solution 0C + pH 7.0 + pe 12.0 O2(g) -0.67 + K 24.e-3 + N(5) 24.e-3 + SOLUTION 1-20 0.001 mM KCl + units mol/kgw + temp 25 # Column is at 25C + pH 7.0 + pe 12.0 O2(g) -0.67 + K 1e-6 + Cl 1e-6 + EXCHANGE 1-20 + KX 0.048 + TRANSPORT # Make column temperature 0C, displace Cl + cells 20 + shifts 19 + flow_direction forward + bcond flux flux + length 1.0 + disp 0.0 # No dispersion + diffc 0.0 # No diffusion + thermal_diffusion 1.0 # No retardation for heat + PRINT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 20. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 20. + reset false + END + SOLUTION 0 Fixed temp 24C, and NaCl conc (first type boundary cond) at inlet + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + SOLUTION 20 Same as soln 0 in cell 20 at closed column end (second type boundary cond) + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + EXCHANGE 20 + NaX 0.048 + TRANSPORT # Diffuse 24C, NaCl solution from column end + shifts 1 + flow_direction diffusion + bcond constant closed + thermal_diffusion 3.0 # heat is retarded equal to Na + diffc 0.3e-9 # m^2/s + timest 1.0e+10 # 317 years, 19 substeps will be used + SELECTED_OUTPUT + file ex12.sel + high_precision true + reset false + distance true + temperature true + USER_PUNCH + heading Na_mmol K_mmol Cl_mmol + 10 PUNCH TOT("Na")*1000, TOT("K")*1000, TOT("Cl")*1000 + END +No memory leaks diff --git a/Sun/examples/ex12.sel b/Sun/examples/ex12.sel new file mode 100644 index 00000000..84fd56c2 --- /dev/null +++ b/Sun/examples/ex12.sel @@ -0,0 +1,44 @@ + dist_x temp Na_mmol K_mmol Cl_mmol + -99 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + -99 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + -99 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + 0.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 1.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 2.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 3.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 4.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 5.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 6.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 7.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 8.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 9.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 10.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 11.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 12.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 13.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 14.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 15.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 16.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 17.5 0.000000000000e+00 0.000000000000e+00 2.400000000010e+01 0.000000000000e+00 + 18.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 19.5 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + 0.5 1.686181418415e+01 1.686181416184e+01 7.138185829939e+00 2.011377529332e+01 + 1.5 6.421492325960e+00 6.421492342616e+00 1.757850764418e+01 1.294968671951e+01 + 2.5 1.759908541854e+00 1.759908557221e+00 2.224009143309e+01 7.342808261321e+00 + 3.5 3.571924631562e-01 3.571924666823e-01 2.364280752813e+01 3.623408283684e+00 + 4.5 5.490209781370e-02 5.490209803302e-02 2.394509789974e+01 1.538555967129e+00 + 5.5 6.484238380348e-03 6.484238322345e-03 2.399351576095e+01 5.556625533113e-01 + 6.5 5.926340095484e-04 5.926339925265e-04 2.399940736587e+01 1.684990632469e-01 + 7.5 4.190926756604e-05 4.190926525116e-05 2.399995809080e+01 4.224784404205e-02 + 8.5 2.276345750780e-06 2.276345548554e-06 2.399999772377e+01 8.664946370896e-03 + 9.5 1.396593677778e-07 1.396593266673e-07 2.399999986046e+01 2.055609847093e-03 + 10.5 1.138869021831e-06 1.138868368161e-06 2.399999886125e+01 4.374443607427e-03 + 11.5 2.090811414205e-05 2.090810331638e-05 2.399997909199e+01 2.044715368548e-02 + 12.5 2.951795282278e-04 2.951793938629e-04 2.399970482061e+01 7.995922685941e-02 + 13.5 3.221164570742e-03 3.221163321490e-03 2.399677883641e+01 2.567109777341e-01 + 14.5 2.715473190226e-02 2.715472330367e-02 2.397284527577e+01 6.850286499844e-01 + 15.5 1.753541123879e-01 1.753540697297e-01 2.382464592812e+01 1.533872870596e+00 + 16.5 8.525032220200e-01 8.525030769812e-01 2.314749691919e+01 2.902126148041e+00 + 17.5 3.032149931402e+00 3.032149625513e+00 2.096785036949e+01 4.663139220104e+00 + 18.5 7.550952821146e+00 7.550952502686e+00 1.644904749357e+01 6.385483516941e+00 + 19.5 1.235834674495e+01 1.235834658501e+01 1.164165341481e+01 7.468268986482e+00 diff --git a/Sun/examples/ex12a.log b/Sun/examples/ex12a.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex12a.out b/Sun/examples/ex12a.out new file mode 100644 index 00000000..1dc02b37 --- /dev/null +++ b/Sun/examples/ex12a.out @@ -0,0 +1,188 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex12a + Output file: ex12a.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 12a.--Advective and diffusive transport of heat and solutes. + Constant boundary condition at one end, closed at other. + The problem is designed so that temperature should equal Na-conc + (in mmol/kgw) after diffusion. Compares with analytical solution + for 20-cell and 60-cell models. + EXCHANGE_SPECIES + Na+ + X- = NaX + log_k 0.0 + gamma 4.0 0.075 + H+ + X- = HX + log_k -99. + gamma 9.0 0.0 + K+ + X- = KX + log_k 0.0 + gamma 3.5 0.015 + SOLUTION 0 Fixed temp 24C, and NaCl conc (first type boundary cond) at inlet + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + SOLUTION 1-19 24.0 mM KNO3 + units mol/kgw + temp 0 # Incoming solution 0C + pH 7.0 + pe 12.0 O2(g) -0.67 + K 24.e-3 + N(5) 24.e-3 + EXCHANGE 1-19 + KX 0.048 + SOLUTION 20 Same as soln 0 in cell 20 at closed column end (second type boundary cond) + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + EXCHANGE 20 + NaX 0.048 + PRINT + reset false + END + TRANSPORT # Diffuse 24C, NaCl solution from column end + cells 20 + shifts 1 + flow_direction diffusion + bcond constant closed + length 1.0 + thermal_diffusion 3.0 # Heat is retarded equal to Na + disp 0.0 # No dispersion + diffc 0.3e-9 # m^2/s + timest 1.0e+10 # 317 years, 19 substeps will be used + SELECTED_OUTPUT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 20. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 20. + file ex12a.sel + high_precision true + reset false + distance true + temperature true + USER_PUNCH + heading Na_mmol K_mmol Cl_mmol Cl-analytic Na_analytic + 10 PUNCH TOT("Na")*1000, TOT("K")*1000, TOT("Cl")*1000 + 20 DATA 0.254829592, -0.284496736, 1.421413741, -1.453152027, 1.061405429 + 30 x = DIST + 40 if (x > 8.5 OR SIM_TIME <= 0) THEN END + 50 IF (ABS(x MOD 0.5) > 1e-3) OR (TC <= 0) THEN END + 60 READ a1, a2, a3, a4, a5 + 70 REM calculate error in Cl + 80 Arg = x / (2*SQRT(3e-10 * SIM_TIME / 1.0)) + 90 e = 1/(1 + 0.3275911 * Arg) + 100 erfc_Cl = (e*(a1+e*(a2+e*(a3+e*(a4+e*a5)))))*EXP(-Arg*Arg) + 110 REM calculate error in Na + 120 Arg = x / (2*SQRT(3e-10 * SIM_TIME / 3.0)) + 130 e = 1/(1 + 0.3275911 * Arg) + 140 erfc_Na = (e*(a1+e*(a2+e*(a3+e*(a4+e*a5)))))*EXP(-Arg*Arg) + 150 REM punch results + 160 error_Cl = 0.024 * erfc_Cl - TOT("Cl") + 170 error_Na = 0.024 * erfc_Na - TOT("Na") + 180 PUNCH error_Cl, error_Na + 190 REM store results + 200 j = x - 0.5 + 210 PUT(error_Cl, SIM_NO, j, 1) + 220 PUT(error_Na, SIM_NO, j, 2) + 500 END + END + SELECTED_OUTPUT + user_punch false + SOLUTION 0 Fixed temp 24C, and NaCl conc (first type boundary cond) at inlet + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + SOLUTION 1-59 24.0 mM KNO3 + units mol/kgw + temp 0 # Incoming solution 0C + pH 7.0 + pe 12.0 O2(g) -0.67 + K 24.e-3 + N(5) 24.e-3 + EXCHANGE 1-59 + KX 0.048 + SOLUTION 60 Same as soln 0 in cell 60 at closed column end (second type boundary cond) + units mol/kgw + temp 24 + pH 7.0 + pe 12.0 O2(g) -0.67 + Na 24.e-3 + Cl 24.e-3 + EXCHANGE 60 + NaX 0.048 + END + TRANSPORT # Diffuse 24C, NaCl solution from column end + cells 60 + shifts 1 + flow_direction diffusion + bcond constant closed + thermal_diffusion 3.0 # Heat is retarded equal to Na + disp 0.0 # No dispersion + diffc 0.3e-9 # m^2/s + length .33333333333333333 + timest 1.0e+10 # 317 years + punch_cells 1-60 + SELECTED_OUTPUT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 60. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 60. + high_precision true + user_punch true + reset false + distance true + temperature true + END + SOLUTION # Initial solution calculation for pure water + PRINT + reset false # Initial solution calculation not printed + user_print true + SELECTED_OUTPUT + high_precision false # Controls precision for USER_PRINT too. + USER_PRINT + 10 PRINT " Error in Cl concentration Error in Na concentration" + 20 PRINT " ------------------------- -------------------------" + 30 PRINT " Distance 20-cell 60-cell 20-cell 60-cell" + 40 PRINT " " + 50 FOR j = 0 TO 8 + 60 PRINT j + 0.5, GET(2, j, 1), GET(4, j, 1), GET(2, j, 2), GET(4, j, 2) + 70 NEXT j + END +----------------------------------User print----------------------------------- + + Error in Cl concentration Error in Na concentration + ------------------------- ------------------------- + Distance 20-cell 60-cell 20-cell 60-cell + + 5.0000e-01 4.3817e-06 9.0009e-08 5.0636e-04 3.9397e-05 + 1.5000e+00 1.7304e-05 1.0407e-06 5.1077e-04 5.5286e-05 + 2.5000e+00 3.5613e-05 3.2028e-06 9.0486e-05 1.4725e-05 + 3.5000e+00 4.9599e-05 5.2170e-06 -3.7312e-05 -3.8884e-06 + 4.5000e+00 5.0063e-05 5.6394e-06 -1.9794e-05 -2.5770e-06 + 5.5000e+00 3.8208e-05 4.4562e-06 -4.0684e-06 -5.0254e-07 + 6.5000e+00 2.2627e-05 2.7007e-06 -4.8926e-07 -4.8938e-08 + 7.5000e+00 1.0547e-05 1.2850e-06 -3.9174e-08 -2.7009e-09 + 8.5000e+00 3.8231e-06 4.5302e-07 -2.2318e-09 -9.0081e-11 + +No memory leaks diff --git a/Sun/examples/ex12a.sel b/Sun/examples/ex12a.sel new file mode 100644 index 00000000..2a0be12f --- /dev/null +++ b/Sun/examples/ex12a.sel @@ -0,0 +1,169 @@ + dist_x temp Na_mmol K_mmol Cl_mmol Cl-analytic Na_analytic + 0.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 1.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 2.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 3.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 4.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 5.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 6.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 7.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 8.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 9.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 10.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 11.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 12.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 13.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 14.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 15.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 16.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 17.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 18.5 0.000000000000e+00 0.000000000000e+00 2.400000000009e+01 0.000000000000e+00 + 19.5 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + 0.5 1.686181418415e+01 1.686181419284e+01 7.138185798940e+00 2.011377529332e+01 4.381717721817e-06 5.063555346726e-04 + 1.5 6.421492325960e+00 6.421492401967e+00 1.757850758482e+01 1.294968671951e+01 1.730376465525e-05 5.107739267532e-04 + 2.5 1.759908541854e+00 1.759908596887e+00 2.224009139342e+01 7.342808261321e+00 3.561257289983e-05 9.048612448212e-05 + 3.5 3.571924631562e-01 3.571924817826e-01 2.364280751302e+01 3.623408283684e+00 4.959925523712e-05 -3.731213350966e-05 + 4.5 5.490209781370e-02 5.490210180416e-02 2.394509789597e+01 1.538555967129e+00 5.006313596727e-05 -1.979378199416e-05 + 5.5 6.484238380348e-03 6.484238983030e-03 2.399351576028e+01 5.556625533113e-01 3.820767165714e-05 -4.068366980646e-06 + 6.5 5.926340095484e-04 5.926340766447e-04 2.399940736578e+01 1.684990632469e-01 2.262672987200e-05 -4.892608394194e-07 + 7.5 4.190926756604e-05 4.190927316640e-05 2.399995809078e+01 4.224784404205e-02 1.054699173423e-05 -3.917411153365e-08 + 8.5 2.276345750780e-06 2.276346101865e-06 2.399999772376e+01 8.664946370896e-03 3.823149392506e-06 -2.231772077916e-09 + 9.5 1.396593677778e-07 1.396593921606e-07 2.399999986046e+01 2.055609847093e-03 + 10.5 1.138869021831e-06 1.138869196840e-06 2.399999886124e+01 4.374443607427e-03 + 11.5 2.090811414205e-05 2.090811693112e-05 2.399997909197e+01 2.044715368548e-02 + 12.5 2.951795282278e-04 2.951795617161e-04 2.399970482043e+01 7.995922685941e-02 + 13.5 3.221164570742e-03 3.221164872772e-03 2.399677883485e+01 2.567109777341e-01 + 14.5 2.715473190226e-02 2.715473392142e-02 2.397284526515e+01 6.850286499844e-01 + 15.5 1.753541123879e-01 1.753541220807e-01 2.382464587576e+01 1.533872870596e+00 + 16.5 8.525032220200e-01 8.525032534626e-01 2.314749674271e+01 2.902126148041e+00 + 17.5 3.032149931402e+00 3.032149994216e+00 2.096785000078e+01 4.663139220104e+00 + 18.5 7.550952821146e+00 7.550952899109e+00 1.644904709714e+01 6.385483516941e+00 + 19.5 1.235834674495e+01 1.235834684370e+01 1.164165315611e+01 7.468268986482e+00 + dist_x temp + -99 2.400000000000e+01 + -99 0.000000000000e+00 + -99 2.400000000000e+01 + -99 2.400000000000e+01 + dist_x temp Na_mmol K_mmol Cl_mmol Cl-analytic Na_analytic + 0.166667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 0.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 0.833333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 1.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 1.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 1.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 2.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 2.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 2.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 3.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 3.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 3.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 4.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 4.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 4.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 5.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 5.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 5.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 6.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 6.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 6.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 7.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 7.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 7.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 8.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 8.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 8.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 9.16667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 9.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 9.83333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 10.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 10.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 10.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 11.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 11.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 11.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 12.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 12.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 12.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 13.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 13.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 13.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 14.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 14.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 14.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 15.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 15.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 15.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 16.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 16.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 16.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 17.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 17.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 17.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 18.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 18.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 18.8333 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 19.1667 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 19.5 0.000000000000e+00 0.000000000000e+00 2.400000000000e+01 0.000000000000e+00 + 19.8333 2.400000000000e+01 2.400000000000e+01 0.000000000000e+00 2.400000000000e+01 + 0.166667 2.173421305916e+01 2.173421306343e+01 2.265786933713e+00 2.269804666237e+01 + 0.5 1.732877230198e+01 1.732877231885e+01 6.671227673618e+00 2.011806700231e+01 9.000873062853e-08 3.939740866218e-05 + 0.833333 1.328083118787e+01 1.328083122259e+01 1.071916876673e+01 1.760855984610e+01 + 1.16667 9.764783869793e+00 9.764783923632e+00 1.423521606399e+01 1.521226338251e+01 + 1.5 6.876979954453e+00 6.876980022636e+00 1.712301996456e+01 1.296594983180e+01 1.040652364160e-06 5.528630608450e-05 + 1.83333 4.633445178532e+00 4.633445251920e+00 1.936655473578e+01 1.089878644688e+01 + 2.16667 2.983957613764e+00 2.983957682799e+00 2.101604230602e+01 9.031332911172e+00 + 2.5 1.835670035272e+00 1.835670093239e+00 2.216432989702e+01 7.375218041863e+00 3.202792358406e-06 1.472462813043e-05 + 2.83333 1.078309641703e+00 1.078309685856e+00 2.292169030595e+01 5.933464823536e+00 + 3.16667 6.047271172834e-01 6.047271481610e-01 2.339527284513e+01 4.701369002513e+00 + 3.5 3.237687663205e-01 3.237687863260e-01 2.367623120832e+01 3.667790505378e+00 5.217033543007e-06 -3.888438053093e-06 + 3.83333 1.655091653734e-01 1.655091774636e-01 2.383449081836e+01 2.816693047508e+00 + 4.16667 8.080184009388e-02 8.080184694439e-02 2.391919814987e+01 2.128765884991e+00 + 4.5 3.768529738011e-02 3.768530103391e-02 2.396231469660e+01 1.582979737206e+00 5.639365889894e-06 -2.576981223905e-06 + 4.83333 1.679748179371e-02 1.679748363383e-02 2.398320251464e+01 1.157961028529e+00 + 5.16667 7.158658672534e-03 7.158659549847e-03 2.399284133922e+01 8.331081560779e-01 + 5.5 2.918406916536e-03 2.918407313331e-03 2.399708159183e+01 5.894139758477e-01 4.456249120743e-06 -5.025353109470e-07 + 5.83333 1.138704483513e-03 1.138704654056e-03 2.399886129476e+01 4.099947290008e-01 + 6.16667 4.254614091980e-04 4.254614789566e-04 2.399957453813e+01 2.803535790356e-01 + 6.5 1.523110828875e-04 1.523111100786e-04 2.399984768864e+01 1.884251292313e-01 2.700663887612e-06 -4.893787285338e-08 + 6.83333 5.227158932778e-05 5.227159943954e-05 2.399994772825e+01 1.244558376472e-01 + 7.16667 1.720693829075e-05 1.720694188206e-05 2.399998279298e+01 8.077556918093e-02 + 7.5 5.436060808742e-06 5.436062028079e-06 2.399999456390e+01 5.150981286307e-02 1.285022913218e-06 -2.700900395322e-09 + 7.83333 1.649087567417e-06 1.649087963540e-06 2.399999835090e+01 3.227276557119e-02 + 8.16667 4.806328011003e-07 4.806329243359e-07 2.399999951938e+01 1.987075437176e-02 + 8.5 1.346545980534e-07 1.346546347973e-07 2.399999986537e+01 1.203507596490e-02 4.530197984976e-07 -9.008061084852e-11 + 8.83333 3.628418612942e-08 3.628419663780e-08 2.399999996375e+01 7.194421703709e-03 + 9.16667 9.420115605087e-09 9.420118494085e-09 2.399999999061e+01 4.290208467916e-03 + 9.5 2.409789753518e-09 2.409790536015e-09 2.399999999763e+01 2.633460429579e-03 + 9.83333 8.318493065839e-10 8.318495907164e-10 2.399999999921e+01 1.799170182453e-03 + 10.1667 1.239138622414e-09 1.239139029450e-09 2.399999999880e+01 1.552911248870e-03 + 10.5 4.450121249069e-09 4.450122620282e-09 2.399999999559e+01 1.804410616828e-03 + 10.8333 1.697307773631e-08 1.697308267056e-08 2.399999998306e+01 2.583364148394e-03 + 11.1667 6.262520065472e-08 6.262521780825e-08 2.399999993741e+01 4.033590225456e-03 + 11.5 2.221760110271e-07 2.221760682136e-07 2.399999977785e+01 6.422343300949e-03 + 11.8333 7.572168365738e-07 7.572170191795e-07 2.399999924281e+01 1.016200278611e-02 + 12.1667 2.477714073998e-06 2.477714631994e-06 2.399999752230e+01 1.584124624556e-02 + 12.5 7.778925375184e-06 7.778927005412e-06 2.399999222108e+01 2.426212581439e-02 + 12.8333 2.341776426203e-05 2.341776881132e-05 2.399997658222e+01 3.647820852624e-02 + 13.1667 6.755207229881e-05 6.755208441218e-05 2.399993244787e+01 5.382725013175e-02 + 13.5 1.865949099352e-04 1.865949406769e-04 2.399981340498e+01 7.795002257855e-02 + 13.8333 4.931967003130e-04 4.931967745830e-04 2.399950680310e+01 1.107853267574e-01 + 14.1667 1.246472753669e-03 1.246472924261e-03 2.399875352688e+01 1.545304347559e-01 + 14.5 3.009977094510e-03 3.009977466523e-03 2.399699002225e+01 2.115568175130e-01 + 14.8333 6.939537438586e-03 6.939538207639e-03 2.399306046140e+01 2.842735712027e-01 + 15.1667 1.526331935379e-02 1.526332085840e-02 2.398473667861e+01 3.749358095681e-01 + 15.5 3.200217915009e-02 3.200218193090e-02 2.396799781737e+01 4.854024361712e-01 + 15.8333 6.391193399667e-02 6.391193884267e-02 2.393608806026e+01 6.168566584837e-01 + 16.1667 1.214834631133e-01 1.214834710604e-01 2.387851652783e+01 7.695123116931e-01 + 16.5 2.196089759550e-01 2.196089881955e-01 2.378039101048e+01 9.423379783552e-01 + 16.8333 3.772704376914e-01 3.772704553669e-01 2.362272954311e+01 1.132837159798e+00 + 17.1667 6.154714589941e-01 6.154714828922e-01 2.338452851541e+01 1.336924520486e+00 + 17.5 9.528239860304e-01 9.528240162733e-01 2.304717598190e+01 1.548934044811e+00 + 17.8333 1.398887571630e+00 1.398887607499e+00 2.260111239061e+01 1.761784203671e+00 + 18.1667 1.946511170344e+00 1.946511210371e+00 2.205348878777e+01 1.967308461518e+00 + 18.5 2.565669345631e+00 2.565669387970e+00 2.143433061028e+01 2.156738468785e+00 + 18.8333 3.201925616708e+00 3.201925659659e+00 2.079807433877e+01 2.321305007457e+00 + 19.1667 3.781994216092e+00 3.781994258530e+00 2.021800574010e+01 2.452901809002e+00 + 19.5 4.226690935644e+00 4.226690977196e+00 1.977330902162e+01 2.544743405451e+00 + 19.8333 4.468507319433e+00 4.468507360365e+00 1.953149263856e+01 2.591943163049e+00 + dist_x temp Na_mmol K_mmol Cl_mmol Cl-analytic Na_analytic + -99 25.000 0.0000e+00 0.0000e+00 0.0000e+00 diff --git a/Sun/examples/ex13a.log b/Sun/examples/ex13a.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex13a.out b/Sun/examples/ex13a.out new file mode 100644 index 00000000..77218db9 --- /dev/null +++ b/Sun/examples/ex13a.out @@ -0,0 +1,310 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex13a + Output file: ex13a.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 13A.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + Implicit definition of first-order exchange model. + SOLUTION 0 # 1 mmol/l NaCl + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + Na 1.0 # Na has Retardation = 2 + Cl 1.0 # Cl has Retardation = 1, stagnant exchange + N(5) 1.0 # NO3 is conservative + END +----- +TITLE +----- + + Example 13A.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + Implicit definition of first-order exchange model. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.500e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.551e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.000e-03 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -33.33 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.046e-07 1.001e-07 -6.981 -7.000 -0.019 + H+ 1.042e-07 1.000e-07 -6.982 -7.000 -0.018 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +Cl 1.000e-03 + Cl- 1.000e-03 9.576e-04 -3.000 -3.019 -0.019 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.573e-04 -3.000 -3.019 -0.019 +Na 1.000e-03 + Na+ 1.000e-03 9.580e-04 -3.000 -3.019 -0.019 + NaOH 6.327e-11 6.329e-11 -10.199 -10.199 0.000 +O(0) 4.374e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.62 -6.04 1.58 NaCl + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1-41 # Column with KNO3 + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + EXCHANGE 1-41 + equilibrate 1 + X 1.e-3 + EXCHANGE_SPECIES # For linear exchange, make KX exch. coeff. equal to NaX + K+ + X- = KX + log_k 0.0 + gamma 3.5 0.015 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.70 -3.66 -2.96 O2 + +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using exchange 1. Exchange assemblage after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + NH4X 6.872e-63 6.872e-63 6.872e-60 -0.016 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 13.605 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.763 -62.779 -0.016 + NH3 0.000e+00 0.000e+00 -65.023 -65.023 0.000 +N(0) 1.994e-19 + N2 9.971e-20 9.973e-20 -19.001 -19.001 0.000 +N(3) 2.291e-16 + NO2- 2.291e-16 2.210e-16 -15.640 -15.656 -0.016 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.74 -19.00 -3.26 N2 + NH3(g) -66.79 -65.02 1.77 NH3 + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + TRANSPORT + cells 20 + shifts 5 + flow_direction forward + timest 3600 + bcond flux flux + diffc 0.0 + length 0.1 + disp 0.015 + stagnant 1 6.8e-6 0.3 0.1 + PRINT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 20. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 20. + reset false + END + SOLUTION 0 # Original solution reenters + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + TRANSPORT + shifts 10 + punch_frequency 10 + punch_cells 1-20 + SELECTED_OUTPUT + file ex13a.sel + reset false + solution + distance true + USER_PUNCH + heading Cl_mmol Na_mmol + 10 PUNCH TOT("Cl")*1000, TOT("Na")*1000 + END +No memory leaks diff --git a/Sun/examples/ex13a.sel b/Sun/examples/ex13a.sel new file mode 100644 index 00000000..68d5fffe --- /dev/null +++ b/Sun/examples/ex13a.sel @@ -0,0 +1,42 @@ + soln dist_x Cl_mmol Na_mmol + 0 -99 0.0000e+00 0.0000e+00 + 1 0.05 9.6495e-01 8.8504e-01 + 2 0.15 9.1812e-01 6.9360e-01 + 3 0.25 8.4451e-01 4.3288e-01 + 4 0.35 7.1652e-01 1.9734e-01 + 5 0.45 4.9952e-01 6.0705e-02 + 6 0.55 2.4048e-01 1.1785e-02 + 7 0.65 7.2812e-02 1.4039e-03 + 8 0.75 1.3132e-02 9.9324e-05 + 9 0.85 1.2882e-03 3.8318e-06 + 10 0.95 5.2940e-05 6.2140e-08 + 11 1.05 0.0000e+00 0.0000e+00 + 12 1.15 0.0000e+00 0.0000e+00 + 13 1.25 0.0000e+00 0.0000e+00 + 14 1.35 0.0000e+00 0.0000e+00 + 15 1.45 0.0000e+00 0.0000e+00 + 16 1.55 0.0000e+00 0.0000e+00 + 17 1.65 0.0000e+00 0.0000e+00 + 18 1.75 0.0000e+00 0.0000e+00 + 19 1.85 0.0000e+00 0.0000e+00 + 20 1.95 0.0000e+00 0.0000e+00 + 1 0.05 7.5889e-03 2.0250e-02 + 2 0.15 1.7993e-02 5.0943e-02 + 3 0.25 3.3135e-02 1.0209e-01 + 4 0.35 5.3591e-02 1.7480e-01 + 5 0.45 8.0158e-02 2.5484e-01 + 6 0.55 1.1396e-01 3.1308e-01 + 7 0.65 1.5767e-01 3.2277e-01 + 8 0.75 2.1666e-01 2.7968e-01 + 9 0.85 2.9573e-01 2.0468e-01 + 10 0.95 3.8769e-01 1.2726e-01 + 11 1.05 4.6467e-01 6.7581e-02 + 12 1.15 4.9243e-01 3.0745e-02 + 13 1.25 4.5811e-01 1.1988e-02 + 14 1.35 3.7620e-01 3.9981e-03 + 15 1.45 2.7323e-01 1.1366e-03 + 16 1.55 1.7416e-01 2.7440e-04 + 17 1.65 9.6074e-02 5.6038e-05 + 18 1.75 4.5211e-02 9.6477e-06 + 19 1.85 1.7934e-02 1.3954e-06 + 20 1.95 6.4869e-03 1.7678e-07 diff --git a/Sun/examples/ex13b.log b/Sun/examples/ex13b.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex13b.out b/Sun/examples/ex13b.out new file mode 100644 index 00000000..f705879b --- /dev/null +++ b/Sun/examples/ex13b.out @@ -0,0 +1,430 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex13b + Output file: ex13b.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 13B.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + Explicit definition of first-order exchange factors. + SOLUTION 0 # 1 mmol/l NaCl + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + Na 1.0 # Na has Retardation = 2 + Cl 1.0 # Cl has Retardation = 1, stagnant exchange + N(5) 1.0 # NO3 is conservative + END +----- +TITLE +----- + + Example 13B.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + Explicit definition of first-order exchange factors. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.500e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.551e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.000e-03 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -33.33 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.046e-07 1.001e-07 -6.981 -7.000 -0.019 + H+ 1.042e-07 1.000e-07 -6.982 -7.000 -0.018 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +Cl 1.000e-03 + Cl- 1.000e-03 9.576e-04 -3.000 -3.019 -0.019 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.573e-04 -3.000 -3.019 -0.019 +Na 1.000e-03 + Na+ 1.000e-03 9.580e-04 -3.000 -3.019 -0.019 + NaOH 6.327e-11 6.329e-11 -10.199 -10.199 0.000 +O(0) 4.374e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.62 -6.04 1.58 NaCl + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1-41 # Column with KNO3 + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + EXCHANGE 1-41 + equilibrate 1 + X 1.e-3 + EXCHANGE_SPECIES # For linear exchange, make KX exch. coeff. equal to NaX + K+ + X- = KX + log_k 0.0 + gamma 3.5 0.015 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.70 -3.66 -2.96 O2 + +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using exchange 1. Exchange assemblage after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + NH4X 6.872e-63 6.872e-63 6.872e-60 -0.016 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 13.605 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.763 -62.779 -0.016 + NH3 0.000e+00 0.000e+00 -65.023 -65.023 0.000 +N(0) 1.994e-19 + N2 9.971e-20 9.973e-20 -19.001 -19.001 0.000 +N(3) 2.291e-16 + NO2- 2.291e-16 2.210e-16 -15.640 -15.656 -0.016 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.74 -19.00 -3.26 N2 + NH3(g) -66.79 -65.02 1.77 NH3 + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + MIX 1 + 1 .93038 + 22 .06962 + MIX 2 + 2 .93038 + 23 .06962 + MIX 3 + 3 .93038 + 24 .06962 + MIX 4 + 4 .93038 + 25 .06962 + MIX 5 + 5 .93038 + 26 .06962 + MIX 6 + 6 .93038 + 27 .06962 + MIX 7 + 7 .93038 + 28 .06962 + MIX 8 + 8 .93038 + 29 .06962 + MIX 9 + 9 .93038 + 30 .06962 + MIX 10 + 10 .93038 + 31 .06962 + MIX 11 + 11 .93038 + 32 .06962 + MIX 12 + 12 .93038 + 33 .06962 + MIX 13 + 13 .93038 + 34 .06962 + MIX 14 + 14 .93038 + 35 .06962 + MIX 15 + 15 .93038 + 36 .06962 + MIX 16 + 16 .93038 + 37 .06962 + MIX 17 + 17 .93038 + 38 .06962 + MIX 18 + 18 .93038 + 39 .06962 + MIX 19 + 19 .93038 + 40 .06962 + MIX 20 + 20 .93038 + 41 .06962 + MIX 22 + 1 .20886 + 22 .79114 + MIX 23 + 2 .20886 + 23 .79114 + MIX 24 + 3 .20886 + 24 .79114 + MIX 25 + 4 .20886 + 25 .79114 + MIX 26 + 5 .20886 + 26 .79114 + MIX 27 + 6 .20886 + 27 .79114 + MIX 28 + 7 .20886 + 28 .79114 + MIX 29 + 8 .20886 + 29 .79114 + MIX 30 + 9 .20886 + 30 .79114 + MIX 31 + 10 .20886 + 31 .79114 + MIX 32 + 11 .20886 + 32 .79114 + MIX 33 + 12 .20886 + 33 .79114 + MIX 34 + 13 .20886 + 34 .79114 + MIX 35 + 14 .20886 + 35 .79114 + MIX 36 + 15 .20886 + 36 .79114 + MIX 37 + 16 .20886 + 37 .79114 + MIX 38 + 17 .20886 + 38 .79114 + MIX 39 + 18 .20886 + 39 .79114 + MIX 40 + 19 .20886 + 40 .79114 + MIX 41 + 20 .20886 + 41 .79114 + TRANSPORT + cells 20 + shifts 5 + flow_direction forward + timest 3600 + bcond flux flux + diffc 0.0 + length 0.1 + disp 0.015 + stagnant 1 + PRINT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 20. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 20. + reset false + END + SOLUTION 0 # Original solution reenters + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + TRANSPORT + shifts 10 + punch_frequency 10 + punch_cells 1-20 + SELECTED_OUTPUT + file ex13b.sel + reset false + distance true + solution + USER_PUNCH + heading Cl_mmol Na_mmol + 10 PUNCH TOT("Cl")*1000, TOT("Na")*1000 + END +No memory leaks diff --git a/Sun/examples/ex13b.sel b/Sun/examples/ex13b.sel new file mode 100644 index 00000000..21837b16 --- /dev/null +++ b/Sun/examples/ex13b.sel @@ -0,0 +1,42 @@ + soln dist_x Cl_mmol Na_mmol + 0 -99 0.0000e+00 0.0000e+00 + 1 0.05 9.6495e-01 8.8504e-01 + 2 0.15 9.1812e-01 6.9360e-01 + 3 0.25 8.4451e-01 4.3288e-01 + 4 0.35 7.1652e-01 1.9734e-01 + 5 0.45 4.9952e-01 6.0705e-02 + 6 0.55 2.4048e-01 1.1785e-02 + 7 0.65 7.2813e-02 1.4039e-03 + 8 0.75 1.3132e-02 9.9324e-05 + 9 0.85 1.2882e-03 3.8318e-06 + 10 0.95 5.2941e-05 6.2140e-08 + 11 1.05 0.0000e+00 0.0000e+00 + 12 1.15 0.0000e+00 0.0000e+00 + 13 1.25 0.0000e+00 0.0000e+00 + 14 1.35 0.0000e+00 0.0000e+00 + 15 1.45 0.0000e+00 0.0000e+00 + 16 1.55 0.0000e+00 0.0000e+00 + 17 1.65 0.0000e+00 0.0000e+00 + 18 1.75 0.0000e+00 0.0000e+00 + 19 1.85 0.0000e+00 0.0000e+00 + 20 1.95 0.0000e+00 0.0000e+00 + 1 0.05 7.5889e-03 2.0249e-02 + 2 0.15 1.7993e-02 5.0943e-02 + 3 0.25 3.3135e-02 1.0209e-01 + 4 0.35 5.3590e-02 1.7480e-01 + 5 0.45 8.0158e-02 2.5484e-01 + 6 0.55 1.1395e-01 3.1308e-01 + 7 0.65 1.5766e-01 3.2277e-01 + 8 0.75 2.1666e-01 2.7969e-01 + 9 0.85 2.9573e-01 2.0468e-01 + 10 0.95 3.8768e-01 1.2727e-01 + 11 1.05 4.6467e-01 6.7581e-02 + 12 1.15 4.9243e-01 3.0745e-02 + 13 1.25 4.5811e-01 1.1988e-02 + 14 1.35 3.7620e-01 3.9981e-03 + 15 1.45 2.7323e-01 1.1366e-03 + 16 1.55 1.7416e-01 2.7440e-04 + 17 1.65 9.6075e-02 5.6039e-05 + 18 1.75 4.5211e-02 9.6477e-06 + 19 1.85 1.7934e-02 1.3954e-06 + 20 1.95 6.4870e-03 1.7678e-07 diff --git a/Sun/examples/ex13c.log b/Sun/examples/ex13c.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex13c.out b/Sun/examples/ex13c.out new file mode 100644 index 00000000..d073ce4e --- /dev/null +++ b/Sun/examples/ex13c.out @@ -0,0 +1,751 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex13c + Output file: ex13c.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 13C.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + 5 layer stagnant zone with finite differences. + SOLUTION 0 # 1 mmol/l NaCl + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + Na 1.0 # Na has Retardation = 2 + Cl 1.0 # Cl has Retardation = 1, stagnant exchange + N(5) 1.0 # NO3 is conservative + END +----- +TITLE +----- + + Example 13C.--1 mmol/l NaCl/NO3 enters column with stagnant zones. + 5 layer stagnant zone with finite differences. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.500e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.551e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.000e-03 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -33.33 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.046e-07 1.001e-07 -6.981 -7.000 -0.019 + H+ 1.042e-07 1.000e-07 -6.982 -7.000 -0.018 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +Cl 1.000e-03 + Cl- 1.000e-03 9.576e-04 -3.000 -3.019 -0.019 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.573e-04 -3.000 -3.019 -0.019 +Na 1.000e-03 + Na+ 1.000e-03 9.580e-04 -3.000 -3.019 -0.019 + NaOH 6.327e-11 6.329e-11 -10.199 -10.199 0.000 +O(0) 4.374e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -7.62 -6.04 1.58 NaCl + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1-121 # Column with KNO3 + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + EXCHANGE 1-121 + equilibrate 1 + X 1.e-3 + EXCHANGE_SPECIES # For linear exchange, make KX exch. coeff. equal to NaX + K+ + X- = KX + log_k 0.0 + gamma 3.5 0.015 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N(5) 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.605 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -0.70 -3.66 -2.96 O2 + +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using exchange 1. Exchange assemblage after simulation 2. + +-----------------------------Exchange composition------------------------------ + +X 1.000e-03 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + KX 1.000e-03 1.000e-03 1.000e+00 -0.016 + NH4X 6.872e-63 6.872e-63 6.872e-60 -0.016 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + K 1.000e-03 1.000e-03 + N 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 13.605 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.351e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.351e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.038e-07 1.001e-07 -6.984 -7.000 -0.016 + H+ 1.034e-07 1.000e-07 -6.985 -7.000 -0.015 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +K 1.000e-03 + K+ 1.000e-03 9.649e-04 -3.000 -3.016 -0.016 + KOH 3.345e-11 3.346e-11 -10.476 -10.476 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -62.763 -62.779 -0.016 + NH3 0.000e+00 0.000e+00 -65.023 -65.023 0.000 +N(0) 1.994e-19 + N2 9.971e-20 9.973e-20 -19.001 -19.001 0.000 +N(3) 2.291e-16 + NO2- 2.291e-16 2.210e-16 -15.640 -15.656 -0.016 +N(5) 1.000e-03 + NO3- 1.000e-03 9.647e-04 -3.000 -3.016 -0.016 +O(0) 4.375e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -15.74 -19.00 -3.26 N2 + NH3(g) -66.79 -65.02 1.77 NH3 + O2(g) -0.70 -3.66 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + MIX 1 + 1 0.90712 + 22 0.09288 + MIX 22 + 1 0.57098 + 22 0.21656 + 42 0.21246 + MIX 42 + 22 0.35027 + 42 0.45270 + 62 0.19703 + MIX 62 + 42 0.38368 + 62 0.44579 + 82 0.17053 + MIX 82 + 62 0.46286 + 82 0.42143 + 102 0.11571 + MIX 102 + 82 0.81000 + 102 0.19000 + MIX 2 + 2 0.90712 + 23 0.09288 + MIX 23 + 2 0.57098 + 23 0.21656 + 43 0.21246 + MIX 43 + 23 0.35027 + 43 0.45270 + 63 0.19703 + MIX 63 + 43 0.38368 + 63 0.44579 + 83 0.17053 + MIX 83 + 63 0.46286 + 83 0.42143 + 103 0.11571 + MIX 103 + 83 0.81000 + 103 0.19000 + MIX 3 + 3 0.90712 + 24 0.09288 + MIX 24 + 3 0.57098 + 24 0.21656 + 44 0.21246 + MIX 44 + 24 0.35027 + 44 0.45270 + 64 0.19703 + MIX 64 + 44 0.38368 + 64 0.44579 + 84 0.17053 + MIX 84 + 64 0.46286 + 84 0.42143 + 104 0.11571 + MIX 104 + 84 0.81000 + 104 0.19000 + MIX 4 + 4 0.90712 + 25 0.09288 + MIX 25 + 4 0.57098 + 25 0.21656 + 45 0.21246 + MIX 45 + 25 0.35027 + 45 0.45270 + 65 0.19703 + MIX 65 + 45 0.38368 + 65 0.44579 + 85 0.17053 + MIX 85 + 65 0.46286 + 85 0.42143 + 105 0.11571 + MIX 105 + 85 0.81000 + 105 0.19000 + MIX 5 + 5 0.90712 + 26 0.09288 + MIX 26 + 5 0.57098 + 26 0.21656 + 46 0.21246 + MIX 46 + 26 0.35027 + 46 0.45270 + 66 0.19703 + MIX 66 + 46 0.38368 + 66 0.44579 + 86 0.17053 + MIX 86 + 66 0.46286 + 86 0.42143 + 106 0.11571 + MIX 106 + 86 0.81000 + 106 0.19000 + MIX 6 + 6 0.90712 + 27 0.09288 + MIX 27 + 6 0.57098 + 27 0.21656 + 47 0.21246 + MIX 47 + 27 0.35027 + 47 0.45270 + 67 0.19703 + MIX 67 + 47 0.38368 + 67 0.44579 + 87 0.17053 + MIX 87 + 67 0.46286 + 87 0.42143 + 107 0.11571 + MIX 107 + 87 0.81000 + 107 0.19000 + MIX 7 + 7 0.90712 + 28 0.09288 + MIX 28 + 7 0.57098 + 28 0.21656 + 48 0.21246 + MIX 48 + 28 0.35027 + 48 0.45270 + 68 0.19703 + MIX 68 + 48 0.38368 + 68 0.44579 + 88 0.17053 + MIX 88 + 68 0.46286 + 88 0.42143 + 108 0.11571 + MIX 108 + 88 0.81000 + 108 0.19000 + MIX 8 + 8 0.90712 + 29 0.09288 + MIX 29 + 8 0.57098 + 29 0.21656 + 49 0.21246 + MIX 49 + 29 0.35027 + 49 0.45270 + 69 0.19703 + MIX 69 + 49 0.38368 + 69 0.44579 + 89 0.17053 + MIX 89 + 69 0.46286 + 89 0.42143 + 109 0.11571 + MIX 109 + 89 0.81000 + 109 0.19000 + MIX 9 + 9 0.90712 + 30 0.09288 + MIX 30 + 9 0.57098 + 30 0.21656 + 50 0.21246 + MIX 50 + 30 0.35027 + 50 0.45270 + 70 0.19703 + MIX 70 + 50 0.38368 + 70 0.44579 + 90 0.17053 + MIX 90 + 70 0.46286 + 90 0.42143 + 110 0.11571 + MIX 110 + 90 0.81000 + 110 0.19000 + MIX 10 + 10 0.90712 + 31 0.09288 + MIX 31 + 10 0.57098 + 31 0.21656 + 51 0.21246 + MIX 51 + 31 0.35027 + 51 0.45270 + 71 0.19703 + MIX 71 + 51 0.38368 + 71 0.44579 + 91 0.17053 + MIX 91 + 71 0.46286 + 91 0.42143 + 111 0.11571 + MIX 111 + 91 0.81000 + 111 0.19000 + MIX 11 + 11 0.90712 + 32 0.09288 + MIX 32 + 11 0.57098 + 32 0.21656 + 52 0.21246 + MIX 52 + 32 0.35027 + 52 0.45270 + 72 0.19703 + MIX 72 + 52 0.38368 + 72 0.44579 + 92 0.17053 + MIX 92 + 72 0.46286 + 92 0.42143 + 112 0.11571 + MIX 112 + 92 0.81000 + 112 0.19000 + MIX 12 + 12 0.90712 + 33 0.09288 + MIX 33 + 12 0.57098 + 33 0.21656 + 53 0.21246 + MIX 53 + 33 0.35027 + 53 0.45270 + 73 0.19703 + MIX 73 + 53 0.38368 + 73 0.44579 + 93 0.17053 + MIX 93 + 73 0.46286 + 93 0.42143 + 113 0.11571 + MIX 113 + 93 0.81000 + 113 0.19000 + MIX 13 + 13 0.90712 + 34 0.09288 + MIX 34 + 13 0.57098 + 34 0.21656 + 54 0.21246 + MIX 54 + 34 0.35027 + 54 0.45270 + 74 0.19703 + MIX 74 + 54 0.38368 + 74 0.44579 + 94 0.17053 + MIX 94 + 74 0.46286 + 94 0.42143 + 114 0.11571 + MIX 114 + 94 0.81000 + 114 0.19000 + MIX 14 + 14 0.90712 + 35 0.09288 + MIX 35 + 14 0.57098 + 35 0.21656 + 55 0.21246 + MIX 55 + 35 0.35027 + 55 0.45270 + 75 0.19703 + MIX 75 + 55 0.38368 + 75 0.44579 + 95 0.17053 + MIX 95 + 75 0.46286 + 95 0.42143 + 115 0.11571 + MIX 115 + 95 0.81000 + 115 0.19000 + MIX 15 + 15 0.90712 + 36 0.09288 + MIX 36 + 15 0.57098 + 36 0.21656 + 56 0.21246 + MIX 56 + 36 0.35027 + 56 0.45270 + 76 0.19703 + MIX 76 + 56 0.38368 + 76 0.44579 + 96 0.17053 + MIX 96 + 76 0.46286 + 96 0.42143 + 116 0.11571 + MIX 116 + 96 0.81000 + 116 0.19000 + MIX 16 + 16 0.90712 + 37 0.09288 + MIX 37 + 16 0.57098 + 37 0.21656 + 57 0.21246 + MIX 57 + 37 0.35027 + 57 0.45270 + 77 0.19703 + MIX 77 + 57 0.38368 + 77 0.44579 + 97 0.17053 + MIX 97 + 77 0.46286 + 97 0.42143 + 117 0.11571 + MIX 117 + 97 0.81000 + 117 0.19000 + MIX 17 + 17 0.90712 + 38 0.09288 + MIX 38 + 17 0.57098 + 38 0.21656 + 58 0.21246 + MIX 58 + 38 0.35027 + 58 0.45270 + 78 0.19703 + MIX 78 + 58 0.38368 + 78 0.44579 + 98 0.17053 + MIX 98 + 78 0.46286 + 98 0.42143 + 118 0.11571 + MIX 118 + 98 0.81000 + 118 0.19000 + MIX 18 + 18 0.90712 + 39 0.09288 + MIX 39 + 18 0.57098 + 39 0.21656 + 59 0.21246 + MIX 59 + 39 0.35027 + 59 0.45270 + 79 0.19703 + MIX 79 + 59 0.38368 + 79 0.44579 + 99 0.17053 + MIX 99 + 79 0.46286 + 99 0.42143 + 119 0.11571 + MIX 119 + 99 0.81000 + 119 0.19000 + MIX 19 + 19 0.90712 + 40 0.09288 + MIX 40 + 19 0.57098 + 40 0.21656 + 60 0.21246 + MIX 60 + 40 0.35027 + 60 0.45270 + 80 0.19703 + MIX 80 + 60 0.38368 + 80 0.44579 + 100 0.17053 + MIX 100 + 80 0.46286 + 100 0.42143 + 120 0.11571 + MIX 120 + 100 0.81000 + 120 0.19000 + MIX 20 + 20 0.90712 + 41 0.09288 + MIX 41 + 20 0.57098 + 41 0.21656 + 61 0.21246 + MIX 61 + 41 0.35027 + 61 0.45270 + 81 0.19703 + MIX 81 + 61 0.38368 + 81 0.44579 + 101 0.17053 + MIX 101 + 81 0.46286 + 101 0.42143 + 121 0.11571 + MIX 121 + 101 0.81000 + 121 0.19000 + TRANSPORT + cells 20 + shifts 5 + flow_direction forward + timest 3600 + tempr 3.0 + bcond flux flux + diffc 0.0 + length 0.10 + disp 0.015 + stagnant 5 + PRINT +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 20. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 20. + reset false + END + SOLUTION 0 # Original solution reenters + units mmol/l + pH 7.0 + pe 13.0 O2(g) -0.7 + K 1.0 + N(5) 1.0 + TRANSPORT + shifts 10 + punch_frequency 10 + punch_cells 1-20 + SELECTED_OUTPUT + file ex13c.sel + reset false + solution + distance true + USER_PUNCH + heading Cl_mmol Na_mmol + 10 PUNCH TOT("Cl")*1000, TOT("Na")*1000 + END +No memory leaks diff --git a/Sun/examples/ex13c.sel b/Sun/examples/ex13c.sel new file mode 100644 index 00000000..7969e528 --- /dev/null +++ b/Sun/examples/ex13c.sel @@ -0,0 +1,42 @@ + soln dist_x Cl_mmol Na_mmol + 0 -99 0.0000e+00 0.0000e+00 + 1 0.05 9.7683e-01 8.8829e-01 + 2 0.15 9.4255e-01 6.9066e-01 + 3 0.25 8.7253e-01 4.2503e-01 + 4 0.35 7.2600e-01 1.9091e-01 + 5 0.45 4.8246e-01 5.8021e-02 + 6 0.55 2.2239e-01 1.1177e-02 + 7 0.65 6.5489e-02 1.3256e-03 + 8 0.75 1.1639e-02 9.3569e-05 + 9 0.85 1.1350e-03 3.6065e-06 + 10 0.95 4.6646e-05 5.8485e-08 + 11 1.05 0.0000e+00 0.0000e+00 + 12 1.15 0.0000e+00 0.0000e+00 + 13 1.25 0.0000e+00 0.0000e+00 + 14 1.35 0.0000e+00 0.0000e+00 + 15 1.45 0.0000e+00 0.0000e+00 + 16 1.55 0.0000e+00 0.0000e+00 + 17 1.65 0.0000e+00 0.0000e+00 + 18 1.75 0.0000e+00 0.0000e+00 + 19 1.85 0.0000e+00 0.0000e+00 + 20 1.95 0.0000e+00 0.0000e+00 + 1 0.05 4.7101e-03 1.6916e-02 + 2 0.15 1.0234e-02 4.9729e-02 + 3 0.25 1.8109e-02 1.0883e-01 + 4 0.35 2.9565e-02 1.9194e-01 + 5 0.45 4.7408e-02 2.7841e-01 + 6 0.55 7.7191e-02 3.3492e-01 + 7 0.65 1.2832e-01 3.3632e-01 + 8 0.75 2.1109e-01 2.8375e-01 + 9 0.85 3.2572e-01 2.0251e-01 + 10 0.95 4.4908e-01 1.2304e-01 + 11 1.05 5.3819e-01 6.3977e-02 + 12 1.15 5.5716e-01 2.8554e-02 + 13 1.25 5.0158e-01 1.0943e-02 + 14 1.35 3.9581e-01 3.5935e-03 + 15 1.45 2.7424e-01 1.0078e-03 + 16 1.55 1.6586e-01 2.4047e-04 + 17 1.65 8.6688e-02 4.8621e-05 + 18 1.75 3.8743e-02 8.3007e-06 + 19 1.85 1.4669e-02 1.1922e-06 + 20 1.95 5.0940e-03 1.5016e-07 diff --git a/Sun/examples/ex14.log b/Sun/examples/ex14.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex14.out b/Sun/examples/ex14.out new file mode 100644 index 00000000..bf8f9286 --- /dev/null +++ b/Sun/examples/ex14.out @@ -0,0 +1,3000 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex14 + Output file: ex14.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/wateq4f.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 14.--Transport with equilibrium_phases, exchange, and surface reactions + *********** + PLEASE NOTE: This problem requires database file wateq4f.dat! + Arsenic data of Archer and Nordstrom (2002) included in + wateq4f.dat (PHREEQC Version 2.8). + Results differ from WRIR 99-4259 because of revised data. + *********** + SURFACE_SPECIES + Hfo_wOH + Mg+2 = Hfo_wOMg+ + H+ + log_k -15. + Hfo_wOH + Ca+2 = Hfo_wOCa+ + H+ + log_k -15. + SOLUTION 1 Brine + pH 5.713 + pe 4.0 O2(g) -0.7 + temp 25. + units mol/kgw + Ca .4655 + Mg .1609 + Na 5.402 + Cl 6.642 charge + C .00396 + S .004725 + As .05 umol/kgw + END +----- +TITLE +----- + + Example 14.--Transport with equilibrium_phases, exchange, and surface reactions +*********** +PLEASE NOTE: This problem requires database file wateq4f.dat! + Arsenic data of Archer and Nordstrom (2002) included in + wateq4f.dat (PHREEQC Version 2.8). + Results differ from WRIR 99-4259 because of revised data. +*********** + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Brine + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 5.000e-08 5.000e-08 + C 3.960e-03 3.960e-03 + Ca 4.655e-01 4.655e-01 + Cl 6.642e+00 6.642e+00 Charge balance + Mg 1.609e-01 1.609e-01 + Na 5.402e+00 5.402e+00 + S 4.725e-03 4.725e-03 + +----------------------------Description of solution---------------------------- + + pH = 5.713 + pe = 14.945 Equilibrium with O2(g) + Activity of water = 0.785 + Ionic strength = 7.269e+00 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.333e-03 + Total CO2 (mol/kg) = 3.960e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.964e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 11 + Total H = 1.110158e+02 + Total O = 5.553645e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.755e-06 1.936e-06 -5.560 -5.713 -0.153 + OH- 7.396e-10 4.056e-09 -9.131 -8.392 0.739 + H2O 5.551e+01 7.846e-01 1.744 -0.105 0.000 +As(3) 2.742e-33 + H3AsO3 2.741e-33 1.462e-32 -32.562 -31.835 0.727 + H2AsO3- 9.743e-37 5.343e-36 -36.011 -35.272 0.739 + H4AsO3+ 2.557e-39 1.402e-38 -38.592 -37.853 0.739 + HAsO3-2 0.000e+00 0.000e+00 -47.216 -44.259 2.956 + AsO3-3 0.000e+00 0.000e+00 -60.898 -54.246 6.652 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -302.180 -301.440 0.739 + As3S4(HS)2- 0.000e+00 0.000e+00 -897.970 -897.231 0.739 +As(5) 5.000e-08 + H2AsO4- 4.997e-08 2.740e-07 -7.301 -6.562 0.739 + H3AsO4 1.986e-11 1.059e-10 -10.702 -9.975 0.727 + HAsO4-2 1.082e-11 9.791e-09 -10.966 -8.009 2.956 + AsO4-3 2.522e-21 1.132e-14 -20.598 -13.946 6.652 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.861 -143.135 0.727 +C(4) 3.960e-03 + HCO3- 1.045e-03 6.049e-04 -2.981 -3.218 -0.238 + CaHCO3+ 1.002e-03 5.494e-03 -2.999 -2.260 0.739 + MgHCO3+ 6.754e-04 3.704e-03 -3.170 -2.431 0.739 + CO2 6.296e-04 3.357e-03 -3.201 -2.474 0.727 + NaHCO3 6.026e-04 3.213e-03 -3.220 -2.493 0.727 + CaCO3 3.278e-06 1.748e-05 -5.484 -4.758 0.727 + MgCO3 1.372e-06 7.316e-06 -5.863 -5.136 0.727 + NaCO3- 4.698e-07 2.577e-06 -6.328 -5.589 0.739 + CO3-2 1.307e-07 1.465e-08 -6.884 -7.834 -0.950 +Ca 4.655e-01 + Ca+2 4.629e-01 7.121e-01 -0.335 -0.147 0.187 + CaSO4 1.606e-03 8.565e-03 -2.794 -2.067 0.727 + CaHCO3+ 1.002e-03 5.494e-03 -2.999 -2.260 0.739 + CaCO3 3.278e-06 1.748e-05 -5.484 -4.758 0.727 + CaHSO4+ 1.772e-08 9.716e-08 -7.752 -7.012 0.739 + CaOH+ 8.731e-09 4.788e-08 -8.059 -7.320 0.739 +Cl 6.642e+00 + Cl- 6.642e+00 3.947e+00 0.822 0.596 -0.226 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -45.192 -44.465 0.727 +Mg 1.609e-01 + Mg+2 1.588e-01 5.233e-01 -0.799 -0.281 0.518 + MgSO4 1.387e-03 7.395e-03 -2.858 -2.131 0.727 + MgHCO3+ 6.754e-04 3.704e-03 -3.170 -2.431 0.739 + MgCO3 1.372e-06 7.316e-06 -5.863 -5.136 0.727 + MgOH+ 1.404e-07 7.698e-07 -6.853 -6.114 0.739 +Na 5.402e+00 + Na+ 5.401e+00 9.445e+00 0.732 0.975 0.243 + NaHCO3 6.026e-04 3.213e-03 -3.220 -2.493 0.727 + NaSO4- 5.203e-04 2.854e-03 -3.284 -2.545 0.739 + NaCO3- 4.698e-07 2.577e-06 -6.328 -5.589 0.739 +O(0) 8.206e-05 + O2 4.103e-05 2.188e-04 -4.387 -3.660 0.727 +S(-2) 0.000e+00 + H2S 0.000e+00 0.000e+00 -140.569 -139.842 0.727 + HS- 0.000e+00 0.000e+00 -141.810 -141.070 0.739 + S5-2 0.000e+00 0.000e+00 -144.480 -144.952 -0.473 + S4-2 0.000e+00 0.000e+00 -144.629 -145.186 -0.558 + S6-2 0.000e+00 0.000e+00 -144.828 -145.238 -0.410 + S3-2 0.000e+00 0.000e+00 -147.960 -148.639 -0.680 + S2-2 0.000e+00 0.000e+00 -149.072 -149.885 -0.813 + S-2 0.000e+00 0.000e+00 -151.232 -148.275 2.956 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -302.180 -301.440 0.739 + As3S4(HS)2- 0.000e+00 0.000e+00 -897.970 -897.231 0.739 +S(6) 4.725e-03 + CaSO4 1.606e-03 8.565e-03 -2.794 -2.067 0.727 + MgSO4 1.387e-03 7.395e-03 -2.858 -2.131 0.727 + SO4-2 1.211e-03 6.028e-05 -2.917 -4.220 -1.303 + NaSO4- 5.203e-04 2.854e-03 -3.284 -2.545 0.739 + CaHSO4+ 1.772e-08 9.716e-08 -7.752 -7.012 0.739 + HSO4- 2.069e-09 1.135e-08 -8.684 -7.945 0.739 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.01 -4.37 -4.36 CaSO4 + Aragonite 0.35 -7.98 -8.34 CaCO3 + Arsenolite -61.97 -63.35 -1.38 As2O3 + Artinite -7.10 2.50 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -27.86 -19.63 8.23 As2O5 + As2S3(am) -458.49 -503.39 -44.90 As2S3 + As_native -80.96 -93.49 -12.53 As + Brucite -5.91 10.93 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -9.85 -28.76 -18.91 Ca3(AsO4)2:4H2O + Calcite 0.50 -7.98 -8.48 CaCO3 + CH4(g) -140.27 -143.13 -2.86 CH4 + Claudetite -62.01 -63.35 -1.34 As2O3 + CO2(g) -1.01 -2.47 -1.47 CO2 + Dolomite 0.99 -16.10 -17.09 CaMg(CO3)2 + Dolomite(d) 0.44 -16.10 -16.54 CaMg(CO3)2 + Epsomite -3.10 -5.24 -2.14 MgSO4:7H2O + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -41.32 -44.47 -3.15 H2 + H2O(g) -1.62 -0.11 1.51 H2O + H2S(g) -138.84 -139.84 -1.00 H2S + Halite -0.01 1.57 1.58 NaCl + Huntite -2.36 -32.33 -29.97 CaMg3(CO3)4 + Hydromagnesite -13.19 -21.95 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.09 -8.12 -8.03 MgCO3 + Mirabilite -2.21 -3.32 -1.11 Na2SO4:10H2O + Nahcolite -1.70 -2.24 -0.55 NaHCO3 + Natron -5.63 -6.94 -1.31 Na2CO3:10H2O + Nesquehonite -2.81 -8.43 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -457.09 -503.39 -46.30 As2S3 + Portlandite -11.73 11.07 22.80 Ca(OH)2 + Realgar -179.02 -198.96 -19.94 AsS + Sulfur -103.36 -118.39 -15.03 S + Thenardite -2.09 -2.27 -0.18 Na2SO4 + Thermonatrite -6.11 -5.99 0.12 Na2CO3:H2O + Trona -7.54 -8.34 -0.80 NaHCO3:Na2CO3:2H2O + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + USE solution 1 + EQUILIBRIUM_PHASES 1 + Dolomite 0.0 1.6 + Calcite 0.0 0.1 + SAVE solution 1 + SELECTED_OUTPUT + file ex14.sel + reset false + step + USER_PUNCH + heading m_Ca m_Mg m_Na umol_As pH + 10 PUNCH TOT("Ca"), TOT("Mg"), TOT("Na"), TOT("As")*1e6, -LA("H+") + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Brine +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e-01 1.020e-01 1.982e-03 + Dolomite 0.00 -17.09 -17.09 1.600e+00 1.599e+00 -7.679e-04 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 5.000e-08 5.000e-08 + C 3.514e-03 3.514e-03 + Ca 4.643e-01 4.643e-01 + Cl 6.642e+00 6.642e+00 + Mg 1.617e-01 1.617e-01 + Na 5.402e+00 5.402e+00 + S 4.725e-03 4.725e-03 + +----------------------------Description of solution---------------------------- + + pH = 5.350 Charge balance + pe = 15.308 Adjusted to redox equilibrium + Activity of water = 0.785 + Ionic strength = 7.269e+00 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.441e-03 + Total CO2 (mol/kg) = 3.514e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 4.107e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 4 + Total H = 1.110158e+02 + Total O = 5.553511e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.361e-06 4.471e-06 -5.196 -5.350 -0.153 + OH- 3.204e-10 1.757e-09 -9.494 -8.755 0.739 + H2O 5.551e+01 7.846e-01 1.744 -0.105 0.000 +As(3) 6.327e-33 + H3AsO3 6.326e-33 3.373e-32 -32.199 -31.472 0.727 + H2AsO3- 9.740e-37 5.341e-36 -36.011 -35.272 0.739 + H4AsO3+ 1.363e-38 7.471e-38 -37.866 -37.127 0.739 + HAsO3-2 0.000e+00 0.000e+00 -47.579 -44.623 2.956 + AsO3-3 0.000e+00 0.000e+00 -61.625 -54.973 6.652 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -300.727 -299.988 0.739 + As3S4(HS)2- 0.000e+00 0.000e+00 -892.885 -892.146 0.739 +As(5) 5.000e-08 + H2AsO4- 4.995e-08 2.739e-07 -7.301 -6.562 0.739 + H3AsO4 4.583e-11 2.443e-10 -10.339 -9.612 0.727 + HAsO4-2 4.687e-12 4.238e-09 -11.329 -8.373 2.956 + AsO4-3 4.733e-22 2.122e-15 -21.325 -14.673 6.652 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.632 -142.905 0.727 +C(4) 3.514e-03 + CO2 1.068e-03 5.694e-03 -2.971 -2.245 0.727 + HCO3- 7.680e-04 4.444e-04 -3.115 -3.352 -0.238 + CaHCO3+ 7.345e-04 4.028e-03 -3.134 -2.395 0.739 + MgHCO3+ 4.991e-04 2.737e-03 -3.302 -2.563 0.739 + NaHCO3 4.428e-04 2.361e-03 -3.354 -2.627 0.727 + CaCO3 1.041e-06 5.550e-06 -5.983 -5.256 0.727 + MgCO3 4.392e-07 2.341e-06 -6.357 -5.631 0.727 + NaCO3- 1.495e-07 8.199e-07 -6.825 -6.086 0.739 + CO3-2 4.158e-08 4.662e-09 -7.381 -8.331 -0.950 +Ca 4.643e-01 + Ca+2 4.619e-01 7.106e-01 -0.335 -0.148 0.187 + CaSO4 1.601e-03 8.538e-03 -2.796 -2.069 0.727 + CaHCO3+ 7.345e-04 4.028e-03 -3.134 -2.395 0.739 + CaCO3 1.041e-06 5.550e-06 -5.983 -5.256 0.727 + CaHSO4+ 4.078e-08 2.236e-07 -7.390 -6.650 0.739 + CaOH+ 3.774e-09 2.069e-08 -8.423 -7.684 0.739 +Cl 6.642e+00 + Cl- 6.642e+00 3.947e+00 0.822 0.596 -0.226 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -45.192 -44.465 0.727 +Mg 1.617e-01 + Mg+2 1.598e-01 5.263e-01 -0.796 -0.279 0.518 + MgSO4 1.394e-03 7.430e-03 -2.856 -2.129 0.727 + MgHCO3+ 4.991e-04 2.737e-03 -3.302 -2.563 0.739 + MgCO3 4.392e-07 2.341e-06 -6.357 -5.631 0.727 + MgOH+ 6.115e-08 3.353e-07 -7.214 -6.475 0.739 +Na 5.402e+00 + Na+ 5.401e+00 9.445e+00 0.732 0.975 0.243 + NaSO4- 5.199e-04 2.851e-03 -3.284 -2.545 0.739 + NaHCO3 4.428e-04 2.361e-03 -3.354 -2.627 0.727 + NaCO3- 1.495e-07 8.199e-07 -6.825 -6.086 0.739 +O(0) 8.206e-05 + O2 4.103e-05 2.188e-04 -4.387 -3.660 0.727 +S(-2) 0.000e+00 + H2S 0.000e+00 0.000e+00 -139.842 -139.115 0.727 + HS- 0.000e+00 0.000e+00 -141.447 -140.707 0.739 + S5-2 0.000e+00 0.000e+00 -144.480 -144.953 -0.473 + S4-2 0.000e+00 0.000e+00 -144.629 -145.187 -0.558 + S6-2 0.000e+00 0.000e+00 -144.829 -145.239 -0.410 + S3-2 0.000e+00 0.000e+00 -147.960 -148.640 -0.680 + S2-2 0.000e+00 0.000e+00 -149.073 -149.886 -0.813 + S-2 0.000e+00 0.000e+00 -151.232 -148.276 2.956 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -300.727 -299.988 0.739 + As3S4(HS)2- 0.000e+00 0.000e+00 -892.885 -892.146 0.739 +S(6) 4.725e-03 + CaSO4 1.601e-03 8.538e-03 -2.796 -2.069 0.727 + MgSO4 1.394e-03 7.430e-03 -2.856 -2.129 0.727 + SO4-2 1.210e-03 6.022e-05 -2.917 -4.220 -1.303 + NaSO4- 5.199e-04 2.851e-03 -3.284 -2.545 0.739 + CaHSO4+ 4.078e-08 2.236e-07 -7.390 -6.650 0.739 + HSO4- 4.774e-09 2.618e-08 -8.321 -7.582 0.739 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.01 -4.37 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Arsenolite -61.25 -62.63 -1.38 As2O3 + Artinite -8.32 1.28 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -27.14 -18.91 8.23 As2O5 + As2S3(am) -455.58 -500.48 -44.90 As2S3 + As_native -80.60 -93.13 -12.53 As + Brucite -6.63 10.21 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -11.31 -30.21 -18.91 Ca3(AsO4)2:4H2O + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -140.04 -142.90 -2.86 CH4 + Claudetite -61.29 -62.63 -1.34 As2O3 + CO2(g) -0.78 -2.24 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -3.10 -5.24 -2.14 MgSO4:7H2O + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -41.32 -44.47 -3.15 H2 + H2O(g) -1.62 -0.11 1.51 H2O + H2S(g) -138.12 -139.12 -1.00 H2S + Halite -0.01 1.57 1.58 NaCl + Huntite -4.34 -34.31 -29.97 CaMg3(CO3)4 + Hydromagnesite -15.89 -24.65 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.58 -8.61 -8.03 MgCO3 + Mirabilite -2.21 -3.32 -1.11 Na2SO4:10H2O + Nahcolite -1.83 -2.38 -0.55 NaHCO3 + Natron -6.12 -7.43 -1.31 Na2CO3:10H2O + Nesquehonite -3.31 -8.93 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -454.18 -500.48 -46.30 As2S3 + Portlandite -12.46 10.34 22.80 Ca(OH)2 + Realgar -177.93 -197.87 -19.94 AsS + Sulfur -102.63 -117.66 -15.03 S + Thenardite -2.09 -2.27 -0.18 Na2SO4 + Thermonatrite -6.61 -6.49 0.12 Na2CO3:H2O + Trona -8.17 -8.97 -0.80 NaHCO3:Na2CO3:2H2O + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + PRINT + selected_output false + EXCHANGE 1 + equilibrate with solution 1 + X 1.0 + SURFACE 1 + equilibrate solution 1 + Hfo_w 0.07 600. 30. + END +------------------------------------------------------- +Beginning of initial exchange-composition calculations. +------------------------------------------------------- + +Exchange 1. + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + NaX 9.355e-01 9.355e-01 9.355e-01 0.000 + CaX2 2.199e-02 4.398e-02 4.398e-02 0.000 + MgX2 1.028e-02 2.055e-02 2.055e-02 0.000 + HX 4.428e-06 4.428e-06 4.428e-06 0.000 + +------------------------------------------------------ +Beginning of initial surface-composition calculations. +------------------------------------------------------ + +Surface 1. + +Hfo + 6.234e-02 Surface charge, eq + 3.342e-01 sigma, C/m**2 + 4.729e-02 psi, V + -1.841e+00 -F*psi/RT + 1.587e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH2+ 6.388e-02 0.913 6.388e-02 -1.195 + Hfo_wOH 4.617e-03 0.066 4.616e-03 -2.336 + Hfo_wSO4- 6.015e-04 0.009 6.015e-04 -3.221 + Hfo_wHAsO4- 5.089e-04 0.007 5.089e-04 -3.293 + Hfo_wH2AsO4 2.279e-04 0.003 2.279e-04 -3.642 + Hfo_wOHAsO4-3 9.316e-05 0.001 9.316e-05 -4.031 + Hfo_wOHSO4-2 6.805e-05 0.001 6.805e-05 -4.167 + Hfo_wO- 7.643e-06 0.000 7.643e-06 -5.117 + Hfo_wOCa+ 1.165e-13 0.000 1.165e-13 -12.934 + Hfo_wOMg+ 8.626e-14 0.000 8.626e-14 -13.064 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + SOLUTION 0 20 x precipitation + pH 4.6 + pe 4.0 O2(g) -0.7 + temp 25. + units mmol/kgw + Ca .191625 + Mg .035797 + Na .122668 + Cl .133704 + C .01096 + S .235153 charge + EQUILIBRIUM_PHASES 0 + Dolomite 0.0 1.6 + Calcite 0.0 0.1 + CO2(g) -1.5 10. + SAVE solution 0 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. 20 x precipitation + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.096e-05 1.096e-05 + Ca 1.916e-04 1.916e-04 + Cl 1.337e-04 1.337e-04 + Mg 3.580e-05 3.580e-05 + Na 1.227e-04 1.227e-04 + S 2.351e-04 2.351e-04 Charge balance + +----------------------------Description of solution---------------------------- + + pH = 4.600 + pe = 16.005 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.035e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -2.630e-05 + Total CO2 (mol/kg) = 1.096e-05 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.119e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 9 + Total H = 1.110125e+02 + Total O = 5.550762e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.600e-05 2.512e-05 -4.585 -4.600 -0.015 + OH- 4.132e-10 3.985e-10 -9.384 -9.400 -0.016 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -145.418 -145.418 0.000 +C(4) 1.096e-05 + CO2 1.076e-05 1.076e-05 -4.968 -4.968 0.000 + HCO3- 1.975e-07 1.906e-07 -6.704 -6.720 -0.015 + CaHCO3+ 4.049e-10 3.905e-10 -9.393 -9.408 -0.016 + MgHCO3+ 6.905e-11 6.660e-11 -10.161 -10.177 -0.016 + NaHCO3 1.267e-11 1.267e-11 -10.897 -10.897 0.000 + CO3-2 4.105e-13 3.559e-13 -12.387 -12.449 -0.062 + CaCO3 9.575e-14 9.577e-14 -13.019 -13.019 0.000 + MgCO3 1.014e-14 1.014e-14 -13.994 -13.994 0.000 + NaCO3- 8.122e-16 7.833e-16 -15.090 -15.106 -0.016 +Ca 1.916e-04 + Ca+2 1.853e-04 1.606e-04 -3.732 -3.794 -0.062 + CaSO4 6.296e-06 6.297e-06 -5.201 -5.201 0.000 + CaHSO4+ 9.608e-10 9.267e-10 -9.017 -9.033 -0.016 + CaHCO3+ 4.049e-10 3.905e-10 -9.393 -9.408 -0.016 + CaOH+ 1.100e-12 1.061e-12 -11.958 -11.974 -0.016 + CaCO3 9.575e-14 9.577e-14 -13.019 -13.019 0.000 +Cl 1.337e-04 + Cl- 1.337e-04 1.289e-04 -3.874 -3.890 -0.016 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.360 -44.360 0.000 +Mg 3.580e-05 + Mg+2 3.442e-05 2.986e-05 -4.463 -4.525 -0.062 + MgSO4 1.375e-06 1.375e-06 -5.862 -5.862 0.000 + MgHCO3+ 6.905e-11 6.660e-11 -10.161 -10.177 -0.016 + MgOH+ 4.475e-12 4.316e-12 -11.349 -11.365 -0.016 + MgCO3 1.014e-14 1.014e-14 -13.994 -13.994 0.000 +Na 1.227e-04 + Na+ 1.225e-04 1.182e-04 -3.912 -3.927 -0.016 + NaSO4- 1.207e-07 1.164e-07 -6.918 -6.934 -0.016 + NaHCO3 1.267e-11 1.267e-11 -10.897 -10.897 0.000 + NaCO3- 8.122e-16 7.833e-16 -15.090 -15.106 -0.016 +O(0) 4.374e-04 + O2 2.187e-04 2.188e-04 -3.660 -3.660 0.000 +S(-2) 0.000e+00 + H2S 0.000e+00 0.000e+00 -137.103 -137.103 0.000 + HS- 0.000e+00 0.000e+00 -139.429 -139.444 -0.016 + S5-2 0.000e+00 0.000e+00 -144.381 -144.439 -0.058 + S4-2 0.000e+00 0.000e+00 -144.614 -144.673 -0.059 + S6-2 0.000e+00 0.000e+00 -144.668 -144.725 -0.057 + S-2 0.000e+00 0.000e+00 -147.700 -147.762 -0.063 + S3-2 0.000e+00 0.000e+00 -148.066 -148.126 -0.060 + S2-2 0.000e+00 0.000e+00 -149.311 -149.372 -0.061 +S(6) 2.351e-04 + SO4-2 2.268e-04 1.965e-04 -3.644 -3.707 -0.062 + CaSO4 6.296e-06 6.297e-06 -5.201 -5.201 0.000 + MgSO4 1.375e-06 1.375e-06 -5.862 -5.862 0.000 + HSO4- 4.975e-07 4.798e-07 -6.303 -6.319 -0.016 + NaSO4- 1.207e-07 1.164e-07 -6.918 -6.934 -0.016 + CaHSO4+ 9.608e-10 9.267e-10 -9.017 -9.033 -0.016 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.14 -7.50 -4.36 CaSO4 + Aragonite -7.91 -16.24 -8.34 CaCO3 + Artinite -21.90 -12.30 9.60 MgCO3:Mg(OH)2:3H2O + Brucite -12.16 4.68 16.84 Mg(OH)2 + Calcite -7.76 -16.24 -8.48 CaCO3 + CH4(g) -142.56 -145.42 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Dolomite -16.13 -33.22 -17.09 CaMg(CO3)2 + Dolomite(d) -16.68 -33.22 -16.54 CaMg(CO3)2 + Epsomite -6.09 -8.23 -2.14 MgSO4:7H2O + Gypsum -2.92 -7.50 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -136.11 -137.10 -1.00 H2S + Halite -9.40 -7.82 1.58 NaCl + Huntite -37.20 -67.16 -29.97 CaMg3(CO3)4 + Hydromagnesite -54.46 -63.22 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -8.94 -16.97 -8.03 MgCO3 + Mirabilite -10.45 -11.56 -1.11 Na2SO4:10H2O + Nahcolite -10.10 -10.65 -0.55 NaHCO3 + Natron -18.99 -20.30 -1.31 Na2CO3:10H2O + Nesquehonite -11.35 -16.97 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Portlandite -17.39 5.41 22.80 Ca(OH)2 + Sulfur -100.73 -115.75 -15.03 S + Thenardite -11.38 -11.56 -0.18 Na2SO4 + Thermonatrite -20.43 -20.30 0.12 Na2CO3:H2O + Trona -30.16 -30.95 -0.80 NaHCO3:Na2CO3:2H2O + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 0. 20 x precipitation +Using pure phase assemblage 0. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e-01 9.966e-02 -3.443e-04 + CO2(g) -1.50 -19.65 -18.15 1.000e+01 9.996e+00 -4.067e-03 + Dolomite 0.00 -17.09 -17.09 1.600e+00 1.599e+00 -1.349e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 7.120e-03 7.119e-03 + Ca 1.885e-03 1.885e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.385e-03 1.384e-03 + Na 1.227e-04 1.227e-04 + S 2.351e-04 2.351e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.047 Charge balance + pe = 13.558 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.629e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.057e-03 + Total CO2 (mol/kg) = 7.120e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.173e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 16 + Total H = 1.110125e+02 + Total O = 5.552487e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.234e-07 1.115e-07 -6.909 -6.953 -0.044 + H+ 9.814e-08 8.977e-08 -7.008 -7.047 -0.039 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.421 -143.420 0.001 +C(4) 7.120e-03 + HCO3- 5.883e-03 5.333e-03 -2.230 -2.273 -0.043 + CO2 1.074e-03 1.077e-03 -2.969 -2.968 0.001 + CaHCO3+ 8.950e-05 8.087e-05 -4.048 -4.092 -0.044 + MgHCO3+ 6.082e-05 5.496e-05 -4.216 -4.260 -0.044 + CaCO3 5.537e-06 5.550e-06 -5.257 -5.256 0.001 + CO3-2 4.124e-06 2.786e-06 -5.385 -5.555 -0.170 + MgCO3 2.336e-06 2.341e-06 -5.631 -5.631 0.001 + NaHCO3 3.310e-07 3.317e-07 -6.480 -6.479 0.001 + NaCO3- 6.351e-09 5.738e-09 -8.197 -8.241 -0.044 +Ca 1.885e-03 + Ca+2 1.761e-03 1.189e-03 -2.754 -2.925 -0.171 + CaHCO3+ 8.950e-05 8.087e-05 -4.048 -4.092 -0.044 + CaSO4 2.881e-05 2.887e-05 -4.540 -4.539 0.001 + CaCO3 5.537e-06 5.550e-06 -5.257 -5.256 0.001 + CaOH+ 2.432e-09 2.198e-09 -8.614 -8.658 -0.044 + CaHSO4+ 1.681e-11 1.518e-11 -10.775 -10.819 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.206e-04 -3.874 -3.919 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.385e-03 + Mg+2 1.296e-03 8.806e-04 -2.887 -3.055 -0.168 + MgHCO3+ 6.082e-05 5.496e-05 -4.216 -4.260 -0.044 + MgSO4 2.507e-05 2.513e-05 -4.601 -4.600 0.001 + MgCO3 2.336e-06 2.341e-06 -5.631 -5.631 0.001 + MgOH+ 3.941e-08 3.561e-08 -7.404 -7.448 -0.044 +Na 1.227e-04 + Na+ 1.223e-04 1.106e-04 -3.913 -3.956 -0.044 + NaHCO3 3.310e-07 3.317e-07 -6.480 -6.479 0.001 + NaSO4- 7.467e-08 6.747e-08 -7.127 -7.171 -0.044 + NaCO3- 6.351e-09 5.738e-09 -8.197 -8.241 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.057 -142.101 -0.044 + H2S 0.000e+00 0.000e+00 -142.207 -142.206 0.001 + S5-2 0.000e+00 0.000e+00 -144.505 -144.649 -0.144 + S4-2 0.000e+00 0.000e+00 -144.732 -144.883 -0.151 + S6-2 0.000e+00 0.000e+00 -144.797 -144.935 -0.138 + S-2 0.000e+00 0.000e+00 -147.796 -147.972 -0.176 + S3-2 0.000e+00 0.000e+00 -148.177 -148.336 -0.159 + S2-2 0.000e+00 0.000e+00 -149.417 -149.582 -0.165 +S(6) 2.351e-04 + SO4-2 1.811e-04 1.217e-04 -3.742 -3.915 -0.173 + CaSO4 2.881e-05 2.887e-05 -4.540 -4.539 0.001 + MgSO4 2.507e-05 2.513e-05 -4.601 -4.600 0.001 + NaSO4- 7.467e-08 6.747e-08 -7.127 -7.171 -0.044 + HSO4- 1.176e-09 1.062e-09 -8.930 -8.974 -0.044 + CaHSO4+ 1.681e-11 1.518e-11 -10.775 -10.819 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.48 -6.84 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Artinite -7.17 2.43 9.60 MgCO3:Mg(OH)2:3H2O + Brucite -5.80 11.04 16.84 Mg(OH)2 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -140.56 -143.42 -2.86 CH4 + CO2(g) -1.50 -2.97 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.83 -6.97 -2.14 MgSO4:7H2O + Gypsum -2.26 -6.84 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.21 -142.21 -1.00 H2S + Halite -9.46 -7.87 1.58 NaCl + Huntite -4.34 -34.31 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.64 -23.40 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.58 -8.61 -8.03 MgCO3 + Mirabilite -10.71 -11.83 -1.11 Na2SO4:10H2O + Nahcolite -5.68 -6.23 -0.55 NaHCO3 + Natron -12.16 -13.47 -1.31 Na2CO3:10H2O + Nesquehonite -2.99 -8.61 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Portlandite -11.63 11.17 22.80 Ca(OH)2 + Sulfur -105.83 -120.86 -15.03 S + Thenardite -11.65 -11.83 -0.18 Na2SO4 + Thermonatrite -13.59 -13.47 0.12 Na2CO3:H2O + Trona -18.90 -19.70 -0.80 NaHCO3:Na2CO3:2H2O + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 5. +------------------------------------ + + PRINT + selected_output true + ADVECTION + cells 1 + shifts 200 + print_frequency 20 + END +------------------------------------ +Beginning of advection calculations. +------------------------------------ + +Beginning of advection time step 1, cumulative pore volumes 1.000000. +Beginning of advection time step 2, cumulative pore volumes 2.000000. +Beginning of advection time step 3, cumulative pore volumes 3.000000. +Beginning of advection time step 4, cumulative pore volumes 4.000000. +Beginning of advection time step 5, cumulative pore volumes 5.000000. +Beginning of advection time step 6, cumulative pore volumes 6.000000. +Beginning of advection time step 7, cumulative pore volumes 7.000000. +Beginning of advection time step 8, cumulative pore volumes 8.000000. +Beginning of advection time step 9, cumulative pore volumes 9.000000. +Beginning of advection time step 10, cumulative pore volumes 10.000000. +Beginning of advection time step 11, cumulative pore volumes 11.000000. +Beginning of advection time step 12, cumulative pore volumes 12.000000. +Beginning of advection time step 13, cumulative pore volumes 13.000000. +Beginning of advection time step 14, cumulative pore volumes 14.000000. +Beginning of advection time step 15, cumulative pore volumes 15.000000. +Beginning of advection time step 16, cumulative pore volumes 16.000000. +Beginning of advection time step 17, cumulative pore volumes 17.000000. +Beginning of advection time step 18, cumulative pore volumes 18.000000. +Beginning of advection time step 19, cumulative pore volumes 19.000000. +Beginning of advection time step 20, cumulative pore volumes 20.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 5.212e-02 5.085e-02 -1.272e-03 + Dolomite 0.00 -17.09 -17.09 1.576e+00 1.575e+00 -1.774e-04 + +------------------------------Surface composition------------------------------ + +Hfo + -2.907e-03 Surface charge, eq + -1.559e-02 sigma, C/m**2 + -5.497e-02 psi, V + 2.140e+00 -F*psi/RT + 8.498e+00 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.310e-02 0.759 5.310e-02 -1.275 + Hfo_wO- 8.255e-03 0.118 8.256e-03 -2.083 + Hfo_wOH2+ 7.823e-03 0.112 7.824e-03 -2.107 + Hfo_wOHAsO4-3 8.244e-04 0.012 8.245e-04 -3.084 + Hfo_wOHSO4-2 6.801e-07 0.000 6.802e-07 -6.167 + Hfo_wHAsO4- 4.008e-07 0.000 4.008e-07 -6.397 + Hfo_wSO4- 5.024e-08 0.000 5.024e-08 -7.299 + Hfo_wH2AsO4 1.911e-09 0.000 1.911e-09 -8.719 + Hfo_wOCa+ 4.391e-12 0.000 4.391e-12 -11.357 + Hfo_wOMg+ 3.252e-12 0.000 3.252e-12 -11.488 + Hfo_wH2AsO3 4.273e-34 0.000 4.274e-34 -33.369 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + NaX 6.110e-01 6.110e-01 6.110e-01 -0.000 + CaX2 1.325e-01 2.651e-01 2.651e-01 -0.000 + MgX2 6.194e-02 1.239e-01 1.239e-01 -0.000 + HX 6.196e-07 6.196e-07 6.196e-07 -0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.542e-07 1.542e-07 + C 8.747e-03 8.746e-03 + Ca 1.972e-05 1.972e-05 + Cl 1.337e-04 1.337e-04 + Mg 1.279e-05 1.279e-05 + Na 9.850e-03 9.850e-03 + S 2.350e-04 2.350e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.051 Charge balance + pe = 11.554 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.065e-02 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 9.399e-03 + Total CO2 (mol/kg) = 8.747e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -8.721e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.44 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.552976e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.251e-05 1.125e-05 -4.903 -4.949 -0.046 + H+ 9.756e-10 8.892e-10 -9.011 -9.051 -0.040 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +As(3) 5.893e-38 + H3AsO3 3.122e-38 3.130e-38 -37.506 -37.504 0.001 + H2AsO3- 2.771e-38 2.492e-38 -37.557 -37.603 -0.046 + HAsO3-2 0.000e+00 0.000e+00 -43.068 -43.252 -0.184 + H4AsO3+ 0.000e+00 0.000e+00 -46.814 -46.860 -0.046 + AsO3-3 0.000e+00 0.000e+00 -49.487 -49.901 -0.414 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -316.500 -316.546 -0.046 + As3S4(HS)2- 0.000e+00 0.000e+00 -949.494 -949.540 -0.046 +As(5) 1.542e-07 + HAsO4-2 1.521e-07 9.955e-08 -6.818 -7.002 -0.184 + H2AsO4- 1.423e-09 1.280e-09 -8.847 -8.893 -0.046 + AsO4-3 6.505e-10 2.506e-10 -9.187 -9.601 -0.414 + H3AsO4 2.265e-16 2.270e-16 -15.645 -15.644 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -145.291 -145.290 0.001 +C(4) 8.747e-03 + HCO3- 8.041e-03 7.259e-03 -2.095 -2.139 -0.044 + CO3-2 5.765e-04 3.828e-04 -3.239 -3.417 -0.178 + NaCO3- 6.950e-05 6.252e-05 -4.158 -4.204 -0.046 + NaHCO3 3.571e-05 3.580e-05 -4.447 -4.446 0.001 + CO2 1.448e-05 1.452e-05 -4.839 -4.838 0.001 + CaCO3 5.536e-06 5.550e-06 -5.257 -5.256 0.001 + MgCO3 2.336e-06 2.341e-06 -5.632 -5.631 0.001 + CaHCO3+ 8.907e-07 8.011e-07 -6.050 -6.096 -0.046 + MgHCO3+ 6.052e-07 5.444e-07 -6.218 -6.264 -0.046 +Ca 1.972e-05 + Ca+2 1.304e-05 8.653e-06 -4.885 -5.063 -0.178 + CaCO3 5.536e-06 5.550e-06 -5.257 -5.256 0.001 + CaHCO3+ 8.907e-07 8.011e-07 -6.050 -6.096 -0.046 + CaSO4 2.584e-07 2.590e-07 -6.588 -6.587 0.001 + CaOH+ 1.795e-09 1.614e-09 -8.746 -8.792 -0.046 + CaHSO4+ 1.500e-15 1.349e-15 -14.824 -14.870 -0.046 +Cl 1.337e-04 + Cl- 1.337e-04 1.200e-04 -3.874 -3.921 -0.047 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.362 -44.361 0.001 +Mg 1.279e-05 + Mg+2 9.592e-06 6.409e-06 -5.018 -5.193 -0.175 + MgCO3 2.336e-06 2.341e-06 -5.632 -5.631 0.001 + MgHCO3+ 6.052e-07 5.444e-07 -6.218 -6.264 -0.046 + MgSO4 2.249e-07 2.254e-07 -6.648 -6.647 0.001 + MgOH+ 2.909e-08 2.616e-08 -7.536 -7.582 -0.046 +Na 9.850e-03 + Na+ 9.738e-03 8.769e-03 -2.012 -2.057 -0.045 + NaCO3- 6.950e-05 6.252e-05 -4.158 -4.204 -0.046 + NaHCO3 3.571e-05 3.580e-05 -4.447 -4.446 0.001 + NaSO4- 7.331e-06 6.594e-06 -5.135 -5.181 -0.046 +O(0) 4.375e-04 + O2 2.187e-04 2.193e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -143.968 -144.014 -0.046 + S5-2 0.000e+00 0.000e+00 -144.409 -144.559 -0.149 + S4-2 0.000e+00 0.000e+00 -144.635 -144.793 -0.157 + S6-2 0.000e+00 0.000e+00 -144.702 -144.845 -0.143 + H2S 0.000e+00 0.000e+00 -146.125 -146.124 0.001 + S-2 0.000e+00 0.000e+00 -147.697 -147.882 -0.184 + S3-2 0.000e+00 0.000e+00 -148.080 -148.246 -0.165 + S2-2 0.000e+00 0.000e+00 -149.319 -149.492 -0.172 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -316.500 -316.546 -0.046 + As3S4(HS)2- 0.000e+00 0.000e+00 -949.494 -949.540 -0.046 +S(6) 2.350e-04 + SO4-2 2.272e-04 1.500e-04 -3.644 -3.824 -0.180 + NaSO4- 7.331e-06 6.594e-06 -5.135 -5.181 -0.046 + CaSO4 2.584e-07 2.590e-07 -6.588 -6.587 0.001 + MgSO4 2.249e-07 2.254e-07 -6.648 -6.647 0.001 + HSO4- 1.442e-11 1.297e-11 -10.841 -10.887 -0.046 + CaHSO4+ 1.500e-15 1.349e-15 -14.824 -14.870 -0.046 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -4.53 -8.89 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Arsenolite -73.63 -75.01 -1.38 As2O3 + Artinite -5.30 4.30 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -39.52 -31.29 8.23 As2O5 + As2S3(am) -489.30 -534.20 -44.90 As2S3 + As_native -86.79 -99.32 -12.53 As + Brucite -3.93 12.91 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -15.49 -34.39 -18.91 Ca3(AsO4)2:4H2O + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -142.43 -145.29 -2.86 CH4 + Claudetite -73.67 -75.01 -1.34 As2O3 + CO2(g) -3.37 -4.84 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -6.88 -9.02 -2.14 MgSO4:7H2O + Gypsum -4.31 -8.89 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -145.13 -146.12 -1.00 H2S + Halite -7.56 -5.98 1.58 NaCl + Huntite -4.34 -34.31 -29.97 CaMg3(CO3)4 + Hydromagnesite -12.77 -21.53 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.58 -8.61 -8.03 MgCO3 + Mirabilite -6.83 -7.94 -1.11 Na2SO4:10H2O + Nahcolite -3.65 -4.20 -0.55 NaHCO3 + Natron -6.22 -7.53 -1.31 Na2CO3:10H2O + Nesquehonite -2.99 -8.61 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -487.90 -534.20 -46.30 As2S3 + Portlandite -9.76 13.04 22.80 Ca(OH)2 + Realgar -191.23 -211.17 -19.94 AsS + Sulfur -109.75 -124.77 -15.03 S + Thenardite -7.76 -7.94 -0.18 Na2SO4 + Thermonatrite -7.66 -7.53 0.12 Na2CO3:H2O + Trona -10.93 -11.73 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 21, cumulative pore volumes 21.000000. +Beginning of advection time step 22, cumulative pore volumes 22.000000. +Beginning of advection time step 23, cumulative pore volumes 23.000000. +Beginning of advection time step 24, cumulative pore volumes 24.000000. +Beginning of advection time step 25, cumulative pore volumes 25.000000. +Beginning of advection time step 26, cumulative pore volumes 26.000000. +Beginning of advection time step 27, cumulative pore volumes 27.000000. +Beginning of advection time step 28, cumulative pore volumes 28.000000. +Beginning of advection time step 29, cumulative pore volumes 29.000000. +Beginning of advection time step 30, cumulative pore volumes 30.000000. +Beginning of advection time step 31, cumulative pore volumes 31.000000. +Beginning of advection time step 32, cumulative pore volumes 32.000000. +Beginning of advection time step 33, cumulative pore volumes 33.000000. +Beginning of advection time step 34, cumulative pore volumes 34.000000. +Beginning of advection time step 35, cumulative pore volumes 35.000000. +Beginning of advection time step 36, cumulative pore volumes 36.000000. +Beginning of advection time step 37, cumulative pore volumes 37.000000. +Beginning of advection time step 38, cumulative pore volumes 38.000000. +Beginning of advection time step 39, cumulative pore volumes 39.000000. +Beginning of advection time step 40, cumulative pore volumes 40.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 2.832e-02 2.720e-02 -1.117e-03 + Dolomite -0.00 -17.09 -17.09 1.573e+00 1.573e+00 -5.221e-05 + +------------------------------Surface composition------------------------------ + +Hfo + -1.480e-03 Surface charge, eq + -7.936e-03 sigma, C/m**2 + -3.318e-02 psi, V + 1.291e+00 -F*psi/RT + 3.638e+00 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.308e-02 0.758 5.308e-02 -1.275 + Hfo_wOH2+ 8.547e-03 0.122 8.548e-03 -2.068 + Hfo_wO- 7.550e-03 0.108 7.551e-03 -2.122 + Hfo_wOHAsO4-3 8.229e-04 0.012 8.229e-04 -3.085 + Hfo_wOHSO4-2 3.772e-06 0.000 3.772e-06 -5.423 + Hfo_wHAsO4- 4.779e-07 0.000 4.779e-07 -6.321 + Hfo_wSO4- 3.045e-07 0.000 3.046e-07 -6.516 + Hfo_wH2AsO4 2.490e-09 0.000 2.490e-09 -8.604 + Hfo_wOCa+ 1.877e-12 0.000 1.877e-12 -11.727 + Hfo_wOMg+ 1.390e-12 0.000 1.390e-12 -11.857 + Hfo_wH2AsO3 5.569e-34 0.000 5.569e-34 -33.254 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + NaX 4.267e-01 4.267e-01 4.267e-01 -0.000 + CaX2 1.954e-01 3.907e-01 3.907e-01 -0.000 + MgX2 9.130e-02 1.826e-01 1.826e-01 -0.000 + HX 1.203e-06 1.203e-06 1.203e-06 -0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 3.060e-08 3.059e-08 + C 8.341e-03 8.341e-03 + Ca 4.111e-05 4.111e-05 + Cl 1.337e-04 1.337e-04 + Mg 2.852e-05 2.851e-05 + Na 8.966e-03 8.965e-03 + S 2.347e-04 2.347e-04 + +----------------------------Description of solution---------------------------- + + pH = 8.644 Charge balance + pe = 11.961 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.555e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 8.564e-03 + Total CO2 (mol/kg) = 8.341e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.232e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.34 + Iterations = 12 + Total H = 1.110124e+02 + Total O = 5.552854e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.877e-06 4.408e-06 -5.312 -5.356 -0.044 + H+ 2.481e-09 2.270e-09 -8.605 -8.644 -0.039 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +As(3) 5.480e-38 + H3AsO3 4.072e-38 4.081e-38 -37.390 -37.389 0.001 + H2AsO3- 1.408e-38 1.273e-38 -37.851 -37.895 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -43.776 -43.951 -0.176 + H4AsO3+ 0.000e+00 0.000e+00 -46.294 -46.338 -0.044 + AsO3-3 0.000e+00 0.000e+00 -50.612 -51.008 -0.395 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -315.151 -315.195 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -944.628 -944.672 -0.044 +As(5) 3.060e-08 + HAsO4-2 2.983e-08 1.991e-08 -7.525 -7.701 -0.176 + H2AsO4- 7.228e-10 6.533e-10 -9.141 -9.185 -0.044 + AsO4-3 4.875e-11 1.963e-11 -10.312 -10.707 -0.395 + H3AsO4 2.953e-16 2.959e-16 -15.530 -15.529 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -144.883 -144.882 0.001 +C(4) 8.341e-03 + HCO3- 8.013e-03 7.267e-03 -2.096 -2.139 -0.042 + CO3-2 2.219e-04 1.501e-04 -3.654 -3.824 -0.170 + CO2 3.702e-05 3.711e-05 -4.432 -4.431 0.001 + NaHCO3 3.284e-05 3.292e-05 -4.484 -4.483 0.001 + NaCO3- 2.491e-05 2.251e-05 -4.604 -4.648 -0.044 + CaCO3 5.537e-06 5.550e-06 -5.257 -5.256 0.001 + MgCO3 2.336e-06 2.341e-06 -5.631 -5.631 0.001 + CaHCO3+ 2.263e-06 2.045e-06 -5.645 -5.689 -0.044 + MgHCO3+ 1.538e-06 1.390e-06 -5.813 -5.857 -0.044 +Ca 4.111e-05 + Ca+2 3.264e-05 2.207e-05 -4.486 -4.656 -0.170 + CaCO3 5.537e-06 5.550e-06 -5.257 -5.256 0.001 + CaHCO3+ 2.263e-06 2.045e-06 -5.645 -5.689 -0.044 + CaSO4 6.701e-07 6.716e-07 -6.174 -6.173 0.001 + CaOH+ 1.784e-09 1.613e-09 -8.749 -8.792 -0.044 + CaHSO4+ 9.883e-15 8.933e-15 -14.005 -14.049 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.207e-04 -3.874 -3.918 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.362 -44.361 0.001 +Mg 2.852e-05 + Mg+2 2.403e-05 1.635e-05 -4.619 -4.787 -0.167 + MgCO3 2.336e-06 2.341e-06 -5.631 -5.631 0.001 + MgHCO3+ 1.538e-06 1.390e-06 -5.813 -5.857 -0.044 + MgSO4 5.832e-07 5.845e-07 -6.234 -6.233 0.001 + MgOH+ 2.891e-08 2.613e-08 -7.539 -7.583 -0.044 +Na 8.966e-03 + Na+ 8.901e-03 8.054e-03 -2.051 -2.094 -0.043 + NaHCO3 3.284e-05 3.292e-05 -4.484 -4.483 0.001 + NaCO3- 2.491e-05 2.251e-05 -4.604 -4.648 -0.044 + NaSO4- 6.812e-06 6.158e-06 -5.167 -5.211 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -143.556 -143.600 -0.044 + S5-2 0.000e+00 0.000e+00 -144.407 -144.551 -0.144 + S4-2 0.000e+00 0.000e+00 -144.634 -144.785 -0.151 + S6-2 0.000e+00 0.000e+00 -144.700 -144.837 -0.137 + H2S 0.000e+00 0.000e+00 -145.303 -145.302 0.001 + S-2 0.000e+00 0.000e+00 -147.699 -147.874 -0.176 + S3-2 0.000e+00 0.000e+00 -148.080 -148.238 -0.158 + S2-2 0.000e+00 0.000e+00 -149.319 -149.484 -0.165 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -315.151 -315.195 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -944.628 -944.672 -0.044 +S(6) 2.347e-04 + SO4-2 2.266e-04 1.525e-04 -3.645 -3.817 -0.172 + NaSO4- 6.812e-06 6.158e-06 -5.167 -5.211 -0.044 + CaSO4 6.701e-07 6.716e-07 -6.174 -6.173 0.001 + MgSO4 5.832e-07 5.845e-07 -6.234 -6.233 0.001 + HSO4- 3.725e-11 3.367e-11 -10.429 -10.473 -0.044 + CaHSO4+ 9.883e-15 8.933e-15 -14.005 -14.049 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -4.11 -8.47 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Arsenolite -73.40 -74.78 -1.38 As2O3 + Artinite -5.71 3.89 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -39.29 -31.06 8.23 As2O5 + As2S3(am) -486.61 -531.51 -44.90 As2S3 + As_native -86.67 -99.20 -12.53 As + Brucite -4.34 12.50 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -16.48 -35.38 -18.91 Ca3(AsO4)2:4H2O + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -142.02 -144.88 -2.86 CH4 + Claudetite -73.44 -74.78 -1.34 As2O3 + CO2(g) -2.96 -4.43 -1.47 CO2 + Dolomite -0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -6.46 -8.60 -2.14 MgSO4:7H2O + Gypsum -3.89 -8.47 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -144.31 -145.30 -1.00 H2S + Halite -7.59 -6.01 1.58 NaCl + Huntite -4.34 -34.31 -29.97 CaMg3(CO3)4 + Hydromagnesite -13.18 -21.94 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.58 -8.61 -8.03 MgCO3 + Mirabilite -6.89 -8.01 -1.11 Na2SO4:10H2O + Nahcolite -3.68 -4.23 -0.55 NaHCO3 + Natron -6.70 -8.01 -1.31 Na2CO3:10H2O + Nesquehonite -2.99 -8.61 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -485.21 -531.51 -46.30 As2S3 + Portlandite -10.17 12.63 22.80 Ca(OH)2 + Realgar -190.29 -210.24 -19.94 AsS + Sulfur -108.93 -123.95 -15.03 S + Thenardite -7.83 -8.00 -0.18 Na2SO4 + Thermonatrite -8.14 -8.01 0.12 Na2CO3:H2O + Trona -11.45 -12.24 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 41, cumulative pore volumes 41.000000. +Beginning of advection time step 42, cumulative pore volumes 42.000000. +Beginning of advection time step 43, cumulative pore volumes 43.000000. +Beginning of advection time step 44, cumulative pore volumes 44.000000. +Beginning of advection time step 45, cumulative pore volumes 45.000000. +Beginning of advection time step 46, cumulative pore volumes 46.000000. +Beginning of advection time step 47, cumulative pore volumes 47.000000. +Beginning of advection time step 48, cumulative pore volumes 48.000000. +Beginning of advection time step 49, cumulative pore volumes 49.000000. +Beginning of advection time step 50, cumulative pore volumes 50.000000. +Beginning of advection time step 51, cumulative pore volumes 51.000000. +Beginning of advection time step 52, cumulative pore volumes 52.000000. +Beginning of advection time step 53, cumulative pore volumes 53.000000. +Beginning of advection time step 54, cumulative pore volumes 54.000000. +Beginning of advection time step 55, cumulative pore volumes 55.000000. +Beginning of advection time step 56, cumulative pore volumes 56.000000. +Beginning of advection time step 57, cumulative pore volumes 57.000000. +Beginning of advection time step 58, cumulative pore volumes 58.000000. +Beginning of advection time step 59, cumulative pore volumes 59.000000. +Beginning of advection time step 60, cumulative pore volumes 60.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 7.030e-03 6.028e-03 -1.002e-03 + Dolomite 0.00 -17.09 -17.09 1.573e+00 1.573e+00 1.267e-05 + +------------------------------Surface composition------------------------------ + +Hfo + -2.886e-04 Surface charge, eq + -1.547e-03 sigma, C/m**2 + -7.102e-03 psi, V + 2.764e-01 -F*psi/RT + 1.318e+00 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.296e-02 0.757 5.296e-02 -1.276 + Hfo_wOH2+ 9.213e-03 0.132 9.213e-03 -2.036 + Hfo_wO- 6.974e-03 0.100 6.975e-03 -2.156 + Hfo_wOHAsO4-3 8.225e-04 0.012 8.226e-04 -3.085 + Hfo_wOHSO4-2 2.832e-05 0.000 2.833e-05 -4.548 + Hfo_wSO4- 2.470e-06 0.000 2.470e-06 -5.607 + Hfo_wHAsO4- 5.574e-07 0.000 5.574e-07 -6.254 + Hfo_wH2AsO4 3.138e-09 0.000 3.138e-09 -8.503 + Hfo_wOCa+ 6.903e-13 0.000 6.904e-13 -12.161 + Hfo_wOMg+ 5.113e-13 0.000 5.114e-13 -12.291 + Hfo_wH2AsO3 7.018e-34 0.000 7.018e-34 -33.154 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + NaX 2.571e-01 2.571e-01 2.571e-01 0.000 + CaX2 2.531e-01 5.063e-01 5.063e-01 0.000 + MgX2 1.183e-01 2.366e-01 2.366e-01 0.000 + HX 2.343e-06 2.343e-06 2.343e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 4.506e-09 4.505e-09 + C 8.097e-03 8.096e-03 + Ca 1.123e-04 1.123e-04 + Cl 1.337e-04 1.337e-04 + Mg 8.089e-05 8.089e-05 + Na 8.229e-03 8.229e-03 + S 2.318e-04 2.318e-04 + +----------------------------Description of solution---------------------------- + + pH = 8.170 Charge balance + pe = 12.436 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.032e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 8.078e-03 + Total CO2 (mol/kg) = 8.097e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.959e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.35 + Iterations = 11 + Total H = 1.110124e+02 + Total O = 5.552779e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.632e-06 1.479e-06 -5.787 -5.830 -0.043 + H+ 7.382e-09 6.767e-09 -8.132 -8.170 -0.038 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +As(3) 5.738e-38 + H3AsO3 5.143e-38 5.154e-38 -37.289 -37.288 0.001 + H2AsO3- 5.950e-39 5.392e-39 -38.225 -38.268 -0.043 + HAsO3-2 0.000e+00 0.000e+00 -44.627 -44.799 -0.171 + H4AsO3+ 0.000e+00 0.000e+00 -45.720 -45.762 -0.043 + AsO3-3 0.000e+00 0.000e+00 -51.944 -52.329 -0.385 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -313.638 -313.680 -0.043 + As3S4(HS)2- 0.000e+00 0.000e+00 -939.137 -939.180 -0.043 +As(5) 4.506e-09 + HAsO4-2 4.198e-09 2.830e-09 -8.377 -8.548 -0.171 + H2AsO4- 3.055e-10 2.768e-10 -9.515 -9.558 -0.043 + AsO4-3 2.274e-12 9.362e-13 -11.643 -12.029 -0.385 + H3AsO4 3.729e-16 3.737e-16 -15.428 -15.427 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -144.416 -144.415 0.001 +C(4) 8.097e-03 + HCO3- 7.859e-03 7.144e-03 -2.105 -2.146 -0.041 + CO2 1.085e-04 1.087e-04 -3.965 -3.964 0.001 + CO3-2 7.251e-05 4.951e-05 -4.140 -4.305 -0.166 + NaHCO3 2.977e-05 2.983e-05 -4.526 -4.525 0.001 + NaCO3- 7.555e-06 6.846e-06 -5.122 -5.165 -0.043 + CaHCO3+ 6.728e-06 6.097e-06 -5.172 -5.215 -0.043 + CaCO3 5.538e-06 5.550e-06 -5.257 -5.256 0.001 + MgHCO3+ 4.572e-06 4.143e-06 -5.340 -5.383 -0.043 + MgCO3 2.337e-06 2.341e-06 -5.631 -5.631 0.001 +Ca 1.123e-04 + Ca+2 9.805e-05 6.691e-05 -4.009 -4.175 -0.166 + CaHCO3+ 6.728e-06 6.097e-06 -5.172 -5.215 -0.043 + CaCO3 5.538e-06 5.550e-06 -5.257 -5.256 0.001 + CaSO4 2.008e-06 2.013e-06 -5.697 -5.696 0.001 + CaOH+ 1.810e-09 1.640e-09 -8.742 -8.785 -0.043 + CaHSO4+ 8.806e-14 7.979e-14 -13.055 -13.098 -0.043 +Cl 1.337e-04 + Cl- 1.337e-04 1.210e-04 -3.874 -3.917 -0.044 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 8.089e-05 + Mg+2 7.221e-05 4.956e-05 -4.141 -4.305 -0.163 + MgHCO3+ 4.572e-06 4.143e-06 -5.340 -5.383 -0.043 + MgCO3 2.337e-06 2.341e-06 -5.631 -5.631 0.001 + MgSO4 1.748e-06 1.752e-06 -5.757 -5.757 0.001 + MgOH+ 2.934e-08 2.658e-08 -7.533 -7.575 -0.043 +Na 8.229e-03 + Na+ 8.186e-03 7.425e-03 -2.087 -2.129 -0.042 + NaHCO3 2.977e-05 2.983e-05 -4.526 -4.525 0.001 + NaCO3- 7.555e-06 6.846e-06 -5.122 -5.165 -0.043 + NaSO4- 6.192e-06 5.611e-06 -5.208 -5.251 -0.043 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -143.088 -143.131 -0.043 + H2S 0.000e+00 0.000e+00 -144.359 -144.359 0.001 + S5-2 0.000e+00 0.000e+00 -144.415 -144.556 -0.141 + S4-2 0.000e+00 0.000e+00 -144.642 -144.790 -0.148 + S6-2 0.000e+00 0.000e+00 -144.707 -144.842 -0.135 + S-2 0.000e+00 0.000e+00 -147.708 -147.879 -0.171 + S3-2 0.000e+00 0.000e+00 -148.088 -148.243 -0.155 + S2-2 0.000e+00 0.000e+00 -149.328 -149.489 -0.161 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -313.638 -313.680 -0.043 + As3S4(HS)2- 0.000e+00 0.000e+00 -939.137 -939.180 -0.043 +S(6) 2.318e-04 + SO4-2 2.219e-04 1.508e-04 -3.654 -3.822 -0.168 + NaSO4- 6.192e-06 5.611e-06 -5.208 -5.251 -0.043 + CaSO4 2.008e-06 2.013e-06 -5.697 -5.696 0.001 + MgSO4 1.748e-06 1.752e-06 -5.757 -5.757 0.001 + HSO4- 1.095e-10 9.919e-11 -9.961 -10.004 -0.043 + CaHSO4+ 8.806e-14 7.979e-14 -13.055 -13.098 -0.043 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.64 -8.00 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Arsenolite -73.20 -74.58 -1.38 As2O3 + Artinite -6.18 3.42 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -39.08 -30.85 8.23 As2O5 + As2S3(am) -483.58 -528.48 -44.90 As2S3 + As_native -86.57 -99.10 -12.53 As + Brucite -4.81 12.03 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -17.68 -36.58 -18.91 Ca3(AsO4)2:4H2O + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -141.56 -144.42 -2.86 CH4 + Claudetite -73.24 -74.58 -1.34 As2O3 + CO2(g) -2.50 -3.96 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -5.99 -8.13 -2.14 MgSO4:7H2O + Gypsum -3.42 -8.00 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -143.36 -144.36 -1.00 H2S + Halite -7.63 -6.05 1.58 NaCl + Huntite -4.34 -34.31 -29.97 CaMg3(CO3)4 + Hydromagnesite -13.65 -22.41 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.58 -8.61 -8.03 MgCO3 + Mirabilite -6.97 -8.08 -1.11 Na2SO4:10H2O + Nahcolite -3.73 -4.28 -0.55 NaHCO3 + Natron -7.25 -8.57 -1.31 Na2CO3:10H2O + Nesquehonite -2.99 -8.61 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -482.18 -528.48 -46.30 As2S3 + Portlandite -10.64 12.16 22.80 Ca(OH)2 + Realgar -189.25 -209.19 -19.94 AsS + Sulfur -107.98 -123.01 -15.03 S + Thenardite -7.90 -8.08 -0.18 Na2SO4 + Thermonatrite -8.69 -8.56 0.12 Na2CO3:H2O + Trona -12.04 -12.84 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 61, cumulative pore volumes 61.000000. +Beginning of advection time step 62, cumulative pore volumes 62.000000. +Beginning of advection time step 63, cumulative pore volumes 63.000000. +Beginning of advection time step 64, cumulative pore volumes 64.000000. +Beginning of advection time step 65, cumulative pore volumes 65.000000. +Beginning of advection time step 66, cumulative pore volumes 66.000000. +Beginning of advection time step 67, cumulative pore volumes 67.000000. +Beginning of advection time step 68, cumulative pore volumes 68.000000. +Beginning of advection time step 69, cumulative pore volumes 69.000000. +Beginning of advection time step 70, cumulative pore volumes 70.000000. +Beginning of advection time step 71, cumulative pore volumes 71.000000. +Beginning of advection time step 72, cumulative pore volumes 72.000000. +Beginning of advection time step 73, cumulative pore volumes 73.000000. +Beginning of advection time step 74, cumulative pore volumes 74.000000. +Beginning of advection time step 75, cumulative pore volumes 75.000000. +Beginning of advection time step 76, cumulative pore volumes 76.000000. +Beginning of advection time step 77, cumulative pore volumes 77.000000. +Beginning of advection time step 78, cumulative pore volumes 78.000000. +Beginning of advection time step 79, cumulative pore volumes 79.000000. +Beginning of advection time step 80, cumulative pore volumes 80.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.01 -8.49 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.568e+00 1.568e+00 -3.004e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 9.677e-04 Surface charge, eq + 5.188e-03 sigma, C/m**2 + 2.356e-02 psi, V + -9.170e-01 -F*psi/RT + 3.997e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.250e-02 0.750 5.251e-02 -1.280 + Hfo_wOH2+ 1.019e-02 0.146 1.019e-02 -1.992 + Hfo_wO- 6.199e-03 0.089 6.199e-03 -2.208 + Hfo_wOHAsO4-3 8.223e-04 0.012 8.224e-04 -3.085 + Hfo_wOHSO4-2 2.636e-04 0.004 2.636e-04 -3.579 + Hfo_wSO4- 2.564e-05 0.000 2.564e-05 -4.591 + Hfo_wHAsO4- 6.933e-07 0.000 6.933e-07 -6.159 + Hfo_wH2AsO4 4.353e-09 0.000 4.353e-09 -8.361 + Hfo_wOCa+ 2.176e-13 0.000 2.176e-13 -12.662 + Hfo_wOMg+ 1.711e-13 0.000 1.712e-13 -12.767 + Hfo_wH2AsO3 9.736e-34 0.000 9.737e-34 -33.012 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 2.972e-01 5.944e-01 5.944e-01 0.000 + MgX2 1.475e-01 2.950e-01 2.950e-01 0.000 + NaX 1.106e-01 1.106e-01 1.106e-01 0.000 + HX 4.756e-06 4.756e-06 4.756e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 5.470e-10 5.469e-10 + C 7.720e-03 7.720e-03 + Ca 4.118e-04 4.117e-04 + Cl 1.337e-04 1.337e-04 + Mg 3.198e-04 3.198e-04 + Na 6.400e-03 6.399e-03 + S 2.072e-04 2.072e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.604 Charge balance + pe = 13.001 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.663e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 7.379e-03 + Total CO2 (mol/kg) = 7.720e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.390e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.41 + Iterations = 13 + Total H = 1.110123e+02 + Total O = 5.552657e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.429e-07 4.020e-07 -6.354 -6.396 -0.042 + H+ 2.712e-08 2.490e-08 -7.567 -7.604 -0.037 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +As(3) 7.424e-38 + H3AsO3 7.198e-38 7.213e-38 -37.143 -37.142 0.001 + H2AsO3- 2.259e-39 2.051e-39 -38.646 -38.688 -0.042 + H4AsO3+ 0.000e+00 0.000e+00 -45.009 -45.051 -0.042 + HAsO3-2 0.000e+00 0.000e+00 -45.616 -45.784 -0.168 + AsO3-3 0.000e+00 0.000e+00 -53.502 -53.880 -0.378 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -311.923 -311.965 -0.042 + As3S4(HS)2- 0.000e+00 0.000e+00 -932.861 -932.903 -0.042 +As(5) 5.470e-10 + HAsO4-2 4.309e-10 2.926e-10 -9.366 -9.534 -0.168 + H2AsO4- 1.160e-10 1.053e-10 -9.936 -9.978 -0.042 + AsO4-3 6.288e-14 2.631e-14 -13.202 -13.580 -0.378 + H3AsO4 5.219e-16 5.230e-16 -15.282 -15.282 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.884 -143.883 0.001 +C(4) 7.720e-03 + HCO3- 7.261e-03 6.611e-03 -2.139 -2.180 -0.041 + CO2 3.694e-04 3.702e-04 -3.432 -3.432 0.001 + CaHCO3+ 2.398e-05 2.177e-05 -4.620 -4.662 -0.042 + NaHCO3 2.149e-05 2.153e-05 -4.668 -4.667 0.001 + CO3-2 1.812e-05 1.245e-05 -4.742 -4.905 -0.163 + MgHCO3+ 1.730e-05 1.571e-05 -4.762 -4.804 -0.042 + CaCO3 5.375e-06 5.385e-06 -5.270 -5.269 0.001 + MgCO3 2.408e-06 2.413e-06 -5.618 -5.617 0.001 + NaCO3- 1.479e-06 1.343e-06 -5.830 -5.872 -0.042 +Ca 4.118e-04 + Ca+2 3.757e-04 2.581e-04 -3.425 -3.588 -0.163 + CaHCO3+ 2.398e-05 2.177e-05 -4.620 -4.662 -0.042 + CaSO4 6.687e-06 6.700e-06 -5.175 -5.174 0.001 + CaCO3 5.375e-06 5.385e-06 -5.270 -5.269 0.001 + CaOH+ 1.895e-09 1.720e-09 -8.722 -8.764 -0.042 + CaHSO4+ 1.077e-12 9.772e-13 -11.968 -12.010 -0.042 +Cl 1.337e-04 + Cl- 1.337e-04 1.212e-04 -3.874 -3.917 -0.043 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 3.198e-04 + Mg+2 2.939e-04 2.030e-04 -3.532 -3.692 -0.161 + MgHCO3+ 1.730e-05 1.571e-05 -4.762 -4.804 -0.042 + MgSO4 6.180e-06 6.192e-06 -5.209 -5.208 0.001 + MgCO3 2.408e-06 2.413e-06 -5.618 -5.617 0.001 + MgOH+ 3.261e-08 2.960e-08 -7.487 -7.529 -0.042 +Na 6.400e-03 + Na+ 6.373e-03 5.791e-03 -2.196 -2.237 -0.042 + NaHCO3 2.149e-05 2.153e-05 -4.668 -4.667 0.001 + NaSO4- 4.160e-06 3.776e-06 -5.381 -5.423 -0.042 + NaCO3- 1.479e-06 1.343e-06 -5.830 -5.872 -0.042 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.587 -142.629 -0.042 + H2S 0.000e+00 0.000e+00 -143.292 -143.291 0.001 + S5-2 0.000e+00 0.000e+00 -144.481 -144.620 -0.139 + S4-2 0.000e+00 0.000e+00 -144.709 -144.854 -0.145 + S6-2 0.000e+00 0.000e+00 -144.773 -144.906 -0.133 + S-2 0.000e+00 0.000e+00 -147.775 -147.943 -0.168 + S3-2 0.000e+00 0.000e+00 -148.155 -148.307 -0.152 + S2-2 0.000e+00 0.000e+00 -149.395 -149.553 -0.158 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -311.923 -311.965 -0.042 + As3S4(HS)2- 0.000e+00 0.000e+00 -932.861 -932.903 -0.042 +S(6) 2.072e-04 + SO4-2 1.902e-04 1.301e-04 -3.721 -3.886 -0.165 + CaSO4 6.687e-06 6.700e-06 -5.175 -5.174 0.001 + MgSO4 6.180e-06 6.192e-06 -5.209 -5.208 0.001 + NaSO4- 4.160e-06 3.776e-06 -5.381 -5.423 -0.042 + HSO4- 3.469e-10 3.149e-10 -9.460 -9.502 -0.042 + CaHSO4+ 1.077e-12 9.772e-13 -11.968 -12.010 -0.042 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.11 -7.47 -4.36 CaSO4 + Aragonite -0.16 -8.49 -8.34 CaCO3 + Arsenolite -72.90 -74.28 -1.38 As2O3 + Artinite -6.68 2.92 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -38.79 -30.56 8.23 As2O5 + As2S3(am) -480.08 -524.98 -44.90 As2S3 + As_native -86.43 -98.96 -12.53 As + Brucite -5.32 11.52 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.02 -37.92 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.01 -8.49 -8.48 CaCO3 + CH4(g) -141.02 -143.88 -2.86 CH4 + Claudetite -72.94 -74.28 -1.34 As2O3 + CO2(g) -1.96 -3.43 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -5.44 -7.58 -2.14 MgSO4:7H2O + Gypsum -2.89 -7.47 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -142.29 -143.29 -1.00 H2S + Halite -7.74 -6.15 1.58 NaCl + Huntite -4.32 -34.28 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.11 -22.87 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.57 -8.60 -8.03 MgCO3 + Mirabilite -7.25 -8.36 -1.11 Na2SO4:10H2O + Nahcolite -3.87 -4.42 -0.55 NaHCO3 + Natron -8.07 -9.38 -1.31 Na2CO3:10H2O + Nesquehonite -2.98 -8.60 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -478.68 -524.98 -46.30 As2S3 + Portlandite -11.18 11.62 22.80 Ca(OH)2 + Realgar -188.04 -207.98 -19.94 AsS + Sulfur -106.91 -121.94 -15.03 S + Thenardite -8.18 -8.36 -0.18 Na2SO4 + Thermonatrite -9.50 -9.38 0.12 Na2CO3:H2O + Trona -13.00 -13.80 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 81, cumulative pore volumes 81.000000. +Beginning of advection time step 82, cumulative pore volumes 82.000000. +Beginning of advection time step 83, cumulative pore volumes 83.000000. +Beginning of advection time step 84, cumulative pore volumes 84.000000. +Beginning of advection time step 85, cumulative pore volumes 85.000000. +Beginning of advection time step 86, cumulative pore volumes 86.000000. +Beginning of advection time step 87, cumulative pore volumes 87.000000. +Beginning of advection time step 88, cumulative pore volumes 88.000000. +Beginning of advection time step 89, cumulative pore volumes 89.000000. +Beginning of advection time step 90, cumulative pore volumes 90.000000. +Beginning of advection time step 91, cumulative pore volumes 91.000000. +Beginning of advection time step 92, cumulative pore volumes 92.000000. +Beginning of advection time step 93, cumulative pore volumes 93.000000. +Beginning of advection time step 94, cumulative pore volumes 94.000000. +Beginning of advection time step 95, cumulative pore volumes 95.000000. +Beginning of advection time step 96, cumulative pore volumes 96.000000. +Beginning of advection time step 97, cumulative pore volumes 97.000000. +Beginning of advection time step 98, cumulative pore volumes 98.000000. +Beginning of advection time step 99, cumulative pore volumes 99.000000. +Beginning of advection time step 100, cumulative pore volumes 100.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.02 -8.50 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 -5.456e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.005e-03 Surface charge, eq + 1.075e-02 sigma, C/m**2 + 4.415e-02 psi, V + -1.719e+00 -F*psi/RT + 1.793e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.116e-02 0.731 5.116e-02 -1.291 + Hfo_wOH2+ 1.176e-02 0.168 1.177e-02 -1.929 + Hfo_wO- 5.096e-03 0.073 5.097e-03 -2.293 + Hfo_wOHSO4-2 1.038e-03 0.015 1.038e-03 -2.984 + Hfo_wOHAsO4-3 8.220e-04 0.012 8.221e-04 -3.085 + Hfo_wSO4- 1.197e-04 0.002 1.197e-04 -3.922 + Hfo_wHAsO4- 9.734e-07 0.000 9.735e-07 -6.012 + Hfo_wH2AsO4 7.244e-09 0.000 7.244e-09 -8.140 + Hfo_wOCa+ 1.086e-13 0.000 1.086e-13 -12.964 + Hfo_wOMg+ 8.842e-14 0.000 8.843e-14 -13.053 + Hfo_wH2AsO3 1.620e-33 0.000 1.620e-33 -32.790 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.218e-01 6.437e-01 6.437e-01 0.000 + MgX2 1.654e-01 3.308e-01 3.308e-01 0.000 + NaX 2.548e-02 2.548e-02 2.548e-02 0.000 + HX 7.530e-06 7.530e-06 7.530e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.811e-10 1.810e-10 + C 7.229e-03 7.228e-03 + Ca 1.222e-03 1.222e-03 + Cl 1.337e-04 1.337e-04 + Mg 9.867e-04 9.866e-04 + Na 2.461e-03 2.461e-03 + S 1.889e-04 1.888e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.182 Charge balance + pe = 13.423 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.921e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.402e-03 + Total CO2 (mol/kg) = 7.229e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.426e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.26 + Iterations = 9 + Total H = 1.110123e+02 + Total O = 5.552502e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.678e-07 1.522e-07 -6.775 -6.818 -0.043 + H+ 7.172e-08 6.577e-08 -7.144 -7.182 -0.038 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.244e-37 + H3AsO3 1.229e-37 1.232e-37 -36.910 -36.909 0.001 + H2AsO3- 1.462e-39 1.326e-39 -38.835 -38.878 -0.043 + H4AsO3+ 0.000e+00 0.000e+00 -44.354 -44.396 -0.043 + HAsO3-2 0.000e+00 0.000e+00 -46.225 -46.396 -0.170 + AsO3-3 0.000e+00 0.000e+00 -54.530 -54.914 -0.383 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -310.604 -310.646 -0.043 + As3S4(HS)2- 0.000e+00 0.000e+00 -928.060 -928.103 -0.043 +As(5) 1.811e-10 + HAsO4-2 1.060e-10 7.159e-11 -9.975 -10.145 -0.170 + H2AsO4- 7.507e-11 6.806e-11 -10.125 -10.167 -0.043 + AsO4-3 5.890e-15 2.437e-15 -14.230 -14.613 -0.383 + H3AsO4 8.914e-16 8.932e-16 -15.050 -15.049 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.527 -143.526 0.001 +C(4) 7.229e-03 + HCO3- 6.259e-03 5.692e-03 -2.204 -2.245 -0.041 + CO2 8.402e-04 8.419e-04 -3.076 -3.075 0.001 + CaHCO3+ 6.233e-05 5.651e-05 -4.205 -4.248 -0.043 + MgHCO3+ 4.658e-05 4.223e-05 -4.332 -4.374 -0.043 + NaHCO3 7.110e-06 7.125e-06 -5.148 -5.147 0.001 + CO3-2 5.932e-06 4.058e-06 -5.227 -5.392 -0.165 + CaCO3 5.281e-06 5.292e-06 -5.277 -5.276 0.001 + MgCO3 2.450e-06 2.455e-06 -5.611 -5.610 0.001 + NaCO3- 1.856e-07 1.682e-07 -6.732 -6.774 -0.043 +Ca 1.222e-03 + Ca+2 1.138e-03 7.784e-04 -2.944 -3.109 -0.165 + CaHCO3+ 6.233e-05 5.651e-05 -4.205 -4.248 -0.043 + CaSO4 1.640e-05 1.644e-05 -4.785 -4.784 0.001 + CaCO3 5.281e-06 5.292e-06 -5.277 -5.276 0.001 + CaOH+ 2.166e-09 1.964e-09 -8.664 -8.707 -0.043 + CaHSO4+ 6.986e-12 6.334e-12 -11.156 -11.198 -0.043 +Cl 1.337e-04 + Cl- 1.337e-04 1.210e-04 -3.874 -3.917 -0.043 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.360 0.001 +Mg 9.867e-04 + Mg+2 9.219e-04 6.340e-04 -3.035 -3.198 -0.163 + MgHCO3+ 4.658e-05 4.223e-05 -4.332 -4.374 -0.043 + MgSO4 1.570e-05 1.573e-05 -4.804 -4.803 0.001 + MgCO3 2.450e-06 2.455e-06 -5.611 -5.610 0.001 + MgOH+ 3.860e-08 3.499e-08 -7.413 -7.456 -0.043 +Na 2.461e-03 + Na+ 2.453e-03 2.226e-03 -2.610 -2.652 -0.042 + NaHCO3 7.110e-06 7.125e-06 -5.148 -5.147 0.001 + NaSO4- 1.302e-06 1.181e-06 -5.885 -5.928 -0.043 + NaCO3- 1.856e-07 1.682e-07 -6.732 -6.774 -0.043 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.254 -142.297 -0.043 + H2S 0.000e+00 0.000e+00 -142.538 -142.537 0.001 + S5-2 0.000e+00 0.000e+00 -144.569 -144.710 -0.140 + S4-2 0.000e+00 0.000e+00 -144.797 -144.944 -0.147 + S6-2 0.000e+00 0.000e+00 -144.862 -144.996 -0.134 + S-2 0.000e+00 0.000e+00 -147.862 -148.033 -0.170 + S3-2 0.000e+00 0.000e+00 -148.243 -148.397 -0.154 + S2-2 0.000e+00 0.000e+00 -149.483 -149.643 -0.160 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -310.604 -310.646 -0.043 + As3S4(HS)2- 0.000e+00 0.000e+00 -928.060 -928.103 -0.043 +S(6) 1.889e-04 + SO4-2 1.554e-04 1.058e-04 -3.808 -3.975 -0.167 + CaSO4 1.640e-05 1.644e-05 -4.785 -4.784 0.001 + MgSO4 1.570e-05 1.573e-05 -4.804 -4.803 0.001 + NaSO4- 1.302e-06 1.181e-06 -5.885 -5.928 -0.043 + HSO4- 7.465e-10 6.768e-10 -9.127 -9.170 -0.043 + CaHSO4+ 6.986e-12 6.334e-12 -11.156 -11.198 -0.043 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.72 -7.08 -4.36 CaSO4 + Aragonite -0.16 -8.50 -8.34 CaCO3 + Arsenolite -72.44 -73.82 -1.38 As2O3 + Artinite -7.02 2.58 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -38.33 -30.10 8.23 As2O5 + As2S3(am) -477.35 -522.25 -44.90 As2S3 + As_native -86.19 -98.72 -12.53 As + Brucite -5.67 11.17 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.65 -38.55 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.02 -8.50 -8.48 CaCO3 + CH4(g) -140.67 -143.53 -2.86 CH4 + Claudetite -72.48 -73.82 -1.34 As2O3 + CO2(g) -1.61 -3.07 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -5.03 -7.17 -2.14 MgSO4:7H2O + Gypsum -2.50 -7.08 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.54 -142.54 -1.00 H2S + Halite -8.15 -6.57 1.58 NaCl + Huntite -4.30 -34.27 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.43 -23.19 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.56 -8.59 -8.03 MgCO3 + Mirabilite -8.17 -9.28 -1.11 Na2SO4:10H2O + Nahcolite -4.35 -4.90 -0.55 NaHCO3 + Natron -9.39 -10.70 -1.31 Na2CO3:10H2O + Nesquehonite -2.97 -8.59 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -475.95 -522.25 -46.30 As2S3 + Portlandite -11.55 11.25 22.80 Ca(OH)2 + Realgar -187.05 -206.99 -19.94 AsS + Sulfur -106.16 -121.19 -15.03 S + Thenardite -9.10 -9.28 -0.18 Na2SO4 + Thermonatrite -10.82 -10.70 0.12 Na2CO3:H2O + Trona -14.80 -15.59 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 101, cumulative pore volumes 101.000000. +Beginning of advection time step 102, cumulative pore volumes 102.000000. +Beginning of advection time step 103, cumulative pore volumes 103.000000. +Beginning of advection time step 104, cumulative pore volumes 104.000000. +Beginning of advection time step 105, cumulative pore volumes 105.000000. +Beginning of advection time step 106, cumulative pore volumes 106.000000. +Beginning of advection time step 107, cumulative pore volumes 107.000000. +Beginning of advection time step 108, cumulative pore volumes 108.000000. +Beginning of advection time step 109, cumulative pore volumes 109.000000. +Beginning of advection time step 110, cumulative pore volumes 110.000000. +Beginning of advection time step 111, cumulative pore volumes 111.000000. +Beginning of advection time step 112, cumulative pore volumes 112.000000. +Beginning of advection time step 113, cumulative pore volumes 113.000000. +Beginning of advection time step 114, cumulative pore volumes 114.000000. +Beginning of advection time step 115, cumulative pore volumes 115.000000. +Beginning of advection time step 116, cumulative pore volumes 116.000000. +Beginning of advection time step 117, cumulative pore volumes 117.000000. +Beginning of advection time step 118, cumulative pore volumes 118.000000. +Beginning of advection time step 119, cumulative pore volumes 119.000000. +Beginning of advection time step 120, cumulative pore volumes 120.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.02 -8.50 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 1.153e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.333e-03 Surface charge, eq + 1.251e-02 sigma, C/m**2 + 4.866e-02 psi, V + -1.894e+00 -F*psi/RT + 1.505e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 5.018e-02 0.717 5.018e-02 -1.299 + Hfo_wOH2+ 1.268e-02 0.181 1.268e-02 -1.897 + Hfo_wO- 4.548e-03 0.065 4.548e-03 -2.342 + Hfo_wOHSO4-2 1.569e-03 0.022 1.569e-03 -2.804 + Hfo_wOHAsO4-3 8.218e-04 0.012 8.219e-04 -3.085 + Hfo_wSO4- 1.988e-04 0.003 1.988e-04 -3.702 + Hfo_wHAsO4- 1.176e-06 0.000 1.176e-06 -5.930 + Hfo_wH2AsO4 9.617e-09 0.000 9.618e-09 -8.017 + Hfo_wOCa+ 9.482e-14 0.000 9.482e-14 -13.023 + Hfo_wOMg+ 7.699e-14 0.000 7.699e-14 -13.114 + Hfo_wH2AsO3 2.151e-33 0.000 2.151e-33 -32.667 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.292e-01 6.584e-01 6.584e-01 0.000 + MgX2 1.687e-01 3.373e-01 3.373e-01 0.000 + NaX 4.301e-03 4.301e-03 4.301e-03 0.000 + HX 8.461e-06 8.461e-06 8.461e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.623e-10 1.623e-10 + C 7.117e-03 7.117e-03 + Ca 1.709e-03 1.709e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.376e-03 1.376e-03 + Na 4.854e-04 4.853e-04 + S 2.190e-04 2.189e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.065 Charge balance + pe = 13.540 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.464e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.091e-03 + Total CO2 (mol/kg) = 7.117e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.811e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.552481e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.285e-07 1.162e-07 -6.891 -6.935 -0.044 + H+ 9.412e-08 8.614e-08 -7.026 -7.065 -0.038 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.679e-37 + H3AsO3 1.664e-37 1.667e-37 -36.779 -36.778 0.001 + H2AsO3- 1.515e-39 1.370e-39 -38.819 -38.863 -0.044 + H4AsO3+ 0.000e+00 0.000e+00 -44.104 -44.148 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -46.324 -46.498 -0.175 + AsO3-3 0.000e+00 0.000e+00 -54.740 -55.134 -0.393 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -310.049 -310.093 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -926.164 -926.208 -0.044 +As(5) 1.623e-10 + HAsO4-2 8.450e-11 5.650e-11 -10.073 -10.248 -0.175 + H2AsO4- 7.779e-11 7.035e-11 -10.109 -10.153 -0.044 + AsO4-3 3.632e-15 1.468e-15 -14.440 -14.833 -0.393 + H3AsO4 1.206e-15 1.209e-15 -14.918 -14.918 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.435 -143.434 0.001 +C(4) 7.117e-03 + HCO3- 5.922e-03 5.373e-03 -2.228 -2.270 -0.042 + CO2 1.039e-03 1.041e-03 -2.984 -2.983 0.001 + CaHCO3+ 8.197e-05 7.412e-05 -4.086 -4.130 -0.044 + MgHCO3+ 6.106e-05 5.522e-05 -4.214 -4.258 -0.044 + CaCO3 5.289e-06 5.300e-06 -5.277 -5.276 0.001 + CO3-2 4.317e-06 2.925e-06 -5.365 -5.534 -0.169 + MgCO3 2.446e-06 2.452e-06 -5.612 -5.611 0.001 + NaHCO3 1.320e-06 1.323e-06 -5.879 -5.878 0.001 + NaCO3- 2.638e-08 2.385e-08 -7.579 -7.622 -0.044 +Ca 1.709e-03 + Ca+2 1.597e-03 1.082e-03 -2.797 -2.966 -0.169 + CaHCO3+ 8.197e-05 7.412e-05 -4.086 -4.130 -0.044 + CaSO4 2.473e-05 2.478e-05 -4.607 -4.606 0.001 + CaCO3 5.289e-06 5.300e-06 -5.277 -5.276 0.001 + CaOH+ 2.304e-09 2.083e-09 -8.638 -8.681 -0.044 + CaHSO4+ 1.383e-11 1.251e-11 -10.859 -10.903 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.207e-04 -3.874 -3.918 -0.044 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.376e-03 + Mg+2 1.289e-03 8.783e-04 -2.890 -3.056 -0.167 + MgHCO3+ 6.106e-05 5.522e-05 -4.214 -4.258 -0.044 + MgSO4 2.359e-05 2.364e-05 -4.627 -4.626 0.001 + MgCO3 2.446e-06 2.452e-06 -5.612 -5.611 0.001 + MgOH+ 4.093e-08 3.701e-08 -7.388 -7.432 -0.044 +Na 4.854e-04 + Na+ 4.837e-04 4.379e-04 -3.315 -3.359 -0.043 + NaHCO3 1.320e-06 1.323e-06 -5.879 -5.878 0.001 + NaSO4- 2.787e-07 2.520e-07 -6.555 -6.599 -0.044 + NaCO3- 2.638e-08 2.385e-08 -7.579 -7.622 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.100 -142.144 -0.044 + H2S 0.000e+00 0.000e+00 -142.268 -142.267 0.001 + S5-2 0.000e+00 0.000e+00 -144.531 -144.674 -0.143 + S4-2 0.000e+00 0.000e+00 -144.758 -144.908 -0.150 + S6-2 0.000e+00 0.000e+00 -144.823 -144.960 -0.137 + S-2 0.000e+00 0.000e+00 -147.822 -147.997 -0.175 + S3-2 0.000e+00 0.000e+00 -148.203 -148.361 -0.158 + S2-2 0.000e+00 0.000e+00 -149.443 -149.607 -0.164 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -310.049 -310.093 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -926.164 -926.208 -0.044 +S(6) 2.190e-04 + SO4-2 1.704e-04 1.148e-04 -3.769 -3.940 -0.171 + CaSO4 2.473e-05 2.478e-05 -4.607 -4.606 0.001 + MgSO4 2.359e-05 2.364e-05 -4.627 -4.626 0.001 + NaSO4- 2.787e-07 2.520e-07 -6.555 -6.599 -0.044 + HSO4- 1.064e-09 9.618e-10 -8.973 -9.017 -0.044 + CaHSO4+ 1.383e-11 1.251e-11 -10.859 -10.903 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.55 -6.91 -4.36 CaSO4 + Aragonite -0.16 -8.50 -8.34 CaCO3 + Arsenolite -72.18 -73.56 -1.38 As2O3 + Artinite -7.12 2.48 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -38.06 -29.83 8.23 As2O5 + As2S3(am) -476.28 -521.18 -44.90 As2S3 + As_native -86.06 -98.59 -12.53 As + Brucite -5.77 11.07 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.66 -38.56 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.02 -8.50 -8.48 CaCO3 + CH4(g) -140.57 -143.43 -2.86 CH4 + Claudetite -72.22 -73.56 -1.34 As2O3 + CO2(g) -1.51 -2.98 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.86 -7.00 -2.14 MgSO4:7H2O + Gypsum -2.33 -6.91 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.27 -142.27 -1.00 H2S + Halite -8.86 -7.28 1.58 NaCl + Huntite -4.30 -34.27 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.53 -23.29 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.56 -8.59 -8.03 MgCO3 + Mirabilite -9.54 -10.66 -1.11 Na2SO4:10H2O + Nahcolite -5.08 -5.63 -0.55 NaHCO3 + Natron -10.94 -12.25 -1.31 Na2CO3:10H2O + Nesquehonite -2.97 -8.59 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -474.88 -521.18 -46.30 As2S3 + Portlandite -11.64 11.16 22.80 Ca(OH)2 + Realgar -186.65 -206.59 -19.94 AsS + Sulfur -105.89 -120.92 -15.03 S + Thenardite -10.48 -10.66 -0.18 Na2SO4 + Thermonatrite -12.38 -12.25 0.12 Na2CO3:H2O + Trona -17.08 -17.88 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 121, cumulative pore volumes 121.000000. +Beginning of advection time step 122, cumulative pore volumes 122.000000. +Beginning of advection time step 123, cumulative pore volumes 123.000000. +Beginning of advection time step 124, cumulative pore volumes 124.000000. +Beginning of advection time step 125, cumulative pore volumes 125.000000. +Beginning of advection time step 126, cumulative pore volumes 126.000000. +Beginning of advection time step 127, cumulative pore volumes 127.000000. +Beginning of advection time step 128, cumulative pore volumes 128.000000. +Beginning of advection time step 129, cumulative pore volumes 129.000000. +Beginning of advection time step 130, cumulative pore volumes 130.000000. +Beginning of advection time step 131, cumulative pore volumes 131.000000. +Beginning of advection time step 132, cumulative pore volumes 132.000000. +Beginning of advection time step 133, cumulative pore volumes 133.000000. +Beginning of advection time step 134, cumulative pore volumes 134.000000. +Beginning of advection time step 135, cumulative pore volumes 135.000000. +Beginning of advection time step 136, cumulative pore volumes 136.000000. +Beginning of advection time step 137, cumulative pore volumes 137.000000. +Beginning of advection time step 138, cumulative pore volumes 138.000000. +Beginning of advection time step 139, cumulative pore volumes 139.000000. +Beginning of advection time step 140, cumulative pore volumes 140.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.02 -8.50 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 2.132e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.378e-03 Surface charge, eq + 1.275e-02 sigma, C/m**2 + 4.912e-02 psi, V + -1.912e+00 -F*psi/RT + 1.478e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 4.994e-02 0.713 4.994e-02 -1.302 + Hfo_wOH2+ 1.289e-02 0.184 1.289e-02 -1.890 + Hfo_wO- 4.431e-03 0.063 4.431e-03 -2.353 + Hfo_wOHSO4-2 1.698e-03 0.024 1.698e-03 -2.770 + Hfo_wOHAsO4-3 8.218e-04 0.012 8.218e-04 -3.085 + Hfo_wSO4- 2.198e-04 0.003 2.198e-04 -3.658 + Hfo_wHAsO4- 1.226e-06 0.000 1.226e-06 -5.911 + Hfo_wH2AsO4 1.025e-08 0.000 1.025e-08 -7.989 + Hfo_wOCa+ 9.387e-14 0.000 9.387e-14 -13.027 + Hfo_wOMg+ 7.538e-14 0.000 7.538e-14 -13.123 + Hfo_wH2AsO3 2.291e-33 0.000 2.292e-33 -32.640 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.314e-01 6.627e-01 6.627e-01 -0.000 + MgX2 1.679e-01 3.358e-01 3.358e-01 -0.000 + NaX 1.435e-03 1.435e-03 1.435e-03 -0.000 + HX 8.602e-06 8.602e-06 8.602e-06 -0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.640e-10 1.639e-10 + C 7.115e-03 7.115e-03 + Ca 1.806e-03 1.805e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.438e-03 1.438e-03 + Na 1.658e-04 1.658e-04 + S 2.323e-04 2.323e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.048 Charge balance + pe = 13.558 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.599e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.055e-03 + Total CO2 (mol/kg) = 7.115e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.682e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 10 + Total H = 1.110125e+02 + Total O = 5.552485e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.236e-07 1.117e-07 -6.908 -6.952 -0.044 + H+ 9.795e-08 8.960e-08 -7.009 -7.048 -0.039 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.797e-37 + H3AsO3 1.781e-37 1.785e-37 -36.749 -36.748 0.001 + H2AsO3- 1.561e-39 1.410e-39 -38.807 -38.851 -0.044 + H4AsO3+ 0.000e+00 0.000e+00 -44.057 -44.101 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -46.327 -46.503 -0.176 + AsO3-3 0.000e+00 0.000e+00 -54.759 -55.155 -0.396 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.927 -309.971 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.763 -925.807 -0.044 +As(5) 1.640e-10 + HAsO4-2 8.383e-11 5.591e-11 -10.077 -10.253 -0.176 + H2AsO4- 8.012e-11 7.240e-11 -10.096 -10.140 -0.044 + AsO4-3 3.475e-15 1.397e-15 -14.459 -14.855 -0.396 + H3AsO4 1.291e-15 1.294e-15 -14.889 -14.888 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.421 -143.420 0.001 +C(4) 7.115e-03 + HCO3- 5.882e-03 5.333e-03 -2.230 -2.273 -0.043 + CO2 1.072e-03 1.075e-03 -2.970 -2.969 0.001 + CaHCO3+ 8.579e-05 7.752e-05 -4.067 -4.111 -0.044 + MgHCO3+ 6.320e-05 5.711e-05 -4.199 -4.243 -0.044 + CaCO3 5.318e-06 5.330e-06 -5.274 -5.273 0.001 + CO3-2 4.130e-06 2.792e-06 -5.384 -5.554 -0.170 + MgCO3 2.433e-06 2.438e-06 -5.614 -5.613 0.001 + NaHCO3 4.474e-07 4.484e-07 -6.349 -6.348 0.001 + NaCO3- 8.600e-09 7.772e-09 -8.065 -8.109 -0.044 +Ca 1.806e-03 + Ca+2 1.687e-03 1.140e-03 -2.773 -2.943 -0.170 + CaHCO3+ 8.579e-05 7.752e-05 -4.067 -4.111 -0.044 + CaSO4 2.733e-05 2.739e-05 -4.563 -4.562 0.001 + CaCO3 5.318e-06 5.330e-06 -5.274 -5.273 0.001 + CaOH+ 2.336e-09 2.111e-09 -8.632 -8.676 -0.044 + CaHSO4+ 1.591e-11 1.437e-11 -10.798 -10.842 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.206e-04 -3.874 -3.919 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.438e-03 + Mg+2 1.346e-03 9.152e-04 -2.871 -3.038 -0.168 + MgHCO3+ 6.320e-05 5.711e-05 -4.199 -4.243 -0.044 + MgSO4 2.578e-05 2.584e-05 -4.589 -4.588 0.001 + MgCO3 2.433e-06 2.438e-06 -5.614 -5.613 0.001 + MgOH+ 4.103e-08 3.708e-08 -7.387 -7.431 -0.044 +Na 1.658e-04 + Na+ 1.653e-04 1.495e-04 -3.782 -3.825 -0.043 + NaHCO3 4.474e-07 4.484e-07 -6.349 -6.348 0.001 + NaSO4- 9.987e-08 9.025e-08 -7.001 -7.045 -0.044 + NaCO3- 8.600e-09 7.772e-09 -8.065 -8.109 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.062 -142.106 -0.044 + H2S 0.000e+00 0.000e+00 -142.213 -142.212 0.001 + S5-2 0.000e+00 0.000e+00 -144.510 -144.654 -0.144 + S4-2 0.000e+00 0.000e+00 -144.737 -144.888 -0.151 + S6-2 0.000e+00 0.000e+00 -144.802 -144.940 -0.138 + S-2 0.000e+00 0.000e+00 -147.801 -147.977 -0.176 + S3-2 0.000e+00 0.000e+00 -148.182 -148.341 -0.159 + S2-2 0.000e+00 0.000e+00 -149.422 -149.587 -0.165 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.927 -309.971 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.763 -925.807 -0.044 +S(6) 2.323e-04 + SO4-2 1.791e-04 1.204e-04 -3.747 -3.919 -0.172 + CaSO4 2.733e-05 2.739e-05 -4.563 -4.562 0.001 + MgSO4 2.578e-05 2.584e-05 -4.589 -4.588 0.001 + NaSO4- 9.987e-08 9.025e-08 -7.001 -7.045 -0.044 + HSO4- 1.161e-09 1.049e-09 -8.935 -8.979 -0.044 + CaHSO4+ 1.591e-11 1.437e-11 -10.798 -10.842 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.50 -6.86 -4.36 CaSO4 + Aragonite -0.16 -8.50 -8.34 CaCO3 + Arsenolite -72.12 -73.50 -1.38 As2O3 + Artinite -7.14 2.46 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -38.00 -29.78 8.23 As2O5 + As2S3(am) -476.06 -520.96 -44.90 As2S3 + As_native -86.03 -98.56 -12.53 As + Brucite -5.78 11.06 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.63 -38.54 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.02 -8.50 -8.48 CaCO3 + CH4(g) -140.56 -143.42 -2.86 CH4 + Claudetite -72.16 -73.50 -1.34 As2O3 + CO2(g) -1.50 -2.97 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.82 -6.96 -2.14 MgSO4:7H2O + Gypsum -2.28 -6.86 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.22 -142.21 -1.00 H2S + Halite -9.33 -7.74 1.58 NaCl + Huntite -4.31 -34.28 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.55 -23.31 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.56 -8.59 -8.03 MgCO3 + Mirabilite -10.46 -11.57 -1.11 Na2SO4:10H2O + Nahcolite -5.55 -6.10 -0.55 NaHCO3 + Natron -11.89 -13.21 -1.31 Na2CO3:10H2O + Nesquehonite -2.97 -8.59 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -474.66 -520.96 -46.30 As2S3 + Portlandite -11.65 11.15 22.80 Ca(OH)2 + Realgar -186.56 -206.51 -19.94 AsS + Sulfur -105.84 -120.86 -15.03 S + Thenardite -11.39 -11.57 -0.18 Na2SO4 + Thermonatrite -13.33 -13.20 0.12 Na2CO3:H2O + Trona -18.51 -19.30 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 141, cumulative pore volumes 141.000000. +Beginning of advection time step 142, cumulative pore volumes 142.000000. +Beginning of advection time step 143, cumulative pore volumes 143.000000. +Beginning of advection time step 144, cumulative pore volumes 144.000000. +Beginning of advection time step 145, cumulative pore volumes 145.000000. +Beginning of advection time step 146, cumulative pore volumes 146.000000. +Beginning of advection time step 147, cumulative pore volumes 147.000000. +Beginning of advection time step 148, cumulative pore volumes 148.000000. +Beginning of advection time step 149, cumulative pore volumes 149.000000. +Beginning of advection time step 150, cumulative pore volumes 150.000000. +Beginning of advection time step 151, cumulative pore volumes 151.000000. +Beginning of advection time step 152, cumulative pore volumes 152.000000. +Beginning of advection time step 153, cumulative pore volumes 153.000000. +Beginning of advection time step 154, cumulative pore volumes 154.000000. +Beginning of advection time step 155, cumulative pore volumes 155.000000. +Beginning of advection time step 156, cumulative pore volumes 156.000000. +Beginning of advection time step 157, cumulative pore volumes 157.000000. +Beginning of advection time step 158, cumulative pore volumes 158.000000. +Beginning of advection time step 159, cumulative pore volumes 159.000000. +Beginning of advection time step 160, cumulative pore volumes 160.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.02 -8.50 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 1.465e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.383e-03 Surface charge, eq + 1.278e-02 sigma, C/m**2 + 4.916e-02 psi, V + -1.914e+00 -F*psi/RT + 1.476e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 4.990e-02 0.713 4.990e-02 -1.302 + Hfo_wOH2+ 1.292e-02 0.185 1.292e-02 -1.889 + Hfo_wO- 4.414e-03 0.063 4.415e-03 -2.355 + Hfo_wOHSO4-2 1.717e-03 0.025 1.717e-03 -2.765 + Hfo_wOHAsO4-3 8.218e-04 0.012 8.218e-04 -3.085 + Hfo_wSO4- 2.229e-04 0.003 2.229e-04 -3.652 + Hfo_wHAsO4- 1.234e-06 0.000 1.234e-06 -5.909 + Hfo_wH2AsO4 1.034e-08 0.000 1.034e-08 -7.985 + Hfo_wOCa+ 9.423e-14 0.000 9.423e-14 -13.026 + Hfo_wOMg+ 7.486e-14 0.000 7.487e-14 -13.126 + Hfo_wH2AsO3 2.312e-33 0.000 2.313e-33 -32.636 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.327e-01 6.654e-01 6.654e-01 0.000 + MgX2 1.668e-01 3.335e-01 3.335e-01 0.000 + NaX 1.101e-03 1.101e-03 1.101e-03 0.000 + HX 8.612e-06 8.612e-06 8.612e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.645e-10 1.645e-10 + C 7.117e-03 7.116e-03 + Ca 1.825e-03 1.825e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.438e-03 1.438e-03 + Na 1.276e-04 1.276e-04 + S 2.347e-04 2.347e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.046 Charge balance + pe = 13.560 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.619e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.052e-03 + Total CO2 (mol/kg) = 7.117e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.135e-08 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110125e+02 + Total O = 5.552486e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.231e-07 1.112e-07 -6.910 -6.954 -0.044 + H+ 9.840e-08 9.000e-08 -7.007 -7.046 -0.039 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.814e-37 + H3AsO3 1.799e-37 1.802e-37 -36.745 -36.744 0.001 + H2AsO3- 1.569e-39 1.418e-39 -38.804 -38.848 -0.044 + H4AsO3+ 0.000e+00 0.000e+00 -44.051 -44.095 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -46.327 -46.503 -0.176 + AsO3-3 0.000e+00 0.000e+00 -54.761 -55.157 -0.396 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.909 -309.953 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.705 -925.749 -0.044 +As(5) 1.645e-10 + HAsO4-2 8.392e-11 5.595e-11 -10.076 -10.252 -0.176 + H2AsO4- 8.055e-11 7.279e-11 -10.094 -10.138 -0.044 + AsO4-3 3.465e-15 1.392e-15 -14.460 -14.856 -0.396 + H3AsO4 1.304e-15 1.307e-15 -14.885 -14.884 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.420 -143.419 0.001 +C(4) 7.117e-03 + HCO3- 5.878e-03 5.330e-03 -2.231 -2.273 -0.043 + CO2 1.076e-03 1.079e-03 -2.968 -2.967 0.001 + CaHCO3+ 8.665e-05 7.829e-05 -4.062 -4.106 -0.044 + MgHCO3+ 6.315e-05 5.707e-05 -4.200 -4.244 -0.044 + CaCO3 5.347e-06 5.358e-06 -5.272 -5.271 0.001 + CO3-2 4.110e-06 2.777e-06 -5.386 -5.556 -0.170 + MgCO3 2.420e-06 2.425e-06 -5.616 -5.615 0.001 + NaHCO3 3.441e-07 3.449e-07 -6.463 -6.462 0.001 + NaCO3- 6.585e-09 5.951e-09 -8.181 -8.225 -0.044 +Ca 1.825e-03 + Ca+2 1.706e-03 1.152e-03 -2.768 -2.939 -0.171 + CaHCO3+ 8.665e-05 7.829e-05 -4.062 -4.106 -0.044 + CaSO4 2.787e-05 2.793e-05 -4.555 -4.554 0.001 + CaCO3 5.347e-06 5.358e-06 -5.272 -5.271 0.001 + CaOH+ 2.350e-09 2.123e-09 -8.629 -8.673 -0.044 + CaHSO4+ 1.630e-11 1.473e-11 -10.788 -10.832 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.206e-04 -3.874 -3.919 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.438e-03 + Mg+2 1.347e-03 9.151e-04 -2.871 -3.039 -0.168 + MgHCO3+ 6.315e-05 5.707e-05 -4.200 -4.244 -0.044 + MgSO4 2.601e-05 2.607e-05 -4.585 -4.584 0.001 + MgCO3 2.420e-06 2.425e-06 -5.616 -5.615 0.001 + MgOH+ 4.085e-08 3.691e-08 -7.389 -7.433 -0.044 +Na 1.276e-04 + Na+ 1.272e-04 1.151e-04 -3.895 -3.939 -0.044 + NaHCO3 3.441e-07 3.449e-07 -6.463 -6.462 0.001 + NaSO4- 7.756e-08 7.009e-08 -7.110 -7.154 -0.044 + NaCO3- 6.585e-09 5.951e-09 -8.181 -8.225 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.056 -142.101 -0.044 + H2S 0.000e+00 0.000e+00 -142.206 -142.205 0.001 + S5-2 0.000e+00 0.000e+00 -144.506 -144.650 -0.144 + S4-2 0.000e+00 0.000e+00 -144.733 -144.884 -0.151 + S6-2 0.000e+00 0.000e+00 -144.798 -144.936 -0.138 + S-2 0.000e+00 0.000e+00 -147.797 -147.973 -0.176 + S3-2 0.000e+00 0.000e+00 -148.178 -148.337 -0.159 + S2-2 0.000e+00 0.000e+00 -149.418 -149.583 -0.165 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.909 -309.953 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.705 -925.749 -0.044 +S(6) 2.347e-04 + SO4-2 1.808e-04 1.215e-04 -3.743 -3.915 -0.172 + CaSO4 2.787e-05 2.793e-05 -4.555 -4.554 0.001 + MgSO4 2.601e-05 2.607e-05 -4.585 -4.584 0.001 + NaSO4- 7.756e-08 7.009e-08 -7.110 -7.154 -0.044 + HSO4- 1.177e-09 1.063e-09 -8.929 -8.973 -0.044 + CaHSO4+ 1.630e-11 1.473e-11 -10.788 -10.832 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.49 -6.85 -4.36 CaSO4 + Aragonite -0.16 -8.50 -8.34 CaCO3 + Arsenolite -72.11 -73.49 -1.38 As2O3 + Artinite -7.14 2.46 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -38.00 -29.77 8.23 As2O5 + As2S3(am) -476.03 -520.93 -44.90 As2S3 + As_native -86.03 -98.56 -12.53 As + Brucite -5.79 11.05 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.62 -38.53 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.02 -8.50 -8.48 CaCO3 + CH4(g) -140.56 -143.42 -2.86 CH4 + Claudetite -72.15 -73.49 -1.34 As2O3 + CO2(g) -1.50 -2.97 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.81 -6.95 -2.14 MgSO4:7H2O + Gypsum -2.27 -6.85 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.21 -142.20 -1.00 H2S + Halite -9.44 -7.86 1.58 NaCl + Huntite -4.31 -34.28 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.57 -23.33 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.57 -8.59 -8.03 MgCO3 + Mirabilite -10.68 -11.79 -1.11 Na2SO4:10H2O + Nahcolite -5.66 -6.21 -0.55 NaHCO3 + Natron -12.12 -13.44 -1.31 Na2CO3:10H2O + Nesquehonite -2.97 -8.60 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -474.63 -520.93 -46.30 As2S3 + Portlandite -11.65 11.15 22.80 Ca(OH)2 + Realgar -186.55 -206.50 -19.94 AsS + Sulfur -105.83 -120.85 -15.03 S + Thenardite -11.61 -11.79 -0.18 Na2SO4 + Thermonatrite -13.56 -13.43 0.12 Na2CO3:H2O + Trona -18.85 -19.65 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 161, cumulative pore volumes 161.000000. +Beginning of advection time step 162, cumulative pore volumes 162.000000. +Beginning of advection time step 163, cumulative pore volumes 163.000000. +Beginning of advection time step 164, cumulative pore volumes 164.000000. +Beginning of advection time step 165, cumulative pore volumes 165.000000. +Beginning of advection time step 166, cumulative pore volumes 166.000000. +Beginning of advection time step 167, cumulative pore volumes 167.000000. +Beginning of advection time step 168, cumulative pore volumes 168.000000. +Beginning of advection time step 169, cumulative pore volumes 169.000000. +Beginning of advection time step 170, cumulative pore volumes 170.000000. +Beginning of advection time step 171, cumulative pore volumes 171.000000. +Beginning of advection time step 172, cumulative pore volumes 172.000000. +Beginning of advection time step 173, cumulative pore volumes 173.000000. +Beginning of advection time step 174, cumulative pore volumes 174.000000. +Beginning of advection time step 175, cumulative pore volumes 175.000000. +Beginning of advection time step 176, cumulative pore volumes 176.000000. +Beginning of advection time step 177, cumulative pore volumes 177.000000. +Beginning of advection time step 178, cumulative pore volumes 178.000000. +Beginning of advection time step 179, cumulative pore volumes 179.000000. +Beginning of advection time step 180, cumulative pore volumes 180.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.01 -8.49 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 1.206e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.384e-03 Surface charge, eq + 1.278e-02 sigma, C/m**2 + 4.916e-02 psi, V + -1.913e+00 -F*psi/RT + 1.476e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 4.990e-02 0.713 4.990e-02 -1.302 + Hfo_wOH2+ 1.292e-02 0.185 1.293e-02 -1.889 + Hfo_wO- 4.413e-03 0.063 4.413e-03 -2.355 + Hfo_wOHSO4-2 1.719e-03 0.025 1.719e-03 -2.765 + Hfo_wOHAsO4-3 8.218e-04 0.012 8.218e-04 -3.085 + Hfo_wSO4- 2.232e-04 0.003 2.232e-04 -3.651 + Hfo_wHAsO4- 1.235e-06 0.000 1.235e-06 -5.908 + Hfo_wH2AsO4 1.035e-08 0.000 1.035e-08 -7.985 + Hfo_wOCa+ 9.467e-14 0.000 9.468e-14 -13.024 + Hfo_wOMg+ 7.451e-14 0.000 7.452e-14 -13.128 + Hfo_wH2AsO3 2.314e-33 0.000 2.314e-33 -32.636 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.337e-01 6.675e-01 6.675e-01 -0.000 + MgX2 1.657e-01 3.315e-01 3.315e-01 -0.000 + NaX 1.062e-03 1.062e-03 1.062e-03 -0.000 + HX 8.606e-06 8.606e-06 8.606e-06 -0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.646e-10 1.646e-10 + C 7.117e-03 7.117e-03 + Ca 1.835e-03 1.834e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.432e-03 1.432e-03 + Na 1.233e-04 1.233e-04 + S 2.351e-04 2.351e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.046 Charge balance + pe = 13.560 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.623e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.053e-03 + Total CO2 (mol/kg) = 7.117e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.004e-09 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 10 + Total H = 1.110125e+02 + Total O = 5.552487e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.230e-07 1.112e-07 -6.910 -6.954 -0.044 + H+ 9.842e-08 9.002e-08 -7.007 -7.046 -0.039 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.816e-37 + H3AsO3 1.800e-37 1.804e-37 -36.745 -36.744 0.001 + H2AsO3- 1.570e-39 1.419e-39 -38.804 -38.848 -0.044 + H4AsO3+ 0.000e+00 0.000e+00 -44.050 -44.094 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -46.326 -46.502 -0.176 + AsO3-3 0.000e+00 0.000e+00 -54.761 -55.157 -0.396 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.907 -309.951 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.700 -925.744 -0.044 +As(5) 1.646e-10 + HAsO4-2 8.397e-11 5.598e-11 -10.076 -10.252 -0.176 + H2AsO4- 8.061e-11 7.284e-11 -10.094 -10.138 -0.044 + AsO4-3 3.467e-15 1.392e-15 -14.460 -14.856 -0.396 + H3AsO4 1.305e-15 1.308e-15 -14.884 -14.883 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.420 -143.419 0.001 +C(4) 7.117e-03 + HCO3- 5.878e-03 5.330e-03 -2.231 -2.273 -0.043 + CO2 1.077e-03 1.079e-03 -2.968 -2.967 0.001 + CaHCO3+ 8.707e-05 7.868e-05 -4.060 -4.104 -0.044 + MgHCO3+ 6.287e-05 5.681e-05 -4.202 -4.246 -0.044 + CaCO3 5.372e-06 5.384e-06 -5.270 -5.269 0.001 + CO3-2 4.109e-06 2.777e-06 -5.386 -5.556 -0.170 + MgCO3 2.408e-06 2.414e-06 -5.618 -5.617 0.001 + NaHCO3 3.323e-07 3.331e-07 -6.478 -6.477 0.001 + NaCO3- 6.359e-09 5.746e-09 -8.197 -8.241 -0.044 +Ca 1.835e-03 + Ca+2 1.714e-03 1.157e-03 -2.766 -2.937 -0.171 + CaHCO3+ 8.707e-05 7.868e-05 -4.060 -4.104 -0.044 + CaSO4 2.804e-05 2.810e-05 -4.552 -4.551 0.001 + CaCO3 5.372e-06 5.384e-06 -5.270 -5.269 0.001 + CaOH+ 2.361e-09 2.133e-09 -8.627 -8.671 -0.044 + CaHSO4+ 1.640e-11 1.482e-11 -10.785 -10.829 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.206e-04 -3.874 -3.919 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.432e-03 + Mg+2 1.341e-03 9.110e-04 -2.873 -3.040 -0.168 + MgHCO3+ 6.287e-05 5.681e-05 -4.202 -4.246 -0.044 + MgSO4 2.593e-05 2.599e-05 -4.586 -4.585 0.001 + MgCO3 2.408e-06 2.414e-06 -5.618 -5.617 0.001 + MgOH+ 4.065e-08 3.673e-08 -7.391 -7.435 -0.044 +Na 1.233e-04 + Na+ 1.228e-04 1.111e-04 -3.911 -3.954 -0.044 + NaHCO3 3.323e-07 3.331e-07 -6.478 -6.477 0.001 + NaSO4- 7.500e-08 6.777e-08 -7.125 -7.169 -0.044 + NaCO3- 6.359e-09 5.746e-09 -8.197 -8.241 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.056 -142.100 -0.044 + H2S 0.000e+00 0.000e+00 -142.205 -142.204 0.001 + S5-2 0.000e+00 0.000e+00 -144.505 -144.649 -0.144 + S4-2 0.000e+00 0.000e+00 -144.732 -144.883 -0.151 + S6-2 0.000e+00 0.000e+00 -144.797 -144.935 -0.138 + S-2 0.000e+00 0.000e+00 -147.796 -147.972 -0.176 + S3-2 0.000e+00 0.000e+00 -148.177 -148.336 -0.159 + S2-2 0.000e+00 0.000e+00 -149.417 -149.582 -0.165 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.907 -309.951 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.700 -925.744 -0.044 +S(6) 2.351e-04 + SO4-2 1.810e-04 1.217e-04 -3.742 -3.915 -0.173 + CaSO4 2.804e-05 2.810e-05 -4.552 -4.551 0.001 + MgSO4 2.593e-05 2.599e-05 -4.586 -4.585 0.001 + NaSO4- 7.500e-08 6.777e-08 -7.125 -7.169 -0.044 + HSO4- 1.179e-09 1.065e-09 -8.929 -8.973 -0.044 + CaHSO4+ 1.640e-11 1.482e-11 -10.785 -10.829 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.49 -6.85 -4.36 CaSO4 + Aragonite -0.16 -8.49 -8.34 CaCO3 + Arsenolite -72.11 -73.49 -1.38 As2O3 + Artinite -7.15 2.45 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -37.99 -29.77 8.23 As2O5 + As2S3(am) -476.02 -520.92 -44.90 As2S3 + As_native -86.03 -98.56 -12.53 As + Brucite -5.79 11.05 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.62 -38.52 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.01 -8.49 -8.48 CaCO3 + CH4(g) -140.56 -143.42 -2.86 CH4 + Claudetite -72.15 -73.49 -1.34 As2O3 + CO2(g) -1.50 -2.97 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.82 -6.96 -2.14 MgSO4:7H2O + Gypsum -2.27 -6.85 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.21 -142.20 -1.00 H2S + Halite -9.45 -7.87 1.58 NaCl + Huntite -4.32 -34.28 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.58 -23.34 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.57 -8.60 -8.03 MgCO3 + Mirabilite -10.71 -11.82 -1.11 Na2SO4:10H2O + Nahcolite -5.68 -6.23 -0.55 NaHCO3 + Natron -12.15 -13.47 -1.31 Na2CO3:10H2O + Nesquehonite -2.98 -8.60 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -474.62 -520.92 -46.30 As2S3 + Portlandite -11.65 11.15 22.80 Ca(OH)2 + Realgar -186.55 -206.49 -19.94 AsS + Sulfur -105.83 -120.85 -15.03 S + Thenardite -11.64 -11.82 -0.18 Na2SO4 + Thermonatrite -13.59 -13.46 0.12 Na2CO3:H2O + Trona -18.90 -19.69 -0.80 NaHCO3:Na2CO3:2H2O + +Beginning of advection time step 181, cumulative pore volumes 181.000000. +Beginning of advection time step 182, cumulative pore volumes 182.000000. +Beginning of advection time step 183, cumulative pore volumes 183.000000. +Beginning of advection time step 184, cumulative pore volumes 184.000000. +Beginning of advection time step 185, cumulative pore volumes 185.000000. +Beginning of advection time step 186, cumulative pore volumes 186.000000. +Beginning of advection time step 187, cumulative pore volumes 187.000000. +Beginning of advection time step 188, cumulative pore volumes 188.000000. +Beginning of advection time step 189, cumulative pore volumes 189.000000. +Beginning of advection time step 190, cumulative pore volumes 190.000000. +Beginning of advection time step 191, cumulative pore volumes 191.000000. +Beginning of advection time step 192, cumulative pore volumes 192.000000. +Beginning of advection time step 193, cumulative pore volumes 193.000000. +Beginning of advection time step 194, cumulative pore volumes 194.000000. +Beginning of advection time step 195, cumulative pore volumes 195.000000. +Beginning of advection time step 196, cumulative pore volumes 196.000000. +Beginning of advection time step 197, cumulative pore volumes 197.000000. +Beginning of advection time step 198, cumulative pore volumes 198.000000. +Beginning of advection time step 199, cumulative pore volumes 199.000000. +Beginning of advection time step 200, cumulative pore volumes 200.000000. + +Cell 1. + +Using solution 1. Solution after simulation 4. +Using exchange 1. Exchange assemblage after simulation 5. +Using surface 1. Surface assemblage after simulation 5. +Using pure phase assemblage 1. Pure-phase assemblage after simulation 5. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite -0.01 -8.49 -8.48 0.000e+00 0.000e+00 + Dolomite 0.00 -17.09 -17.09 1.565e+00 1.565e+00 1.046e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.383e-03 Surface charge, eq + 1.278e-02 sigma, C/m**2 + 4.915e-02 psi, V + -1.913e+00 -F*psi/RT + 1.476e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 1.800e+04 m**2 for 3.000e+01 g + + +Hfo_w + 7.000e-02 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 4.990e-02 0.713 4.990e-02 -1.302 + Hfo_wOH2+ 1.292e-02 0.185 1.292e-02 -1.889 + Hfo_wO- 4.413e-03 0.063 4.414e-03 -2.355 + Hfo_wOHSO4-2 1.719e-03 0.025 1.719e-03 -2.765 + Hfo_wOHAsO4-3 8.218e-04 0.012 8.218e-04 -3.085 + Hfo_wSO4- 2.231e-04 0.003 2.232e-04 -3.651 + Hfo_wHAsO4- 1.234e-06 0.000 1.234e-06 -5.909 + Hfo_wH2AsO4 1.035e-08 0.000 1.035e-08 -7.985 + Hfo_wOCa+ 9.507e-14 0.000 9.508e-14 -13.022 + Hfo_wOMg+ 7.422e-14 0.000 7.422e-14 -13.129 + Hfo_wH2AsO3 2.314e-33 0.000 2.314e-33 -32.636 + +-----------------------------Exchange composition------------------------------ + +X 1.000e+00 mol + + Equiv- Equivalent Log + Species Moles alents Fraction Gamma + + CaX2 3.346e-01 6.693e-01 6.693e-01 0.000 + MgX2 1.648e-01 3.297e-01 3.297e-01 0.000 + NaX 1.058e-03 1.058e-03 1.058e-03 0.000 + HX 8.599e-06 8.599e-06 8.599e-06 0.000 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + As 1.646e-10 1.646e-10 + C 7.117e-03 7.117e-03 + Ca 1.841e-03 1.841e-03 + Cl 1.337e-04 1.337e-04 + Mg 1.426e-03 1.426e-03 + Na 1.228e-04 1.228e-04 + S 2.351e-04 2.351e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.046 Charge balance + pe = 13.559 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.624e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.053e-03 + Total CO2 (mol/kg) = 7.117e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 1.225e-08 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 10 + Total H = 1.110125e+02 + Total O = 5.552487e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.231e-07 1.112e-07 -6.910 -6.954 -0.044 + H+ 9.839e-08 9.000e-08 -7.007 -7.046 -0.039 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +As(3) 1.815e-37 + H3AsO3 1.800e-37 1.804e-37 -36.745 -36.744 0.001 + H2AsO3- 1.570e-39 1.419e-39 -38.804 -38.848 -0.044 + H4AsO3+ 0.000e+00 0.000e+00 -44.051 -44.095 -0.044 + HAsO3-2 0.000e+00 0.000e+00 -46.326 -46.502 -0.176 + AsO3-3 0.000e+00 0.000e+00 -54.760 -55.157 -0.396 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.907 -309.951 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.701 -925.745 -0.044 +As(5) 1.646e-10 + HAsO4-2 8.400e-11 5.600e-11 -10.076 -10.252 -0.176 + H2AsO4- 8.061e-11 7.284e-11 -10.094 -10.138 -0.044 + AsO4-3 3.469e-15 1.393e-15 -14.460 -14.856 -0.396 + H3AsO4 1.305e-15 1.308e-15 -14.884 -14.883 0.001 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -143.420 -143.419 0.001 +C(4) 7.117e-03 + HCO3- 5.879e-03 5.330e-03 -2.231 -2.273 -0.043 + CO2 1.076e-03 1.079e-03 -2.968 -2.967 0.001 + CaHCO3+ 8.741e-05 7.898e-05 -4.058 -4.102 -0.044 + MgHCO3+ 6.260e-05 5.656e-05 -4.203 -4.247 -0.044 + CaCO3 5.394e-06 5.406e-06 -5.268 -5.267 0.001 + CO3-2 4.111e-06 2.778e-06 -5.386 -5.556 -0.170 + MgCO3 2.398e-06 2.404e-06 -5.620 -5.619 0.001 + NaHCO3 3.310e-07 3.317e-07 -6.480 -6.479 0.001 + NaCO3- 6.335e-09 5.724e-09 -8.198 -8.242 -0.044 +Ca 1.841e-03 + Ca+2 1.721e-03 1.162e-03 -2.764 -2.935 -0.171 + CaHCO3+ 8.741e-05 7.898e-05 -4.058 -4.102 -0.044 + CaSO4 2.815e-05 2.821e-05 -4.551 -4.550 0.001 + CaCO3 5.394e-06 5.406e-06 -5.268 -5.267 0.001 + CaOH+ 2.371e-09 2.142e-09 -8.625 -8.669 -0.044 + CaHSO4+ 1.646e-11 1.487e-11 -10.784 -10.828 -0.044 +Cl 1.337e-04 + Cl- 1.337e-04 1.206e-04 -3.874 -3.919 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.361 -44.361 0.001 +Mg 1.426e-03 + Mg+2 1.335e-03 9.069e-04 -2.875 -3.042 -0.168 + MgHCO3+ 6.260e-05 5.656e-05 -4.203 -4.247 -0.044 + MgSO4 2.582e-05 2.587e-05 -4.588 -4.587 0.001 + MgCO3 2.398e-06 2.404e-06 -5.620 -5.619 0.001 + MgOH+ 4.049e-08 3.658e-08 -7.393 -7.437 -0.044 +Na 1.228e-04 + Na+ 1.224e-04 1.107e-04 -3.912 -3.956 -0.044 + NaHCO3 3.310e-07 3.317e-07 -6.480 -6.479 0.001 + NaSO4- 7.471e-08 6.751e-08 -7.127 -7.171 -0.044 + NaCO3- 6.335e-09 5.724e-09 -8.198 -8.242 -0.044 +O(0) 4.375e-04 + O2 2.187e-04 2.192e-04 -3.660 -3.659 0.001 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -142.056 -142.100 -0.044 + H2S 0.000e+00 0.000e+00 -142.205 -142.204 0.001 + S5-2 0.000e+00 0.000e+00 -144.505 -144.649 -0.144 + S4-2 0.000e+00 0.000e+00 -144.732 -144.883 -0.151 + S6-2 0.000e+00 0.000e+00 -144.797 -144.935 -0.138 + S-2 0.000e+00 0.000e+00 -147.796 -147.972 -0.176 + S3-2 0.000e+00 0.000e+00 -148.177 -148.336 -0.159 + S2-2 0.000e+00 0.000e+00 -149.417 -149.582 -0.165 + AsS(OH)(HS)- 0.000e+00 0.000e+00 -309.907 -309.951 -0.044 + As3S4(HS)2- 0.000e+00 0.000e+00 -925.701 -925.745 -0.044 +S(6) 2.351e-04 + SO4-2 1.811e-04 1.217e-04 -3.742 -3.915 -0.173 + CaSO4 2.815e-05 2.821e-05 -4.551 -4.550 0.001 + MgSO4 2.582e-05 2.587e-05 -4.588 -4.587 0.001 + NaSO4- 7.471e-08 6.751e-08 -7.127 -7.171 -0.044 + HSO4- 1.178e-09 1.065e-09 -8.929 -8.973 -0.044 + CaHSO4+ 1.646e-11 1.487e-11 -10.784 -10.828 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.49 -6.85 -4.36 CaSO4 + Aragonite -0.16 -8.49 -8.34 CaCO3 + Arsenolite -72.11 -73.49 -1.38 As2O3 + Artinite -7.15 2.45 9.60 MgCO3:Mg(OH)2:3H2O + As2O5(cr) -37.99 -29.77 8.23 As2O5 + As2S3(am) -476.02 -520.92 -44.90 As2S3 + As_native -86.03 -98.56 -12.53 As + Brucite -5.79 11.05 16.84 Mg(OH)2 + Ca3(AsO4)2:4w -19.61 -38.52 -18.91 Ca3(AsO4)2:4H2O + Calcite -0.01 -8.49 -8.48 CaCO3 + CH4(g) -140.56 -143.42 -2.86 CH4 + Claudetite -72.15 -73.49 -1.34 As2O3 + CO2(g) -1.50 -2.97 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Dolomite(d) -0.55 -17.09 -16.54 CaMg(CO3)2 + Epsomite -4.82 -6.96 -2.14 MgSO4:7H2O + Gypsum -2.27 -6.85 -4.58 CaSO4:2H2O + H2(g) -41.21 -44.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -141.21 -142.20 -1.00 H2S + Halite -9.46 -7.87 1.58 NaCl + Huntite -4.32 -34.29 -29.97 CaMg3(CO3)4 + Hydromagnesite -14.58 -23.35 -8.76 Mg5(CO3)4(OH)2:4H2O + Magnesite -0.57 -8.60 -8.03 MgCO3 + Mirabilite -10.71 -11.83 -1.11 Na2SO4:10H2O + Nahcolite -5.68 -6.23 -0.55 NaHCO3 + Natron -12.16 -13.47 -1.31 Na2CO3:10H2O + Nesquehonite -2.98 -8.60 -5.62 MgCO3:3H2O + O2(g) -0.70 -3.66 -2.96 O2 + Orpiment -474.62 -520.92 -46.30 As2S3 + Portlandite -11.64 11.16 22.80 Ca(OH)2 + Realgar -186.55 -206.49 -19.94 AsS + Sulfur -105.83 -120.85 -15.03 S + Thenardite -11.65 -11.83 -0.18 Na2SO4 + Thermonatrite -13.59 -13.47 0.12 Na2CO3:H2O + Trona -18.90 -19.70 -0.80 NaHCO3:Na2CO3:2H2O + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 6. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex14.sel b/Sun/examples/ex14.sel new file mode 100644 index 00000000..48a4e9ba --- /dev/null +++ b/Sun/examples/ex14.sel @@ -0,0 +1,202 @@ + step m_Ca m_Mg m_Na umol_As pH + 1 4.6428e-01 1.6167e-01 5.4020e+00 5.0000e-02 5.3496e+00 + 1 5.2071e-04 3.6797e-04 1.0345e-01 2.9703e-04 7.0358e+00 + 2 4.3418e-05 3.0073e-05 2.7681e-02 1.4274e-02 8.4251e+00 + 3 1.6723e-05 1.0553e-05 1.5102e-02 1.7369e-01 9.0861e+00 + 4 1.3810e-05 8.4300e-06 1.2580e-02 3.4749e-01 9.2687e+00 + 5 1.3241e-05 8.0170e-06 1.1705e-02 4.2057e-01 9.3189e+00 + 6 1.3253e-05 8.0279e-06 1.1293e-02 4.3148e-01 9.3249e+00 + 7 1.3481e-05 8.1962e-06 1.1055e-02 4.1548e-01 9.3142e+00 + 8 1.3805e-05 8.4346e-06 1.0889e-02 3.9004e-01 9.2967e+00 + 9 1.4178e-05 8.7091e-06 1.0758e-02 3.6247e-01 9.2767e+00 + 10 1.4581e-05 9.0053e-06 1.0645e-02 3.3557e-01 9.2558e+00 + 11 1.5006e-05 9.3176e-06 1.0542e-02 3.1029e-01 9.2348e+00 + 12 1.5449e-05 9.6438e-06 1.0447e-02 2.8686e-01 9.2138e+00 + 13 1.5911e-05 9.9834e-06 1.0358e-02 2.6525e-01 9.1929e+00 + 14 1.6392e-05 1.0337e-05 1.0274e-02 2.4534e-01 9.1722e+00 + 15 1.6892e-05 1.0704e-05 1.0195e-02 2.2698e-01 9.1517e+00 + 16 1.7412e-05 1.1087e-05 1.0119e-02 2.1004e-01 9.1314e+00 + 17 1.7954e-05 1.1485e-05 1.0047e-02 1.9440e-01 9.1111e+00 + 18 1.8519e-05 1.1901e-05 9.9787e-03 1.7994e-01 9.0910e+00 + 19 1.9109e-05 1.2335e-05 9.9131e-03 1.6656e-01 9.0710e+00 + 20 1.9725e-05 1.2787e-05 9.8504e-03 1.5418e-01 9.0510e+00 + 21 2.0368e-05 1.3260e-05 9.7904e-03 1.4270e-01 9.0311e+00 + 22 2.1041e-05 1.3755e-05 9.7328e-03 1.3206e-01 9.0112e+00 + 23 2.1745e-05 1.4273e-05 9.6775e-03 1.2220e-01 8.9913e+00 + 24 2.2482e-05 1.4815e-05 9.6243e-03 1.1304e-01 8.9714e+00 + 25 2.3254e-05 1.5383e-05 9.5731e-03 1.0454e-01 8.9515e+00 + 26 2.4064e-05 1.5978e-05 9.5238e-03 9.6657e-02 8.9316e+00 + 27 2.4914e-05 1.6603e-05 9.4761e-03 8.9334e-02 8.9116e+00 + 28 2.5807e-05 1.7260e-05 9.4301e-03 8.2534e-02 8.8916e+00 + 29 2.6745e-05 1.7950e-05 9.3855e-03 7.6219e-02 8.8715e+00 + 30 2.7732e-05 1.8675e-05 9.3423e-03 7.0356e-02 8.8514e+00 + 31 2.8770e-05 1.9439e-05 9.3004e-03 6.4912e-02 8.8312e+00 + 32 2.9863e-05 2.0243e-05 9.2597e-03 5.9857e-02 8.8109e+00 + 33 3.1015e-05 2.1090e-05 9.2200e-03 5.5166e-02 8.7905e+00 + 34 3.2230e-05 2.1983e-05 9.1814e-03 5.0812e-02 8.7699e+00 + 35 3.3513e-05 2.2926e-05 9.1436e-03 4.6773e-02 8.7493e+00 + 36 3.4867e-05 2.3922e-05 9.1067e-03 4.3028e-02 8.7285e+00 + 37 3.6299e-05 2.4975e-05 9.0705e-03 3.9555e-02 8.7076e+00 + 38 3.7813e-05 2.6089e-05 9.0350e-03 3.6337e-02 8.6865e+00 + 39 3.9416e-05 2.7267e-05 9.0000e-03 3.3356e-02 8.6653e+00 + 40 4.1113e-05 2.8516e-05 8.9656e-03 3.0597e-02 8.6439e+00 + 41 4.2913e-05 2.9840e-05 8.9315e-03 2.8043e-02 8.6224e+00 + 42 4.4823e-05 3.1244e-05 8.8978e-03 2.5682e-02 8.6006e+00 + 43 4.6851e-05 3.2736e-05 8.8643e-03 2.3500e-02 8.5787e+00 + 44 4.9006e-05 3.4321e-05 8.8310e-03 2.1485e-02 8.5565e+00 + 45 5.1298e-05 3.6006e-05 8.7977e-03 1.9626e-02 8.5342e+00 + 46 5.3738e-05 3.7800e-05 8.7644e-03 1.7911e-02 8.5116e+00 + 47 5.6337e-05 3.9712e-05 8.7309e-03 1.6331e-02 8.4889e+00 + 48 5.9107e-05 4.1749e-05 8.6973e-03 1.4877e-02 8.4658e+00 + 49 6.2064e-05 4.3924e-05 8.6633e-03 1.3539e-02 8.4426e+00 + 50 6.5221e-05 4.6246e-05 8.6288e-03 1.2309e-02 8.4191e+00 + 51 6.8596e-05 4.8728e-05 8.5938e-03 1.1181e-02 8.3954e+00 + 52 7.2206e-05 5.1383e-05 8.5581e-03 1.0146e-02 8.3714e+00 + 53 7.6071e-05 5.4225e-05 8.5216e-03 9.1972e-03 8.3471e+00 + 54 8.0212e-05 5.7271e-05 8.4840e-03 8.3294e-03 8.3226e+00 + 55 8.4653e-05 6.0537e-05 8.4454e-03 7.5361e-03 8.2978e+00 + 56 8.9419e-05 6.4042e-05 8.4055e-03 6.8118e-03 8.2727e+00 + 57 9.4538e-05 6.7807e-05 8.3641e-03 6.1514e-03 8.2473e+00 + 58 1.0004e-04 7.1853e-05 8.3211e-03 5.5498e-03 8.2217e+00 + 59 1.0596e-04 7.6206e-05 8.2762e-03 5.0027e-03 8.1958e+00 + 60 1.1233e-04 8.0892e-05 8.2293e-03 4.5057e-03 8.1696e+00 + 61 1.1919e-04 8.5939e-05 8.1800e-03 4.0548e-03 8.1431e+00 + 62 1.2659e-04 9.1378e-05 8.1283e-03 3.6464e-03 8.1164e+00 + 63 1.3456e-04 9.7244e-05 8.0737e-03 3.2769e-03 8.0893e+00 + 64 1.4317e-04 1.0357e-04 8.0161e-03 2.9432e-03 8.0621e+00 + 65 1.5246e-04 1.1040e-04 7.9550e-03 2.6421e-03 8.0345e+00 + 66 1.6249e-04 1.1778e-04 7.8904e-03 2.3710e-03 8.0067e+00 + 67 1.7301e-04 1.2608e-04 7.8205e-03 2.1257e-03 7.9786e+00 + 68 1.8432e-04 1.3516e-04 7.7465e-03 1.9049e-03 7.9501e+00 + 69 1.9654e-04 1.4497e-04 7.6681e-03 1.7071e-03 7.9214e+00 + 70 2.0974e-04 1.5559e-04 7.5847e-03 1.5302e-03 7.8925e+00 + 71 2.2397e-04 1.6707e-04 7.4960e-03 1.3724e-03 7.8636e+00 + 72 2.3933e-04 1.7947e-04 7.4015e-03 1.2317e-03 7.8345e+00 + 73 2.5587e-04 1.9285e-04 7.3009e-03 1.1064e-03 7.8054e+00 + 74 2.7370e-04 2.0729e-04 7.1938e-03 9.9507e-04 7.7763e+00 + 75 2.9288e-04 2.2286e-04 7.0799e-03 8.9618e-04 7.7472e+00 + 76 3.1349e-04 2.3961e-04 6.9590e-03 8.0843e-04 7.7182e+00 + 77 3.3561e-04 2.5763e-04 6.8306e-03 7.3066e-04 7.6893e+00 + 78 3.5933e-04 2.7696e-04 6.6948e-03 6.6179e-04 7.6606e+00 + 79 3.8469e-04 2.9767e-04 6.5512e-03 6.0086e-04 7.6321e+00 + 80 4.1177e-04 3.1980e-04 6.3998e-03 5.4698e-04 7.6039e+00 + 81 4.4060e-04 3.4340e-04 6.2406e-03 4.9938e-04 7.5760e+00 + 82 4.7122e-04 3.6849e-04 6.0737e-03 4.5735e-04 7.5485e+00 + 83 5.0365e-04 3.9509e-04 5.8993e-03 4.2027e-04 7.5215e+00 + 84 5.3788e-04 4.2320e-04 5.7176e-03 3.8756e-04 7.4950e+00 + 85 5.7386e-04 4.5277e-04 5.5290e-03 3.5874e-04 7.4691e+00 + 86 6.1156e-04 4.8377e-04 5.3342e-03 3.3335e-04 7.4438e+00 + 87 6.5087e-04 5.1613e-04 5.1337e-03 3.1101e-04 7.4193e+00 + 88 6.9168e-04 5.4973e-04 4.9284e-03 2.9135e-04 7.3955e+00 + 89 7.3384e-04 5.8447e-04 4.7190e-03 2.7407e-04 7.3726e+00 + 90 7.7716e-04 6.2017e-04 4.5066e-03 2.5890e-04 7.3505e+00 + 91 8.2146e-04 6.5669e-04 4.2923e-03 2.4559e-04 7.3293e+00 + 92 8.6649e-04 6.9381e-04 4.0771e-03 2.3392e-04 7.3090e+00 + 93 9.1201e-04 7.3133e-04 3.8623e-03 2.2372e-04 7.2897e+00 + 94 9.5775e-04 7.6903e-04 3.6490e-03 2.1480e-04 7.2714e+00 + 95 1.0035e-03 8.0669e-04 3.4384e-03 2.0702e-04 7.2541e+00 + 96 1.0489e-03 8.4407e-04 3.2315e-03 2.0024e-04 7.2377e+00 + 97 1.0937e-03 8.8096e-04 3.0295e-03 1.9436e-04 7.2223e+00 + 98 1.1377e-03 9.1715e-04 2.8333e-03 1.8926e-04 7.2079e+00 + 99 1.1807e-03 9.5246e-04 2.6436e-03 1.8485e-04 7.1945e+00 + 100 1.2224e-03 9.8670e-04 2.4613e-03 1.8105e-04 7.1819e+00 + 101 1.2628e-03 1.0197e-03 2.2869e-03 1.7780e-04 7.1703e+00 + 102 1.3015e-03 1.0514e-03 2.1208e-03 1.7501e-04 7.1595e+00 + 103 1.3386e-03 1.0817e-03 1.9634e-03 1.7264e-04 7.1495e+00 + 104 1.3740e-03 1.1105e-03 1.8148e-03 1.7063e-04 7.1403e+00 + 105 1.4074e-03 1.1377e-03 1.6752e-03 1.6893e-04 7.1318e+00 + 106 1.4391e-03 1.1633e-03 1.5444e-03 1.6752e-04 7.1239e+00 + 107 1.4689e-03 1.1874e-03 1.4225e-03 1.6634e-04 7.1168e+00 + 108 1.4968e-03 1.2099e-03 1.3090e-03 1.6537e-04 7.1102e+00 + 109 1.5229e-03 1.2309e-03 1.2038e-03 1.6458e-04 7.1042e+00 + 110 1.5472e-03 1.2503e-03 1.1066e-03 1.6394e-04 7.0987e+00 + 111 1.5699e-03 1.2683e-03 1.0170e-03 1.6344e-04 7.0937e+00 + 112 1.5909e-03 1.2849e-03 9.3458e-04 1.6305e-04 7.0891e+00 + 113 1.6103e-03 1.3002e-03 8.5895e-04 1.6275e-04 7.0850e+00 + 114 1.6282e-03 1.3143e-03 7.8970e-04 1.6254e-04 7.0812e+00 + 115 1.6448e-03 1.3271e-03 7.2642e-04 1.6239e-04 7.0777e+00 + 116 1.6600e-03 1.3389e-03 6.6867e-04 1.6229e-04 7.0746e+00 + 117 1.6740e-03 1.3496e-03 6.1608e-04 1.6225e-04 7.0718e+00 + 118 1.6868e-03 1.3594e-03 5.6824e-04 1.6224e-04 7.0692e+00 + 119 1.6986e-03 1.3682e-03 5.2478e-04 1.6226e-04 7.0669e+00 + 120 1.7093e-03 1.3763e-03 4.8535e-04 1.6230e-04 7.0648e+00 + 121 1.7192e-03 1.3836e-03 4.4962e-04 1.6236e-04 7.0629e+00 + 122 1.7282e-03 1.3901e-03 4.1726e-04 1.6244e-04 7.0612e+00 + 123 1.7365e-03 1.3960e-03 3.8800e-04 1.6252e-04 7.0596e+00 + 124 1.7441e-03 1.4014e-03 3.6155e-04 1.6262e-04 7.0582e+00 + 125 1.7509e-03 1.4062e-03 3.3765e-04 1.6272e-04 7.0569e+00 + 126 1.7572e-03 1.4105e-03 3.1609e-04 1.6282e-04 7.0558e+00 + 127 1.7630e-03 1.4143e-03 2.9664e-04 1.6292e-04 7.0547e+00 + 128 1.7683e-03 1.4178e-03 2.7910e-04 1.6302e-04 7.0538e+00 + 129 1.7731e-03 1.4208e-03 2.6330e-04 1.6312e-04 7.0529e+00 + 130 1.7774e-03 1.4236e-03 2.4907e-04 1.6321e-04 7.0522e+00 + 131 1.7815e-03 1.4260e-03 2.3626e-04 1.6331e-04 7.0515e+00 + 132 1.7851e-03 1.4281e-03 2.2472e-04 1.6339e-04 7.0509e+00 + 133 1.7885e-03 1.4300e-03 2.1435e-04 1.6348e-04 7.0503e+00 + 134 1.7916e-03 1.4317e-03 2.0502e-04 1.6356e-04 7.0498e+00 + 135 1.7944e-03 1.4331e-03 1.9662e-04 1.6364e-04 7.0494e+00 + 136 1.7970e-03 1.4344e-03 1.8908e-04 1.6371e-04 7.0490e+00 + 137 1.7994e-03 1.4355e-03 1.8230e-04 1.6377e-04 7.0486e+00 + 138 1.8016e-03 1.4364e-03 1.7621e-04 1.6384e-04 7.0483e+00 + 139 1.8036e-03 1.4372e-03 1.7073e-04 1.6390e-04 7.0480e+00 + 140 1.8055e-03 1.4379e-03 1.6582e-04 1.6395e-04 7.0477e+00 + 141 1.8072e-03 1.4385e-03 1.6140e-04 1.6400e-04 7.0475e+00 + 142 1.8088e-03 1.4390e-03 1.5743e-04 1.6405e-04 7.0473e+00 + 143 1.8103e-03 1.4394e-03 1.5387e-04 1.6409e-04 7.0471e+00 + 144 1.8117e-03 1.4397e-03 1.5068e-04 1.6413e-04 7.0469e+00 + 145 1.8130e-03 1.4399e-03 1.4780e-04 1.6417e-04 7.0467e+00 + 146 1.8142e-03 1.4401e-03 1.4523e-04 1.6421e-04 7.0466e+00 + 147 1.8153e-03 1.4402e-03 1.4291e-04 1.6424e-04 7.0465e+00 + 148 1.8164e-03 1.4402e-03 1.4084e-04 1.6427e-04 7.0464e+00 + 149 1.8174e-03 1.4402e-03 1.3897e-04 1.6429e-04 7.0463e+00 + 150 1.8183e-03 1.4402e-03 1.3730e-04 1.6432e-04 7.0462e+00 + 151 1.8192e-03 1.4401e-03 1.3580e-04 1.6434e-04 7.0461e+00 + 152 1.8200e-03 1.4400e-03 1.3445e-04 1.6436e-04 7.0461e+00 + 153 1.8208e-03 1.4399e-03 1.3325e-04 1.6438e-04 7.0460e+00 + 154 1.8216e-03 1.4397e-03 1.3216e-04 1.6440e-04 7.0459e+00 + 155 1.8223e-03 1.4396e-03 1.3119e-04 1.6441e-04 7.0459e+00 + 156 1.8230e-03 1.4394e-03 1.3032e-04 1.6443e-04 7.0459e+00 + 157 1.8236e-03 1.4391e-03 1.2953e-04 1.6444e-04 7.0458e+00 + 158 1.8243e-03 1.4389e-03 1.2883e-04 1.6446e-04 7.0458e+00 + 159 1.8249e-03 1.4386e-03 1.2820e-04 1.6447e-04 7.0458e+00 + 160 1.8255e-03 1.4384e-03 1.2763e-04 1.6448e-04 7.0457e+00 + 161 1.8260e-03 1.4381e-03 1.2713e-04 1.6449e-04 7.0457e+00 + 162 1.8266e-03 1.4378e-03 1.2667e-04 1.6450e-04 7.0457e+00 + 163 1.8271e-03 1.4375e-03 1.2626e-04 1.6451e-04 7.0457e+00 + 164 1.8276e-03 1.4372e-03 1.2590e-04 1.6451e-04 7.0457e+00 + 165 1.8281e-03 1.4369e-03 1.2557e-04 1.6452e-04 7.0457e+00 + 166 1.8286e-03 1.4366e-03 1.2527e-04 1.6453e-04 7.0457e+00 + 167 1.8291e-03 1.4363e-03 1.2501e-04 1.6453e-04 7.0456e+00 + 168 1.8296e-03 1.4360e-03 1.2477e-04 1.6454e-04 7.0456e+00 + 169 1.8300e-03 1.4356e-03 1.2456e-04 1.6454e-04 7.0456e+00 + 170 1.8305e-03 1.4353e-03 1.2437e-04 1.6455e-04 7.0456e+00 + 171 1.8309e-03 1.4350e-03 1.2420e-04 1.6455e-04 7.0456e+00 + 172 1.8313e-03 1.4347e-03 1.2404e-04 1.6456e-04 7.0456e+00 + 173 1.8318e-03 1.4343e-03 1.2390e-04 1.6456e-04 7.0456e+00 + 174 1.8322e-03 1.4340e-03 1.2378e-04 1.6456e-04 7.0456e+00 + 175 1.8326e-03 1.4337e-03 1.2367e-04 1.6457e-04 7.0456e+00 + 176 1.8330e-03 1.4333e-03 1.2357e-04 1.6457e-04 7.0456e+00 + 177 1.8334e-03 1.4330e-03 1.2348e-04 1.6457e-04 7.0456e+00 + 178 1.8338e-03 1.4327e-03 1.2340e-04 1.6458e-04 7.0456e+00 + 179 1.8342e-03 1.4323e-03 1.2333e-04 1.6458e-04 7.0457e+00 + 180 1.8346e-03 1.4320e-03 1.2326e-04 1.6458e-04 7.0457e+00 + 181 1.8349e-03 1.4317e-03 1.2321e-04 1.6458e-04 7.0457e+00 + 182 1.8353e-03 1.4313e-03 1.2315e-04 1.6459e-04 7.0457e+00 + 183 1.8357e-03 1.4310e-03 1.2311e-04 1.6459e-04 7.0457e+00 + 184 1.8360e-03 1.4307e-03 1.2306e-04 1.6459e-04 7.0457e+00 + 185 1.8364e-03 1.4304e-03 1.2303e-04 1.6459e-04 7.0457e+00 + 186 1.8368e-03 1.4300e-03 1.2299e-04 1.6460e-04 7.0457e+00 + 187 1.8371e-03 1.4297e-03 1.2296e-04 1.6460e-04 7.0457e+00 + 188 1.8375e-03 1.4294e-03 1.2294e-04 1.6460e-04 7.0457e+00 + 189 1.8378e-03 1.4291e-03 1.2291e-04 1.6460e-04 7.0457e+00 + 190 1.8382e-03 1.4287e-03 1.2289e-04 1.6460e-04 7.0457e+00 + 191 1.8385e-03 1.4284e-03 1.2287e-04 1.6460e-04 7.0457e+00 + 192 1.8388e-03 1.4281e-03 1.2285e-04 1.6461e-04 7.0457e+00 + 193 1.8392e-03 1.4278e-03 1.2284e-04 1.6461e-04 7.0457e+00 + 194 1.8395e-03 1.4275e-03 1.2282e-04 1.6461e-04 7.0457e+00 + 195 1.8398e-03 1.4272e-03 1.2281e-04 1.6461e-04 7.0457e+00 + 196 1.8402e-03 1.4269e-03 1.2280e-04 1.6461e-04 7.0458e+00 + 197 1.8405e-03 1.4266e-03 1.2279e-04 1.6461e-04 7.0458e+00 + 198 1.8408e-03 1.4263e-03 1.2278e-04 1.6462e-04 7.0458e+00 + 199 1.8411e-03 1.4260e-03 1.2277e-04 1.6462e-04 7.0458e+00 + 200 1.8415e-03 1.4257e-03 1.2276e-04 1.6462e-04 7.0458e+00 diff --git a/Sun/examples/ex15.log b/Sun/examples/ex15.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex15.out b/Sun/examples/ex15.out new file mode 100644 index 00000000..fd32cad1 --- /dev/null +++ b/Sun/examples/ex15.out @@ -0,0 +1,2299 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex15 + Output file: ex15.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex15.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 15.--1D Transport: Kinetic Biodegradation, Cell Growth, and Sorption + *********** + PLEASE NOTE: This problem requires database file ex15.dat!! + *********** + SOLUTION 0 Pulse solution with NTA and cobalt + units umol/L + pH 6 + C .49 + O(0) 62.5 + Nta 5.23 + Co 5.23 + Na 1000 + Cl 1000 + END +----- +TITLE +----- + + Example 15.--1D Transport: Kinetic Biodegradation, Cell Growth, and Sorption +*********** +PLEASE NOTE: This problem requires database file ex15.dat!! +*********** + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. Pulse solution with NTA and cobalt + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.900e-07 4.900e-07 + Cl 1.000e-03 1.000e-03 + Co 5.230e-06 5.230e-06 + Na 1.000e-03 1.000e-03 + Nta 5.230e-06 5.230e-06 + O(0) 6.250e-05 6.250e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.005e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.539e-05 + Total CO2 (mol/kg) = 4.900e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.954e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.20 + Iterations = 6 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + O(-2)/O(0) 14.3937 0.8515 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.000e-06 1.000e-06 -6.000 -6.000 -0.000 + OH- 1.000e-08 1.000e-08 -8.000 -8.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 4.900e-07 + CO2 3.387e-07 3.387e-07 -6.470 -6.470 0.000 + HCO3- 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CO3-2 7.077e-12 7.077e-12 -11.150 -11.150 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 5.230e-06 + CoNta- 4.793e-06 4.793e-06 -5.319 -5.319 -0.000 + Co+2 4.370e-07 4.370e-07 -6.360 -6.360 -0.000 + CoOH+ 8.719e-11 8.719e-11 -10.060 -10.060 -0.000 + CoOHNta-2 3.024e-11 3.024e-11 -10.519 -10.519 -0.000 + CoNta2-4 6.618e-14 6.618e-14 -13.179 -13.179 -0.000 + Co(OH)2 5.501e-18 5.501e-18 -17.260 -17.260 0.000 + Co(OH)3- 1.382e-20 1.382e-20 -19.860 -19.860 -0.000 +H(0) 1.416e-23 + H2 7.079e-24 7.079e-24 -23.150 -23.150 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 5.230e-06 + CoNta- 4.793e-06 4.793e-06 -5.319 -5.319 -0.000 + HNta-2 4.366e-07 4.366e-07 -6.360 -6.360 -0.000 + H2Nta- 4.366e-10 4.366e-10 -9.360 -9.360 -0.000 + CoOHNta-2 3.024e-11 3.024e-11 -10.519 -10.519 -0.000 + Nta-3 2.188e-11 2.188e-11 -10.660 -10.660 -0.000 + CoNta2-4 6.618e-14 6.618e-14 -13.179 -13.179 -0.000 + H3Nta 1.738e-14 1.738e-14 -13.760 -13.760 0.000 +O(0) 6.250e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1-10 Background solution initially filling column # 1-20 + units umol/L + pH 6 + C .49 + O(0) 62.5 + Na 1000 + Cl 1000 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Background solution initially filling column + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.900e-07 4.900e-07 + Cl 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + O(0) 6.250e-05 6.250e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.414e-07 + Total CO2 (mol/kg) = 4.900e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 4 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + O(-2)/O(0) 14.3937 0.8515 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.000e-06 1.000e-06 -6.000 -6.000 -0.000 + OH- 1.000e-08 1.000e-08 -8.000 -8.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 4.900e-07 + CO2 3.387e-07 3.387e-07 -6.470 -6.470 0.000 + HCO3- 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CO3-2 7.077e-12 7.077e-12 -11.150 -11.150 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +H(0) 1.416e-23 + H2 7.079e-24 7.079e-24 -23.150 -23.150 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +O(0) 6.250e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + RATES Rate expressions for the four kinetic reactions + HNTA-2 + start + 10 Ks = 7.64e-7 + 20 Ka = 6.25e-6 + 30 qm = 1.407e-3/3600 + 40 f1 = MOL("HNta-2")/(Ks + MOL("HNta-2")) + 50 f2 = MOL("O2")/(Ka + MOL("O2")) + 60 rate = -qm * KIN("Biomass") * f1 * f2 + 70 moles = rate * TIME + 80 PUT(rate, 1) # save the rate for use in Biomass rate calculation + 90 SAVE moles + end + Biomass + start + 10 Y = 65.14 + 20 b = 0.00208/3600 + 30 rate = GET(1) # uses rate calculated in HTNA-2 rate calculation + 40 rate = -Y*rate -b*M + 50 moles = -rate * TIME + 60 if (M + moles) < 0 then moles = -M + 70 SAVE moles + end + Co_sorption + start + 10 km = 1/3600 + 20 kd = 5.07e-3 + 30 solids = 3.75e3 + 40 rate = -km*(MOL("Co+2") - (M/solids)/kd) + 50 moles = rate * TIME + 60 if (M - moles) < 0 then moles = M + 70 SAVE moles + end + CoNta_sorption + start + 10 km = 1/3600 + 20 kd = 5.33e-4 + 30 solids = 3.75e3 + 40 rate = -km*(MOL("CoNta-") - (M/solids)/kd) + 50 moles = rate * TIME + 60 if (M - moles) < 0 then moles = M + 70 SAVE moles + end + KINETICS 1-10 Four kinetic reactions for all cells # 1-20 + HNTA-2 + formula C -3.12 H -1.968 O -4.848 N -0.424 Nta 1. + Biomass + formula H 0.0 + m 1.36e-4 + Co_sorption + formula CoCl2 + m 0.0 + tol 1e-11 + CoNta_sorption + formula NaCoNta + m 0.0 + tol 1e-11 + SELECTED_OUTPUT + file ex15.sel + molalities Nta-3 CoNta- HNta-2 Co+2 + USER_PUNCH + heading hours Co_sorb CoNta_sorb Biomass + start + 10 punch TOTAL_TIME/3600 + 1800/3600 # TOTAL_TIME/3600 + 900/3600 + 20 punch KIN("Co_sorption")/3.75e3 + 30 punch KIN("CoNta_sorption")/3.75e3 + 40 punch KIN("Biomass") + end + TRANSPORT First 20 hours have NTA and cobalt in infilling solution + cells 10 # 20 + length 1 # 0.5 + shifts 20 # 40 + time_step 3600 # 1800 + flow_direction forward + boundary_conditions flux flux + dispersivity .05 + correct_disp true + diffusion_coefficient 0.0e-9 + punch_cells 10 # 20 + punch_frequency 1 # 2 + print_cells 10 # 20 + print_frequency 5 # 10 + END +WARNING: Cell-lengths were read for 1 cells. Last value is used till cell 10. +WARNING: Dispersivities were read for 1 cells. Last value is used till cell 10. +------------------------------------ +Beginning of transport calculations. +------------------------------------ + +------------------------------- +Equilibrating initial solutions +------------------------------- + +Using solution 10. Background solution initially filling column + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.900e-07 4.900e-07 + Cl 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.000 Charge balance + pe = 14.394 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.414e-07 + Total CO2 (mol/kg) = 4.900e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.000e-06 1.000e-06 -6.000 -6.000 -0.000 + OH- 1.000e-08 1.000e-08 -8.000 -8.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 4.900e-07 + CO2 3.387e-07 3.387e-07 -6.470 -6.470 0.000 + HCO3- 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CO3-2 7.077e-12 7.077e-12 -11.150 -11.150 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +O(0) 6.250e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 1. + +Transport step 1. Mixrun 1. + +Transport step 2. + +Transport step 2. Mixrun 1. + +Transport step 3. + +Transport step 3. Mixrun 1. + +Transport step 4. + +Transport step 4. Mixrun 1. + +Transport step 5. + +Transport step 5. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 3. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 3. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 18000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 9.570e-14 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass -2.804e-07 1.346e-04 H 0 + Co_sorption 2.317e-14 2.317e-14 CoCl2 1 + CoNta_sorption 5.391e-19 5.391e-19 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.900e-07 4.900e-07 + Cl 1.000e-03 1.000e-03 + Co 2.318e-14 2.318e-14 + N 4.652e-13 4.652e-13 + Na 1.000e-03 1.000e-03 + Nta 8.316e-13 8.316e-13 + +----------------------------Description of solution---------------------------- + + pH = 6.000 Charge balance + pe = 14.394 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.414e-07 + Total CO2 (mol/kg) = 4.900e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.000e-06 1.000e-06 -6.000 -6.000 -0.000 + OH- 1.000e-08 1.000e-08 -8.000 -8.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 4.900e-07 + CO2 3.387e-07 3.387e-07 -6.470 -6.470 0.000 + HCO3- 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CO3-2 7.077e-12 7.077e-12 -11.150 -11.150 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 2.318e-14 + Co+2 2.317e-14 2.317e-14 -13.635 -13.635 -0.000 + CoOH+ 4.623e-18 4.623e-18 -17.335 -17.335 -0.000 + CoNta- 4.836e-19 4.836e-19 -18.316 -18.316 -0.000 + CoOHNta-2 3.051e-24 3.051e-24 -23.516 -23.516 -0.000 + Co(OH)2 2.917e-25 2.917e-25 -24.535 -24.535 0.000 + Co(OH)3- 7.327e-28 7.327e-28 -27.135 -27.135 -0.000 + CoNta2-4 1.270e-32 1.270e-32 -31.896 -31.896 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +N 4.652e-13 + NH4+ 4.649e-13 4.649e-13 -12.333 -12.333 -0.000 + NH3 2.330e-16 2.330e-16 -15.633 -15.633 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 8.316e-13 + HNta-2 8.308e-13 8.308e-13 -12.081 -12.081 -0.000 + H2Nta- 8.308e-16 8.308e-16 -15.081 -15.081 -0.000 + Nta-3 4.164e-17 4.164e-17 -16.381 -16.381 -0.000 + CoNta- 4.836e-19 4.836e-19 -18.316 -18.316 -0.000 + H3Nta 3.307e-20 3.307e-20 -19.481 -19.481 0.000 + CoOHNta-2 3.051e-24 3.051e-24 -23.516 -23.516 -0.000 + CoNta2-4 1.270e-32 1.270e-32 -31.896 -31.896 -0.000 +O(0) 6.250e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 6. + +Transport step 6. Mixrun 1. + +Transport step 7. + +Transport step 7. Mixrun 1. + +Transport step 8. + +Transport step 8. Mixrun 1. + +Transport step 9. + +Transport step 9. Mixrun 1. + +Transport step 10. + +Transport step 10. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 3. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 3. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 36000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 2.135e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 1.110e-06 1.356e-04 H 0 + Co_sorption 1.871e-09 3.691e-09 CoCl2 1 + CoNta_sorption 7.149e-09 9.228e-09 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.541e-06 1.541e-06 + Cl 9.992e-04 9.992e-04 + Co 9.656e-09 9.656e-09 + N 1.429e-07 1.429e-07 + Na 9.967e-04 9.967e-04 + Nta 1.196e-07 1.196e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.237 Charge balance + pe = 14.155 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.989e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.439e-06 + Total CO2 (mol/kg) = 1.541e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.646e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.13 + Iterations = 25 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 5.796e-07 5.796e-07 -6.237 -6.237 -0.000 + OH- 1.725e-08 1.725e-08 -7.763 -7.763 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 1.541e-06 + CO2 8.705e-07 8.705e-07 -6.060 -6.060 0.000 + HCO3- 6.709e-07 6.709e-07 -6.173 -6.173 -0.000 + CO3-2 5.414e-11 5.414e-11 -10.266 -10.266 -0.000 +Cl 9.992e-04 + Cl- 9.992e-04 9.992e-04 -3.000 -3.000 -0.000 +Co 9.656e-09 + CoNta- 8.000e-09 8.000e-09 -8.097 -8.097 -0.000 + Co+2 1.655e-09 1.655e-09 -8.781 -8.781 -0.000 + CoOH+ 5.698e-13 5.698e-13 -12.244 -12.244 -0.000 + CoOHNta-2 8.710e-14 8.710e-14 -13.060 -13.060 -0.000 + CoNta2-4 4.869e-17 4.869e-17 -16.313 -16.313 -0.000 + Co(OH)2 6.203e-20 6.203e-20 -19.207 -19.207 0.000 + Co(OH)3- 2.688e-22 2.688e-22 -21.571 -21.571 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.934 -43.934 0.000 +N 1.429e-07 + NH4+ 1.428e-07 1.428e-07 -6.845 -6.845 -0.000 + NH3 1.235e-10 1.235e-10 -9.908 -9.908 0.000 +Na 9.967e-04 + Na+ 9.967e-04 9.967e-04 -3.001 -3.001 -0.000 +Nta 1.196e-07 + HNta-2 1.115e-07 1.115e-07 -6.953 -6.953 -0.000 + CoNta- 8.000e-09 8.000e-09 -8.097 -8.097 -0.000 + H2Nta- 6.464e-11 6.464e-11 -10.190 -10.190 -0.000 + Nta-3 9.645e-12 9.645e-12 -11.016 -11.016 -0.000 + CoOHNta-2 8.710e-14 8.710e-14 -13.060 -13.060 -0.000 + H3Nta 1.491e-15 1.491e-15 -14.826 -14.826 0.000 + CoNta2-4 4.869e-17 4.869e-17 -16.313 -16.313 -0.000 +O(0) 6.141e-05 + O2 3.071e-05 3.071e-05 -4.513 -4.513 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 11. + +Transport step 11. Mixrun 1. + +Transport step 12. + +Transport step 12. Mixrun 1. + +Transport step 13. + +Transport step 13. Mixrun 1. + +Transport step 14. + +Transport step 14. Mixrun 1. + +Transport step 15. + +Transport step 15. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 3. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 3. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 54000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 4.019e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 2.318e-06 1.453e-04 H 0 + Co_sorption 1.090e-08 3.661e-08 CoCl2 1 + CoNta_sorption 9.432e-08 2.656e-07 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.330e-06 2.330e-06 + Cl 9.985e-04 9.985e-04 + Co 1.862e-07 1.862e-07 + N 2.500e-07 2.500e-07 + Na 9.958e-04 9.958e-04 + Nta 4.001e-07 4.001e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.448 Charge balance + pe = 13.942 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.987e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 6.603e-06 + Total CO2 (mol/kg) = 2.330e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.954e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.20 + Iterations = 21 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.564e-07 3.564e-07 -6.448 -6.448 -0.000 + OH- 2.806e-08 2.806e-08 -7.552 -7.552 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.330e-06 + HCO3- 1.296e-06 1.296e-06 -5.887 -5.887 -0.000 + CO2 1.034e-06 1.034e-06 -5.985 -5.985 0.000 + CO3-2 1.700e-10 1.700e-10 -9.769 -9.769 -0.000 +Cl 9.985e-04 + Cl- 9.985e-04 9.985e-04 -3.001 -3.001 -0.000 +Co 1.862e-07 + CoNta- 1.751e-07 1.751e-07 -6.757 -6.757 -0.000 + Co+2 1.105e-08 1.105e-08 -7.957 -7.957 -0.000 + CoOH+ 6.187e-12 6.187e-12 -11.209 -11.209 -0.000 + CoOHNta-2 3.100e-12 3.100e-12 -11.509 -11.509 -0.000 + CoNta2-4 3.494e-15 3.494e-15 -14.457 -14.457 -0.000 + Co(OH)2 1.095e-18 1.095e-18 -17.960 -17.960 0.000 + Co(OH)3- 7.718e-21 7.718e-21 -20.112 -20.112 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.931 -43.931 0.000 +N 2.500e-07 + NH4+ 2.497e-07 2.497e-07 -6.603 -6.603 -0.000 + NH3 3.511e-10 3.511e-10 -9.455 -9.455 0.000 +Na 9.958e-04 + Na+ 9.958e-04 9.958e-04 -3.002 -3.002 -0.000 +Nta 4.001e-07 + HNta-2 2.249e-07 2.249e-07 -6.648 -6.648 -0.000 + CoNta- 1.751e-07 1.751e-07 -6.757 -6.757 -0.000 + H2Nta- 8.014e-11 8.014e-11 -10.096 -10.096 -0.000 + Nta-3 3.162e-11 3.162e-11 -10.500 -10.500 -0.000 + CoOHNta-2 3.100e-12 3.100e-12 -11.509 -11.509 -0.000 + CoNta2-4 3.494e-15 3.494e-15 -14.457 -14.457 -0.000 + H3Nta 1.137e-15 1.137e-15 -14.944 -14.944 0.000 +O(0) 6.059e-05 + O2 3.030e-05 3.030e-05 -4.519 -4.519 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 16. + +Transport step 16. Mixrun 1. + +Transport step 17. + +Transport step 17. Mixrun 1. + +Transport step 18. + +Transport step 18. Mixrun 1. + +Transport step 19. + +Transport step 19. Mixrun 1. + +Transport step 20. + +Transport step 20. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 3. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 3. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 72000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 4.950e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 2.897e-06 1.588e-04 H 0 + Co_sorption 2.585e-08 1.347e-07 CoCl2 1 + CoNta_sorption 2.379e-07 1.169e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.638e-06 2.638e-06 + Cl 9.982e-04 9.982e-04 + Co 7.184e-07 7.184e-07 + N 2.918e-07 2.918e-07 + Na 9.965e-04 9.965e-04 + Nta 9.571e-07 9.571e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.540 Charge balance + pe = 13.850 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.994e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.227e-06 + Total CO2 (mol/kg) = 2.638e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.954e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.20 + Iterations = 51 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.887e-07 2.887e-07 -6.540 -6.540 -0.000 + OH- 3.464e-08 3.464e-08 -7.460 -7.460 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.638e-06 + HCO3- 1.602e-06 1.602e-06 -5.795 -5.795 -0.000 + CO2 1.035e-06 1.035e-06 -5.985 -5.985 0.000 + CO3-2 2.596e-10 2.596e-10 -9.586 -9.586 -0.000 +Cl 9.982e-04 + Cl- 9.982e-04 9.982e-04 -3.001 -3.001 -0.000 +Co 7.184e-07 + CoNta- 6.888e-07 6.888e-07 -6.162 -6.162 -0.000 + Co+2 2.952e-08 2.952e-08 -7.530 -7.530 -0.000 + CoOH+ 2.040e-11 2.040e-11 -10.690 -10.690 -0.000 + CoOHNta-2 1.505e-11 1.505e-11 -10.822 -10.822 -0.000 + CoNta2-4 2.024e-14 2.024e-14 -13.694 -13.694 -0.000 + Co(OH)2 4.459e-18 4.459e-18 -17.351 -17.351 0.000 + Co(OH)3- 3.880e-20 3.880e-20 -19.411 -19.411 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.930 -43.930 0.000 +N 2.918e-07 + NH4+ 2.913e-07 2.913e-07 -6.536 -6.536 -0.000 + NH3 5.058e-10 5.058e-10 -9.296 -9.296 0.000 +Na 9.965e-04 + Na+ 9.965e-04 9.965e-04 -3.002 -3.002 -0.000 +Nta 9.571e-07 + CoNta- 6.888e-07 6.888e-07 -6.162 -6.162 -0.000 + HNta-2 2.682e-07 2.682e-07 -6.572 -6.572 -0.000 + H2Nta- 7.742e-11 7.742e-11 -10.111 -10.111 -0.000 + Nta-3 4.656e-11 4.656e-11 -10.332 -10.332 -0.000 + CoOHNta-2 1.505e-11 1.505e-11 -10.822 -10.822 -0.000 + CoNta2-4 2.024e-14 2.024e-14 -13.694 -13.694 -0.000 + H3Nta 8.897e-16 8.897e-16 -15.051 -15.051 0.000 +O(0) 6.027e-05 + O2 3.014e-05 3.014e-05 -4.521 -4.521 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + PRINT + selected_output false + SOLUTION 0 New infilling solution, same as background solution + units umol/L + pH 6 + C .49 + O(0) 62.5 + Na 1000 + Cl 1000 + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 0. New infilling solution, same as background solution + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.900e-07 4.900e-07 + Cl 1.000e-03 1.000e-03 + Na 1.000e-03 1.000e-03 + O(0) 6.250e-05 6.250e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.414e-07 + Total CO2 (mol/kg) = 4.900e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 4 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + O(-2)/O(0) 14.3937 0.8515 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.000e-06 1.000e-06 -6.000 -6.000 -0.000 + OH- 1.000e-08 1.000e-08 -8.000 -8.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 4.900e-07 + CO2 3.387e-07 3.387e-07 -6.470 -6.470 0.000 + HCO3- 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CO3-2 7.077e-12 7.077e-12 -11.150 -11.150 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +H(0) 1.416e-23 + H2 7.079e-24 7.079e-24 -23.150 -23.150 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +O(0) 6.250e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 5. +------------------------------------ + + PRINT + selected_output true + TRANSPORT Last 55 hours with background infilling solution + shifts 55 # 110 + END +------------------------------------ +Column data retained from former run +------------------------------------ + +------------------------------------ +Beginning of transport calculations. +------------------------------------ + +------------------------------- +Equilibrating initial solutions +------------------------------- + +Using solution 10. Solution after simulation 3. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.638e-06 2.638e-06 + Cl 9.982e-04 9.982e-04 + Co 7.184e-07 7.184e-07 + N 2.918e-07 2.918e-07 + Na 9.965e-04 9.965e-04 + Nta 9.571e-07 9.571e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.540 Charge balance + pe = 13.850 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.994e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.227e-06 + Total CO2 (mol/kg) = 2.638e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.954e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.20 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.887e-07 2.887e-07 -6.540 -6.540 -0.000 + OH- 3.464e-08 3.464e-08 -7.460 -7.460 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.638e-06 + HCO3- 1.602e-06 1.602e-06 -5.795 -5.795 -0.000 + CO2 1.035e-06 1.035e-06 -5.985 -5.985 0.000 + CO3-2 2.596e-10 2.596e-10 -9.586 -9.586 -0.000 +Cl 9.982e-04 + Cl- 9.982e-04 9.982e-04 -3.001 -3.001 -0.000 +Co 7.184e-07 + CoNta- 6.888e-07 6.888e-07 -6.162 -6.162 -0.000 + Co+2 2.952e-08 2.952e-08 -7.530 -7.530 -0.000 + CoOH+ 2.040e-11 2.040e-11 -10.690 -10.690 -0.000 + CoOHNta-2 1.505e-11 1.505e-11 -10.822 -10.822 -0.000 + CoNta2-4 2.024e-14 2.024e-14 -13.694 -13.694 -0.000 + Co(OH)2 4.459e-18 4.459e-18 -17.351 -17.351 0.000 + Co(OH)3- 3.880e-20 3.880e-20 -19.411 -19.411 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.930 -43.930 0.000 +N 2.918e-07 + NH4+ 2.913e-07 2.913e-07 -6.536 -6.536 -0.000 + NH3 5.058e-10 5.058e-10 -9.296 -9.296 0.000 +Na 9.965e-04 + Na+ 9.965e-04 9.965e-04 -3.002 -3.002 -0.000 +Nta 9.571e-07 + CoNta- 6.888e-07 6.888e-07 -6.162 -6.162 -0.000 + HNta-2 2.682e-07 2.682e-07 -6.572 -6.572 -0.000 + H2Nta- 7.742e-11 7.742e-11 -10.111 -10.111 -0.000 + Nta-3 4.656e-11 4.656e-11 -10.332 -10.332 -0.000 + CoOHNta-2 1.505e-11 1.505e-11 -10.822 -10.822 -0.000 + CoNta2-4 2.024e-14 2.024e-14 -13.694 -13.694 -0.000 + H3Nta 8.897e-16 8.897e-16 -15.051 -15.051 0.000 +O(0) 6.027e-05 + O2 3.014e-05 3.014e-05 -4.521 -4.521 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 1. + +Transport step 1. Mixrun 1. + +Transport step 2. + +Transport step 2. Mixrun 1. + +Transport step 3. + +Transport step 3. Mixrun 1. + +Transport step 4. + +Transport step 4. Mixrun 1. + +Transport step 5. + +Transport step 5. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 90000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 5.582e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 3.276e-06 1.744e-04 H 0 + Co_sorption 4.161e-08 3.117e-07 CoCl2 1 + CoNta_sorption 3.270e-07 2.663e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.855e-06 2.855e-06 + Cl 9.981e-04 9.981e-04 + Co 1.525e-06 1.525e-06 + N 3.213e-07 3.213e-07 + Na 9.973e-04 9.973e-04 + Nta 1.754e-06 1.754e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.593 Charge balance + pe = 13.797 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.000e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.229e-05 + Total CO2 (mol/kg) = 2.855e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.954e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.20 + Iterations = 49 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.555e-07 2.555e-07 -6.593 -6.593 -0.000 + OH- 3.914e-08 3.914e-08 -7.407 -7.407 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.855e-06 + HCO3- 1.816e-06 1.816e-06 -5.741 -5.741 -0.000 + CO2 1.039e-06 1.039e-06 -5.984 -5.984 0.000 + CO3-2 3.324e-10 3.324e-10 -9.478 -9.478 -0.000 +Cl 9.981e-04 + Cl- 9.981e-04 9.981e-04 -3.001 -3.001 -0.000 +Co 1.525e-06 + CoNta- 1.472e-06 1.472e-06 -5.832 -5.832 -0.000 + Co+2 5.314e-08 5.314e-08 -7.275 -7.275 -0.000 + CoOH+ 4.150e-11 4.150e-11 -10.382 -10.382 -0.000 + CoOHNta-2 3.634e-11 3.634e-11 -10.440 -10.440 -0.000 + CoNta2-4 5.131e-14 5.131e-14 -13.290 -13.290 -0.000 + Co(OH)2 1.025e-17 1.025e-17 -16.989 -16.989 0.000 + Co(OH)3- 1.008e-19 1.008e-19 -18.997 -18.997 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.929 -43.929 0.000 +N 3.213e-07 + NH4+ 3.207e-07 3.207e-07 -6.494 -6.494 -0.000 + NH3 6.291e-10 6.291e-10 -9.201 -9.201 0.000 +Na 9.973e-04 + Na+ 9.973e-04 9.973e-04 -3.001 -3.001 -0.000 +Nta 1.754e-06 + CoNta- 1.472e-06 1.472e-06 -5.832 -5.832 -0.000 + HNta-2 2.817e-07 2.817e-07 -6.550 -6.550 -0.000 + H2Nta- 7.197e-11 7.197e-11 -10.143 -10.143 -0.000 + Nta-3 5.526e-11 5.526e-11 -10.258 -10.258 -0.000 + CoOHNta-2 3.634e-11 3.634e-11 -10.440 -10.440 -0.000 + CoNta2-4 5.131e-14 5.131e-14 -13.290 -13.290 -0.000 + H3Nta 7.320e-16 7.320e-16 -15.136 -15.136 0.000 +O(0) 6.005e-05 + O2 3.002e-05 3.002e-05 -4.523 -4.523 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 6. + +Transport step 6. Mixrun 1. + +Transport step 7. + +Transport step 7. Mixrun 1. + +Transport step 8. + +Transport step 8. Mixrun 1. + +Transport step 9. + +Transport step 9. Mixrun 1. + +Transport step 10. + +Transport step 10. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 108000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 5.493e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 3.184e-06 1.911e-04 H 0 + Co_sorption 5.379e-08 5.596e-07 CoCl2 1 + CoNta_sorption 3.109e-07 4.300e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.617e-06 2.617e-06 + Cl 9.984e-04 9.984e-04 + Co 2.356e-06 2.356e-06 + N 2.891e-07 2.891e-07 + Na 1.002e-03 1.002e-03 + Nta 2.524e-06 2.524e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.680 Charge balance + pe = 13.710 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.003e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.418e-05 + Total CO2 (mol/kg) = 2.617e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -4.697e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 47 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.092e-07 2.092e-07 -6.680 -6.680 -0.000 + OH- 4.781e-08 4.781e-08 -7.321 -7.321 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.617e-06 + HCO3- 1.782e-06 1.782e-06 -5.749 -5.749 -0.000 + CO2 8.346e-07 8.346e-07 -6.079 -6.079 0.000 + CO3-2 3.985e-10 3.985e-10 -9.400 -9.400 -0.000 +Cl 9.984e-04 + Cl- 9.984e-04 9.984e-04 -3.001 -3.001 -0.000 +Co 2.356e-06 + CoNta- 2.278e-06 2.278e-06 -5.642 -5.642 -0.000 + Co+2 7.711e-08 7.711e-08 -7.113 -7.113 -0.000 + CoOH+ 7.356e-11 7.356e-11 -10.133 -10.133 -0.000 + CoOHNta-2 6.872e-11 6.872e-11 -10.163 -10.163 -0.000 + CoNta2-4 8.474e-14 8.474e-14 -13.072 -13.072 -0.000 + Co(OH)2 2.219e-17 2.219e-17 -16.654 -16.654 0.000 + Co(OH)3- 2.664e-19 2.664e-19 -18.574 -18.574 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.930 -43.930 0.000 +N 2.891e-07 + NH4+ 2.884e-07 2.884e-07 -6.540 -6.540 -0.000 + NH3 6.910e-10 6.910e-10 -9.161 -9.161 0.000 +Na 1.002e-03 + Na+ 1.002e-03 1.002e-03 -2.999 -2.999 -0.000 +Nta 2.524e-06 + CoNta- 2.278e-06 2.278e-06 -5.642 -5.642 -0.000 + HNta-2 2.460e-07 2.460e-07 -6.609 -6.609 -0.000 + CoOHNta-2 6.872e-11 6.872e-11 -10.163 -10.163 -0.000 + Nta-3 5.895e-11 5.895e-11 -10.230 -10.230 -0.000 + H2Nta- 5.146e-11 5.146e-11 -10.289 -10.289 -0.000 + CoNta2-4 8.474e-14 8.474e-14 -13.072 -13.072 -0.000 + H3Nta 4.285e-16 4.285e-16 -15.368 -15.368 0.000 +O(0) 6.029e-05 + O2 3.015e-05 3.015e-05 -4.521 -4.521 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 11. + +Transport step 11. Mixrun 1. + +Transport step 12. + +Transport step 12. Mixrun 1. + +Transport step 13. + +Transport step 13. Mixrun 1. + +Transport step 14. + +Transport step 14. Mixrun 1. + +Transport step 15. + +Transport step 15. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 126000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 5.701e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 3.286e-06 2.072e-04 H 0 + Co_sorption 6.691e-08 8.668e-07 CoCl2 1 + CoNta_sorption 1.292e-07 5.375e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.207e-06 2.207e-06 + Cl 9.987e-04 9.987e-04 + Co 2.833e-06 2.833e-06 + N 2.334e-07 2.334e-07 + Na 1.004e-03 1.004e-03 + Nta 2.963e-06 2.963e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.644 Charge balance + pe = 13.747 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.004e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.435e-05 + Total CO2 (mol/kg) = 2.207e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.384e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 18 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.271e-07 2.271e-07 -6.644 -6.644 -0.000 + OH- 4.403e-08 4.403e-08 -7.356 -7.356 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 2.207e-06 + HCO3- 1.463e-06 1.463e-06 -5.835 -5.835 -0.000 + CO2 7.440e-07 7.440e-07 -6.128 -6.128 0.000 + CO3-2 3.013e-10 3.013e-10 -9.521 -9.521 -0.000 +Cl 9.987e-04 + Cl- 9.987e-04 9.987e-04 -3.001 -3.001 -0.000 +Co 2.833e-06 + CoNta- 2.728e-06 2.728e-06 -5.564 -5.564 -0.000 + Co+2 1.049e-07 1.049e-07 -6.979 -6.979 -0.000 + CoOH+ 9.212e-11 9.212e-11 -10.036 -10.036 -0.000 + CoOHNta-2 7.577e-11 7.577e-11 -10.120 -10.120 -0.000 + CoNta2-4 8.932e-14 8.932e-14 -13.049 -13.049 -0.000 + Co(OH)2 2.559e-17 2.559e-17 -16.592 -16.592 0.000 + Co(OH)3- 2.830e-19 2.830e-19 -18.548 -18.548 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.931 -43.931 0.000 +N 2.334e-07 + NH4+ 2.329e-07 2.329e-07 -6.633 -6.633 -0.000 + NH3 5.139e-10 5.139e-10 -9.289 -9.289 0.000 +Na 1.004e-03 + Na+ 1.004e-03 1.004e-03 -2.998 -2.998 -0.000 +Nta 2.963e-06 + CoNta- 2.728e-06 2.728e-06 -5.564 -5.564 -0.000 + HNta-2 2.352e-07 2.352e-07 -6.629 -6.629 -0.000 + CoOHNta-2 7.577e-11 7.577e-11 -10.120 -10.120 -0.000 + H2Nta- 5.342e-11 5.342e-11 -10.272 -10.272 -0.000 + Nta-3 5.190e-11 5.190e-11 -10.285 -10.285 -0.000 + CoNta2-4 8.932e-14 8.932e-14 -13.049 -13.049 -0.000 + H3Nta 4.830e-16 4.830e-16 -15.316 -15.316 0.000 +O(0) 6.072e-05 + O2 3.036e-05 3.036e-05 -4.518 -4.518 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 16. + +Transport step 16. Mixrun 1. + +Transport step 17. + +Transport step 17. Mixrun 1. + +Transport step 18. + +Transport step 18. Mixrun 1. + +Transport step 19. + +Transport step 19. Mixrun 1. + +Transport step 20. + +Transport step 20. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 144000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 5.782e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 3.305e-06 2.237e-04 H 0 + Co_sorption 7.697e-08 1.234e-06 CoCl2 1 + CoNta_sorption -1.235e-07 5.251e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.847e-06 1.847e-06 + Cl 9.990e-04 9.990e-04 + Co 2.681e-06 2.681e-06 + N 1.845e-07 1.845e-07 + Na 1.003e-03 1.003e-03 + Nta 2.767e-06 2.767e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.540 Charge balance + pe = 13.851 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.004e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.265e-05 + Total CO2 (mol/kg) = 1.847e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 19 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.881e-07 2.881e-07 -6.540 -6.540 -0.000 + OH- 3.471e-08 3.471e-08 -7.460 -7.460 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 1.847e-06 + HCO3- 1.123e-06 1.123e-06 -5.950 -5.950 -0.000 + CO2 7.243e-07 7.243e-07 -6.140 -6.140 0.000 + CO3-2 1.823e-10 1.823e-10 -9.739 -9.739 -0.000 +Cl 9.990e-04 + Cl- 9.990e-04 9.990e-04 -3.000 -3.000 -0.000 +Co 2.681e-06 + CoNta- 2.547e-06 2.547e-06 -5.594 -5.594 -0.000 + Co+2 1.332e-07 1.332e-07 -6.875 -6.875 -0.000 + CoOH+ 9.225e-11 9.225e-11 -10.035 -10.035 -0.000 + CoOHNta-2 5.579e-11 5.579e-11 -10.253 -10.253 -0.000 + CoNta2-4 6.133e-14 6.133e-14 -13.212 -13.212 -0.000 + Co(OH)2 2.020e-17 2.020e-17 -16.695 -16.695 0.000 + Co(OH)3- 1.761e-19 1.761e-19 -18.754 -18.754 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.933 -43.933 0.000 +N 1.845e-07 + NH4+ 1.841e-07 1.841e-07 -6.735 -6.735 -0.000 + NH3 3.203e-10 3.203e-10 -9.494 -9.494 0.000 +Na 1.003e-03 + Na+ 1.003e-03 1.003e-03 -2.999 -2.999 -0.000 +Nta 2.767e-06 + CoNta- 2.547e-06 2.547e-06 -5.594 -5.594 -0.000 + HNta-2 2.193e-07 2.193e-07 -6.659 -6.659 -0.000 + H2Nta- 6.319e-11 6.319e-11 -10.199 -10.199 -0.000 + CoOHNta-2 5.579e-11 5.579e-11 -10.253 -10.253 -0.000 + Nta-3 3.816e-11 3.816e-11 -10.418 -10.418 -0.000 + CoNta2-4 6.133e-14 6.133e-14 -13.212 -13.212 -0.000 + H3Nta 7.247e-16 7.247e-16 -15.140 -15.140 0.000 +O(0) 6.109e-05 + O2 3.055e-05 3.055e-05 -4.515 -4.515 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 21. + +Transport step 21. Mixrun 1. + +Transport step 22. + +Transport step 22. Mixrun 1. + +Transport step 23. + +Transport step 23. Mixrun 1. + +Transport step 24. + +Transport step 24. Mixrun 1. + +Transport step 25. + +Transport step 25. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 162000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 5.421e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 3.036e-06 2.396e-04 H 0 + Co_sorption 7.935e-08 1.630e-06 CoCl2 1 + CoNta_sorption -2.766e-07 4.115e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.473e-06 1.473e-06 + Cl 9.994e-04 9.994e-04 + Co 2.065e-06 2.065e-06 + N 1.336e-07 1.336e-07 + Na 1.002e-03 1.002e-03 + Nta 2.097e-06 2.097e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.412 Charge balance + pe = 13.980 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.003e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.478e-06 + Total CO2 (mol/kg) = 1.473e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 50 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.871e-07 3.871e-07 -6.412 -6.412 -0.000 + OH- 2.584e-08 2.584e-08 -7.588 -7.588 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 1.473e-06 + HCO3- 7.893e-07 7.893e-07 -6.103 -6.103 -0.000 + CO2 6.840e-07 6.840e-07 -6.165 -6.165 0.000 + CO3-2 9.539e-11 9.539e-11 -10.021 -10.021 -0.000 +Cl 9.994e-04 + Cl- 9.994e-04 9.994e-04 -3.000 -3.000 -0.000 +Co 2.065e-06 + CoNta- 1.909e-06 1.909e-06 -5.719 -5.719 -0.000 + Co+2 1.565e-07 1.565e-07 -6.806 -6.806 -0.000 + CoOH+ 8.067e-11 8.067e-11 -10.093 -10.093 -0.000 + CoOHNta-2 3.111e-11 3.111e-11 -10.507 -10.507 -0.000 + CoNta2-4 2.931e-14 2.931e-14 -13.533 -13.533 -0.000 + Co(OH)2 1.315e-17 1.315e-17 -16.881 -16.881 0.000 + Co(OH)3- 8.534e-20 8.534e-20 -19.069 -19.069 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.934 -43.934 0.000 +N 1.336e-07 + NH4+ 1.335e-07 1.335e-07 -6.875 -6.875 -0.000 + NH3 1.728e-10 1.728e-10 -9.762 -9.762 0.000 +Na 1.002e-03 + Na+ 1.002e-03 1.002e-03 -2.999 -2.999 -0.000 +Nta 2.097e-06 + CoNta- 1.909e-06 1.909e-06 -5.719 -5.719 -0.000 + HNta-2 1.879e-07 1.879e-07 -6.726 -6.726 -0.000 + H2Nta- 7.274e-11 7.274e-11 -10.138 -10.138 -0.000 + CoOHNta-2 3.111e-11 3.111e-11 -10.507 -10.507 -0.000 + Nta-3 2.434e-11 2.434e-11 -10.614 -10.614 -0.000 + CoNta2-4 2.931e-14 2.931e-14 -13.533 -13.533 -0.000 + H3Nta 1.121e-15 1.121e-15 -14.950 -14.950 0.000 +O(0) 6.148e-05 + O2 3.074e-05 3.074e-05 -4.512 -4.512 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 26. + +Transport step 26. Mixrun 1. + +Transport step 27. + +Transport step 27. Mixrun 1. + +Transport step 28. + +Transport step 28. Mixrun 1. + +Transport step 29. + +Transport step 29. Mixrun 1. + +Transport step 30. + +Transport step 30. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 180000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 4.557e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 2.444e-06 2.531e-04 H 0 + Co_sorption 7.182e-08 2.008e-06 CoCl2 1 + CoNta_sorption -2.844e-07 2.658e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.132e-06 1.132e-06 + Cl 9.997e-04 9.997e-04 + Co 1.349e-06 1.349e-06 + N 8.723e-08 8.723e-08 + Na 1.002e-03 1.002e-03 + Nta 1.324e-06 1.324e-06 + +----------------------------Description of solution---------------------------- + + pH = 6.278 Charge balance + pe = 14.115 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.002e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 6.102e-06 + Total CO2 (mol/kg) = 1.132e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 50 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 5.273e-07 5.273e-07 -6.278 -6.278 -0.000 + OH- 1.896e-08 1.896e-08 -7.722 -7.722 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 1.132e-06 + CO2 6.128e-07 6.128e-07 -6.213 -6.213 0.000 + HCO3- 5.191e-07 5.191e-07 -6.285 -6.285 -0.000 + CO3-2 4.605e-11 4.605e-11 -10.337 -10.337 -0.000 +Cl 9.997e-04 + Cl- 9.997e-04 9.997e-04 -3.000 -3.000 -0.000 +Co 1.349e-06 + CoNta- 1.179e-06 1.179e-06 -5.929 -5.929 -0.000 + Co+2 1.705e-07 1.705e-07 -6.768 -6.768 -0.000 + CoOH+ 6.450e-11 6.450e-11 -10.190 -10.190 -0.000 + CoOHNta-2 1.411e-11 1.411e-11 -10.851 -10.851 -0.000 + CoNta2-4 1.026e-14 1.026e-14 -13.989 -13.989 -0.000 + Co(OH)2 7.719e-18 7.719e-18 -17.112 -17.112 0.000 + Co(OH)3- 3.677e-20 3.677e-20 -19.435 -19.435 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.935 -43.935 0.000 +N 8.723e-08 + NH4+ 8.715e-08 8.715e-08 -7.060 -7.060 -0.000 + NH3 8.284e-11 8.284e-11 -10.082 -10.082 0.000 +Na 1.002e-03 + Na+ 1.002e-03 1.002e-03 -2.999 -2.999 -0.000 +Nta 1.324e-06 + CoNta- 1.179e-06 1.179e-06 -5.929 -5.929 -0.000 + HNta-2 1.452e-07 1.452e-07 -6.838 -6.838 -0.000 + H2Nta- 7.654e-11 7.654e-11 -10.116 -10.116 -0.000 + CoOHNta-2 1.411e-11 1.411e-11 -10.851 -10.851 -0.000 + Nta-3 1.380e-11 1.380e-11 -10.860 -10.860 -0.000 + CoNta2-4 1.026e-14 1.026e-14 -13.989 -13.989 -0.000 + H3Nta 1.607e-15 1.607e-15 -14.794 -14.794 0.000 +O(0) 6.184e-05 + O2 3.092e-05 3.092e-05 -4.510 -4.510 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 31. + +Transport step 31. Mixrun 1. + +Transport step 32. + +Transport step 32. Mixrun 1. + +Transport step 33. + +Transport step 33. Mixrun 1. + +Transport step 34. + +Transport step 34. Mixrun 1. + +Transport step 35. + +Transport step 35. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 198000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 3.282e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 1.593e-06 2.629e-04 H 0 + Co_sorption 5.514e-08 2.320e-06 CoCl2 1 + CoNta_sorption -2.069e-07 1.451e-06 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 8.578e-07 8.578e-07 + Cl 1.000e-03 1.000e-03 + Co 7.877e-07 7.877e-07 + N 4.998e-08 4.998e-08 + Na 1.001e-03 1.001e-03 + Nta 7.128e-07 7.128e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.162 Charge balance + pe = 14.231 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.002e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.419e-06 + Total CO2 (mol/kg) = 8.578e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 20 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.892e-07 6.892e-07 -6.162 -6.162 -0.000 + OH- 1.451e-08 1.451e-08 -7.838 -7.838 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 8.578e-07 + CO2 5.205e-07 5.205e-07 -6.284 -6.284 0.000 + HCO3- 3.373e-07 3.373e-07 -6.472 -6.472 -0.000 + CO3-2 2.289e-11 2.289e-11 -10.640 -10.640 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 7.877e-07 + CoNta- 6.150e-07 6.150e-07 -6.211 -6.211 -0.000 + Co+2 1.727e-07 1.727e-07 -6.763 -6.763 -0.000 + CoOH+ 4.999e-11 4.999e-11 -10.301 -10.301 -0.000 + CoOHNta-2 5.630e-12 5.630e-12 -11.249 -11.249 -0.000 + CoNta2-4 2.757e-15 2.757e-15 -14.560 -14.560 -0.000 + Co(OH)2 4.577e-18 4.577e-18 -17.339 -17.339 0.000 + Co(OH)3- 1.668e-20 1.668e-20 -19.778 -19.778 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.936 -43.936 0.000 +N 4.998e-08 + NH4+ 4.995e-08 4.995e-08 -7.301 -7.301 -0.000 + NH3 3.632e-11 3.632e-11 -10.440 -10.440 0.000 +Na 1.001e-03 + Na+ 1.001e-03 1.001e-03 -3.000 -3.000 -0.000 +Nta 7.128e-07 + CoNta- 6.150e-07 6.150e-07 -6.211 -6.211 -0.000 + HNta-2 9.771e-08 9.771e-08 -7.010 -7.010 -0.000 + H2Nta- 6.734e-11 6.734e-11 -10.172 -10.172 -0.000 + Nta-3 7.106e-12 7.106e-12 -11.148 -11.148 -0.000 + CoOHNta-2 5.630e-12 5.630e-12 -11.249 -11.249 -0.000 + CoNta2-4 2.757e-15 2.757e-15 -14.560 -14.560 -0.000 + H3Nta 1.848e-15 1.848e-15 -14.733 -14.733 0.000 +O(0) 6.212e-05 + O2 3.106e-05 3.106e-05 -4.508 -4.508 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 36. + +Transport step 36. Mixrun 1. + +Transport step 37. + +Transport step 37. Mixrun 1. + +Transport step 38. + +Transport step 38. Mixrun 1. + +Transport step 39. + +Transport step 39. Mixrun 1. + +Transport step 40. + +Transport step 40. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 216000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 1.946e-08 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 7.109e-07 2.681e-04 H 0 + Co_sorption 3.544e-08 2.536e-06 CoCl2 1 + CoNta_sorption -1.186e-07 6.881e-07 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 6.715e-07 6.715e-07 + Cl 1.000e-03 1.000e-03 + Co 4.456e-07 4.456e-07 + N 2.467e-08 2.467e-08 + Na 1.000e-03 1.000e-03 + Nta 3.350e-07 3.350e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.081 Charge balance + pe = 14.313 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.709e-06 + Total CO2 (mol/kg) = 6.715e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 8.307e-07 8.307e-07 -6.081 -6.081 -0.000 + OH- 1.204e-08 1.204e-08 -7.919 -7.919 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 6.715e-07 + CO2 4.367e-07 4.367e-07 -6.360 -6.360 0.000 + HCO3- 2.348e-07 2.348e-07 -6.629 -6.629 -0.000 + CO3-2 1.322e-11 1.322e-11 -10.879 -10.879 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 4.456e-07 + CoNta- 2.794e-07 2.794e-07 -6.554 -6.554 -0.000 + Co+2 1.662e-07 1.662e-07 -6.779 -6.779 -0.000 + CoOH+ 3.992e-11 3.992e-11 -10.399 -10.399 -0.000 + CoOHNta-2 2.122e-12 2.122e-12 -11.673 -11.673 -0.000 + CoNta2-4 5.911e-16 5.911e-16 -15.228 -15.228 -0.000 + Co(OH)2 3.032e-18 3.032e-18 -17.518 -17.518 0.000 + Co(OH)3- 9.168e-21 9.168e-21 -20.038 -20.038 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +N 2.467e-08 + NH4+ 2.465e-08 2.465e-08 -7.608 -7.608 -0.000 + NH3 1.487e-11 1.487e-11 -10.828 -10.828 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 3.350e-07 + CoNta- 2.794e-07 2.794e-07 -6.554 -6.554 -0.000 + HNta-2 5.558e-08 5.558e-08 -7.255 -7.255 -0.000 + H2Nta- 4.618e-11 4.618e-11 -10.336 -10.336 -0.000 + Nta-3 3.353e-12 3.353e-12 -11.475 -11.475 -0.000 + CoOHNta-2 2.122e-12 2.122e-12 -11.673 -11.673 -0.000 + H3Nta 1.527e-15 1.527e-15 -14.816 -14.816 0.000 + CoNta2-4 5.911e-16 5.911e-16 -15.228 -15.228 -0.000 +O(0) 6.232e-05 + O2 3.116e-05 3.116e-05 -4.506 -4.506 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 41. + +Transport step 41. Mixrun 1. + +Transport step 42. + +Transport step 42. Mixrun 1. + +Transport step 43. + +Transport step 43. Mixrun 1. + +Transport step 44. + +Transport step 44. Mixrun 1. + +Transport step 45. + +Transport step 45. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 234000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 9.475e-09 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass 5.654e-08 2.696e-04 H 0 + Co_sorption 2.003e-08 2.664e-06 CoCl2 1 + CoNta_sorption -5.697e-08 2.930e-07 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.676e-07 5.676e-07 + Cl 1.000e-03 1.000e-03 + Co 2.732e-07 2.732e-07 + N 1.054e-08 1.054e-08 + Na 1.000e-03 1.000e-03 + Nta 1.416e-07 1.416e-07 + +----------------------------Description of solution---------------------------- + + pH = 6.035 Charge balance + pe = 14.359 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.065e-07 + Total CO2 (mol/kg) = 5.676e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 23 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.228e-07 9.228e-07 -6.035 -6.035 -0.000 + OH- 1.084e-08 1.084e-08 -7.965 -7.965 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 5.676e-07 + CO2 3.825e-07 3.825e-07 -6.417 -6.417 0.000 + HCO3- 1.851e-07 1.851e-07 -6.733 -6.733 -0.000 + CO3-2 9.383e-12 9.383e-12 -11.028 -11.028 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 2.732e-07 + Co+2 1.583e-07 1.583e-07 -6.801 -6.801 -0.000 + CoNta- 1.149e-07 1.149e-07 -6.940 -6.940 -0.000 + CoOH+ 3.422e-11 3.422e-11 -10.466 -10.466 -0.000 + CoOHNta-2 7.856e-13 7.856e-13 -12.105 -12.105 -0.000 + CoNta2-4 1.050e-16 1.050e-16 -15.979 -15.979 -0.000 + Co(OH)2 2.339e-18 2.339e-18 -17.631 -17.631 0.000 + Co(OH)3- 6.368e-21 6.368e-21 -20.196 -20.196 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +N 1.054e-08 + NH4+ 1.054e-08 1.054e-08 -7.977 -7.977 -0.000 + NH3 5.723e-12 5.723e-12 -11.242 -11.242 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 1.416e-07 + CoNta- 1.149e-07 1.149e-07 -6.940 -6.940 -0.000 + HNta-2 2.667e-08 2.667e-08 -7.574 -7.574 -0.000 + H2Nta- 2.461e-11 2.461e-11 -10.609 -10.609 -0.000 + Nta-3 1.449e-12 1.449e-12 -11.839 -11.839 -0.000 + CoOHNta-2 7.856e-13 7.856e-13 -12.105 -12.105 -0.000 + H3Nta 9.043e-16 9.043e-16 -15.044 -15.044 0.000 + CoNta2-4 1.050e-16 1.050e-16 -15.979 -15.979 -0.000 +O(0) 6.242e-05 + O2 3.121e-05 3.121e-05 -4.506 -4.506 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 46. + +Transport step 46. Mixrun 1. + +Transport step 47. + +Transport step 47. Mixrun 1. + +Transport step 48. + +Transport step 48. Mixrun 1. + +Transport step 49. + +Transport step 49. Mixrun 1. + +Transport step 50. + +Transport step 50. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 252000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 3.947e-09 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass -3.021e-07 2.687e-04 H 0 + Co_sorption 1.119e-08 2.735e-06 CoCl2 1 + CoNta_sorption -2.428e-08 1.158e-07 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.197e-07 5.197e-07 + Cl 1.000e-03 1.000e-03 + Co 1.976e-07 1.976e-07 + N 4.028e-09 4.028e-09 + Na 1.000e-03 1.000e-03 + Nta 5.550e-08 5.550e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.014 Charge balance + pe = 14.380 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.997e-07 + Total CO2 (mol/kg) = 5.197e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 23 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.693e-07 9.693e-07 -6.014 -6.014 -0.000 + OH- 1.032e-08 1.032e-08 -7.986 -7.986 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 5.197e-07 + CO2 3.557e-07 3.557e-07 -6.449 -6.449 0.000 + HCO3- 1.639e-07 1.639e-07 -6.785 -6.785 -0.000 + CO3-2 7.911e-12 7.911e-12 -11.102 -11.102 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 1.976e-07 + Co+2 1.533e-07 1.533e-07 -6.815 -6.815 -0.000 + CoNta- 4.433e-08 4.433e-08 -7.353 -7.353 -0.000 + CoOH+ 3.155e-11 3.155e-11 -10.501 -10.501 -0.000 + CoOHNta-2 2.886e-13 2.886e-13 -12.540 -12.540 -0.000 + CoNta2-4 1.614e-17 1.614e-17 -16.792 -16.792 -0.000 + Co(OH)2 2.054e-18 2.054e-18 -17.687 -17.687 0.000 + Co(OH)3- 5.322e-21 5.322e-21 -20.274 -20.274 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +N 4.028e-09 + NH4+ 4.026e-09 4.026e-09 -8.395 -8.395 -0.000 + NH3 2.082e-12 2.082e-12 -11.682 -11.682 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 5.550e-08 + CoNta- 4.433e-08 4.433e-08 -7.353 -7.353 -0.000 + HNta-2 1.116e-08 1.116e-08 -7.952 -7.952 -0.000 + H2Nta- 1.082e-11 1.082e-11 -10.966 -10.966 -0.000 + Nta-3 5.770e-13 5.770e-13 -12.239 -12.239 -0.000 + CoOHNta-2 2.886e-13 2.886e-13 -12.540 -12.540 -0.000 + H3Nta 4.174e-16 4.174e-16 -15.379 -15.379 0.000 + CoNta2-4 1.614e-17 1.614e-17 -16.792 -16.792 -0.000 +O(0) 6.247e-05 + O2 3.124e-05 3.124e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +Transport step 51. + +Transport step 51. Mixrun 1. + +Transport step 52. + +Transport step 52. Mixrun 1. + +Transport step 53. + +Transport step 53. Mixrun 1. + +Transport step 54. + +Transport step 54. Mixrun 1. + +Transport step 55. + +Transport step 55. Mixrun 1. + +Using mix 10. +Using kinetics 10. Kinetics defined in simulation 3. + +Mixture 10. + + 6.000e-02 Solution 9 Solution after simulation 5. + 0.000e+00 Solution 11 Background solution initially filling column + 9.400e-01 Solution 10 Solution after simulation 5. + +Kinetics 10. Kinetics defined in simulation 3. + + Time: 270000 seconds + Time step: 3600 seconds + + Rate name Delta Moles Total Moles Reactant Coefficient + + HNTA-2 1.487e-09 1.000e+00 C -3.12 + H -1.968 + O -4.848 + N -0.424 + Nta 1 + Biomass -4.583e-07 2.667e-04 H 0 + Co_sorption 6.974e-09 2.777e-06 CoCl2 1 + CoNta_sorption -9.586e-09 4.346e-08 NaCoNta 1 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.005e-07 5.005e-07 + Cl 1.000e-03 1.000e-03 + Co 1.677e-07 1.677e-07 + N 1.429e-09 1.429e-09 + Na 1.000e-03 1.000e-03 + Nta 2.065e-08 2.065e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.005 Charge balance + pe = 14.389 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.001e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.359e-07 + Total CO2 (mol/kg) = 5.005e-07 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.387e-07 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.04 + Iterations = 23 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.888e-07 9.888e-07 -6.005 -6.005 -0.000 + OH- 1.011e-08 1.011e-08 -7.995 -7.995 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C 5.005e-07 + CO2 3.448e-07 3.448e-07 -6.462 -6.462 0.000 + HCO3- 1.558e-07 1.558e-07 -6.808 -6.808 -0.000 + CO3-2 7.368e-12 7.368e-12 -11.133 -11.133 -0.000 +Cl 1.000e-03 + Cl- 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Co 1.677e-07 + Co+2 1.513e-07 1.513e-07 -6.820 -6.820 -0.000 + CoNta- 1.638e-08 1.638e-08 -7.786 -7.786 -0.000 + CoOH+ 3.053e-11 3.053e-11 -10.515 -10.515 -0.000 + CoOHNta-2 1.045e-13 1.045e-13 -12.981 -12.981 -0.000 + CoNta2-4 2.232e-18 2.232e-18 -17.651 -17.651 -0.000 + Co(OH)2 1.948e-18 1.948e-18 -17.710 -17.710 0.000 + Co(OH)3- 4.948e-21 4.948e-21 -20.306 -20.306 -0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.937 -43.937 0.000 +N 1.429e-09 + NH4+ 1.429e-09 1.429e-09 -8.845 -8.845 -0.000 + NH3 7.241e-13 7.241e-13 -12.140 -12.140 0.000 +Na 1.000e-03 + Na+ 1.000e-03 1.000e-03 -3.000 -3.000 -0.000 +Nta 2.065e-08 + CoNta- 1.638e-08 1.638e-08 -7.786 -7.786 -0.000 + HNta-2 4.262e-09 4.262e-09 -8.370 -8.370 -0.000 + H2Nta- 4.214e-12 4.214e-12 -11.375 -11.375 -0.000 + Nta-3 2.160e-13 2.160e-13 -12.666 -12.666 -0.000 + CoOHNta-2 1.045e-13 1.045e-13 -12.981 -12.981 -0.000 + H3Nta 1.659e-16 1.659e-16 -15.780 -15.780 0.000 + CoNta2-4 2.232e-18 2.232e-18 -17.651 -17.651 -0.000 +O(0) 6.249e-05 + O2 3.125e-05 3.125e-05 -4.505 -4.505 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 6. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex15.sel b/Sun/examples/ex15.sel new file mode 100644 index 00000000..ecf04dff --- /dev/null +++ b/Sun/examples/ex15.sel @@ -0,0 +1,78 @@ + sim state soln dist_x time step pH pe m_Nta-3 m_CoNta- m_HNta-2 m_Co+2 hours Co_sorb CoNta_sorb Biomass + 1 transp 10 9.5 0 0 6 14.3937 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 5.0000e-01 0.0000e+00 0.0000e+00 0.0000e+00 + 1 transp 10 9.5 3600 1 6 14.3937 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 1.5000e+00 0.0000e+00 0.0000e+00 1.3572e-04 + 1 transp 10 9.5 7200 2 6 14.3937 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 2.5000e+00 0.0000e+00 0.0000e+00 1.3544e-04 + 1 transp 10 9.5 10800 3 6 14.3937 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 3.5000e+00 0.0000e+00 0.0000e+00 1.3515e-04 + 1 transp 10 9.5 14400 4 6 14.3937 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 4.5000e+00 0.0000e+00 0.0000e+00 1.3487e-04 + 1 transp 10 9.5 18000 5 6 14.3937 4.1637e-17 4.8355e-19 8.3076e-13 2.3172e-14 5.5000e+00 6.1781e-18 1.4377e-22 1.3459e-04 + 1 transp 10 9.5 21600 6 6.00019 14.3935 5.3587e-15 7.6672e-15 1.0687e-10 2.8548e-12 6.5000e+00 1.0994e-15 2.6066e-18 1.3431e-04 + 1 transp 10 9.5 25200 7 6.00441 14.3893 1.1039e-13 3.4338e-12 2.1803e-09 6.2065e-11 7.5000e+00 2.2731e-14 9.7754e-16 1.3406e-04 + 1 transp 10 9.5 28800 8 6.03587 14.3576 8.7248e-13 1.8088e-10 1.6028e-08 4.1366e-10 8.5000e+00 1.5703e-13 4.8045e-14 1.3399e-04 + 1 transp 10 9.5 32400 9 6.12883 14.264 3.7779e-12 1.9561e-09 5.6030e-08 1.0331e-09 9.5000e+00 4.8525e-13 5.5433e-13 1.3445e-04 + 1 transp 10 9.5 36000 10 6.2369 14.1549 9.6448e-12 8.0004e-09 1.1153e-07 1.6551e-09 1.0500e+01 9.8421e-13 2.4608e-12 1.3556e-04 + 1 transp 10 9.5 39600 11 6.30614 14.0851 1.5152e-11 2.0272e-08 1.4940e-07 2.6695e-09 1.1500e+01 1.7623e-12 6.7849e-12 1.3707e-04 + 1 transp 10 9.5 43200 12 6.35376 14.0371 1.9799e-11 4.1065e-08 1.7494e-07 4.1384e-09 1.2500e+01 2.9364e-12 1.4662e-11 1.3886e-04 + 1 transp 10 9.5 46800 13 6.3909 13.9998 2.3996e-11 7.2616e-08 1.9464e-07 6.0380e-09 1.3500e+01 4.6059e-12 2.7261e-11 1.4085e-04 + 1 transp 10 9.5 50400 14 6.4217 13.9688 2.7923e-11 1.1683e-07 2.1099e-07 8.3484e-09 1.4500e+01 6.8561e-12 4.5675e-11 1.4301e-04 + 1 transp 10 9.5 54000 15 6.44804 13.9423 3.1619e-11 1.7515e-07 2.2486e-07 1.1052e-08 1.5500e+01 9.7615e-12 7.0827e-11 1.4533e-04 + 1 transp 10 9.5 57600 16 6.47097 13.9193 3.5087e-11 2.4844e-07 2.3669e-07 1.4128e-08 1.6500e+01 1.3385e-11 1.0340e-10 1.4778e-04 + 1 transp 10 9.5 61200 17 6.49117 13.8989 3.8321e-11 3.3699e-07 2.4675e-07 1.7546e-08 1.7500e+01 1.7779e-11 1.4381e-10 1.5036e-04 + 1 transp 10 9.5 64800 18 6.50914 13.8808 4.1316e-11 4.4051e-07 2.5526e-07 2.1274e-08 1.8500e+01 2.2982e-11 1.9215e-10 1.5306e-04 + 1 transp 10 9.5 68400 19 6.52519 13.8647 4.4065e-11 5.5820e-07 2.6236e-07 2.5276e-08 1.9500e+01 2.9022e-11 2.4826e-10 1.5586e-04 + 1 transp 10 9.5 72000 20 6.53959 13.8502 4.6562e-11 6.8880e-07 2.6819e-07 2.9517e-08 2.0500e+01 3.5915e-11 3.1170e-10 1.5876e-04 + 2 transp 10 9.5 72000 0 6.53959 13.8502 4.6562e-11 6.8880e-07 2.6819e-07 2.9517e-08 2.0500e+01 0.0000e+00 0.0000e+00 0.0000e+00 + 2 transp 10 9.5 75600 1 6.55254 13.8371 4.8804e-11 8.3068e-07 2.7284e-07 3.3961e-08 2.1500e+01 4.3669e-11 3.8179e-10 1.6174e-04 + 2 transp 10 9.5 79200 2 6.56419 13.8254 5.0791e-11 9.8198e-07 2.7644e-07 3.8576e-08 2.2500e+01 5.2280e-11 4.5769e-10 1.6481e-04 + 2 transp 10 9.5 82800 3 6.57469 13.8148 5.2526e-11 1.1406e-06 2.7905e-07 4.3329e-08 2.3500e+01 6.1739e-11 5.3842e-10 1.6796e-04 + 2 transp 10 9.5 86400 4 6.58413 13.8053 5.4012e-11 1.3046e-06 2.8077e-07 4.8193e-08 2.4500e+01 7.2027e-11 6.2293e-10 1.7117e-04 + 2 transp 10 9.5 90000 5 6.59263 13.7967 5.5256e-11 1.4717e-06 2.8168e-07 5.3142e-08 2.5500e+01 8.3123e-11 7.1013e-10 1.7444e-04 + 2 transp 10 9.5 93600 6 6.60028 13.789 5.6269e-11 1.6400e-06 2.8183e-07 5.8153e-08 2.6500e+01 9.4998e-11 7.9893e-10 1.7778e-04 + 2 transp 10 9.5 97200 7 6.60754 13.7817 5.7056e-11 1.8075e-06 2.8103e-07 6.3208e-08 2.7500e+01 1.0762e-10 8.8826e-10 1.8116e-04 + 2 transp 10 9.5 100800 8 6.61795 13.7713 5.7637e-11 1.9718e-06 2.7717e-07 6.8258e-08 2.8500e+01 1.2096e-10 9.7697e-10 1.8457e-04 + 2 transp 10 9.5 104400 9 6.64212 13.7473 5.8212e-11 2.1299e-06 2.6478e-07 7.3002e-08 2.9500e+01 1.3490e-10 1.0636e-09 1.8791e-04 + 2 transp 10 9.5 108000 10 6.6795 13.7103 5.8949e-11 2.2783e-06 2.4602e-07 7.7114e-08 3.0500e+01 1.4924e-10 1.1465e-09 1.9109e-04 + 2 transp 10 9.5 111600 11 6.69156 13.6985 5.8746e-11 2.4117e-06 2.3846e-07 8.1911e-08 3.1500e+01 1.6415e-10 1.2236e-09 1.9424e-04 + 2 transp 10 9.5 115200 12 6.68638 13.7039 5.7684e-11 2.5260e-06 2.3696e-07 8.7374e-08 3.2500e+01 1.7978e-10 1.2925e-09 1.9741e-04 + 2 transp 10 9.5 118800 13 6.67462 13.7157 5.6097e-11 2.6183e-06 2.3676e-07 9.3127e-08 3.3500e+01 1.9616e-10 1.3514e-09 2.0062e-04 + 2 transp 10 9.5 122400 14 6.66009 13.7304 5.4144e-11 2.6860e-06 2.3630e-07 9.8982e-08 3.4500e+01 2.1330e-10 1.3987e-09 2.0387e-04 + 2 transp 10 9.5 126000 15 6.64373 13.7469 5.1900e-11 2.7276e-06 2.3520e-07 1.0486e-07 3.5500e+01 2.3114e-10 1.4332e-09 2.0716e-04 + 2 transp 10 9.5 129600 16 6.62579 13.7649 4.9419e-11 2.7424e-06 2.3341e-07 1.1072e-07 3.6500e+01 2.4964e-10 1.4540e-09 2.1047e-04 + 2 transp 10 9.5 133200 17 6.60638 13.7845 4.6754e-11 2.7304e-06 2.3091e-07 1.1652e-07 3.7500e+01 2.6875e-10 1.4608e-09 2.1379e-04 + 2 transp 10 9.5 136800 18 6.58562 13.8054 4.3956e-11 2.6927e-06 2.2772e-07 1.2223e-07 3.8500e+01 2.8841e-10 1.4537e-09 2.1712e-04 + 2 transp 10 9.5 140400 19 6.56361 13.8275 4.1075e-11 2.6309e-06 2.2386e-07 1.2780e-07 3.9500e+01 3.0854e-10 1.4333e-09 2.2044e-04 + 2 transp 10 9.5 144000 20 6.54047 13.8508 3.8158e-11 2.5474e-06 2.1934e-07 1.3320e-07 4.0500e+01 3.2906e-10 1.4004e-09 2.2375e-04 + 2 transp 10 9.5 147600 21 6.51631 13.8751 3.5247e-11 2.4449e-06 2.1419e-07 1.3841e-07 4.1500e+01 3.4990e-10 1.3562e-09 2.2702e-04 + 2 transp 10 9.5 151200 22 6.49127 13.9003 3.2379e-11 2.3266e-06 2.0845e-07 1.4337e-07 4.2500e+01 3.7097e-10 1.3021e-09 2.3026e-04 + 2 transp 10 9.5 154800 23 6.46547 13.9262 2.9588e-11 2.1956e-06 2.0213e-07 1.4806e-07 4.3500e+01 3.9217e-10 1.2398e-09 2.3344e-04 + 2 transp 10 9.5 158400 24 6.43907 13.9527 2.6899e-11 2.0552e-06 1.9529e-07 1.5245e-07 4.4500e+01 4.1340e-10 1.1710e-09 2.3656e-04 + 2 transp 10 9.5 162000 25 6.41223 13.9797 2.4336e-11 1.9087e-06 1.8794e-07 1.5649e-07 4.5500e+01 4.3456e-10 1.0972e-09 2.3959e-04 + 2 transp 10 9.5 165600 26 6.38512 14.0069 2.1913e-11 1.7589e-06 1.8013e-07 1.6016e-07 4.6500e+01 4.5554e-10 1.0202e-09 2.4253e-04 + 2 transp 10 9.5 169200 27 6.35794 14.0343 1.9643e-11 1.6088e-06 1.7189e-07 1.6342e-07 4.7500e+01 4.7623e-10 9.4150e-10 2.4537e-04 + 2 transp 10 9.5 172800 28 6.33089 14.0614 1.7532e-11 1.4607e-06 1.6329e-07 1.6624e-07 4.8500e+01 4.9652e-10 8.6254e-10 2.4809e-04 + 2 transp 10 9.5 176400 29 6.30416 14.0883 1.5584e-11 1.3168e-06 1.5436e-07 1.6859e-07 4.9500e+01 5.1630e-10 7.8460e-10 2.5068e-04 + 2 transp 10 9.5 180000 30 6.27797 14.1146 1.3798e-11 1.1788e-06 1.4516e-07 1.7047e-07 5.0500e+01 5.3545e-10 7.0877e-10 2.5312e-04 + 2 transp 10 9.5 183600 31 6.25252 14.1402 1.2170e-11 1.0482e-06 1.3576e-07 1.7185e-07 5.1500e+01 5.5388e-10 6.3597e-10 2.5541e-04 + 2 transp 10 9.5 187200 32 6.228 14.1648 1.0695e-11 9.2591e-07 1.2623e-07 1.7274e-07 5.2500e+01 5.7148e-10 5.6693e-10 2.5754e-04 + 2 transp 10 9.5 190800 33 6.20459 14.1883 9.3648e-12 8.1273e-07 1.1666e-07 1.7316e-07 5.3500e+01 5.8818e-10 5.0219e-10 2.5949e-04 + 2 transp 10 9.5 194400 34 6.18244 14.2105 8.1717e-12 7.0904e-07 1.0712e-07 1.7312e-07 5.4500e+01 6.0391e-10 4.4212e-10 2.6127e-04 + 2 transp 10 9.5 198000 35 6.16167 14.2314 7.1059e-12 6.1497e-07 9.7713e-08 1.7268e-07 5.5500e+01 6.1861e-10 3.8695e-10 2.6286e-04 + 2 transp 10 9.5 201600 36 6.14237 14.2508 6.1578e-12 5.3042e-07 8.8524e-08 1.7187e-07 5.6500e+01 6.3226e-10 3.3676e-10 2.6427e-04 + 2 transp 10 9.5 205200 37 6.12459 14.2686 5.3178e-12 4.5509e-07 7.9641e-08 1.7075e-07 5.7500e+01 6.4483e-10 2.9149e-10 2.6550e-04 + 2 transp 10 9.5 208800 38 6.10837 14.2849 4.5763e-12 3.8853e-07 7.1145e-08 1.6940e-07 5.8500e+01 6.5634e-10 2.5101e-10 2.6655e-04 + 2 transp 10 9.5 212400 39 6.09369 14.2996 3.9244e-12 3.3017e-07 6.3107e-08 1.6787e-07 5.9500e+01 6.6679e-10 2.1511e-10 2.6742e-04 + 2 transp 10 9.5 216000 40 6.08053 14.3129 3.3534e-12 2.7937e-07 5.5584e-08 1.6623e-07 6.0500e+01 6.7624e-10 1.8349e-10 2.6813e-04 + 2 transp 10 9.5 219600 41 6.06883 14.3246 2.8552e-12 2.3545e-07 4.8619e-08 1.6454e-07 6.1500e+01 6.8474e-10 1.5585e-10 2.6869e-04 + 2 transp 10 9.5 223200 42 6.05851 14.335 2.4224e-12 1.9772e-07 4.2241e-08 1.6286e-07 6.2500e+01 6.9233e-10 1.3184e-10 2.6910e-04 + 2 transp 10 9.5 226800 43 6.04948 14.3441 2.0479e-12 1.6548e-07 3.6461e-08 1.6123e-07 6.3500e+01 6.9911e-10 1.1112e-10 2.6938e-04 + 2 transp 10 9.5 230400 44 6.04163 14.3519 1.7253e-12 1.3809e-07 3.1277e-08 1.5969e-07 6.4500e+01 7.0513e-10 9.3326e-11 2.6955e-04 + 2 transp 10 9.5 234000 45 6.03487 14.3587 1.4485e-12 1.1491e-07 2.6672e-08 1.5827e-07 6.5500e+01 7.1047e-10 7.8132e-11 2.6960e-04 + 2 transp 10 9.5 237600 46 6.02908 14.3645 1.2122e-12 9.5378e-08 2.2620e-08 1.5699e-07 6.6500e+01 7.1521e-10 6.5220e-11 2.6957e-04 + 2 transp 10 9.5 241200 47 6.02415 14.3695 1.0113e-12 7.8988e-08 1.9086e-08 1.5585e-07 6.7500e+01 7.1941e-10 5.4292e-11 2.6945e-04 + 2 transp 10 9.5 244800 48 6.01999 14.3737 8.4110e-13 6.5277e-08 1.6027e-08 1.5485e-07 6.8500e+01 7.2315e-10 4.5082e-11 2.6926e-04 + 2 transp 10 9.5 248400 49 6.01648 14.3772 6.9760e-13 5.3842e-08 1.3400e-08 1.5400e-07 6.9500e+01 7.2648e-10 3.7348e-11 2.6901e-04 + 2 transp 10 9.5 252000 50 6.01355 14.3801 5.7705e-13 4.4330e-08 1.1160e-08 1.5328e-07 7.0500e+01 7.2947e-10 3.0873e-11 2.6870e-04 + 2 transp 10 9.5 255600 51 6.01111 14.3826 4.7615e-13 3.6437e-08 9.2604e-09 1.5268e-07 7.1500e+01 7.3215e-10 2.5469e-11 2.6836e-04 + 2 transp 10 9.5 259200 52 6.00908 14.3846 3.9198e-13 2.9901e-08 7.6592e-09 1.5220e-07 7.2500e+01 7.3458e-10 2.0972e-11 2.6798e-04 + 2 transp 10 9.5 262800 53 6.00741 14.3863 3.2200e-13 2.4501e-08 6.3161e-09 1.5182e-07 7.3500e+01 7.3678e-10 1.7238e-11 2.6756e-04 + 2 transp 10 9.5 266400 54 6.00603 14.3877 2.6398e-13 2.0046e-08 5.1944e-09 1.5152e-07 7.4500e+01 7.3880e-10 1.4145e-11 2.6713e-04 + 2 transp 10 9.5 270000 55 6.0049 14.3888 2.1600e-13 1.6379e-08 4.2615e-09 1.5130e-07 7.5500e+01 7.4066e-10 1.1589e-11 2.6667e-04 diff --git a/Sun/examples/ex16.log b/Sun/examples/ex16.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex16.out b/Sun/examples/ex16.out new file mode 100644 index 00000000..afb2e8ae --- /dev/null +++ b/Sun/examples/ex16.out @@ -0,0 +1,435 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex16 + Output file: ex16.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 16.--Inverse modeling of Sierra springs + SOLUTION_SPREAD + units mmol/L + Number pH Si Ca Mg Na K Alkalinity S(6) Cl + 1 6.2 0.273 0.078 0.029 0.134 0.028 0.328 0.01 0.014 + 2 6.8 0.41 0.26 0.071 0.259 0.04 0.895 0.025 0.03 + INVERSE_MODELING 1 + solutions 1 2 + uncertainty 0.025 + range + phases + Halite + Gypsum + Kaolinite precip + Ca-montmorillonite precip + CO2(g) + Calcite + Chalcedony precip + Biotite dissolve + Plagioclase dissolve + balances + Ca 0.05 0.025 + PHASES + Biotite + KMg3AlSi3O10(OH)2 + 6H+ + 4H2O = K+ + 3Mg+2 + Al(OH)4- + 3H4SiO4 + log_k 0.0 # No log_k, Inverse modeling only + Plagioclase + Na0.62Ca0.38Al1.38Si2.62O8 + 5.52 H+ + 2.48H2O = 0.62Na+ + 0.38Ca+2 + 1.38Al+3 + 2.62H4SiO4 + log_k 0.0 # No log_k, inverse modeling only + END +----- +TITLE +----- + + Example 16.--Inverse modeling of Sierra springs + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Alkalinity 3.280e-04 3.280e-04 + Ca 7.800e-05 7.800e-05 + Cl 1.400e-05 1.400e-05 + K 2.800e-05 2.800e-05 + Mg 2.900e-05 2.900e-05 + Na 1.340e-04 1.340e-04 + S(6) 1.000e-05 1.000e-05 + Si 2.730e-04 2.730e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.200 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 4.851e-04 + Mass of water (kg) = 1.000e+00 + Total carbon (mol/kg) = 7.825e-04 + Total CO2 (mol/kg) = 7.825e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 1.400e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 1.90 + Iterations = 7 + Total H = 1.110139e+02 + Total O = 5.550924e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.464e-07 6.310e-07 -6.189 -6.200 -0.011 + OH- 1.627e-08 1.587e-08 -7.789 -7.800 -0.011 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(4) 7.825e-04 + CO2 4.540e-04 4.540e-04 -3.343 -3.343 0.000 + HCO3- 3.281e-04 3.200e-04 -3.484 -3.495 -0.011 + CaHCO3+ 2.940e-07 2.868e-07 -6.532 -6.542 -0.011 + MgHCO3+ 1.003e-07 9.783e-08 -6.999 -7.010 -0.011 + CO3-2 2.628e-08 2.379e-08 -7.580 -7.624 -0.043 + NaHCO3 2.351e-08 2.352e-08 -7.629 -7.629 0.000 + CaCO3 2.806e-09 2.807e-09 -8.552 -8.552 0.000 + MgCO3 5.929e-10 5.930e-10 -9.227 -9.227 0.000 + NaCO3- 5.935e-11 5.788e-11 -10.227 -10.237 -0.011 +Ca 7.800e-05 + Ca+2 7.758e-05 7.023e-05 -4.110 -4.153 -0.043 + CaHCO3+ 2.940e-07 2.868e-07 -6.532 -6.542 -0.011 + CaSO4 1.244e-07 1.245e-07 -6.905 -6.905 0.000 + CaCO3 2.806e-09 2.807e-09 -8.552 -8.552 0.000 + CaOH+ 1.894e-11 1.847e-11 -10.723 -10.733 -0.011 + CaHSO4+ 4.717e-13 4.600e-13 -12.326 -12.337 -0.011 +Cl 1.400e-05 + Cl- 1.400e-05 1.365e-05 -4.854 -4.865 -0.011 +H(0) 5.636e-24 + H2 2.818e-24 2.818e-24 -23.550 -23.550 0.000 +K 2.800e-05 + K+ 2.800e-05 2.730e-05 -4.553 -4.564 -0.011 + KSO4- 1.747e-09 1.704e-09 -8.758 -8.769 -0.011 + KOH 1.500e-13 1.500e-13 -12.824 -12.824 0.000 +Mg 2.900e-05 + Mg+2 2.885e-05 2.612e-05 -4.540 -4.583 -0.043 + MgHCO3+ 1.003e-07 9.783e-08 -6.999 -7.010 -0.011 + MgSO4 5.438e-08 5.439e-08 -7.265 -7.264 0.000 + MgCO3 5.929e-10 5.930e-10 -9.227 -9.227 0.000 + MgOH+ 1.541e-10 1.503e-10 -9.812 -9.823 -0.011 +Na 1.340e-04 + Na+ 1.340e-04 1.307e-04 -3.873 -3.884 -0.011 + NaHCO3 2.351e-08 2.352e-08 -7.629 -7.629 0.000 + NaSO4- 5.964e-09 5.816e-09 -8.224 -8.235 -0.011 + NaCO3- 5.935e-11 5.788e-11 -10.227 -10.237 -0.011 + NaOH 1.368e-12 1.368e-12 -11.864 -11.864 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -45.280 -45.280 0.000 +S(6) 1.000e-05 + SO4-2 9.813e-06 8.882e-06 -5.008 -5.052 -0.043 + CaSO4 1.244e-07 1.245e-07 -6.905 -6.905 0.000 + MgSO4 5.438e-08 5.439e-08 -7.265 -7.264 0.000 + NaSO4- 5.964e-09 5.816e-09 -8.224 -8.235 -0.011 + KSO4- 1.747e-09 1.704e-09 -8.758 -8.769 -0.011 + HSO4- 5.587e-10 5.448e-10 -9.253 -9.264 -0.011 + CaHSO4+ 4.717e-13 4.600e-13 -12.326 -12.337 -0.011 +Si 2.730e-04 + H4SiO4 2.729e-04 2.730e-04 -3.564 -3.564 0.000 + H3SiO4- 6.541e-08 6.379e-08 -7.184 -7.195 -0.011 + H2SiO4-2 7.604e-15 6.877e-15 -14.119 -14.163 -0.044 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -4.84 -9.20 -4.36 CaSO4 + Aragonite -3.44 -11.78 -8.34 CaCO3 + Calcite -3.30 -11.78 -8.48 CaCO3 + Chalcedony -0.01 -3.56 -3.55 SiO2 + Chrysotile -15.88 16.32 32.20 Mg3Si2O5(OH)4 + CO2(g) -1.87 -3.34 -1.47 CO2 + Dolomite -6.89 -23.98 -17.09 CaMg(CO3)2 + Gypsum -4.62 -9.20 -4.58 CaSO4:2H2O + H2(g) -20.40 -23.55 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -10.33 -8.75 1.58 NaCl + O2(g) -42.32 -45.28 -2.96 O2 + Quartz 0.42 -3.56 -3.98 SiO2 + Sepiolite -10.82 4.94 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -13.72 4.94 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -0.85 -3.56 -2.71 SiO2 + Talc -12.20 9.20 21.40 Mg3Si4O10(OH)2 + +Initial solution 2. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Alkalinity 8.951e-04 8.951e-04 + Ca 2.600e-04 2.600e-04 + Cl 3.000e-05 3.000e-05 + K 4.000e-05 4.000e-05 + Mg 7.101e-05 7.101e-05 + Na 2.590e-04 2.590e-04 + S(6) 2.500e-05 2.500e-05 + Si 4.100e-04 4.100e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.800 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.313e-03 + Mass of water (kg) = 1.000e+00 + Total carbon (mol/kg) = 1.199e-03 + Total CO2 (mol/kg) = 1.199e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.400e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.73 + Iterations = 6 + Total H = 1.110150e+02 + Total O = 5.551125e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.647e-07 1.585e-07 -6.783 -6.800 -0.017 + OH- 6.579e-08 6.316e-08 -7.182 -7.200 -0.018 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(4) 1.199e-03 + HCO3- 8.907e-04 8.559e-04 -3.050 -3.068 -0.017 + CO2 3.049e-04 3.050e-04 -3.516 -3.516 0.000 + CaHCO3+ 2.485e-06 2.387e-06 -5.605 -5.622 -0.017 + MgHCO3+ 6.235e-07 5.987e-07 -6.205 -6.223 -0.018 + CO3-2 2.971e-07 2.533e-07 -6.527 -6.596 -0.069 + NaHCO3 1.196e-07 1.197e-07 -6.922 -6.922 0.000 + CaCO3 9.299e-08 9.302e-08 -7.032 -7.031 0.000 + MgCO3 1.444e-08 1.445e-08 -7.840 -7.840 0.000 + NaCO3- 1.221e-09 1.173e-09 -8.913 -8.931 -0.018 +Ca 2.600e-04 + Ca+2 2.566e-04 2.186e-04 -3.591 -3.660 -0.069 + CaHCO3+ 2.485e-06 2.387e-06 -5.605 -5.622 -0.017 + CaSO4 8.841e-07 8.843e-07 -6.054 -6.053 0.000 + CaCO3 9.299e-08 9.302e-08 -7.032 -7.031 0.000 + CaOH+ 2.384e-10 2.289e-10 -9.623 -9.640 -0.018 + CaHSO4+ 8.551e-13 8.211e-13 -12.068 -12.086 -0.018 +Cl 3.000e-05 + Cl- 3.000e-05 2.880e-05 -4.523 -4.541 -0.018 +H(0) 3.555e-25 + H2 1.778e-25 1.778e-25 -24.750 -24.750 0.000 +K 4.000e-05 + K+ 4.000e-05 3.840e-05 -4.398 -4.416 -0.018 + KSO4- 5.696e-09 5.470e-09 -8.244 -8.262 -0.018 + KOH 8.398e-13 8.401e-13 -12.076 -12.076 0.000 +Mg 7.101e-05 + Mg+2 7.008e-05 5.978e-05 -4.154 -4.223 -0.069 + MgHCO3+ 6.235e-07 5.987e-07 -6.205 -6.223 -0.018 + MgSO4 2.840e-07 2.841e-07 -6.547 -6.547 0.000 + MgCO3 1.444e-08 1.445e-08 -7.840 -7.840 0.000 + MgOH+ 1.426e-09 1.370e-09 -8.846 -8.863 -0.018 +Na 2.590e-04 + Na+ 2.589e-04 2.486e-04 -3.587 -3.604 -0.018 + NaHCO3 1.196e-07 1.197e-07 -6.922 -6.922 0.000 + NaSO4- 2.631e-08 2.526e-08 -7.580 -7.598 -0.018 + NaCO3- 1.221e-09 1.173e-09 -8.913 -8.931 -0.018 + NaOH 1.036e-11 1.036e-11 -10.985 -10.984 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.880 -42.880 0.000 +S(6) 2.500e-05 + SO4-2 2.380e-05 2.027e-05 -4.623 -4.693 -0.070 + CaSO4 8.841e-07 8.843e-07 -6.054 -6.053 0.000 + MgSO4 2.840e-07 2.841e-07 -6.547 -6.547 0.000 + NaSO4- 2.631e-08 2.526e-08 -7.580 -7.598 -0.018 + KSO4- 5.696e-09 5.470e-09 -8.244 -8.262 -0.018 + HSO4- 3.253e-10 3.124e-10 -9.488 -9.505 -0.018 + CaHSO4+ 8.551e-13 8.211e-13 -12.068 -12.086 -0.018 +Si 4.100e-04 + H4SiO4 4.096e-04 4.098e-04 -3.388 -3.387 0.000 + H3SiO4- 3.970e-07 3.812e-07 -6.401 -6.419 -0.018 + H2SiO4-2 1.924e-13 1.636e-13 -12.716 -12.786 -0.070 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.99 -8.35 -4.36 CaSO4 + Aragonite -1.92 -10.26 -8.34 CaCO3 + Calcite -1.78 -10.26 -8.48 CaCO3 + Chalcedony 0.16 -3.39 -3.55 SiO2 + Chrysotile -10.85 21.35 32.20 Mg3Si2O5(OH)4 + CO2(g) -2.05 -3.52 -1.47 CO2 + Dolomite -3.99 -21.08 -17.09 CaMg(CO3)2 + Gypsum -3.77 -8.35 -4.58 CaSO4:2H2O + H2(g) -21.60 -24.75 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -9.73 -8.14 1.58 NaCl + O2(g) -39.92 -42.88 -2.96 O2 + Quartz 0.59 -3.39 -3.98 SiO2 + Sepiolite -7.17 8.59 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -10.07 8.59 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -0.68 -3.39 -2.71 SiO2 + Talc -6.82 14.58 21.40 Mg3Si4O10(OH)2 + +------------------------------------------- +Beginning of inverse modeling calculations. +------------------------------------------- + + +Solution 1: + + Input Delta Input+Delta + pH 6.200e+00 + 1.246e-02 = 6.212e+00 + Al 0.000e+00 + 0.000e+00 = 0.000e+00 + Alkalinity 3.280e-04 + 5.500e-06 = 3.335e-04 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 7.825e-04 + 0.000e+00 = 7.825e-04 + Ca 7.800e-05 + -3.900e-06 = 7.410e-05 + Cl 1.400e-05 + 0.000e+00 = 1.400e-05 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 2.800e-05 + -7.000e-07 = 2.730e-05 + Mg 2.900e-05 + 0.000e+00 = 2.900e-05 + Na 1.340e-04 + 0.000e+00 = 1.340e-04 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 1.000e-05 + 0.000e+00 = 1.000e-05 + Si 2.730e-04 + 0.000e+00 = 2.730e-04 + +Solution 2: + + Input Delta Input+Delta + pH 6.800e+00 + -3.407e-03 = 6.797e+00 + Al 0.000e+00 + 0.000e+00 = 0.000e+00 + Alkalinity 8.951e-04 + -1.796e-06 = 8.933e-04 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 1.199e-03 + 0.000e+00 = 1.199e-03 + Ca 2.600e-04 + 6.501e-06 = 2.665e-04 + Cl 3.000e-05 + 0.000e+00 = 3.000e-05 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 4.000e-05 + 1.000e-06 = 4.100e-05 + Mg 7.101e-05 + -8.979e-07 = 7.011e-05 + Na 2.590e-04 + 0.000e+00 = 2.590e-04 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 2.500e-05 + 0.000e+00 = 2.500e-05 + Si 4.100e-04 + 0.000e+00 = 4.100e-04 + +Solution fractions: Minimum Maximum + Solution 1 1.000e+00 1.000e+00 1.000e+00 + Solution 2 1.000e+00 1.000e+00 1.000e+00 + +Phase mole transfers: Minimum Maximum + Halite 1.600e-05 1.490e-05 1.710e-05 NaCl + Gypsum 1.500e-05 1.413e-05 1.588e-05 CaSO4:2H2O + Kaolinite -3.392e-05 -5.587e-05 -1.224e-05 Al2Si2O5(OH)4 +Ca-Montmorillon -8.090e-05 -1.100e-04 -5.154e-05 Ca0.165Al2.33Si3.67O10(OH)2 + CO2(g) 2.928e-04 2.363e-04 3.563e-04 CO2 + Calcite 1.240e-04 1.007e-04 1.309e-04 CaCO3 + Biotite 1.370e-05 1.317e-05 1.370e-05 KMg3AlSi3O10(OH)2 + Plagioclase 1.758e-04 1.582e-04 1.935e-04 Na0.62Ca0.38Al1.38Si2.62O8 + +Redox mole transfers: + +Sum of residuals (epsilons in documentation): 5.574e+00 +Sum of delta/uncertainty limit: 5.574e+00 +Maximum fractional error in element concentration: 5.000e-02 + +Model contains minimum number of phases. +=============================================================================== + + +Solution 1: + + Input Delta Input+Delta + pH 6.200e+00 + 1.246e-02 = 6.212e+00 + Al 0.000e+00 + 0.000e+00 = 0.000e+00 + Alkalinity 3.280e-04 + 5.500e-06 = 3.335e-04 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 7.825e-04 + 0.000e+00 = 7.825e-04 + Ca 7.800e-05 + -3.900e-06 = 7.410e-05 + Cl 1.400e-05 + 0.000e+00 = 1.400e-05 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 2.800e-05 + -7.000e-07 = 2.730e-05 + Mg 2.900e-05 + 0.000e+00 = 2.900e-05 + Na 1.340e-04 + 0.000e+00 = 1.340e-04 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 1.000e-05 + 0.000e+00 = 1.000e-05 + Si 2.730e-04 + 0.000e+00 = 2.730e-04 + +Solution 2: + + Input Delta Input+Delta + pH 6.800e+00 + -3.407e-03 = 6.797e+00 + Al 0.000e+00 + 0.000e+00 = 0.000e+00 + Alkalinity 8.951e-04 + -1.796e-06 = 8.933e-04 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 1.199e-03 + 0.000e+00 = 1.199e-03 + Ca 2.600e-04 + 6.501e-06 = 2.665e-04 + Cl 3.000e-05 + 0.000e+00 = 3.000e-05 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 4.000e-05 + 1.000e-06 = 4.100e-05 + Mg 7.101e-05 + -8.980e-07 = 7.011e-05 + Na 2.590e-04 + 0.000e+00 = 2.590e-04 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 2.500e-05 + 0.000e+00 = 2.500e-05 + Si 4.100e-04 + 0.000e+00 = 4.100e-04 + +Solution fractions: Minimum Maximum + Solution 1 1.000e+00 1.000e+00 1.000e+00 + Solution 2 1.000e+00 1.000e+00 1.000e+00 + +Phase mole transfers: Minimum Maximum + Halite 1.600e-05 1.490e-05 1.710e-05 NaCl + Gypsum 1.500e-05 1.413e-05 1.588e-05 CaSO4:2H2O + Kaolinite -1.282e-04 -1.403e-04 -1.159e-04 Al2Si2O5(OH)4 + CO2(g) 3.061e-04 2.490e-04 3.703e-04 CO2 + Calcite 1.106e-04 8.680e-05 1.182e-04 CaCO3 + Chalcedony -1.084e-04 -1.473e-04 -6.906e-05 SiO2 + Biotite 1.370e-05 1.317e-05 1.370e-05 KMg3AlSi3O10(OH)2 + Plagioclase 1.758e-04 1.582e-04 1.935e-04 Na0.62Ca0.38Al1.38Si2.62O8 + +Redox mole transfers: + +Sum of residuals (epsilons in documentation): 5.574e+00 +Sum of delta/uncertainty limit: 5.574e+00 +Maximum fractional error in element concentration: 5.000e-02 + +Model contains minimum number of phases. +=============================================================================== + + +Summary of inverse modeling: + + Number of models found: 2 + Number of minimal models found: 2 + Number of infeasible sets of phases saved: 20 + Number of calls to cl1: 62 +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex17.log b/Sun/examples/ex17.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex17.out b/Sun/examples/ex17.out new file mode 100644 index 00000000..857c94be --- /dev/null +++ b/Sun/examples/ex17.out @@ -0,0 +1,349 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex17 + Output file: ex17.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 17.--Inverse modeling of Black Sea water evaporation + SOLUTION 1 Black Sea water + units mg/L + density 1.014 + pH 8.0 # estimated + Ca 233 + Mg 679 + Na 5820 + K 193 + S(6) 1460 + Cl 10340 + Br 35 + C 1 CO2(g) -3.5 + SOLUTION 2 Composition during halite precipitation + units mg/L + density 1.271 + pH 5.0 # estimated + Ca 0.0 + Mg 50500 + Na 55200 + K 15800 + S(6) 76200 + Cl 187900 + Br 2670 + C 1 CO2(g) -3.5 + INVERSE_MODELING + solutions 1 2 + uncertainties .025 + range + balances + Br + K + Mg + phases + H2O(g) pre + Calcite pre + CO2(g) pre + Gypsum pre + Halite pre + END +----- +TITLE +----- + + Example 17.--Inverse modeling of Black Sea water evaporation + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Black Sea water + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Br 4.401e-04 4.401e-04 + C 8.284e-04 8.284e-04 Equilibrium with CO2(g) + Ca 5.841e-03 5.841e-03 + Cl 2.930e-01 2.930e-01 + K 4.959e-03 4.959e-03 + Mg 2.806e-02 2.806e-02 + Na 2.544e-01 2.544e-01 + S(6) 1.527e-02 1.527e-02 + +----------------------------Description of solution---------------------------- + + pH = 8.000 + pe = 4.000 + Activity of water = 0.990 + Ionic strength = 3.540e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.625e-04 + Total CO2 (mol/kg) = 8.284e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.240e-03 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.36 + Iterations = 5 + Total H = 1.110132e+02 + Total O = 5.556978e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.500e-06 9.909e-07 -5.824 -6.004 -0.180 + H+ 1.288e-08 1.000e-08 -7.890 -8.000 -0.110 + H2O 5.551e+01 9.899e-01 1.744 -0.004 0.000 +Br 4.401e-04 + Br- 4.401e-04 2.835e-04 -3.356 -3.547 -0.191 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -76.604 -76.569 0.035 +C(4) 8.284e-04 + HCO3- 6.657e-04 4.740e-04 -3.177 -3.324 -0.147 + MgHCO3+ 5.725e-05 4.187e-05 -4.242 -4.378 -0.136 + NaHCO3 4.444e-05 4.822e-05 -4.352 -4.317 0.035 + MgCO3 1.476e-05 1.601e-05 -4.831 -4.796 0.035 + CaHCO3+ 1.247e-05 8.879e-06 -4.904 -5.052 -0.147 + NaCO3- 1.024e-05 7.488e-06 -4.990 -5.126 -0.136 + CO2 9.923e-06 1.077e-05 -5.003 -4.968 0.035 + CO3-2 8.646e-06 2.223e-06 -5.063 -5.653 -0.590 + CaCO3 5.053e-06 5.483e-06 -5.296 -5.261 0.035 +Ca 5.841e-03 + Ca+2 5.267e-03 1.468e-03 -2.278 -2.833 -0.555 + CaSO4 5.563e-04 6.035e-04 -3.255 -3.219 0.035 + CaHCO3+ 1.247e-05 8.879e-06 -4.904 -5.052 -0.147 + CaCO3 5.053e-06 5.483e-06 -5.296 -5.261 0.035 + CaOH+ 3.298e-08 2.412e-08 -7.482 -7.618 -0.136 + CaHSO4+ 4.835e-11 3.536e-11 -10.316 -10.452 -0.136 +Cl 2.930e-01 + Cl- 2.930e-01 1.960e-01 -0.533 -0.708 -0.175 +H(0) 1.305e-27 + H2 6.525e-28 7.079e-28 -27.185 -27.150 0.035 +K 4.959e-03 + K+ 4.895e-03 3.274e-03 -2.310 -2.485 -0.175 + KSO4- 6.480e-05 4.739e-05 -4.188 -4.324 -0.136 + KOH 1.036e-09 1.124e-09 -8.985 -8.949 0.035 +Mg 2.806e-02 + Mg+2 2.463e-02 7.549e-03 -1.609 -2.122 -0.514 + MgSO4 3.360e-03 3.646e-03 -2.474 -2.438 0.035 + MgHCO3+ 5.725e-05 4.187e-05 -4.242 -4.378 -0.136 + MgCO3 1.476e-05 1.601e-05 -4.831 -4.796 0.035 + MgOH+ 3.710e-06 2.713e-06 -5.431 -5.567 -0.136 +Na 2.544e-01 + Na+ 2.518e-01 1.809e-01 -0.599 -0.743 -0.144 + NaSO4- 2.554e-03 1.868e-03 -2.593 -2.729 -0.136 + NaHCO3 4.444e-05 4.822e-05 -4.352 -4.317 0.035 + NaCO3- 1.024e-05 7.488e-06 -4.990 -5.126 -0.136 + NaOH 1.090e-07 1.183e-07 -6.962 -6.927 0.035 +O(0) 1.502e-38 + O2 7.512e-39 8.150e-39 -38.124 -38.089 0.035 +S(6) 1.527e-02 + SO4-2 8.735e-03 2.060e-03 -2.059 -2.686 -0.627 + MgSO4 3.360e-03 3.646e-03 -2.474 -2.438 0.035 + NaSO4- 2.554e-03 1.868e-03 -2.593 -2.729 -0.136 + CaSO4 5.563e-04 6.035e-04 -3.255 -3.219 0.035 + KSO4- 6.480e-05 4.739e-05 -4.188 -4.324 -0.136 + HSO4- 2.739e-09 2.003e-09 -8.562 -8.698 -0.136 + CaHSO4+ 4.835e-11 3.536e-11 -10.316 -10.452 -0.136 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -1.16 -5.52 -4.36 CaSO4 + Aragonite -0.15 -8.49 -8.34 CaCO3 + Calcite -0.01 -8.49 -8.48 CaCO3 + CH4(g) -73.71 -76.57 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Dolomite 0.83 -16.26 -17.09 CaMg(CO3)2 + Gypsum -0.95 -5.53 -4.58 CaSO4:2H2O + H2(g) -24.00 -27.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -3.03 -1.45 1.58 NaCl + O2(g) -35.13 -38.09 -2.96 O2 + +Initial solution 2. Composition during halite precipitation + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Br 3.785e-02 3.785e-02 + C 7.019e-06 7.019e-06 Equilibrium with CO2(g) + Cl 6.004e+00 6.004e+00 + K 4.578e-01 4.578e-01 + Mg 2.353e+00 2.353e+00 + Na 2.720e+00 2.720e+00 + S(6) 8.986e-01 8.986e-01 + +----------------------------Description of solution---------------------------- + + pH = 5.000 + pe = 4.000 + Activity of water = 0.802 + Ionic strength = 7.827e+00 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -9.195e-06 + Total CO2 (mol/kg) = 7.019e-06 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 4.491e-02 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.36 + Iterations = 10 + Total H = 1.110125e+02 + Total O = 5.910064e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.425e-05 1.000e-05 -4.846 -5.000 -0.154 + OH- 1.749e-09 8.029e-10 -8.757 -9.095 -0.338 + H2O 5.551e+01 8.021e-01 1.744 -0.096 0.000 +Br 3.785e-02 + Br- 3.785e-02 1.580e-02 -1.422 -1.801 -0.379 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -53.169 -52.386 0.783 +C(4) 7.019e-06 + MgHCO3+ 4.391e-06 2.905e-05 -5.357 -4.537 0.821 + CO2 1.776e-06 1.077e-05 -5.751 -4.968 0.783 + HCO3- 6.660e-07 3.841e-07 -6.177 -6.416 -0.239 + NaHCO3 1.847e-07 1.120e-06 -6.734 -5.951 0.783 + MgCO3 1.833e-09 1.111e-08 -8.737 -7.954 0.783 + NaCO3- 2.628e-11 1.739e-10 -10.580 -9.760 0.821 + CO3-2 1.629e-11 1.801e-12 -10.788 -11.744 -0.956 +Cl 6.004e+00 + Cl- 6.004e+00 3.612e+00 0.778 0.558 -0.221 +H(0) 2.335e-22 + H2 1.168e-22 7.079e-22 -21.933 -21.150 0.783 +K 4.578e-01 + K+ 4.568e-01 2.748e-01 -0.340 -0.561 -0.221 + KSO4- 9.513e-04 6.294e-03 -3.022 -2.201 0.821 + KOH 1.261e-11 7.643e-11 -10.899 -10.117 0.783 +Mg 2.353e+00 + Mg+2 1.538e+00 6.465e+00 0.187 0.811 0.624 + MgSO4 8.148e-01 4.940e+00 -0.089 0.694 0.783 + MgHCO3+ 4.391e-06 2.905e-05 -5.357 -4.537 0.821 + MgOH+ 2.845e-07 1.883e-06 -6.546 -5.725 0.821 + MgCO3 1.833e-09 1.111e-08 -8.737 -7.954 0.783 +Na 2.720e+00 + Na+ 2.707e+00 5.184e+00 0.433 0.715 0.282 + NaSO4- 1.280e-02 8.469e-02 -1.893 -1.072 0.821 + NaHCO3 1.847e-07 1.120e-06 -6.734 -5.951 0.783 + NaOH 4.531e-10 2.747e-09 -9.344 -8.561 0.783 + NaCO3- 2.628e-11 1.739e-10 -10.580 -9.760 0.821 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -51.054 -50.272 0.783 +S(6) 8.986e-01 + MgSO4 8.148e-01 4.940e+00 -0.089 0.694 0.783 + SO4-2 7.004e-02 3.259e-03 -1.155 -2.487 -1.332 + NaSO4- 1.280e-02 8.469e-02 -1.893 -1.072 0.821 + KSO4- 9.513e-04 6.294e-03 -3.022 -2.201 0.821 + HSO4- 4.789e-07 3.169e-06 -6.320 -5.499 0.821 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + CH4(g) -49.53 -52.39 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + H2(g) -18.00 -21.15 -3.15 H2 + H2O(g) -1.61 -0.10 1.51 H2O + Halite -0.31 1.27 1.58 NaCl + O2(g) -47.31 -50.27 -2.96 O2 + +------------------------------------------- +Beginning of inverse modeling calculations. +------------------------------------------- + + +Solution 1: Black Sea water + + Input Delta Input+Delta + pH 8.000e+00 + 0.000e+00 = 8.000e+00 + Alkalinity 8.625e-04 + 0.000e+00 = 8.625e-04 + Br 4.401e-04 + 0.000e+00 = 4.401e-04 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 8.284e-04 + 0.000e+00 = 8.284e-04 + Ca 5.841e-03 + 0.000e+00 = 5.841e-03 + Cl 2.930e-01 + 7.845e-04 = 2.938e-01 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 4.959e-03 + 1.034e-04 = 5.063e-03 + Mg 2.806e-02 + -7.016e-04 = 2.736e-02 + Na 2.544e-01 + 0.000e+00 = 2.544e-01 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 1.527e-02 + 7.768e-05 = 1.535e-02 + +Solution 2: Composition during halite precipitation + + Input Delta Input+Delta + pH 5.000e+00 + 5.711e-14 = 5.000e+00 + Alkalinity -9.195e-06 + 0.000e+00 = -9.195e-06 + Br 3.785e-02 + 9.440e-04 = 3.880e-02 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 7.019e-06 + 0.000e+00 = 7.019e-06 + Ca 0.000e+00 + 0.000e+00 = 0.000e+00 + Cl 6.004e+00 + 1.501e-01 = 6.154e+00 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 4.578e-01 + -1.144e-02 = 4.463e-01 + Mg 2.353e+00 + 5.883e-02 = 2.412e+00 + Na 2.720e+00 + -4.500e-02 = 2.675e+00 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 8.986e-01 + -2.247e-02 = 8.761e-01 + +Solution fractions: Minimum Maximum + Solution 1 8.815e+01 8.780e+01 8.815e+01 + Solution 2 1.000e+00 1.000e+00 1.000e+00 + +Phase mole transfers: Minimum Maximum + H2O(g) -4.837e+03 -4.817e+03 -4.817e+03 H2O + Calcite -3.802e-02 -3.897e-02 -3.692e-02 CaCO3 + CO2(g) -3.500e-02 -3.615e-02 -3.371e-02 CO2 + Gypsum -4.769e-01 -4.907e-01 -4.612e-01 CaSO4:2H2O + Halite -1.975e+01 -2.033e+01 -1.901e+01 NaCl + +Redox mole transfers: + +Sum of residuals (epsilons in documentation): 1.947e+02 +Sum of delta/uncertainty limit: 7.804e+00 +Maximum fractional error in element concentration: 2.500e-02 + +Model contains minimum number of phases. +=============================================================================== + + +Summary of inverse modeling: + + Number of models found: 1 + Number of minimal models found: 1 + Number of infeasible sets of phases saved: 6 + Number of calls to cl1: 22 +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex18.log b/Sun/examples/ex18.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex18.out b/Sun/examples/ex18.out new file mode 100644 index 00000000..106cdf99 --- /dev/null +++ b/Sun/examples/ex18.out @@ -0,0 +1,550 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex18 + Output file: ex18.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 18.--Inverse modeling of Madison aquifer + SOLUTION 1 Recharge number 3 + units mmol/kgw + temp 9.9 + pe 0. + pH 7.55 + Ca 1.2 + Mg 1.01 + Na 0.02 + K 0.02 + Fe(2) 0.001 + Cl 0.02 + S(6) 0.16 + S(-2) 0 + C(4) 4.30 + isotope 13C -7.0 1.4 + isotope 34S 9.7 0.9 + SOLUTION 2 Mysse + units mmol/kgw + temp 63. + pH 6.61 + pe 0. + redox S(6)/S(-2) + Ca 11.28 + Mg 4.54 + Na 31.89 + K 2.54 + Fe(2) 0.0004 + Cl 17.85 + S(6) 19.86 + S(-2) 0.26 + C(4) 6.87 + isotope 13C -2.3 0.2 + isotope 34S(6) 16.3 1.5 + isotope 34S(-2) -22.1 7 + INVERSE_MODELING 1 + solutions 1 2 + uncertainty 0.05 + range + isotopes + 13C + 34S + balances + Fe(2) 1.0 + ph 0.1 + phases + Dolomite dis 13C 3.0 2 + Calcite pre 13C -1.5 1 + Anhydrite dis 34S 13.5 2 + CH2O dis 13C -25.0 5 + Goethite + Pyrite pre 34S -22. 2 + CaX2 pre + Ca.75Mg.25X2 pre + MgX2 pre + NaX + Halite + Sylvite + PHASES + Sylvite + KCl = K+ + Cl- + log_k 0.0 + CH2O + CH2O + H2O = CO2 + 4H+ + 4e- + log_k 0.0 + EXCHANGE_SPECIES + 0.75Ca+2 + 0.25Mg+2 + 2X- = Ca.75Mg.25X2 + log_k 0.0 + END +----- +TITLE +----- + + Example 18.--Inverse modeling of Madison aquifer + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Recharge number 3 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C(4) 4.300e-03 4.300e-03 + Ca 1.200e-03 1.200e-03 + Cl 2.000e-05 2.000e-05 + Fe(2) 1.000e-06 1.000e-06 + K 2.000e-05 2.000e-05 + Mg 1.010e-03 1.010e-03 + Na 2.000e-05 2.000e-05 + S(6) 1.600e-04 1.600e-04 + +----------------------------Description of solution---------------------------- + + pH = 7.550 + pe = 0.000 + Activity of water = 1.000 + Ionic strength = 6.543e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.016e-03 + Total CO2 (mol/kg) = 4.300e-03 + Temperature (deg C) = 9.900 + Electrical balance (eq) = 1.061e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 1.24 + Iterations = 8 + Total H = 1.110164e+02 + Total O = 5.551946e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.120e-07 1.029e-07 -6.951 -6.988 -0.037 + H+ 3.038e-08 2.818e-08 -7.517 -7.550 -0.033 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(4) 4.300e-03 + HCO3- 3.929e-03 3.623e-03 -2.406 -2.441 -0.035 + CO2 2.970e-04 2.974e-04 -3.527 -3.527 0.001 + MgHCO3+ 3.098e-05 2.850e-05 -4.509 -4.545 -0.036 + CaHCO3+ 3.027e-05 2.792e-05 -4.519 -4.554 -0.035 + CO3-2 5.765e-06 4.168e-06 -5.239 -5.380 -0.141 + CaCO3 4.727e-06 4.734e-06 -5.325 -5.325 0.001 + MgCO3 2.208e-06 2.211e-06 -5.656 -5.655 0.001 + FeHCO3+ 2.086e-07 1.919e-07 -6.681 -6.717 -0.036 + FeCO3 5.289e-08 5.297e-08 -7.277 -7.276 0.001 + NaHCO3 3.737e-08 3.742e-08 -7.428 -7.427 0.001 + NaCO3- 6.948e-10 6.391e-10 -9.158 -9.194 -0.036 +Ca 1.200e-03 + Ca+2 1.151e-03 8.317e-04 -2.939 -3.080 -0.141 + CaHCO3+ 3.027e-05 2.792e-05 -4.519 -4.554 -0.035 + CaSO4 1.393e-05 1.395e-05 -4.856 -4.855 0.001 + CaCO3 4.727e-06 4.734e-06 -5.325 -5.325 0.001 + CaOH+ 5.323e-09 4.897e-09 -8.274 -8.310 -0.036 + CaHSO4+ 2.136e-12 1.965e-12 -11.670 -11.707 -0.036 +Cl 2.000e-05 + Cl- 2.000e-05 1.838e-05 -4.699 -4.736 -0.037 + FeCl+ 1.461e-11 1.344e-11 -10.835 -10.872 -0.036 +Fe(2) 1.000e-06 + Fe+2 7.296e-07 5.298e-07 -6.137 -6.276 -0.139 + FeHCO3+ 2.086e-07 1.919e-07 -6.681 -6.717 -0.036 + FeCO3 5.289e-08 5.297e-08 -7.277 -7.276 0.001 + FeSO4 6.861e-09 6.871e-09 -8.164 -8.163 0.001 + FeOH+ 1.969e-09 1.811e-09 -8.706 -8.742 -0.036 + FeCl+ 1.461e-11 1.344e-11 -10.835 -10.872 -0.036 + FeHSO4+ 1.361e-15 1.252e-15 -14.866 -14.903 -0.036 +H(0) 1.316e-18 + H2 6.579e-19 6.588e-19 -18.182 -18.181 0.001 +K 2.000e-05 + K+ 1.999e-05 1.837e-05 -4.699 -4.736 -0.037 + KSO4- 1.037e-08 9.538e-09 -7.984 -8.021 -0.036 + KOH 2.256e-12 2.260e-12 -11.647 -11.646 0.001 +Mg 1.010e-03 + Mg+2 9.662e-04 7.011e-04 -3.015 -3.154 -0.139 + MgHCO3+ 3.098e-05 2.850e-05 -4.509 -4.545 -0.036 + MgSO4 1.063e-05 1.064e-05 -4.974 -4.973 0.001 + MgCO3 2.208e-06 2.211e-06 -5.656 -5.655 0.001 + MgOH+ 2.335e-08 2.148e-08 -7.632 -7.668 -0.036 +Na 2.000e-05 + Na+ 1.995e-05 1.837e-05 -4.700 -4.736 -0.036 + NaHCO3 3.737e-08 3.742e-08 -7.428 -7.427 0.001 + NaSO4- 8.826e-09 8.119e-09 -8.054 -8.090 -0.036 + NaCO3- 6.948e-10 6.391e-10 -9.158 -9.194 -0.036 + NaOH 4.299e-12 4.306e-12 -11.367 -11.366 0.001 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -61.151 -61.151 0.001 +S(6) 1.600e-04 + SO4-2 1.354e-04 9.754e-05 -3.868 -4.011 -0.142 + CaSO4 1.393e-05 1.395e-05 -4.856 -4.855 0.001 + MgSO4 1.063e-05 1.064e-05 -4.974 -4.973 0.001 + KSO4- 1.037e-08 9.538e-09 -7.984 -8.021 -0.036 + NaSO4- 8.826e-09 8.119e-09 -8.054 -8.090 -0.036 + FeSO4 6.861e-09 6.871e-09 -8.164 -8.163 0.001 + HSO4- 2.136e-10 1.965e-10 -9.670 -9.707 -0.036 + CaHSO4+ 2.136e-12 1.965e-12 -11.670 -11.707 -0.036 + FeHSO4+ 1.361e-15 1.252e-15 -14.866 -14.903 -0.036 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.76 -7.09 -4.34 CaSO4 + Aragonite -0.21 -8.46 -8.25 CaCO3 + Calcite -0.05 -8.46 -8.41 CaCO3 + CH2O -33.73 -33.73 0.00 CH2O + CO2(g) -2.26 -3.53 -1.27 CO2 + Dolomite -0.27 -16.99 -16.72 CaMg(CO3)2 + Gypsum -2.50 -7.09 -4.59 CaSO4:2H2O + H2(g) -15.10 -18.18 -3.08 H2 + H2O(g) -1.92 -0.00 1.92 H2O + Halite -11.02 -9.47 1.55 NaCl + Melanterite -7.88 -10.29 -2.41 FeSO4:7H2O + O2(g) -58.26 -61.15 -2.89 O2 + Siderite -0.86 -11.66 -10.79 FeCO3 + Sylvite -9.47 -9.47 0.00 KCl + +Initial solution 2. Mysse + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C(4) 6.870e-03 6.870e-03 + Ca 1.128e-02 1.128e-02 + Cl 1.785e-02 1.785e-02 + Fe(2) 4.000e-07 4.000e-07 + K 2.540e-03 2.540e-03 + Mg 4.540e-03 4.540e-03 + Na 3.189e-02 3.189e-02 + S(-2) 2.600e-04 2.600e-04 + S(6) 1.986e-02 1.986e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.610 + pe = 0.000 + Activity of water = 0.999 + Ionic strength = 7.256e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.258e-03 + Total CO2 (mol/kg) = 6.870e-03 + Temperature (deg C) = 63.000 + Electrical balance (eq) = 3.242e-03 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 3.20 + Iterations = 8 + Total H = 1.110179e+02 + Total O = 5.560448e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + S(-2)/S(6) -3.6487 -0.2434 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.726e-07 4.419e-07 -6.242 -6.355 -0.112 + H+ 2.963e-07 2.455e-07 -6.528 -6.610 -0.082 + H2O 5.551e+01 9.985e-01 1.744 -0.001 0.000 +C(4) 6.870e-03 + HCO3- 4.711e-03 3.746e-03 -2.327 -2.426 -0.100 + CO2 1.784e-03 1.814e-03 -2.749 -2.741 0.007 + CaHCO3+ 2.347e-04 1.867e-04 -3.629 -3.729 -0.100 + MgHCO3+ 6.578e-05 5.169e-05 -4.182 -4.287 -0.105 + NaHCO3 5.046e-05 5.131e-05 -4.297 -4.290 0.007 + CaCO3 1.560e-05 1.586e-05 -4.807 -4.800 0.007 + NaCO3- 3.512e-06 2.760e-06 -5.454 -5.559 -0.105 + CO3-2 2.780e-06 1.112e-06 -5.556 -5.954 -0.398 + MgCO3 1.642e-06 1.670e-06 -5.784 -5.777 0.007 + FeHCO3+ 1.177e-08 9.248e-09 -7.929 -8.034 -0.105 + FeCO3 6.474e-10 6.583e-10 -9.189 -9.182 0.007 +Ca 1.128e-02 + Ca+2 7.217e-03 2.899e-03 -2.142 -2.538 -0.396 + CaSO4 3.813e-03 3.877e-03 -2.419 -2.411 0.007 + CaHCO3+ 2.347e-04 1.867e-04 -3.629 -3.729 -0.100 + CaCO3 1.560e-05 1.586e-05 -4.807 -4.800 0.007 + CaHSO4+ 1.322e-08 1.039e-08 -7.879 -7.983 -0.105 + CaOH+ 2.491e-09 1.957e-09 -8.604 -8.708 -0.105 +Cl 1.785e-02 + Cl- 1.785e-02 1.381e-02 -1.748 -1.860 -0.111 + FeCl+ 5.988e-10 4.706e-10 -9.223 -9.327 -0.105 +Fe(2) 4.000e-07 + Fe(HS)2 2.830e-07 2.878e-07 -6.548 -6.541 0.007 + Fe+2 5.978e-08 2.468e-08 -7.223 -7.608 -0.384 + FeSO4 3.911e-08 3.977e-08 -7.408 -7.400 0.007 + FeHCO3+ 1.177e-08 9.248e-09 -7.929 -8.034 -0.105 + Fe(HS)3- 4.561e-09 3.585e-09 -8.341 -8.446 -0.105 + FeCO3 6.474e-10 6.583e-10 -9.189 -9.182 0.007 + FeCl+ 5.988e-10 4.706e-10 -9.223 -9.327 -0.105 + FeOH+ 5.014e-10 3.940e-10 -9.300 -9.404 -0.105 + FeHSO4+ 1.125e-13 8.843e-14 -12.949 -13.053 -0.105 +H(0) 1.190e-09 + H2 5.948e-10 6.048e-10 -9.226 -9.218 0.007 +K 2.540e-03 + K+ 2.394e-03 1.852e-03 -2.621 -2.732 -0.111 + KSO4- 1.459e-04 1.146e-04 -3.836 -3.941 -0.105 + KOH 2.569e-11 2.613e-11 -10.590 -10.583 0.007 +Mg 4.540e-03 + MgSO4 2.360e-03 2.399e-03 -2.627 -2.620 0.007 + Mg+2 2.113e-03 8.783e-04 -2.675 -3.056 -0.381 + MgHCO3+ 6.578e-05 5.169e-05 -4.182 -4.287 -0.105 + MgCO3 1.642e-06 1.670e-06 -5.784 -5.777 0.007 + MgOH+ 3.463e-07 2.721e-07 -6.461 -6.565 -0.105 +Na 3.189e-02 + Na+ 3.090e-02 2.435e-02 -1.510 -1.613 -0.103 + NaSO4- 9.408e-04 7.393e-04 -3.027 -3.131 -0.105 + NaHCO3 5.046e-05 5.131e-05 -4.297 -4.290 0.007 + NaCO3- 3.512e-06 2.760e-06 -5.454 -5.559 -0.105 + NaOH 6.437e-10 6.545e-10 -9.191 -9.184 0.007 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -63.075 -63.067 0.007 +S(-2) 2.600e-04 + HS- 1.482e-04 1.144e-04 -3.829 -3.942 -0.112 + H2S 1.112e-04 1.131e-04 -3.954 -3.947 0.007 + Fe(HS)2 2.830e-07 2.878e-07 -6.548 -6.541 0.007 + Fe(HS)3- 4.561e-09 3.585e-09 -8.341 -8.446 -0.105 + S-2 1.449e-09 5.662e-10 -8.839 -9.247 -0.408 +S(6) 1.986e-02 + SO4-2 1.260e-02 4.892e-03 -1.900 -2.311 -0.411 + CaSO4 3.813e-03 3.877e-03 -2.419 -2.411 0.007 + MgSO4 2.360e-03 2.399e-03 -2.627 -2.620 0.007 + NaSO4- 9.408e-04 7.393e-04 -3.027 -3.131 -0.105 + KSO4- 1.459e-04 1.146e-04 -3.836 -3.941 -0.105 + HSO4- 3.792e-07 2.980e-07 -6.421 -6.526 -0.105 + FeSO4 3.911e-08 3.977e-08 -7.408 -7.400 0.007 + CaHSO4+ 1.322e-08 1.039e-08 -7.879 -7.983 -0.105 + FeHSO4+ 1.125e-13 8.843e-14 -12.949 -13.053 -0.105 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.14 -4.85 -4.71 CaSO4 + Aragonite 0.18 -8.49 -8.67 CaCO3 + Calcite 0.30 -8.49 -8.79 CaCO3 + CH2O -14.59 -14.59 0.00 CH2O + CO2(g) -0.94 -2.74 -1.80 CO2 + Dolomite 0.37 -17.50 -17.87 CaMg(CO3)2 + FeS(ppt) -1.02 -4.94 -3.92 FeS + Gypsum -0.18 -4.85 -4.67 CaSO4:2H2O + H2(g) -5.92 -9.22 -3.30 H2 + H2O(g) -0.64 -0.00 0.64 H2O + H2S(g) -2.57 -3.95 -1.38 H2S + Halite -5.13 -3.47 1.66 NaCl + Mackinawite -0.29 -4.94 -4.65 FeS + Melanterite -8.07 -9.92 -1.85 FeSO4:7H2O + O2(g) -59.95 -63.07 -3.11 O2 + Pyrite 7.97 -9.57 -17.54 FeS2 + Siderite -2.47 -13.56 -11.10 FeCO3 + Sulfur -2.12 1.98 4.09 S + Sylvite -4.59 -4.59 0.00 KCl + +------------------------------------------- +Beginning of inverse modeling calculations. +------------------------------------------- + + +Solution 1: Recharge number 3 + + Input Delta Input+Delta + pH 7.550e+00 + 0.000e+00 = 7.550e+00 + Alkalinity 4.016e-03 + 0.000e+00 = 4.016e-03 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 4.300e-03 + 0.000e+00 = 4.300e-03 + Ca 1.200e-03 + -5.306e-05 = 1.147e-03 + Cl 2.000e-05 + 0.000e+00 = 2.000e-05 + Fe(2) 1.000e-06 + 0.000e+00 = 1.000e-06 + Fe(3) 0.000e+00 + 0.000e+00 = 0.000e+00 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 2.000e-05 + 0.000e+00 = 2.000e-05 + Mg 1.010e-03 + 0.000e+00 = 1.010e-03 + Na 2.000e-05 + 0.000e+00 = 2.000e-05 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 1.600e-04 + 0.000e+00 = 1.600e-04 + X 0.000e+00 + 0.000e+00 = 0.000e+00 + 13C(-4) -7 + 0 = -7 + 13C(4) -7 + 0 = -7 + 34S(-2) 9.7 + 0 = 9.7 + 34S(6) 9.7 + 0 = 9.7 + +Solution 2: Mysse + + Input Delta Input+Delta + pH 6.610e+00 + 0.000e+00 = 6.610e+00 + Alkalinity 5.258e-03 + 0.000e+00 = 5.258e-03 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 6.870e-03 + 0.000e+00 = 6.870e-03 + Ca 1.128e-02 + 0.000e+00 = 1.128e-02 + Cl 1.785e-02 + 0.000e+00 = 1.785e-02 + Fe(2) 4.000e-07 + 0.000e+00 = 4.000e-07 + Fe(3) 0.000e+00 + 0.000e+00 = 0.000e+00 + H(0) 1.190e-09 + 0.000e+00 = 1.190e-09 + K 2.540e-03 + 0.000e+00 = 2.540e-03 + Mg 4.540e-03 + 0.000e+00 = 4.540e-03 + Na 3.189e-02 + -1.256e-03 = 3.063e-02 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 2.600e-04 + 0.000e+00 = 2.600e-04 + S(6) 1.986e-02 + 9.930e-04 = 2.085e-02 + X 0.000e+00 + 0.000e+00 = 0.000e+00 + 13C(-4) -2.3 + 0 = -2.3 + 13C(4) -2.3 + 0 = -2.3 + 34S(-2) -22.1 + 0 = -22.1 + 34S(6) 16.3 + 0 = 16.3 + +Isotopic composition of phases: + 13C Dolomite 3 + 0 = 3 + 13C Calcite -1.5 + 0 = -1.5 + 34S Anhydrite 13.5 + -0.65116 = 12.8488 + 13C CH2O -25 + 3.56577 = -21.4342 + 34S Pyrite -22 + 2 = -20 + +Solution fractions: Minimum Maximum + Solution 1 1.000e+00 9.999e-01 1.000e+00 + Solution 2 1.000e+00 1.000e+00 1.000e+00 + +Phase mole transfers: Minimum Maximum + Dolomite 1.118e-02 1.022e-02 1.193e-02 CaMg(CO3)2 + Calcite -2.393e-02 -2.567e-02 -2.144e-02 CaCO3 + Anhydrite 2.288e-02 2.076e-02 2.348e-02 CaSO4 + CH2O 4.138e-03 3.003e-03 5.273e-03 CH2O + Goethite 9.642e-04 6.533e-04 1.275e-03 FeOOH + Pyrite -9.648e-04 -1.274e-03 -6.553e-04 FeS2 + MgX2 -7.652e-03 -8.576e-03 -6.972e-03 MgX2 + NaX 1.530e-02 1.394e-02 1.715e-02 NaX + Halite 1.531e-02 1.429e-02 1.633e-02 NaCl + Sylvite 2.520e-03 2.392e-03 2.648e-03 KCl + +Redox mole transfers: + Fe(3) 9.642e-04 + H(0) -1.190e-09 + S(-2) -2.190e-03 + +Sum of residuals (epsilons in documentation): 2.684e+00 +Sum of delta/uncertainty limit: 4.711e+00 +Maximum fractional error in element concentration: 5.000e-02 + +Model contains minimum number of phases. +=============================================================================== + + +Solution 1: Recharge number 3 + + Input Delta Input+Delta + pH 7.550e+00 + 0.000e+00 = 7.550e+00 + Alkalinity 4.016e-03 + 1.061e-04 = 4.122e-03 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 4.300e-03 + 1.136e-04 = 4.414e-03 + Ca 1.200e-03 + 0.000e+00 = 1.200e-03 + Cl 2.000e-05 + 0.000e+00 = 2.000e-05 + Fe(2) 1.000e-06 + 0.000e+00 = 1.000e-06 + Fe(3) 0.000e+00 + 0.000e+00 = 0.000e+00 + H(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + K 2.000e-05 + 0.000e+00 = 2.000e-05 + Mg 1.010e-03 + 0.000e+00 = 1.010e-03 + Na 2.000e-05 + 0.000e+00 = 2.000e-05 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(6) 1.600e-04 + 0.000e+00 = 1.600e-04 + X 0.000e+00 + 0.000e+00 = 0.000e+00 + 13C(-4) -7 + 0 = -7 + 13C(4) -7 + 0 = -7 + 34S(-2) 9.7 + 0 = 9.7 + 34S(6) 9.7 + 0 = 9.7 + +Solution 2: Mysse + + Input Delta Input+Delta + pH 6.610e+00 + 5.872e-02 = 6.669e+00 + Alkalinity 5.258e-03 + 0.000e+00 = 5.258e-03 + C(-4) 0.000e+00 + 0.000e+00 = 0.000e+00 + C(4) 6.870e-03 + -2.581e-04 = 6.612e-03 + Ca 1.128e-02 + 0.000e+00 = 1.128e-02 + Cl 1.785e-02 + 0.000e+00 = 1.785e-02 + Fe(2) 4.000e-07 + 0.000e+00 = 4.000e-07 + Fe(3) 0.000e+00 + 0.000e+00 = 0.000e+00 + H(0) 1.190e-09 + 0.000e+00 = 1.190e-09 + K 2.540e-03 + 0.000e+00 = 2.540e-03 + Mg 4.540e-03 + 0.000e+00 = 4.540e-03 + Na 3.189e-02 + -1.256e-03 = 3.063e-02 + O(0) 0.000e+00 + 0.000e+00 = 0.000e+00 + S(-2) 2.600e-04 + 0.000e+00 = 2.600e-04 + S(6) 1.986e-02 + 9.930e-04 = 2.085e-02 + X 0.000e+00 + 0.000e+00 = 0.000e+00 + 13C(-4) -2.3 + 0 = -2.3 + 13C(4) -2.3 + 0 = -2.3 + 34S(-2) -22.1 + 0 = -22.1 + 34S(6) 16.3 + 0 = 16.3 + +Isotopic composition of phases: + 13C Dolomite 3 + 2 = 5 + 13C Calcite -1.5 + -1 = -2.5 + 34S Anhydrite 13.5 + -0.119926 = 13.3801 + 13C CH2O -25 + 5 = -20 + 34S Pyrite -22 + 2 = -20 + +Solution fractions: Minimum Maximum + Solution 1 1.000e+00 1.000e+00 1.000e+00 + Solution 2 1.000e+00 1.000e+00 1.000e+00 + +Phase mole transfers: Minimum Maximum + Dolomite 5.443e-03 4.995e-03 5.838e-03 CaMg(CO3)2 + Calcite -1.214e-02 -1.333e-02 -1.098e-02 CaCO3 + Anhydrite 2.252e-02 2.076e-02 2.297e-02 CaSO4 + CH2O 3.455e-03 3.003e-03 4.297e-03 CH2O + Goethite 7.821e-04 6.533e-04 1.015e-03 FeOOH + Pyrite -7.827e-04 -1.014e-03 -6.553e-04 FeS2 + Ca.75Mg.25X2 -7.652e-03 -8.576e-03 -6.972e-03 Ca.75Mg.25X2 + NaX 1.530e-02 1.394e-02 1.715e-02 NaX + Halite 1.531e-02 1.429e-02 1.633e-02 NaCl + Sylvite 2.520e-03 2.392e-03 2.648e-03 KCl + +Redox mole transfers: + Fe(3) 7.821e-04 + H(0) -1.190e-09 + S(-2) -1.825e-03 + +Sum of residuals (epsilons in documentation): 4.207e+00 +Sum of delta/uncertainty limit: 8.243e+00 +Maximum fractional error in element concentration: 5.000e-02 + +Model contains minimum number of phases. +=============================================================================== + + +Summary of inverse modeling: + + Number of models found: 2 + Number of minimal models found: 2 + Number of infeasible sets of phases saved: 28 + Number of calls to cl1: 80 +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex2.log b/Sun/examples/ex2.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex2.out b/Sun/examples/ex2.out new file mode 100644 index 00000000..5f57d4e9 --- /dev/null +++ b/Sun/examples/ex2.out @@ -0,0 +1,4037 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex2 + Output file: ex2.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 2.--Temperature dependence of solubility + of gypsum and anhydrite + SOLUTION 1 Pure water + pH 7.0 + temp 25.0 + EQUILIBRIUM_PHASES 1 + Gypsum 0.0 1.0 + Anhydrite 0.0 1.0 + REACTION_TEMPERATURE 1 + 25.0 75.0 in 51 steps + SELECTED_OUTPUT + file ex2.sel + temperature + si anhydrite gypsum + END +----- +TITLE +----- + + Example 2.--Temperature dependence of solubility + of gypsum and anhydrite + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Pure water + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Pure water + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.082e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.002e-07 1.001e-07 -6.999 -6.999 -0.000 + H+ 1.001e-07 1.000e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 0.000 0.000 +H(0) 1.416e-25 + H2 7.079e-26 7.079e-26 -25.150 -25.150 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.080 -42.080 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 0.00 1.51 H2O + O2(g) -39.12 -42.08 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.22 -4.58 -4.36 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.849e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.564e-02 1.508e-02 + S 1.564e-02 1.508e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.067 Charge balance + pe = 10.686 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.178e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -9.881e-11 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070728e+02 + Total O = 5.359671e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.417e-07 1.167e-07 -6.849 -6.933 -0.084 + H+ 9.957e-08 8.575e-08 -7.002 -7.067 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.564e-02 + Ca+2 1.045e-02 5.176e-03 -1.981 -2.286 -0.305 + CaSO4 5.191e-03 5.242e-03 -2.285 -2.281 0.004 + CaOH+ 1.204e-08 1.001e-08 -7.919 -7.999 -0.080 + CaHSO4+ 3.166e-09 2.633e-09 -8.499 -8.580 -0.080 +H(0) 4.375e-39 + H2 2.187e-39 2.209e-39 -38.660 -38.656 0.004 +O(0) 1.691e-15 + O2 8.457e-16 8.539e-16 -15.073 -15.069 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -117.650 -117.734 -0.084 + H2S 0.000e+00 0.000e+00 -117.863 -117.859 0.004 + S-2 0.000e+00 0.000e+00 -123.274 -123.585 -0.312 +S(6) 1.564e-02 + SO4-2 1.045e-02 5.075e-03 -1.981 -2.295 -0.313 + CaSO4 5.191e-03 5.242e-03 -2.285 -2.281 0.004 + HSO4- 5.088e-08 4.231e-08 -7.293 -7.374 -0.080 + CaHSO4+ 3.166e-09 2.633e-09 -8.499 -8.580 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.22 -4.58 -4.36 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -35.51 -38.66 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -116.86 -117.86 -1.00 H2S + O2(g) -12.11 -15.07 -2.96 O2 + Sulfur -87.24 -82.35 4.88 S + +Reaction step 2. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.22 -4.58 -4.37 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.849e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.569e-02 1.514e-02 + S 1.569e-02 1.514e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.053 Charge balance + pe = 10.617 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.182e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 26.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.070730e+02 + Total O = 5.359703e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.482e-07 1.220e-07 -6.829 -6.914 -0.084 + H+ 1.027e-07 8.845e-08 -6.988 -7.053 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.569e-02 + Ca+2 1.046e-02 5.174e-03 -1.981 -2.286 -0.306 + CaSO4 5.236e-03 5.287e-03 -2.281 -2.277 0.004 + CaOH+ 1.167e-08 9.704e-09 -7.933 -8.013 -0.080 + CaHSO4+ 3.337e-09 2.774e-09 -8.477 -8.557 -0.080 +H(0) 6.343e-39 + H2 3.172e-39 3.202e-39 -38.499 -38.495 0.004 +O(0) 1.687e-15 + O2 8.436e-16 8.517e-16 -15.074 -15.070 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -117.121 -117.205 -0.084 + H2S 0.000e+00 0.000e+00 -117.334 -117.330 0.004 + S-2 0.000e+00 0.000e+00 -122.728 -123.041 -0.312 +S(6) 1.569e-02 + SO4-2 1.046e-02 5.073e-03 -1.981 -2.295 -0.314 + CaSO4 5.236e-03 5.287e-03 -2.281 -2.277 0.004 + HSO4- 5.364e-08 4.459e-08 -7.270 -7.351 -0.080 + CaHSO4+ 3.337e-09 2.774e-09 -8.477 -8.557 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.22 -4.58 -4.37 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -35.34 -38.49 -3.15 H2 + H2O(g) -1.48 -0.00 1.48 H2O + H2S(g) -116.32 -117.33 -1.01 H2S + O2(g) -12.11 -15.07 -2.96 O2 + Sulfur -86.85 -81.99 4.86 S + +Reaction step 3. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.21 -4.58 -4.37 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.848e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.574e-02 1.519e-02 + S 1.574e-02 1.519e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.040 Charge balance + pe = 10.572 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.186e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 27.000 + Electrical balance (eq) = -1.001e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 20 + Total H = 1.070732e+02 + Total O = 5.359733e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.548e-07 1.274e-07 -6.810 -6.895 -0.085 + H+ 1.060e-07 9.122e-08 -6.975 -7.040 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.574e-02 + Ca+2 1.047e-02 5.172e-03 -1.980 -2.286 -0.306 + CaSO4 5.279e-03 5.330e-03 -2.277 -2.273 0.004 + CaOH+ 1.132e-08 9.405e-09 -7.946 -8.027 -0.080 + CaHSO4+ 3.516e-09 2.922e-09 -8.454 -8.534 -0.080 +H(0) 8.213e-39 + H2 4.107e-39 4.146e-39 -38.387 -38.382 0.004 +O(0) 2.100e-15 + O2 1.050e-15 1.060e-15 -14.979 -14.975 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -116.788 -116.873 -0.085 + H2S 0.000e+00 0.000e+00 -117.001 -116.997 0.004 + S-2 0.000e+00 0.000e+00 -122.379 -122.692 -0.313 +S(6) 1.574e-02 + SO4-2 1.047e-02 5.071e-03 -1.980 -2.295 -0.315 + CaSO4 5.279e-03 5.330e-03 -2.277 -2.273 0.004 + HSO4- 5.655e-08 4.699e-08 -7.248 -7.328 -0.080 + CaHSO4+ 3.516e-09 2.922e-09 -8.454 -8.534 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.21 -4.58 -4.37 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -35.22 -38.38 -3.16 H2 + H2O(g) -1.46 -0.00 1.46 H2O + H2S(g) -115.98 -117.00 -1.02 H2S + O2(g) -12.01 -14.97 -2.97 O2 + Sulfur -86.61 -81.77 4.84 S + +Reaction step 4. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.21 -4.58 -4.37 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.848e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.579e-02 1.523e-02 + S 1.579e-02 1.523e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.027 Charge balance + pe = 10.479 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.189e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 28.000 + Electrical balance (eq) = -9.955e-11 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 22 + Total H = 1.070734e+02 + Total O = 5.359762e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.617e-07 1.330e-07 -6.791 -6.876 -0.085 + H+ 1.093e-07 9.404e-08 -6.961 -7.027 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.579e-02 + Ca+2 1.047e-02 5.168e-03 -1.980 -2.287 -0.307 + CaSO4 5.321e-03 5.373e-03 -2.274 -2.270 0.004 + CaOH+ 1.097e-08 9.117e-09 -7.960 -8.040 -0.081 + CaHSO4+ 3.703e-09 3.076e-09 -8.431 -8.512 -0.081 +H(0) 1.325e-38 + H2 6.624e-39 6.688e-39 -38.179 -38.175 0.004 +O(0) 1.677e-15 + O2 8.383e-16 8.464e-16 -15.077 -15.072 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -116.073 -116.158 -0.085 + H2S 0.000e+00 0.000e+00 -116.285 -116.281 0.004 + S-2 0.000e+00 0.000e+00 -121.647 -121.961 -0.314 +S(6) 1.579e-02 + SO4-2 1.047e-02 5.067e-03 -1.980 -2.295 -0.315 + CaSO4 5.321e-03 5.373e-03 -2.274 -2.270 0.004 + HSO4- 5.959e-08 4.950e-08 -7.225 -7.305 -0.081 + CaHSO4+ 3.703e-09 3.076e-09 -8.431 -8.512 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.21 -4.58 -4.37 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -35.01 -38.17 -3.16 H2 + H2O(g) -1.43 -0.00 1.43 H2O + H2S(g) -115.25 -116.28 -1.03 H2S + O2(g) -12.10 -15.07 -2.97 O2 + Sulfur -86.08 -81.27 4.81 S + +Reaction step 5. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.20 -4.58 -4.38 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.847e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.584e-02 1.528e-02 + S 1.584e-02 1.528e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.014 Charge balance + pe = 10.411 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.191e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 29.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.070735e+02 + Total O = 5.359788e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.688e-07 1.388e-07 -6.773 -6.858 -0.085 + H+ 1.127e-07 9.693e-08 -6.948 -7.014 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.584e-02 + Ca+2 1.048e-02 5.164e-03 -1.980 -2.287 -0.307 + CaSO4 5.361e-03 5.413e-03 -2.271 -2.267 0.004 + CaOH+ 1.064e-08 8.838e-09 -7.973 -8.054 -0.081 + CaHSO4+ 3.899e-09 3.238e-09 -8.409 -8.490 -0.081 +H(0) 1.909e-38 + H2 9.547e-39 9.639e-39 -38.020 -38.016 0.004 +O(0) 1.668e-15 + O2 8.339e-16 8.420e-16 -15.079 -15.075 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -115.552 -115.637 -0.085 + H2S 0.000e+00 0.000e+00 -115.764 -115.759 0.004 + S-2 0.000e+00 0.000e+00 -121.110 -121.424 -0.314 +S(6) 1.584e-02 + SO4-2 1.048e-02 5.063e-03 -1.980 -2.296 -0.316 + CaSO4 5.361e-03 5.413e-03 -2.271 -2.267 0.004 + HSO4- 6.279e-08 5.214e-08 -7.202 -7.283 -0.081 + CaHSO4+ 3.899e-09 3.238e-09 -8.409 -8.490 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.20 -4.58 -4.38 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -34.85 -38.02 -3.17 H2 + H2O(g) -1.41 -0.00 1.41 H2O + H2S(g) -114.72 -115.76 -1.04 H2S + O2(g) -12.10 -15.07 -2.98 O2 + Sulfur -85.70 -80.91 4.79 S + +Reaction step 6. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.20 -4.58 -4.39 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.847e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.588e-02 1.532e-02 + S 1.588e-02 1.532e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.001 Charge balance + pe = 10.344 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.193e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 30.000 + Electrical balance (eq) = -9.775e-11 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.070737e+02 + Total O = 5.359813e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.762e-07 1.448e-07 -6.754 -6.839 -0.085 + H+ 1.161e-07 9.988e-08 -6.935 -7.001 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.588e-02 + Ca+2 1.048e-02 5.160e-03 -1.980 -2.287 -0.308 + CaSO4 5.400e-03 5.453e-03 -2.268 -2.263 0.004 + CaOH+ 1.032e-08 8.569e-09 -7.986 -8.067 -0.081 + CaHSO4+ 4.103e-09 3.406e-09 -8.387 -8.468 -0.081 +H(0) 2.734e-38 + H2 1.367e-38 1.380e-38 -37.864 -37.860 0.004 +O(0) 1.673e-15 + O2 8.364e-16 8.445e-16 -15.078 -15.073 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -115.042 -115.128 -0.085 + H2S 0.000e+00 0.000e+00 -115.253 -115.249 0.004 + S-2 0.000e+00 0.000e+00 -120.584 -120.899 -0.315 +S(6) 1.588e-02 + SO4-2 1.048e-02 5.059e-03 -1.980 -2.296 -0.316 + CaSO4 5.400e-03 5.453e-03 -2.268 -2.263 0.004 + HSO4- 6.614e-08 5.491e-08 -7.180 -7.260 -0.081 + CaHSO4+ 4.103e-09 3.406e-09 -8.387 -8.468 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.20 -4.58 -4.39 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -34.69 -37.86 -3.17 H2 + H2O(g) -1.38 -0.00 1.38 H2O + H2S(g) -114.20 -115.25 -1.05 H2S + O2(g) -12.09 -15.07 -2.98 O2 + Sulfur -85.33 -80.56 4.77 S + +Reaction step 7. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.19 -4.58 -4.39 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.58 -4.58 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.592e-02 1.536e-02 + S 1.592e-02 1.536e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.988 Charge balance + pe = 10.277 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.194e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 31.000 + Electrical balance (eq) = -1.014e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.070739e+02 + Total O = 5.359836e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.837e-07 1.510e-07 -6.736 -6.821 -0.085 + H+ 1.197e-07 1.029e-07 -6.922 -6.988 -0.066 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.592e-02 + Ca+2 1.049e-02 5.154e-03 -1.979 -2.288 -0.308 + CaSO4 5.438e-03 5.491e-03 -2.265 -2.260 0.004 + CaOH+ 1.001e-08 8.310e-09 -7.999 -8.080 -0.081 + CaHSO4+ 4.317e-09 3.582e-09 -8.365 -8.446 -0.081 +H(0) 3.917e-38 + H2 1.959e-38 1.978e-38 -37.708 -37.704 0.004 +O(0) 1.668e-15 + O2 8.342e-16 8.423e-16 -15.079 -15.075 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -114.531 -114.617 -0.085 + H2S 0.000e+00 0.000e+00 -114.740 -114.736 0.004 + S-2 0.000e+00 0.000e+00 -120.057 -120.372 -0.315 +S(6) 1.592e-02 + SO4-2 1.048e-02 5.053e-03 -1.979 -2.296 -0.317 + CaSO4 5.438e-03 5.491e-03 -2.265 -2.260 0.004 + HSO4- 6.966e-08 5.780e-08 -7.157 -7.238 -0.081 + CaHSO4+ 4.317e-09 3.582e-09 -8.365 -8.446 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.19 -4.58 -4.39 CaSO4 + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -34.53 -37.70 -3.18 H2 + H2O(g) -1.36 -0.00 1.36 H2O + H2S(g) -113.67 -114.74 -1.06 H2S + O2(g) -12.09 -15.07 -2.99 O2 + Sulfur -84.95 -80.21 4.74 S + +Reaction step 8. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.19 -4.59 -4.40 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.596e-02 1.539e-02 + S 1.596e-02 1.539e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.975 Charge balance + pe = 10.210 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.194e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 32.000 + Electrical balance (eq) = -1.029e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070740e+02 + Total O = 5.359858e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.916e-07 1.573e-07 -6.718 -6.803 -0.085 + H+ 1.233e-07 1.060e-07 -6.909 -6.975 -0.066 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.596e-02 + Ca+2 1.049e-02 5.148e-03 -1.979 -2.288 -0.309 + CaSO4 5.474e-03 5.527e-03 -2.262 -2.258 0.004 + CaOH+ 9.715e-09 8.059e-09 -8.013 -8.094 -0.081 + CaHSO4+ 4.540e-09 3.766e-09 -8.343 -8.424 -0.081 +H(0) 5.596e-38 + H2 2.798e-38 2.825e-38 -37.553 -37.549 0.004 +O(0) 1.666e-15 + O2 8.330e-16 8.410e-16 -15.079 -15.075 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -114.024 -114.110 -0.085 + H2S 0.000e+00 0.000e+00 -114.232 -114.228 0.004 + S-2 0.000e+00 0.000e+00 -119.534 -119.850 -0.316 +S(6) 1.596e-02 + SO4-2 1.049e-02 5.047e-03 -1.979 -2.297 -0.318 + CaSO4 5.474e-03 5.527e-03 -2.262 -2.258 0.004 + HSO4- 7.334e-08 6.084e-08 -7.135 -7.216 -0.081 + CaHSO4+ 4.540e-09 3.766e-09 -8.343 -8.424 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.19 -4.59 -4.40 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -34.37 -37.55 -3.18 H2 + H2O(g) -1.33 -0.00 1.33 H2O + H2S(g) -113.15 -114.23 -1.07 H2S + O2(g) -12.08 -15.08 -2.99 O2 + Sulfur -84.58 -79.86 4.72 S + +Reaction step 9. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.18 -4.59 -4.40 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.599e-02 1.543e-02 + S 1.599e-02 1.543e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.962 Charge balance + pe = 10.149 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.194e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 33.000 + Electrical balance (eq) = -9.966e-11 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.070741e+02 + Total O = 5.359877e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.996e-07 1.639e-07 -6.700 -6.785 -0.086 + H+ 1.270e-07 1.091e-07 -6.896 -6.962 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.599e-02 + Ca+2 1.049e-02 5.142e-03 -1.979 -2.289 -0.309 + CaSO4 5.508e-03 5.562e-03 -2.259 -2.255 0.004 + CaOH+ 9.427e-09 7.818e-09 -8.026 -8.107 -0.081 + CaHSO4+ 4.772e-09 3.957e-09 -8.321 -8.403 -0.081 +H(0) 7.777e-38 + H2 3.888e-38 3.926e-38 -37.410 -37.406 0.004 +O(0) 1.749e-15 + O2 8.746e-16 8.831e-16 -15.058 -15.054 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -113.565 -113.650 -0.086 + H2S 0.000e+00 0.000e+00 -113.771 -113.767 0.004 + S-2 0.000e+00 0.000e+00 -119.058 -119.374 -0.316 +S(6) 1.599e-02 + SO4-2 1.048e-02 5.041e-03 -1.979 -2.297 -0.318 + CaSO4 5.508e-03 5.562e-03 -2.259 -2.255 0.004 + HSO4- 7.720e-08 6.402e-08 -7.112 -7.194 -0.081 + CaHSO4+ 4.772e-09 3.957e-09 -8.321 -8.403 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.18 -4.59 -4.40 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -34.22 -37.41 -3.18 H2 + H2O(g) -1.31 -0.00 1.31 H2O + H2S(g) -112.68 -113.77 -1.08 H2S + O2(g) -12.06 -15.05 -3.00 O2 + Sulfur -84.24 -79.54 4.70 S + +Reaction step 10. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.18 -4.59 -4.41 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.985e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.602e-02 1.546e-02 + S 1.602e-02 1.546e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.950 Charge balance + pe = 10.078 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.193e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 34.000 + Electrical balance (eq) = -1.005e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.070743e+02 + Total O = 5.359895e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.079e-07 1.707e-07 -6.682 -6.768 -0.086 + H+ 1.307e-07 1.123e-07 -6.884 -6.950 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.602e-02 + Ca+2 1.048e-02 5.134e-03 -1.980 -2.290 -0.310 + CaSO4 5.541e-03 5.595e-03 -2.256 -2.252 0.004 + CaOH+ 9.149e-09 7.585e-09 -8.039 -8.120 -0.081 + CaHSO4+ 5.015e-09 4.157e-09 -8.300 -8.381 -0.081 +H(0) 1.129e-37 + H2 5.647e-38 5.701e-38 -37.248 -37.244 0.004 +O(0) 1.675e-15 + O2 8.373e-16 8.454e-16 -15.077 -15.073 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -113.028 -113.114 -0.086 + H2S 0.000e+00 0.000e+00 -113.233 -113.229 0.004 + S-2 0.000e+00 0.000e+00 -118.505 -118.822 -0.317 +S(6) 1.602e-02 + SO4-2 1.048e-02 5.034e-03 -1.980 -2.298 -0.319 + CaSO4 5.541e-03 5.595e-03 -2.256 -2.252 0.004 + HSO4- 8.124e-08 6.734e-08 -7.090 -7.172 -0.081 + CaHSO4+ 5.015e-09 4.157e-09 -8.300 -8.381 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.18 -4.59 -4.41 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -34.06 -37.24 -3.19 H2 + H2O(g) -1.28 -0.00 1.28 H2O + H2S(g) -112.13 -113.23 -1.10 H2S + O2(g) -12.07 -15.07 -3.00 O2 + Sulfur -83.85 -79.17 4.68 S + +Reaction step 11. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.17 -4.59 -4.42 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.985e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.605e-02 1.548e-02 + S 1.605e-02 1.548e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.937 Charge balance + pe = 10.013 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.191e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 35.000 + Electrical balance (eq) = -1.043e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 20 + Total H = 1.070744e+02 + Total O = 5.359911e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.165e-07 1.776e-07 -6.665 -6.750 -0.086 + H+ 1.345e-07 1.155e-07 -6.871 -6.937 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.605e-02 + Ca+2 1.048e-02 5.126e-03 -1.980 -2.290 -0.310 + CaSO4 5.573e-03 5.627e-03 -2.254 -2.250 0.004 + CaOH+ 8.881e-09 7.360e-09 -8.052 -8.133 -0.082 + CaHSO4+ 5.267e-09 4.365e-09 -8.278 -8.360 -0.082 +H(0) 1.600e-37 + H2 8.002e-38 8.080e-38 -37.097 -37.093 0.004 +O(0) 1.676e-15 + O2 8.378e-16 8.459e-16 -15.077 -15.073 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -112.533 -112.619 -0.086 + H2S 0.000e+00 0.000e+00 -112.737 -112.733 0.004 + S-2 0.000e+00 0.000e+00 -117.994 -118.312 -0.317 +S(6) 1.605e-02 + SO4-2 1.048e-02 5.026e-03 -1.980 -2.299 -0.319 + CaSO4 5.573e-03 5.627e-03 -2.254 -2.250 0.004 + HSO4- 8.546e-08 7.082e-08 -7.068 -7.150 -0.082 + CaHSO4+ 5.267e-09 4.365e-09 -8.278 -8.360 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.17 -4.59 -4.42 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -33.90 -37.09 -3.19 H2 + H2O(g) -1.26 -0.00 1.26 H2O + H2S(g) -111.63 -112.73 -1.11 H2S + O2(g) -12.07 -15.07 -3.00 O2 + Sulfur -83.49 -78.83 4.66 S + +Reaction step 12. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.17 -4.59 -4.42 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.608e-02 1.551e-02 + S 1.608e-02 1.551e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.925 Charge balance + pe = 9.946 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.189e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 36.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.070745e+02 + Total O = 5.359925e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.253e-07 1.848e-07 -6.647 -6.733 -0.086 + H+ 1.384e-07 1.189e-07 -6.859 -6.925 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.608e-02 + Ca+2 1.047e-02 5.118e-03 -1.980 -2.291 -0.311 + CaSO4 5.603e-03 5.657e-03 -2.252 -2.247 0.004 + CaOH+ 8.622e-09 7.143e-09 -8.064 -8.146 -0.082 + CaHSO4+ 5.530e-09 4.582e-09 -8.257 -8.339 -0.082 +H(0) 2.285e-37 + H2 1.143e-37 1.154e-37 -36.942 -36.938 0.004 +O(0) 1.644e-15 + O2 8.221e-16 8.301e-16 -15.085 -15.081 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -112.024 -112.110 -0.086 + H2S 0.000e+00 0.000e+00 -112.227 -112.223 0.004 + S-2 0.000e+00 0.000e+00 -117.470 -117.788 -0.318 +S(6) 1.608e-02 + SO4-2 1.047e-02 5.018e-03 -1.980 -2.300 -0.320 + CaSO4 5.603e-03 5.657e-03 -2.252 -2.247 0.004 + HSO4- 8.988e-08 7.446e-08 -7.046 -7.128 -0.082 + CaHSO4+ 5.530e-09 4.582e-09 -8.257 -8.339 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.17 -4.59 -4.42 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -33.74 -36.94 -3.20 H2 + H2O(g) -1.24 -0.00 1.24 H2O + H2S(g) -111.11 -112.22 -1.12 H2S + O2(g) -12.07 -15.08 -3.01 O2 + Sulfur -83.11 -78.48 4.63 S + +Reaction step 13. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.16 -4.59 -4.43 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.610e-02 1.553e-02 + S 1.610e-02 1.553e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.913 Charge balance + pe = 9.884 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.186e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 37.000 + Electrical balance (eq) = -1.048e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 22 + Total H = 1.070745e+02 + Total O = 5.359938e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.344e-07 1.922e-07 -6.630 -6.716 -0.086 + H+ 1.423e-07 1.222e-07 -6.847 -6.913 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.610e-02 + Ca+2 1.047e-02 5.109e-03 -1.980 -2.292 -0.311 + CaSO4 5.632e-03 5.686e-03 -2.249 -2.245 0.004 + CaOH+ 8.373e-09 6.934e-09 -8.077 -8.159 -0.082 + CaHSO4+ 5.804e-09 4.807e-09 -8.236 -8.318 -0.082 +H(0) 3.186e-37 + H2 1.593e-37 1.609e-37 -36.798 -36.794 0.004 +O(0) 1.684e-15 + O2 8.422e-16 8.504e-16 -15.075 -15.070 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -111.557 -111.643 -0.086 + H2S 0.000e+00 0.000e+00 -111.757 -111.753 0.004 + S-2 0.000e+00 0.000e+00 -116.986 -117.305 -0.318 +S(6) 1.610e-02 + SO4-2 1.047e-02 5.009e-03 -1.980 -2.300 -0.320 + CaSO4 5.632e-03 5.686e-03 -2.249 -2.245 0.004 + HSO4- 9.450e-08 7.827e-08 -7.025 -7.106 -0.082 + CaHSO4+ 5.804e-09 4.807e-09 -8.236 -8.318 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.16 -4.59 -4.43 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -33.59 -36.79 -3.20 H2 + H2O(g) -1.21 -0.00 1.21 H2O + H2S(g) -110.63 -111.75 -1.13 H2S + O2(g) -12.06 -15.07 -3.01 O2 + Sulfur -82.77 -78.16 4.61 S + +Reaction step 14. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.15 -4.59 -4.44 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.59 -4.59 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.612e-02 1.554e-02 + S 1.612e-02 1.554e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.901 Charge balance + pe = 9.865 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.183e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 38.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070746e+02 + Total O = 5.359949e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.438e-07 1.999e-07 -6.613 -6.699 -0.086 + H+ 1.464e-07 1.256e-07 -6.835 -6.901 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.612e-02 + Ca+2 1.046e-02 5.099e-03 -1.981 -2.293 -0.312 + CaSO4 5.659e-03 5.714e-03 -2.247 -2.243 0.004 + CaOH+ 8.132e-09 6.733e-09 -8.090 -8.172 -0.082 + CaHSO4+ 6.089e-09 5.042e-09 -8.215 -8.297 -0.082 +H(0) 3.638e-37 + H2 1.819e-37 1.837e-37 -36.740 -36.736 0.004 +O(0) 2.562e-15 + O2 1.281e-15 1.293e-15 -14.893 -14.888 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -111.435 -111.521 -0.086 + H2S 0.000e+00 0.000e+00 -111.634 -111.630 0.004 + S-2 0.000e+00 0.000e+00 -116.849 -117.168 -0.319 +S(6) 1.612e-02 + SO4-2 1.046e-02 4.999e-03 -1.981 -2.301 -0.321 + CaSO4 5.659e-03 5.714e-03 -2.247 -2.243 0.004 + HSO4- 9.933e-08 8.224e-08 -7.003 -7.085 -0.082 + CaHSO4+ 6.089e-09 5.042e-09 -8.215 -8.297 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.15 -4.59 -4.44 CaSO4 + Gypsum 0.00 -4.59 -4.59 CaSO4:2H2O + H2(g) -33.53 -36.74 -3.20 H2 + H2O(g) -1.19 -0.00 1.19 H2O + H2S(g) -110.49 -111.63 -1.14 H2S + O2(g) -11.87 -14.89 -3.02 O2 + Sulfur -82.69 -78.10 4.59 S + +Reaction step 15. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.15 -4.60 -4.45 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.60 -4.60 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.613e-02 1.556e-02 + S 1.613e-02 1.556e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.889 Charge balance + pe = 9.755 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.179e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 39.000 + Electrical balance (eq) = -1.056e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070747e+02 + Total O = 5.359958e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.534e-07 2.077e-07 -6.596 -6.683 -0.086 + H+ 1.504e-07 1.291e-07 -6.823 -6.889 -0.066 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.613e-02 + Ca+2 1.045e-02 5.089e-03 -1.981 -2.293 -0.312 + CaSO4 5.684e-03 5.739e-03 -2.245 -2.241 0.004 + CaOH+ 7.899e-09 6.538e-09 -8.102 -8.185 -0.082 + CaHSO4+ 6.386e-09 5.286e-09 -8.195 -8.277 -0.082 +H(0) 6.313e-37 + H2 3.156e-37 3.187e-37 -36.501 -36.497 0.004 +O(0) 1.680e-15 + O2 8.399e-16 8.480e-16 -15.076 -15.072 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -110.586 -110.673 -0.086 + H2S 0.000e+00 0.000e+00 -110.783 -110.779 0.004 + S-2 0.000e+00 0.000e+00 -115.984 -116.304 -0.319 +S(6) 1.613e-02 + SO4-2 1.045e-02 4.989e-03 -1.981 -2.302 -0.321 + CaSO4 5.684e-03 5.739e-03 -2.245 -2.241 0.004 + HSO4- 1.044e-07 8.640e-08 -6.981 -7.064 -0.082 + CaHSO4+ 6.386e-09 5.286e-09 -8.195 -8.277 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.15 -4.60 -4.45 CaSO4 + Gypsum 0.00 -4.60 -4.60 CaSO4:2H2O + H2(g) -33.29 -36.50 -3.21 H2 + H2O(g) -1.16 -0.00 1.16 H2O + H2S(g) -109.63 -110.78 -1.15 H2S + O2(g) -12.05 -15.07 -3.02 O2 + Sulfur -82.06 -77.49 4.57 S + +Reaction step 16. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.14 -4.60 -4.46 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.60 -4.60 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.614e-02 1.557e-02 + S 1.614e-02 1.557e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.877 Charge balance + pe = 9.692 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.174e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 40.000 + Electrical balance (eq) = -1.037e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070747e+02 + Total O = 5.359965e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.634e-07 2.158e-07 -6.579 -6.666 -0.086 + H+ 1.546e-07 1.326e-07 -6.811 -6.877 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.614e-02 + Ca+2 1.044e-02 5.078e-03 -1.981 -2.294 -0.313 + CaSO4 5.708e-03 5.764e-03 -2.243 -2.239 0.004 + CaOH+ 7.675e-09 6.351e-09 -8.115 -8.197 -0.082 + CaHSO4+ 6.694e-09 5.539e-09 -8.174 -8.257 -0.082 +H(0) 8.826e-37 + H2 4.413e-37 4.456e-37 -36.355 -36.351 0.004 +O(0) 1.689e-15 + O2 8.445e-16 8.527e-16 -15.073 -15.069 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -110.112 -110.198 -0.086 + H2S 0.000e+00 0.000e+00 -110.307 -110.303 0.004 + S-2 0.000e+00 0.000e+00 -115.494 -115.814 -0.320 +S(6) 1.614e-02 + SO4-2 1.044e-02 4.979e-03 -1.981 -2.303 -0.321 + CaSO4 5.708e-03 5.764e-03 -2.243 -2.239 0.004 + HSO4- 1.097e-07 9.073e-08 -6.960 -7.042 -0.082 + CaHSO4+ 6.694e-09 5.539e-09 -8.174 -8.257 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.14 -4.60 -4.46 CaSO4 + Gypsum 0.00 -4.60 -4.60 CaSO4:2H2O + H2(g) -33.14 -36.35 -3.21 H2 + H2O(g) -1.14 -0.00 1.14 H2O + H2S(g) -109.15 -110.30 -1.16 H2S + O2(g) -12.04 -15.07 -3.02 O2 + Sulfur -81.71 -77.16 4.55 S + +Reaction step 17. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.13 -4.60 -4.47 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.60 -4.60 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.615e-02 1.558e-02 + S 1.615e-02 1.558e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.866 Charge balance + pe = 9.629 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.169e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 41.000 + Electrical balance (eq) = -1.043e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070748e+02 + Total O = 5.359970e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.736e-07 2.241e-07 -6.563 -6.649 -0.087 + H+ 1.588e-07 1.362e-07 -6.799 -6.866 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.615e-02 + Ca+2 1.042e-02 5.066e-03 -1.982 -2.295 -0.313 + CaSO4 5.731e-03 5.786e-03 -2.242 -2.238 0.004 + CaOH+ 7.458e-09 6.170e-09 -8.127 -8.210 -0.082 + CaHSO4+ 7.014e-09 5.802e-09 -8.154 -8.236 -0.082 +H(0) 1.237e-36 + H2 6.185e-37 6.244e-37 -36.209 -36.205 0.004 +O(0) 1.683e-15 + O2 8.416e-16 8.497e-16 -15.075 -15.071 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -109.633 -109.719 -0.087 + H2S 0.000e+00 0.000e+00 -109.826 -109.822 0.004 + S-2 0.000e+00 0.000e+00 -115.000 -115.320 -0.320 +S(6) 1.615e-02 + SO4-2 1.042e-02 4.967e-03 -1.982 -2.304 -0.322 + CaSO4 5.731e-03 5.786e-03 -2.242 -2.238 0.004 + HSO4- 1.152e-07 9.526e-08 -6.939 -7.021 -0.082 + CaHSO4+ 7.014e-09 5.802e-09 -8.154 -8.236 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.13 -4.60 -4.47 CaSO4 + Gypsum 0.00 -4.60 -4.60 CaSO4:2H2O + H2(g) -32.99 -36.20 -3.22 H2 + H2O(g) -1.12 -0.00 1.12 H2O + H2S(g) -108.65 -109.82 -1.17 H2S + O2(g) -12.04 -15.07 -3.03 O2 + Sulfur -81.36 -76.83 4.53 S + +Reaction step 18. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.13 -4.60 -4.47 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.60 -4.60 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.616e-02 1.559e-02 + S 1.616e-02 1.559e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.854 Charge balance + pe = 9.564 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.164e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 42.000 + Electrical balance (eq) = -1.067e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070748e+02 + Total O = 5.359974e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.842e-07 2.327e-07 -6.546 -6.633 -0.087 + H+ 1.631e-07 1.398e-07 -6.788 -6.854 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.616e-02 + Ca+2 1.041e-02 5.054e-03 -1.983 -2.296 -0.314 + CaSO4 5.752e-03 5.808e-03 -2.240 -2.236 0.004 + CaHSO4+ 7.346e-09 6.075e-09 -8.134 -8.216 -0.082 + CaOH+ 7.249e-09 5.995e-09 -8.140 -8.222 -0.082 +H(0) 1.736e-36 + H2 8.682e-37 8.766e-37 -36.061 -36.057 0.004 +O(0) 1.664e-15 + O2 8.322e-16 8.402e-16 -15.080 -15.076 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -109.150 -109.237 -0.087 + H2S 0.000e+00 0.000e+00 -109.341 -109.337 0.004 + S-2 0.000e+00 0.000e+00 -114.502 -114.822 -0.321 +S(6) 1.616e-02 + SO4-2 1.041e-02 4.956e-03 -1.983 -2.305 -0.322 + CaSO4 5.752e-03 5.808e-03 -2.240 -2.236 0.004 + HSO4- 1.209e-07 9.998e-08 -6.918 -7.000 -0.082 + CaHSO4+ 7.346e-09 6.075e-09 -8.134 -8.216 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.13 -4.60 -4.47 CaSO4 + Gypsum 0.00 -4.60 -4.60 CaSO4:2H2O + H2(g) -32.84 -36.06 -3.22 H2 + H2O(g) -1.09 -0.00 1.09 H2O + H2S(g) -108.16 -109.34 -1.18 H2S + O2(g) -12.04 -15.08 -3.03 O2 + Sulfur -81.01 -76.50 4.51 S + +Reaction step 19. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.12 -4.60 -4.48 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.60 -4.60 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.616e-02 1.559e-02 + S 1.616e-02 1.559e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.843 Charge balance + pe = 9.503 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.157e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 43.000 + Electrical balance (eq) = -1.056e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070748e+02 + Total O = 5.359977e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.950e-07 2.416e-07 -6.530 -6.617 -0.087 + H+ 1.674e-07 1.435e-07 -6.776 -6.843 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.616e-02 + Ca+2 1.039e-02 5.042e-03 -1.983 -2.297 -0.314 + CaSO4 5.772e-03 5.827e-03 -2.239 -2.235 0.004 + CaHSO4+ 7.691e-09 6.359e-09 -8.114 -8.197 -0.083 + CaOH+ 7.048e-09 5.827e-09 -8.152 -8.235 -0.083 +H(0) 2.404e-36 + H2 1.202e-36 1.213e-36 -35.920 -35.916 0.004 +O(0) 1.686e-15 + O2 8.429e-16 8.510e-16 -15.074 -15.070 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -108.692 -108.778 -0.087 + H2S 0.000e+00 0.000e+00 -108.881 -108.877 0.004 + S-2 0.000e+00 0.000e+00 -114.027 -114.348 -0.321 +S(6) 1.616e-02 + SO4-2 1.039e-02 4.944e-03 -1.983 -2.306 -0.323 + CaSO4 5.772e-03 5.827e-03 -2.239 -2.235 0.004 + HSO4- 1.269e-07 1.049e-07 -6.897 -6.979 -0.083 + CaHSO4+ 7.691e-09 6.359e-09 -8.114 -8.197 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.12 -4.60 -4.48 CaSO4 + Gypsum 0.00 -4.60 -4.60 CaSO4:2H2O + H2(g) -32.69 -35.92 -3.22 H2 + H2O(g) -1.07 -0.00 1.07 H2O + H2S(g) -107.69 -108.88 -1.19 H2S + O2(g) -12.03 -15.07 -3.04 O2 + Sulfur -80.67 -76.18 4.49 S + +Reaction step 20. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.11 -4.61 -4.49 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.61 -4.61 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.617e-02 1.559e-02 + S 1.617e-02 1.559e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.832 Charge balance + pe = 9.445 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.150e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 44.000 + Electrical balance (eq) = -1.062e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070748e+02 + Total O = 5.359977e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.062e-07 2.506e-07 -6.514 -6.601 -0.087 + H+ 1.718e-07 1.473e-07 -6.765 -6.832 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.617e-02 + Ca+2 1.038e-02 5.028e-03 -1.984 -2.299 -0.315 + CaSO4 5.790e-03 5.845e-03 -2.237 -2.233 0.004 + CaHSO4+ 8.049e-09 6.653e-09 -8.094 -8.177 -0.083 + CaOH+ 6.853e-09 5.665e-09 -8.164 -8.247 -0.083 +H(0) 3.282e-36 + H2 1.641e-36 1.657e-36 -35.785 -35.781 0.004 +O(0) 1.748e-15 + O2 8.739e-16 8.823e-16 -15.059 -15.054 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -108.256 -108.343 -0.087 + H2S 0.000e+00 0.000e+00 -108.443 -108.439 0.004 + S-2 0.000e+00 0.000e+00 -113.577 -113.898 -0.321 +S(6) 1.617e-02 + SO4-2 1.038e-02 4.931e-03 -1.984 -2.307 -0.323 + CaSO4 5.790e-03 5.845e-03 -2.237 -2.233 0.004 + HSO4- 1.331e-07 1.100e-07 -6.876 -6.958 -0.083 + CaHSO4+ 8.049e-09 6.653e-09 -8.094 -8.177 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.11 -4.61 -4.49 CaSO4 + Gypsum 0.00 -4.61 -4.61 CaSO4:2H2O + H2(g) -32.55 -35.78 -3.23 H2 + H2O(g) -1.05 -0.00 1.05 H2O + H2S(g) -107.24 -108.44 -1.20 H2S + O2(g) -12.01 -15.05 -3.04 O2 + Sulfur -80.35 -75.89 4.46 S + +Reaction step 21. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.11 -4.61 -4.50 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.61 -4.61 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.616e-02 1.559e-02 + S 1.616e-02 1.559e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.821 Charge balance + pe = 9.379 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.143e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 45.000 + Electrical balance (eq) = -1.068e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070748e+02 + Total O = 5.359976e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.177e-07 2.600e-07 -6.498 -6.585 -0.087 + H+ 1.762e-07 1.510e-07 -6.754 -6.821 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.616e-02 + Ca+2 1.036e-02 5.015e-03 -1.985 -2.300 -0.315 + CaSO4 5.806e-03 5.862e-03 -2.236 -2.232 0.004 + CaHSO4+ 8.419e-09 6.957e-09 -8.075 -8.158 -0.083 + CaOH+ 6.666e-09 5.508e-09 -8.176 -8.259 -0.083 +H(0) 4.641e-36 + H2 2.320e-36 2.343e-36 -35.634 -35.630 0.004 +O(0) 1.682e-15 + O2 8.410e-16 8.491e-16 -15.075 -15.071 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -107.759 -107.846 -0.087 + H2S 0.000e+00 0.000e+00 -107.944 -107.940 0.004 + S-2 0.000e+00 0.000e+00 -113.064 -113.386 -0.322 +S(6) 1.616e-02 + SO4-2 1.036e-02 4.918e-03 -1.985 -2.308 -0.323 + CaSO4 5.806e-03 5.862e-03 -2.236 -2.232 0.004 + HSO4- 1.396e-07 1.154e-07 -6.855 -6.938 -0.083 + CaHSO4+ 8.419e-09 6.957e-09 -8.075 -8.158 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.11 -4.61 -4.50 CaSO4 + Gypsum 0.00 -4.61 -4.61 CaSO4:2H2O + H2(g) -32.40 -35.63 -3.23 H2 + H2O(g) -1.03 -0.00 1.03 H2O + H2S(g) -106.73 -107.94 -1.21 H2S + O2(g) -12.03 -15.07 -3.04 O2 + Sulfur -79.98 -75.54 4.44 S + +Reaction step 22. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.10 -4.61 -4.51 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.61 -4.61 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.616e-02 1.559e-02 + S 1.616e-02 1.559e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.810 Charge balance + pe = 9.316 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.135e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 46.000 + Electrical balance (eq) = -1.073e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070748e+02 + Total O = 5.359973e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.296e-07 2.696e-07 -6.482 -6.569 -0.087 + H+ 1.807e-07 1.549e-07 -6.743 -6.810 -0.067 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +Ca 1.616e-02 + Ca+2 1.034e-02 5.001e-03 -1.986 -2.301 -0.315 + CaSO4 5.821e-03 5.877e-03 -2.235 -2.231 0.004 + CaHSO4+ 8.804e-09 7.273e-09 -8.055 -8.138 -0.083 + CaOH+ 6.484e-09 5.357e-09 -8.188 -8.271 -0.083 +H(0) 6.456e-36 + H2 3.228e-36 3.259e-36 -35.491 -35.487 0.004 +O(0) 1.666e-15 + O2 8.330e-16 8.410e-16 -15.079 -15.075 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -107.291 -107.378 -0.087 + H2S 0.000e+00 0.000e+00 -107.473 -107.469 0.004 + S-2 0.000e+00 0.000e+00 -112.580 -112.902 -0.322 +S(6) 1.616e-02 + SO4-2 1.034e-02 4.904e-03 -1.986 -2.309 -0.324 + CaSO4 5.821e-03 5.877e-03 -2.235 -2.231 0.004 + HSO4- 1.464e-07 1.210e-07 -6.834 -6.917 -0.083 + CaHSO4+ 8.804e-09 7.273e-09 -8.055 -8.138 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.10 -4.61 -4.51 CaSO4 + Gypsum 0.00 -4.61 -4.61 CaSO4:2H2O + H2(g) -32.25 -35.49 -3.23 H2 + H2O(g) -1.00 -0.00 1.00 H2O + H2S(g) -106.25 -107.47 -1.22 H2S + O2(g) -12.03 -15.08 -3.05 O2 + Sulfur -79.64 -75.22 4.42 S + +Reaction step 23. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.09 -4.61 -4.52 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.61 -4.61 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.615e-02 1.558e-02 + S 1.615e-02 1.558e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.799 Charge balance + pe = 9.255 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.127e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 47.000 + Electrical balance (eq) = -1.079e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.070747e+02 + Total O = 5.359969e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.417e-07 2.795e-07 -6.466 -6.554 -0.087 + H+ 1.852e-07 1.587e-07 -6.732 -6.799 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.615e-02 + Ca+2 1.032e-02 4.986e-03 -1.986 -2.302 -0.316 + CaSO4 5.835e-03 5.891e-03 -2.234 -2.230 0.004 + CaHSO4+ 9.202e-09 7.600e-09 -8.036 -8.119 -0.083 + CaOH+ 6.310e-09 5.211e-09 -8.200 -8.283 -0.083 +H(0) 8.884e-36 + H2 4.442e-36 4.485e-36 -35.352 -35.348 0.004 +O(0) 1.679e-15 + O2 8.396e-16 8.477e-16 -15.076 -15.072 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -106.840 -106.927 -0.087 + H2S 0.000e+00 0.000e+00 -107.020 -107.016 0.004 + S-2 0.000e+00 0.000e+00 -112.114 -112.436 -0.323 +S(6) 1.615e-02 + SO4-2 1.032e-02 4.890e-03 -1.986 -2.311 -0.324 + CaSO4 5.835e-03 5.891e-03 -2.234 -2.230 0.004 + HSO4- 1.535e-07 1.268e-07 -6.814 -6.897 -0.083 + CaHSO4+ 9.202e-09 7.600e-09 -8.036 -8.119 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.09 -4.61 -4.52 CaSO4 + Gypsum 0.00 -4.61 -4.61 CaSO4:2H2O + H2(g) -32.11 -35.35 -3.24 H2 + H2O(g) -0.98 -0.00 0.98 H2O + H2S(g) -105.79 -107.02 -1.23 H2S + O2(g) -12.02 -15.07 -3.05 O2 + Sulfur -79.31 -74.91 4.40 S + +Reaction step 24. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.08 -4.62 -4.53 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.62 -4.62 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.614e-02 1.557e-02 + S 1.614e-02 1.557e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.789 Charge balance + pe = 9.192 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.118e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 48.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070747e+02 + Total O = 5.359963e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.543e-07 2.897e-07 -6.451 -6.538 -0.087 + H+ 1.898e-07 1.626e-07 -6.722 -6.789 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.614e-02 + Ca+2 1.029e-02 4.971e-03 -1.987 -2.304 -0.316 + CaSO4 5.847e-03 5.903e-03 -2.233 -2.229 0.004 + CaHSO4+ 9.614e-09 7.938e-09 -8.017 -8.100 -0.083 + CaOH+ 6.141e-09 5.070e-09 -8.212 -8.295 -0.083 +H(0) 1.237e-35 + H2 6.183e-36 6.242e-36 -35.209 -35.205 0.004 +O(0) 1.648e-15 + O2 8.239e-16 8.317e-16 -15.084 -15.080 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -106.369 -106.456 -0.087 + H2S 0.000e+00 0.000e+00 -106.546 -106.542 0.004 + S-2 0.000e+00 0.000e+00 -111.627 -111.950 -0.323 +S(6) 1.614e-02 + SO4-2 1.029e-02 4.875e-03 -1.987 -2.312 -0.325 + CaSO4 5.847e-03 5.903e-03 -2.233 -2.229 0.004 + HSO4- 1.609e-07 1.328e-07 -6.794 -6.877 -0.083 + CaHSO4+ 9.614e-09 7.938e-09 -8.017 -8.100 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.08 -4.62 -4.53 CaSO4 + Gypsum 0.00 -4.62 -4.62 CaSO4:2H2O + H2(g) -31.96 -35.20 -3.24 H2 + H2O(g) -0.96 -0.00 0.96 H2O + H2S(g) -105.31 -106.54 -1.24 H2S + O2(g) -12.02 -15.08 -3.06 O2 + Sulfur -78.96 -74.58 4.38 S + +Reaction step 25. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.08 -4.62 -4.54 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.62 -4.62 1.000e+00 1.984e+00 9.844e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.613e-02 1.556e-02 + S 1.613e-02 1.556e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.778 Charge balance + pe = 9.142 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.108e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 49.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070747e+02 + Total O = 5.359956e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.672e-07 3.002e-07 -6.435 -6.523 -0.087 + H+ 1.945e-07 1.666e-07 -6.711 -6.778 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.613e-02 + Ca+2 1.027e-02 4.956e-03 -1.988 -2.305 -0.317 + CaSO4 5.858e-03 5.914e-03 -2.232 -2.228 0.004 + CaHSO4+ 1.004e-08 8.288e-09 -7.998 -8.082 -0.083 + CaOH+ 5.978e-09 4.935e-09 -8.223 -8.307 -0.083 +H(0) 1.623e-35 + H2 8.115e-36 8.192e-36 -35.091 -35.087 0.004 +O(0) 1.812e-15 + O2 9.060e-16 9.146e-16 -15.043 -15.039 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -106.000 -106.087 -0.087 + H2S 0.000e+00 0.000e+00 -106.175 -106.171 0.004 + S-2 0.000e+00 0.000e+00 -111.243 -111.566 -0.323 +S(6) 1.613e-02 + SO4-2 1.027e-02 4.860e-03 -1.988 -2.313 -0.325 + CaSO4 5.858e-03 5.914e-03 -2.232 -2.228 0.004 + HSO4- 1.685e-07 1.391e-07 -6.773 -6.857 -0.083 + CaHSO4+ 1.004e-08 8.288e-09 -7.998 -8.082 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.08 -4.62 -4.54 CaSO4 + Gypsum 0.00 -4.62 -4.62 CaSO4:2H2O + H2(g) -31.84 -35.09 -3.25 H2 + H2O(g) -0.94 -0.00 0.94 H2O + H2S(g) -104.92 -106.17 -1.25 H2S + O2(g) -11.98 -15.04 -3.06 O2 + Sulfur -78.69 -74.33 4.36 S + +Reaction step 26. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.07 -4.62 -4.55 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.62 -4.62 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.611e-02 1.554e-02 + S 1.611e-02 1.554e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.768 Charge balance + pe = 9.071 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.098e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 50.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070746e+02 + Total O = 5.359947e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.805e-07 3.110e-07 -6.420 -6.507 -0.088 + H+ 1.992e-07 1.706e-07 -6.701 -6.768 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.611e-02 + Ca+2 1.025e-02 4.940e-03 -1.989 -2.306 -0.317 + CaSO4 5.867e-03 5.923e-03 -2.232 -2.227 0.004 + CaHSO4+ 1.048e-08 8.650e-09 -7.980 -8.063 -0.083 + CaOH+ 5.820e-09 4.804e-09 -8.235 -8.318 -0.083 +H(0) 2.343e-35 + H2 1.172e-35 1.183e-35 -34.931 -34.927 0.004 +O(0) 1.639e-15 + O2 8.196e-16 8.274e-16 -15.086 -15.082 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -105.464 -105.552 -0.088 + H2S 0.000e+00 0.000e+00 -105.636 -105.632 0.004 + S-2 0.000e+00 0.000e+00 -110.692 -111.015 -0.324 +S(6) 1.611e-02 + SO4-2 1.025e-02 4.845e-03 -1.989 -2.315 -0.325 + CaSO4 5.867e-03 5.923e-03 -2.232 -2.227 0.004 + HSO4- 1.765e-07 1.457e-07 -6.753 -6.837 -0.083 + CaHSO4+ 1.048e-08 8.650e-09 -7.980 -8.063 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.07 -4.62 -4.55 CaSO4 + Gypsum 0.00 -4.62 -4.62 CaSO4:2H2O + H2(g) -31.68 -34.93 -3.25 H2 + H2O(g) -0.91 -0.00 0.91 H2O + H2S(g) -104.38 -105.63 -1.26 H2S + O2(g) -12.02 -15.08 -3.06 O2 + Sulfur -78.30 -73.96 4.34 S + +Reaction step 27. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.06 -4.62 -4.56 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.62 -4.62 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.609e-02 1.552e-02 + S 1.609e-02 1.552e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.758 Charge balance + pe = 9.012 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.088e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 51.000 + Electrical balance (eq) = -1.081e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.070745e+02 + Total O = 5.359936e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.941e-07 3.221e-07 -6.404 -6.492 -0.088 + H+ 2.039e-07 1.746e-07 -6.691 -6.758 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.609e-02 + Ca+2 1.022e-02 4.923e-03 -1.991 -2.308 -0.317 + CaSO4 5.875e-03 5.930e-03 -2.231 -2.227 0.004 + CaHSO4+ 1.094e-08 9.025e-09 -7.961 -8.045 -0.083 + CaOH+ 5.668e-09 4.677e-09 -8.247 -8.330 -0.083 +H(0) 3.183e-35 + H2 1.592e-35 1.607e-35 -34.798 -34.794 0.004 +O(0) 1.669e-15 + O2 8.347e-16 8.426e-16 -15.078 -15.074 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -105.034 -105.122 -0.088 + H2S 0.000e+00 0.000e+00 -105.204 -105.200 0.004 + S-2 0.000e+00 0.000e+00 -110.247 -110.570 -0.324 +S(6) 1.609e-02 + SO4-2 1.022e-02 4.829e-03 -1.991 -2.316 -0.326 + CaSO4 5.875e-03 5.930e-03 -2.231 -2.227 0.004 + HSO4- 1.848e-07 1.525e-07 -6.733 -6.817 -0.083 + CaHSO4+ 1.094e-08 9.025e-09 -7.961 -8.045 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.06 -4.62 -4.56 CaSO4 + Gypsum 0.00 -4.62 -4.62 CaSO4:2H2O + H2(g) -31.54 -34.79 -3.25 H2 + H2O(g) -0.89 -0.00 0.89 H2O + H2S(g) -103.93 -105.20 -1.27 H2S + O2(g) -12.01 -15.07 -3.07 O2 + Sulfur -77.98 -73.66 4.32 S + +Reaction step 28. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.05 -4.63 -4.58 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.63 -4.63 1.000e+00 1.984e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.607e-02 1.550e-02 + S 1.607e-02 1.550e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.748 Charge balance + pe = 8.953 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.077e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 52.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070744e+02 + Total O = 5.359924e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.081e-07 3.335e-07 -6.389 -6.477 -0.088 + H+ 2.087e-07 1.787e-07 -6.680 -6.748 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.607e-02 + Ca+2 1.019e-02 4.906e-03 -1.992 -2.309 -0.318 + CaSO4 5.881e-03 5.937e-03 -2.231 -2.226 0.004 + CaHSO4+ 1.141e-08 9.411e-09 -7.943 -8.026 -0.084 + CaOH+ 5.521e-09 4.555e-09 -8.258 -8.342 -0.084 +H(0) 4.352e-35 + H2 2.176e-35 2.196e-35 -34.662 -34.658 0.004 +O(0) 1.672e-15 + O2 8.358e-16 8.437e-16 -15.078 -15.074 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -104.592 -104.680 -0.088 + H2S 0.000e+00 0.000e+00 -104.759 -104.755 0.004 + S-2 0.000e+00 0.000e+00 -109.789 -110.114 -0.324 +S(6) 1.607e-02 + SO4-2 1.019e-02 4.813e-03 -1.992 -2.318 -0.326 + CaSO4 5.881e-03 5.937e-03 -2.231 -2.226 0.004 + HSO4- 1.934e-07 1.596e-07 -6.714 -6.797 -0.084 + CaHSO4+ 1.141e-08 9.411e-09 -7.943 -8.026 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.05 -4.63 -4.58 CaSO4 + Gypsum 0.00 -4.63 -4.63 CaSO4:2H2O + H2(g) -31.40 -34.66 -3.26 H2 + H2O(g) -0.87 -0.00 0.87 H2O + H2S(g) -103.48 -104.76 -1.28 H2S + O2(g) -12.00 -15.07 -3.07 O2 + Sulfur -77.66 -73.35 4.30 S + +Reaction step 29. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.04 -4.63 -4.59 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.63 -4.63 1.000e+00 1.985e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.605e-02 1.548e-02 + S 1.605e-02 1.548e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.738 Charge balance + pe = 8.891 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.066e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 53.000 + Electrical balance (eq) = 1.076e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 24 + Total H = 1.070744e+02 + Total O = 5.359910e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.225e-07 3.452e-07 -6.374 -6.462 -0.088 + H+ 2.136e-07 1.828e-07 -6.670 -6.738 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.605e-02 + Ca+2 1.016e-02 4.889e-03 -1.993 -2.311 -0.318 + CaSO4 5.886e-03 5.942e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.189e-08 9.811e-09 -7.925 -8.008 -0.084 + CaOH+ 5.379e-09 4.437e-09 -8.269 -8.353 -0.084 +H(0) 5.999e-35 + H2 3.000e-35 3.028e-35 -34.523 -34.519 0.004 +O(0) 1.640e-15 + O2 8.200e-16 8.278e-16 -15.086 -15.082 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -104.136 -104.224 -0.088 + H2S 0.000e+00 0.000e+00 -104.300 -104.296 0.004 + S-2 0.000e+00 0.000e+00 -109.318 -109.642 -0.325 +S(6) 1.605e-02 + SO4-2 1.016e-02 4.796e-03 -1.993 -2.319 -0.326 + CaSO4 5.886e-03 5.942e-03 -2.230 -2.226 0.004 + HSO4- 2.024e-07 1.669e-07 -6.694 -6.778 -0.084 + CaHSO4+ 1.189e-08 9.811e-09 -7.925 -8.008 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.04 -4.63 -4.59 CaSO4 + Gypsum 0.00 -4.63 -4.63 CaSO4:2H2O + H2(g) -31.26 -34.52 -3.26 H2 + H2O(g) -0.85 -0.00 0.85 H2O + H2S(g) -103.01 -104.30 -1.28 H2S + O2(g) -12.01 -15.08 -3.08 O2 + Sulfur -77.32 -73.04 4.28 S + +Reaction step 30. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.03 -4.63 -4.60 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.63 -4.63 1.000e+00 1.985e+00 9.845e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.602e-02 1.546e-02 + S 1.602e-02 1.546e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.728 Charge balance + pe = 8.834 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.054e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 54.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.070743e+02 + Total O = 5.359895e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.374e-07 3.573e-07 -6.359 -6.447 -0.088 + H+ 2.184e-07 1.869e-07 -6.661 -6.728 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.602e-02 + Ca+2 1.013e-02 4.871e-03 -1.994 -2.312 -0.318 + CaSO4 5.890e-03 5.945e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.240e-08 1.022e-08 -7.907 -7.990 -0.084 + CaOH+ 5.242e-09 4.323e-09 -8.280 -8.364 -0.084 +H(0) 8.078e-35 + H2 4.039e-35 4.077e-35 -34.394 -34.390 0.004 +O(0) 1.680e-15 + O2 8.401e-16 8.480e-16 -15.076 -15.072 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -103.720 -103.807 -0.088 + H2S 0.000e+00 0.000e+00 -103.881 -103.877 0.004 + S-2 0.000e+00 0.000e+00 -108.886 -109.211 -0.325 +S(6) 1.602e-02 + SO4-2 1.013e-02 4.779e-03 -1.994 -2.321 -0.327 + CaSO4 5.890e-03 5.945e-03 -2.230 -2.226 0.004 + HSO4- 2.117e-07 1.746e-07 -6.674 -6.758 -0.084 + CaHSO4+ 1.240e-08 1.022e-08 -7.907 -7.990 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.03 -4.63 -4.60 CaSO4 + Gypsum 0.00 -4.63 -4.63 CaSO4:2H2O + H2(g) -31.13 -34.39 -3.26 H2 + H2O(g) -0.83 -0.00 0.83 H2O + H2S(g) -102.58 -103.88 -1.29 H2S + O2(g) -11.99 -15.07 -3.08 O2 + Sulfur -77.02 -72.75 4.26 S + +Reaction step 31. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.03 -4.64 -4.61 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.64 -4.64 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.600e-02 1.543e-02 + S 1.600e-02 1.543e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.719 Charge balance + pe = 8.773 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.042e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 55.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.070741e+02 + Total O = 5.359879e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.526e-07 3.697e-07 -6.344 -6.432 -0.088 + H+ 2.233e-07 1.911e-07 -6.651 -6.719 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.600e-02 + Ca+2 1.010e-02 4.853e-03 -1.995 -2.314 -0.318 + CaSO4 5.892e-03 5.947e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.292e-08 1.065e-08 -7.889 -7.973 -0.084 + CaOH+ 5.110e-09 4.213e-09 -8.292 -8.375 -0.084 +H(0) 1.113e-34 + H2 5.565e-35 5.617e-35 -34.255 -34.250 0.004 +O(0) 1.638e-15 + O2 8.188e-16 8.264e-16 -15.087 -15.083 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -103.263 -103.351 -0.088 + H2S 0.000e+00 0.000e+00 -103.421 -103.417 0.004 + S-2 0.000e+00 0.000e+00 -108.414 -108.739 -0.325 +S(6) 1.600e-02 + SO4-2 1.010e-02 4.761e-03 -1.995 -2.322 -0.327 + CaSO4 5.892e-03 5.947e-03 -2.230 -2.226 0.004 + HSO4- 2.214e-07 1.825e-07 -6.655 -6.739 -0.084 + CaHSO4+ 1.292e-08 1.065e-08 -7.889 -7.973 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.03 -4.64 -4.61 CaSO4 + Gypsum 0.00 -4.64 -4.64 CaSO4:2H2O + H2(g) -30.98 -34.25 -3.27 H2 + H2O(g) -0.81 -0.00 0.80 H2O + H2S(g) -102.11 -103.42 -1.30 H2S + O2(g) -12.00 -15.08 -3.08 O2 + Sulfur -76.68 -72.43 4.25 S + +Reaction step 32. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.02 -4.64 -4.62 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.64 -4.64 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.597e-02 1.540e-02 + S 1.597e-02 1.540e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.709 Charge balance + pe = 8.716 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.029e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 56.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 20 + Total H = 1.070740e+02 + Total O = 5.359861e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.683e-07 3.824e-07 -6.330 -6.417 -0.088 + H+ 2.283e-07 1.953e-07 -6.642 -6.709 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.597e-02 + Ca+2 1.007e-02 4.835e-03 -1.997 -2.316 -0.319 + CaSO4 5.893e-03 5.948e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.345e-08 1.109e-08 -7.871 -7.955 -0.084 + CaOH+ 4.982e-09 4.106e-09 -8.303 -8.387 -0.084 +H(0) 1.497e-34 + H2 7.485e-35 7.554e-35 -34.126 -34.122 0.004 +O(0) 1.669e-15 + O2 8.344e-16 8.422e-16 -15.079 -15.075 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -102.848 -102.936 -0.088 + H2S 0.000e+00 0.000e+00 -103.003 -102.999 0.004 + S-2 0.000e+00 0.000e+00 -107.984 -108.309 -0.325 +S(6) 1.597e-02 + SO4-2 1.007e-02 4.743e-03 -1.997 -2.324 -0.327 + CaSO4 5.893e-03 5.948e-03 -2.230 -2.226 0.004 + HSO4- 2.314e-07 1.907e-07 -6.636 -6.720 -0.084 + CaHSO4+ 1.345e-08 1.109e-08 -7.871 -7.955 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.02 -4.64 -4.62 CaSO4 + Gypsum 0.00 -4.64 -4.64 CaSO4:2H2O + H2(g) -30.85 -34.12 -3.27 H2 + H2O(g) -0.78 -0.00 0.78 H2O + H2S(g) -101.69 -103.00 -1.31 H2S + O2(g) -11.99 -15.07 -3.09 O2 + Sulfur -76.38 -72.15 4.23 S + +Reaction step 33. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite -0.01 -4.64 -4.63 1.000e+00 -1.000e+00 + Gypsum 0.00 -4.64 -4.64 1.000e+00 1.985e+00 9.846e-01 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.593e-02 1.537e-02 + S 1.593e-02 1.537e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.700 Charge balance + pe = 8.659 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.016e-02 + Mass of water (kg) = 9.645e-01 + Total alkalinity (eq/kg) = 1.122e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 57.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 23 + Total H = 1.070739e+02 + Total O = 5.359842e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.844e-07 3.955e-07 -6.315 -6.403 -0.088 + H+ 2.333e-07 1.995e-07 -6.632 -6.700 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.593e-02 + Ca+2 1.004e-02 4.816e-03 -1.998 -2.317 -0.319 + CaSO4 5.892e-03 5.947e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.400e-08 1.154e-08 -7.854 -7.938 -0.084 + CaOH+ 4.858e-09 4.004e-09 -8.314 -8.398 -0.084 +H(0) 2.017e-34 + H2 1.009e-34 1.018e-34 -33.996 -33.992 0.004 +O(0) 1.688e-15 + O2 8.441e-16 8.519e-16 -15.074 -15.070 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -102.429 -102.517 -0.088 + H2S 0.000e+00 0.000e+00 -102.581 -102.577 0.004 + S-2 0.000e+00 0.000e+00 -107.549 -107.875 -0.326 +S(6) 1.593e-02 + SO4-2 1.004e-02 4.725e-03 -1.998 -2.326 -0.327 + CaSO4 5.892e-03 5.947e-03 -2.230 -2.226 0.004 + HSO4- 2.418e-07 1.993e-07 -6.616 -6.700 -0.084 + CaHSO4+ 1.400e-08 1.154e-08 -7.854 -7.938 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.01 -4.64 -4.63 CaSO4 + Gypsum 0.00 -4.64 -4.64 CaSO4:2H2O + H2(g) -30.72 -33.99 -3.27 H2 + H2O(g) -0.76 -0.00 0.76 H2O + H2S(g) -101.26 -102.58 -1.32 H2S + O2(g) -11.98 -15.07 -3.09 O2 + Sulfur -76.07 -71.86 4.21 S + +Reaction step 34. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.65 -4.65 1.000e+00 1.984e+00 9.835e-01 + Gypsum -0.00 -4.65 -4.65 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.588e-02 1.646e-02 + S 1.588e-02 1.646e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.691 Charge balance + pe = 8.590 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.000e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 58.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.150124e+02 + Total O = 5.757204e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.008e-07 4.089e-07 -6.300 -6.388 -0.088 + H+ 2.383e-07 2.038e-07 -6.623 -6.691 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.588e-02 + Ca+2 1.000e-02 4.794e-03 -2.000 -2.319 -0.319 + CaSO4 5.884e-03 5.939e-03 -2.230 -2.226 0.004 + CaHSO4+ 1.456e-08 1.200e-08 -7.837 -7.921 -0.084 + CaOH+ 4.735e-09 3.902e-09 -8.325 -8.409 -0.084 +H(0) 2.861e-34 + H2 1.431e-34 1.444e-34 -33.844 -33.840 0.004 +O(0) 1.535e-15 + O2 7.677e-16 7.749e-16 -15.115 -15.111 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -101.920 -102.008 -0.088 + H2S 0.000e+00 0.000e+00 -102.070 -102.066 0.004 + S-2 0.000e+00 0.000e+00 -107.026 -107.352 -0.326 +S(6) 1.588e-02 + SO4-2 9.999e-03 4.704e-03 -2.000 -2.328 -0.327 + CaSO4 5.884e-03 5.939e-03 -2.230 -2.226 0.004 + HSO4- 2.526e-07 2.081e-07 -6.598 -6.682 -0.084 + CaHSO4+ 1.456e-08 1.200e-08 -7.837 -7.921 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.65 -4.65 CaSO4 + Gypsum -0.00 -4.65 -4.65 CaSO4:2H2O + H2(g) -30.56 -33.84 -3.28 H2 + H2O(g) -0.74 -0.00 0.74 H2O + H2S(g) -100.74 -102.07 -1.33 H2S + O2(g) -12.02 -15.11 -3.09 O2 + Sulfur -75.69 -71.50 4.19 S + +Reaction step 35. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.66 -4.66 1.000e+00 1.984e+00 9.839e-01 + Gypsum -0.01 -4.66 -4.65 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.558e-02 1.614e-02 + S 1.558e-02 1.614e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.681 Charge balance + pe = 8.533 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.929e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 59.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.757079e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.158e-07 4.215e-07 -6.288 -6.375 -0.088 + H+ 2.438e-07 2.087e-07 -6.613 -6.681 -0.068 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.558e-02 + Ca+2 9.822e-03 4.724e-03 -2.008 -2.326 -0.318 + CaSO4 5.760e-03 5.812e-03 -2.240 -2.236 0.004 + CaHSO4+ 1.485e-08 1.225e-08 -7.828 -7.912 -0.084 + CaOH+ 4.554e-09 3.756e-09 -8.342 -8.425 -0.084 +H(0) 3.871e-34 + H2 1.935e-34 1.953e-34 -33.713 -33.709 0.004 +O(0) 1.530e-15 + O2 7.652e-16 7.721e-16 -15.116 -15.112 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -101.498 -101.585 -0.088 + H2S 0.000e+00 0.000e+00 -101.643 -101.639 0.004 + S-2 0.000e+00 0.000e+00 -106.590 -106.915 -0.324 +S(6) 1.558e-02 + SO4-2 9.822e-03 4.637e-03 -2.008 -2.334 -0.326 + CaSO4 5.760e-03 5.812e-03 -2.240 -2.236 0.004 + HSO4- 2.615e-07 2.157e-07 -6.582 -6.666 -0.084 + CaHSO4+ 1.485e-08 1.225e-08 -7.828 -7.912 -0.084 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.66 -4.66 CaSO4 + Gypsum -0.01 -4.66 -4.65 CaSO4:2H2O + H2(g) -30.43 -33.71 -3.28 H2 + H2O(g) -0.72 -0.00 0.72 H2O + H2S(g) -100.30 -101.64 -1.34 H2S + O2(g) -12.01 -15.11 -3.10 O2 + Sulfur -75.38 -71.21 4.17 S + +Reaction step 36. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.67 -4.67 1.000e+00 1.984e+00 9.842e-01 + Gypsum -0.02 -4.67 -4.65 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.528e-02 1.583e-02 + S 1.528e-02 1.583e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.670 Charge balance + pe = 8.477 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.858e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 60.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756954e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.310e-07 4.344e-07 -6.275 -6.362 -0.087 + H+ 2.494e-07 2.136e-07 -6.603 -6.670 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.528e-02 + Ca+2 9.645e-03 4.654e-03 -2.016 -2.332 -0.316 + CaSO4 5.636e-03 5.686e-03 -2.249 -2.245 0.004 + CaHSO4+ 1.515e-08 1.250e-08 -7.820 -7.903 -0.083 + CaOH+ 4.379e-09 3.615e-09 -8.359 -8.442 -0.083 +H(0) 5.203e-34 + H2 2.602e-34 2.625e-34 -33.585 -33.581 0.004 +O(0) 1.539e-15 + O2 7.696e-16 7.765e-16 -15.114 -15.110 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -101.086 -101.173 -0.087 + H2S 0.000e+00 0.000e+00 -101.226 -101.222 0.004 + S-2 0.000e+00 0.000e+00 -106.166 -106.489 -0.323 +S(6) 1.528e-02 + SO4-2 9.644e-03 4.570e-03 -2.016 -2.340 -0.324 + CaSO4 5.636e-03 5.686e-03 -2.249 -2.245 0.004 + HSO4- 2.707e-07 2.234e-07 -6.568 -6.651 -0.083 + CaHSO4+ 1.515e-08 1.250e-08 -7.820 -7.903 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.67 -4.67 CaSO4 + Gypsum -0.02 -4.67 -4.65 CaSO4:2H2O + H2(g) -30.30 -33.58 -3.29 H2 + H2O(g) -0.70 -0.00 0.70 H2O + H2S(g) -99.87 -101.22 -1.35 H2S + O2(g) -12.01 -15.11 -3.10 O2 + Sulfur -75.08 -70.93 4.15 S + +Reaction step 37. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.69 -4.69 1.000e+00 1.984e+00 9.845e-01 + Gypsum -0.03 -4.69 -4.66 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.498e-02 1.552e-02 + S 1.498e-02 1.552e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.660 Charge balance + pe = 8.422 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.787e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 61.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756829e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.465e-07 4.476e-07 -6.262 -6.349 -0.087 + H+ 2.551e-07 2.186e-07 -6.593 -6.660 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.498e-02 + Ca+2 9.468e-03 4.584e-03 -2.024 -2.339 -0.315 + CaSO4 5.511e-03 5.559e-03 -2.259 -2.255 0.004 + CaHSO4+ 1.544e-08 1.275e-08 -7.811 -7.894 -0.083 + CaOH+ 4.211e-09 3.479e-09 -8.376 -8.459 -0.083 +H(0) 6.963e-34 + H2 3.482e-34 3.512e-34 -33.458 -33.454 0.004 +O(0) 1.557e-15 + O2 7.783e-16 7.851e-16 -15.109 -15.105 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -100.681 -100.768 -0.087 + H2S 0.000e+00 0.000e+00 -100.816 -100.812 0.004 + S-2 0.000e+00 0.000e+00 -105.748 -106.070 -0.321 +S(6) 1.498e-02 + SO4-2 9.467e-03 4.503e-03 -2.024 -2.347 -0.323 + CaSO4 5.511e-03 5.559e-03 -2.259 -2.255 0.004 + HSO4- 2.801e-07 2.314e-07 -6.553 -6.636 -0.083 + CaHSO4+ 1.544e-08 1.275e-08 -7.811 -7.894 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.69 -4.69 CaSO4 + Gypsum -0.03 -4.69 -4.66 CaSO4:2H2O + H2(g) -30.17 -33.45 -3.29 H2 + H2O(g) -0.68 -0.00 0.68 H2O + H2S(g) -99.45 -100.81 -1.36 H2S + O2(g) -12.00 -15.11 -3.11 O2 + Sulfur -74.78 -70.65 4.13 S + +Reaction step 38. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.70 -4.70 1.000e+00 1.985e+00 9.848e-01 + Gypsum -0.04 -4.70 -4.66 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.468e-02 1.521e-02 + S 1.468e-02 1.521e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.650 Charge balance + pe = 8.365 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.717e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 62.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756704e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.623e-07 4.611e-07 -6.250 -6.336 -0.086 + H+ 2.608e-07 2.236e-07 -6.584 -6.650 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.468e-02 + Ca+2 9.291e-03 4.514e-03 -2.032 -2.345 -0.314 + CaSO4 5.386e-03 5.433e-03 -2.269 -2.265 0.004 + CaHSO4+ 1.572e-08 1.300e-08 -7.803 -7.886 -0.083 + CaOH+ 4.049e-09 3.349e-09 -8.393 -8.475 -0.083 +H(0) 9.437e-34 + H2 4.719e-34 4.759e-34 -33.326 -33.322 0.004 +O(0) 1.529e-15 + O2 7.646e-16 7.712e-16 -15.117 -15.113 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -100.254 -100.340 -0.086 + H2S 0.000e+00 0.000e+00 -100.384 -100.380 0.004 + S-2 0.000e+00 0.000e+00 -105.309 -105.628 -0.320 +S(6) 1.468e-02 + SO4-2 9.291e-03 4.435e-03 -2.032 -2.353 -0.321 + CaSO4 5.386e-03 5.433e-03 -2.269 -2.265 0.004 + HSO4- 2.897e-07 2.396e-07 -6.538 -6.621 -0.083 + CaHSO4+ 1.572e-08 1.300e-08 -7.803 -7.886 -0.083 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.70 -4.70 CaSO4 + Gypsum -0.04 -4.70 -4.66 CaSO4:2H2O + H2(g) -30.03 -33.32 -3.29 H2 + H2O(g) -0.66 -0.00 0.66 H2O + H2S(g) -99.01 -100.38 -1.37 H2S + O2(g) -12.00 -15.11 -3.11 O2 + Sulfur -74.46 -70.35 4.11 S + +Reaction step 39. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.71 -4.71 1.000e+00 1.985e+00 9.851e-01 + Gypsum -0.05 -4.71 -4.67 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.438e-02 1.490e-02 + S 1.438e-02 1.490e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.641 Charge balance + pe = 8.221 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.646e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 63.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756580e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.784e-07 4.748e-07 -6.238 -6.324 -0.086 + H+ 2.666e-07 2.287e-07 -6.574 -6.641 -0.067 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.438e-02 + Ca+2 9.116e-03 4.444e-03 -2.040 -2.352 -0.312 + CaSO4 5.262e-03 5.307e-03 -2.279 -2.275 0.004 + CaHSO4+ 1.600e-08 1.325e-08 -7.796 -7.878 -0.082 + CaOH+ 3.894e-09 3.223e-09 -8.410 -8.492 -0.082 +H(0) 1.894e-33 + H2 9.471e-34 9.551e-34 -33.024 -33.020 0.004 +O(0) 6.826e-16 + O2 3.413e-16 3.442e-16 -15.467 -15.463 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -99.144 -99.230 -0.086 + H2S 0.000e+00 0.000e+00 -99.269 -99.265 0.004 + S-2 0.000e+00 0.000e+00 -104.186 -104.504 -0.318 +S(6) 1.438e-02 + SO4-2 9.115e-03 4.368e-03 -2.040 -2.360 -0.319 + CaSO4 5.262e-03 5.307e-03 -2.279 -2.275 0.004 + HSO4- 2.995e-07 2.479e-07 -6.524 -6.606 -0.082 + CaHSO4+ 1.600e-08 1.325e-08 -7.796 -7.878 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.71 -4.71 CaSO4 + Gypsum -0.05 -4.71 -4.67 CaSO4:2H2O + H2(g) -29.72 -33.02 -3.30 H2 + H2O(g) -0.64 -0.00 0.64 H2O + H2S(g) -97.89 -99.27 -1.38 H2S + O2(g) -12.35 -15.46 -3.11 O2 + Sulfur -73.64 -69.54 4.09 S + +Reaction step 40. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.73 -4.73 1.000e+00 1.985e+00 9.854e-01 + Gypsum -0.06 -4.73 -4.67 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.408e-02 1.459e-02 + S 1.408e-02 1.459e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.631 Charge balance + pe = 8.254 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.576e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 64.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756456e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.948e-07 4.888e-07 -6.226 -6.311 -0.085 + H+ 2.725e-07 2.339e-07 -6.565 -6.631 -0.066 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.408e-02 + Ca+2 8.941e-03 4.374e-03 -2.049 -2.359 -0.310 + CaSO4 5.138e-03 5.181e-03 -2.289 -2.286 0.004 + CaHSO4+ 1.628e-08 1.349e-08 -7.788 -7.870 -0.082 + CaOH+ 3.744e-09 3.102e-09 -8.427 -8.508 -0.082 +H(0) 1.693e-33 + H2 8.466e-34 8.536e-34 -33.072 -33.069 0.004 +O(0) 1.531e-15 + O2 7.655e-16 7.718e-16 -15.116 -15.112 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -99.439 -99.524 -0.085 + H2S 0.000e+00 0.000e+00 -99.559 -99.555 0.004 + S-2 0.000e+00 0.000e+00 -104.469 -104.785 -0.316 +S(6) 1.408e-02 + SO4-2 8.941e-03 4.301e-03 -2.049 -2.366 -0.318 + CaSO4 5.138e-03 5.181e-03 -2.289 -2.286 0.004 + HSO4- 3.096e-07 2.565e-07 -6.509 -6.591 -0.082 + CaHSO4+ 1.628e-08 1.349e-08 -7.788 -7.870 -0.082 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.73 -4.73 CaSO4 + Gypsum -0.06 -4.73 -4.67 CaSO4:2H2O + H2(g) -29.77 -33.07 -3.30 H2 + H2O(g) -0.62 -0.00 0.62 H2O + H2S(g) -98.17 -99.56 -1.38 H2S + O2(g) -12.00 -15.11 -3.12 O2 + Sulfur -73.86 -69.79 4.08 S + +Reaction step 41. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.74 -4.74 1.000e+00 1.986e+00 9.857e-01 + Gypsum -0.07 -4.74 -4.67 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.378e-02 1.428e-02 + S 1.378e-02 1.428e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.621 Charge balance + pe = 8.199 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.507e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 65.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756333e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.114e-07 5.030e-07 -6.214 -6.298 -0.085 + H+ 2.785e-07 2.392e-07 -6.555 -6.621 -0.066 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.378e-02 + Ca+2 8.767e-03 4.305e-03 -2.057 -2.366 -0.309 + CaSO4 5.015e-03 5.056e-03 -2.300 -2.296 0.004 + CaHSO4+ 1.656e-08 1.373e-08 -7.781 -7.862 -0.081 + CaOH+ 3.600e-09 2.986e-09 -8.444 -8.525 -0.081 +H(0) 2.266e-33 + H2 1.133e-33 1.142e-33 -32.946 -32.942 0.004 +O(0) 1.527e-15 + O2 7.634e-16 7.696e-16 -15.117 -15.114 0.004 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -99.033 -99.117 -0.085 + H2S 0.000e+00 0.000e+00 -99.147 -99.144 0.004 + S-2 0.000e+00 0.000e+00 -104.050 -104.365 -0.315 +S(6) 1.378e-02 + SO4-2 8.767e-03 4.234e-03 -2.057 -2.373 -0.316 + CaSO4 5.015e-03 5.056e-03 -2.300 -2.296 0.004 + HSO4- 3.199e-07 2.653e-07 -6.495 -6.576 -0.081 + CaHSO4+ 1.656e-08 1.373e-08 -7.781 -7.862 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.74 -4.74 CaSO4 + Gypsum -0.07 -4.74 -4.67 CaSO4:2H2O + H2(g) -29.64 -32.94 -3.30 H2 + H2O(g) -0.60 -0.00 0.60 H2O + H2S(g) -97.75 -99.14 -1.39 H2S + O2(g) -11.99 -15.11 -3.12 O2 + Sulfur -73.56 -69.50 4.06 S + +Reaction step 42. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.75 -4.75 1.000e+00 1.986e+00 9.860e-01 + Gypsum -0.08 -4.75 -4.68 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.349e-02 1.397e-02 + S 1.349e-02 1.397e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.612 Charge balance + pe = 8.055 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.438e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 66.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.756211e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.283e-07 5.176e-07 -6.202 -6.286 -0.084 + H+ 2.845e-07 2.445e-07 -6.546 -6.612 -0.066 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.349e-02 + Ca+2 8.594e-03 4.236e-03 -2.066 -2.373 -0.307 + CaSO4 4.893e-03 4.931e-03 -2.310 -2.307 0.003 + CaHSO4+ 1.683e-08 1.397e-08 -7.774 -7.855 -0.081 + CaOH+ 3.462e-09 2.874e-09 -8.461 -8.541 -0.081 +H(0) 4.558e-33 + H2 2.279e-33 2.297e-33 -32.642 -32.639 0.003 +O(0) 6.716e-16 + O2 3.358e-16 3.384e-16 -15.474 -15.471 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -97.918 -98.002 -0.084 + H2S 0.000e+00 0.000e+00 -98.027 -98.024 0.003 + S-2 0.000e+00 0.000e+00 -102.923 -103.236 -0.313 +S(6) 1.349e-02 + SO4-2 8.594e-03 4.167e-03 -2.066 -2.380 -0.314 + CaSO4 4.893e-03 4.931e-03 -2.310 -2.307 0.003 + HSO4- 3.304e-07 2.743e-07 -6.481 -6.562 -0.081 + CaHSO4+ 1.683e-08 1.397e-08 -7.774 -7.855 -0.081 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.75 -4.75 CaSO4 + Gypsum -0.08 -4.75 -4.68 CaSO4:2H2O + H2(g) -29.33 -32.64 -3.31 H2 + H2O(g) -0.58 -0.00 0.58 H2O + H2S(g) -96.62 -98.02 -1.40 H2S + O2(g) -12.35 -15.47 -3.12 O2 + Sulfur -72.73 -68.69 4.04 S + +Reaction step 43. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.77 -4.77 1.000e+00 1.986e+00 9.863e-01 + Gypsum -0.09 -4.77 -4.68 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.319e-02 1.367e-02 + S 1.319e-02 1.367e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.602 Charge balance + pe = 8.092 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.369e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 67.000 + Electrical balance (eq) = -1.080e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.756089e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.456e-07 5.324e-07 -6.190 -6.274 -0.084 + H+ 2.905e-07 2.499e-07 -6.537 -6.602 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.319e-02 + Ca+2 8.423e-03 4.167e-03 -2.075 -2.380 -0.306 + CaSO4 4.771e-03 4.808e-03 -2.321 -2.318 0.003 + CaHSO4+ 1.709e-08 1.420e-08 -7.767 -7.848 -0.080 + CaOH+ 3.329e-09 2.766e-09 -8.478 -8.558 -0.080 +H(0) 3.979e-33 + H2 1.990e-33 2.005e-33 -32.701 -32.698 0.003 +O(0) 1.562e-15 + O2 7.812e-16 7.873e-16 -15.107 -15.104 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -98.253 -98.336 -0.084 + H2S 0.000e+00 0.000e+00 -98.356 -98.353 0.003 + S-2 0.000e+00 0.000e+00 -103.246 -103.557 -0.311 +S(6) 1.319e-02 + SO4-2 8.422e-03 4.101e-03 -2.075 -2.387 -0.313 + CaSO4 4.771e-03 4.808e-03 -2.321 -2.318 0.003 + HSO4- 3.412e-07 2.835e-07 -6.467 -6.547 -0.080 + CaHSO4+ 1.709e-08 1.420e-08 -7.767 -7.848 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.77 -4.77 CaSO4 + Gypsum -0.09 -4.77 -4.68 CaSO4:2H2O + H2(g) -29.39 -32.70 -3.31 H2 + H2O(g) -0.56 -0.00 0.56 H2O + H2S(g) -96.94 -98.35 -1.41 H2S + O2(g) -11.98 -15.10 -3.13 O2 + Sulfur -72.99 -68.96 4.02 S + +Reaction step 44. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.78 -4.78 1.000e+00 1.987e+00 9.866e-01 + Gypsum -0.10 -4.78 -4.69 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.290e-02 1.337e-02 + S 1.290e-02 1.337e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.593 Charge balance + pe = 8.038 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.301e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 68.000 + Electrical balance (eq) = -1.073e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.755969e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.631e-07 5.475e-07 -6.178 -6.262 -0.083 + H+ 2.966e-07 2.553e-07 -6.528 -6.593 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.290e-02 + Ca+2 8.252e-03 4.098e-03 -2.083 -2.387 -0.304 + CaSO4 4.650e-03 4.685e-03 -2.333 -2.329 0.003 + CaHSO4+ 1.735e-08 1.443e-08 -7.761 -7.841 -0.080 + CaOH+ 3.201e-09 2.663e-09 -8.495 -8.575 -0.080 +H(0) 5.280e-33 + H2 2.640e-33 2.660e-33 -32.578 -32.575 0.003 +O(0) 1.569e-15 + O2 7.846e-16 7.906e-16 -15.105 -15.102 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -97.860 -97.943 -0.083 + H2S 0.000e+00 0.000e+00 -97.958 -97.955 0.003 + S-2 0.000e+00 0.000e+00 -102.841 -103.150 -0.309 +S(6) 1.290e-02 + SO4-2 8.252e-03 4.034e-03 -2.083 -2.394 -0.311 + CaSO4 4.650e-03 4.685e-03 -2.333 -2.329 0.003 + HSO4- 3.522e-07 2.929e-07 -6.453 -6.533 -0.080 + CaHSO4+ 1.735e-08 1.443e-08 -7.761 -7.841 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.78 -4.78 CaSO4 + Gypsum -0.10 -4.78 -4.69 CaSO4:2H2O + H2(g) -29.26 -32.58 -3.31 H2 + H2O(g) -0.54 -0.00 0.54 H2O + H2S(g) -96.54 -97.95 -1.42 H2S + O2(g) -11.97 -15.10 -3.13 O2 + Sulfur -72.70 -68.69 4.00 S + +Reaction step 45. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.80 -4.80 1.000e+00 1.987e+00 9.869e-01 + Gypsum -0.11 -4.80 -4.69 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.261e-02 1.307e-02 + S 1.261e-02 1.307e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.584 Charge balance + pe = 7.985 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.233e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 69.000 + Electrical balance (eq) = -1.068e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.755849e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.808e-07 5.628e-07 -6.167 -6.250 -0.083 + H+ 3.028e-07 2.608e-07 -6.519 -6.584 -0.065 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +Ca 1.261e-02 + Ca+2 8.083e-03 4.029e-03 -2.092 -2.395 -0.302 + CaSO4 4.530e-03 4.564e-03 -2.344 -2.341 0.003 + CaHSO4+ 1.760e-08 1.466e-08 -7.754 -7.834 -0.080 + CaOH+ 3.078e-09 2.563e-09 -8.512 -8.591 -0.080 +H(0) 6.996e-33 + H2 3.498e-33 3.524e-33 -32.456 -32.453 0.003 +O(0) 1.575e-15 + O2 7.874e-16 7.932e-16 -15.104 -15.101 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -97.469 -97.552 -0.083 + H2S 0.000e+00 0.000e+00 -97.562 -97.558 0.003 + S-2 0.000e+00 0.000e+00 -102.438 -102.746 -0.308 +S(6) 1.261e-02 + SO4-2 8.083e-03 3.968e-03 -2.092 -2.401 -0.309 + CaSO4 4.530e-03 4.564e-03 -2.344 -2.341 0.003 + HSO4- 3.634e-07 3.026e-07 -6.440 -6.519 -0.080 + CaHSO4+ 1.760e-08 1.466e-08 -7.754 -7.834 -0.080 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.80 -4.80 CaSO4 + Gypsum -0.11 -4.80 -4.69 CaSO4:2H2O + H2(g) -29.14 -32.45 -3.32 H2 + H2O(g) -0.52 -0.00 0.52 H2O + H2S(g) -96.13 -97.56 -1.43 H2S + O2(g) -11.97 -15.10 -3.13 O2 + Sulfur -72.41 -68.42 3.99 S + +Reaction step 46. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.81 -4.81 1.000e+00 1.987e+00 9.872e-01 + Gypsum -0.12 -4.81 -4.69 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.233e-02 1.277e-02 + S 1.233e-02 1.277e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.574 Charge balance + pe = 7.930 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.166e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 70.000 + Electrical balance (eq) = -1.062e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.755730e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.989e-07 5.785e-07 -6.156 -6.238 -0.082 + H+ 3.091e-07 2.664e-07 -6.510 -6.574 -0.065 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.233e-02 + Ca+2 7.916e-03 3.961e-03 -2.101 -2.402 -0.301 + CaSO4 4.411e-03 4.444e-03 -2.355 -2.352 0.003 + CaHSO4+ 1.785e-08 1.488e-08 -7.748 -7.827 -0.079 + CaOH+ 2.959e-09 2.467e-09 -8.529 -8.608 -0.079 +H(0) 9.312e-33 + H2 4.656e-33 4.690e-33 -32.332 -32.329 0.003 +O(0) 1.561e-15 + O2 7.805e-16 7.862e-16 -15.108 -15.104 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -97.070 -97.152 -0.082 + H2S 0.000e+00 0.000e+00 -97.157 -97.154 0.003 + S-2 0.000e+00 0.000e+00 -102.027 -102.333 -0.306 +S(6) 1.233e-02 + SO4-2 7.916e-03 3.902e-03 -2.102 -2.409 -0.307 + CaSO4 4.411e-03 4.444e-03 -2.355 -2.352 0.003 + HSO4- 3.748e-07 3.125e-07 -6.426 -6.505 -0.079 + CaHSO4+ 1.785e-08 1.488e-08 -7.748 -7.827 -0.079 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.81 -4.81 CaSO4 + Gypsum -0.12 -4.81 -4.69 CaSO4:2H2O + H2(g) -29.01 -32.33 -3.32 H2 + H2O(g) -0.50 -0.00 0.50 H2O + H2S(g) -95.72 -97.15 -1.44 H2S + O2(g) -11.97 -15.10 -3.14 O2 + Sulfur -72.11 -68.14 3.97 S + +Reaction step 47. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.83 -4.83 1.000e+00 1.988e+00 9.875e-01 + Gypsum -0.13 -4.83 -4.70 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.204e-02 1.248e-02 + S 1.204e-02 1.248e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.565 Charge balance + pe = 7.877 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.100e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 71.000 + Electrical balance (eq) = -1.058e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.755613e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.173e-07 5.944e-07 -6.144 -6.226 -0.082 + H+ 3.154e-07 2.720e-07 -6.501 -6.565 -0.064 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.204e-02 + Ca+2 7.750e-03 3.893e-03 -2.111 -2.410 -0.299 + CaSO4 4.294e-03 4.325e-03 -2.367 -2.364 0.003 + CaHSO4+ 1.809e-08 1.510e-08 -7.742 -7.821 -0.079 + CaOH+ 2.846e-09 2.375e-09 -8.546 -8.624 -0.079 +H(0) 1.231e-32 + H2 6.154e-33 6.198e-33 -32.211 -32.208 0.003 +O(0) 1.564e-15 + O2 7.818e-16 7.874e-16 -15.107 -15.104 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -96.683 -96.764 -0.082 + H2S 0.000e+00 0.000e+00 -96.764 -96.761 0.003 + S-2 0.000e+00 0.000e+00 -101.628 -101.932 -0.304 +S(6) 1.204e-02 + SO4-2 7.750e-03 3.837e-03 -2.111 -2.416 -0.305 + CaSO4 4.294e-03 4.325e-03 -2.367 -2.364 0.003 + HSO4- 3.865e-07 3.225e-07 -6.413 -6.491 -0.079 + CaHSO4+ 1.809e-08 1.510e-08 -7.742 -7.821 -0.079 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.83 -4.83 CaSO4 + Gypsum -0.13 -4.83 -4.70 CaSO4:2H2O + H2(g) -28.89 -32.21 -3.32 H2 + H2O(g) -0.48 -0.00 0.48 H2O + H2S(g) -95.32 -96.76 -1.44 H2S + O2(g) -11.96 -15.10 -3.14 O2 + Sulfur -71.83 -67.88 3.95 S + +Reaction step 48. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.84 -4.84 1.000e+00 1.988e+00 9.878e-01 + Gypsum -0.14 -4.84 -4.70 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.176e-02 1.219e-02 + S 1.176e-02 1.219e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.556 Charge balance + pe = 7.824 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.034e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 72.000 + Electrical balance (eq) = -1.056e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.150124e+02 + Total O = 5.755497e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.359e-07 6.106e-07 -6.133 -6.214 -0.081 + H+ 3.218e-07 2.777e-07 -6.492 -6.556 -0.064 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.176e-02 + Ca+2 7.586e-03 3.826e-03 -2.120 -2.417 -0.297 + CaSO4 4.178e-03 4.207e-03 -2.379 -2.376 0.003 + CaHSO4+ 1.833e-08 1.531e-08 -7.737 -7.815 -0.078 + CaOH+ 2.736e-09 2.286e-09 -8.563 -8.641 -0.078 +H(0) 1.624e-32 + H2 8.122e-33 8.179e-33 -32.090 -32.087 0.003 +O(0) 1.566e-15 + O2 7.832e-16 7.887e-16 -15.106 -15.103 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -96.298 -96.379 -0.081 + H2S 0.000e+00 0.000e+00 -96.373 -96.370 0.003 + S-2 0.000e+00 0.000e+00 -101.231 -101.533 -0.302 +S(6) 1.176e-02 + SO4-2 7.585e-03 3.772e-03 -2.120 -2.423 -0.303 + CaSO4 4.178e-03 4.207e-03 -2.379 -2.376 0.003 + HSO4- 3.984e-07 3.328e-07 -6.400 -6.478 -0.078 + CaHSO4+ 1.833e-08 1.531e-08 -7.737 -7.815 -0.078 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.84 -4.84 CaSO4 + Gypsum -0.14 -4.84 -4.70 CaSO4:2H2O + H2(g) -28.76 -32.09 -3.33 H2 + H2O(g) -0.46 -0.00 0.46 H2O + H2S(g) -94.92 -96.37 -1.45 H2S + O2(g) -11.96 -15.10 -3.14 O2 + Sulfur -71.54 -67.61 3.93 S + +Reaction step 49. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.86 -4.86 1.000e+00 1.988e+00 9.881e-01 + Gypsum -0.15 -4.86 -4.71 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.149e-02 1.190e-02 + S 1.149e-02 1.190e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.547 Charge balance + pe = 7.769 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.969e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 73.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.755382e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.548e-07 6.271e-07 -6.122 -6.203 -0.081 + H+ 3.282e-07 2.835e-07 -6.484 -6.547 -0.064 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.149e-02 + Ca+2 7.423e-03 3.759e-03 -2.129 -2.425 -0.295 + CaSO4 4.063e-03 4.091e-03 -2.391 -2.388 0.003 + CaHSO4+ 1.856e-08 1.552e-08 -7.731 -7.809 -0.078 + CaOH+ 2.631e-09 2.200e-09 -8.580 -8.658 -0.078 +H(0) 2.169e-32 + H2 1.084e-32 1.092e-32 -31.965 -31.962 0.003 +O(0) 1.528e-15 + O2 7.641e-16 7.694e-16 -15.117 -15.114 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -95.892 -95.973 -0.081 + H2S 0.000e+00 0.000e+00 -95.962 -95.959 0.003 + S-2 0.000e+00 0.000e+00 -100.813 -101.114 -0.300 +S(6) 1.149e-02 + SO4-2 7.423e-03 3.707e-03 -2.129 -2.431 -0.302 + CaSO4 4.063e-03 4.091e-03 -2.391 -2.388 0.003 + HSO4- 4.106e-07 3.434e-07 -6.387 -6.464 -0.078 + CaHSO4+ 1.856e-08 1.552e-08 -7.731 -7.809 -0.078 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.86 -4.86 CaSO4 + Gypsum -0.15 -4.86 -4.71 CaSO4:2H2O + H2(g) -28.63 -31.96 -3.33 H2 + H2O(g) -0.44 -0.00 0.44 H2O + H2S(g) -94.50 -95.96 -1.46 H2S + O2(g) -11.97 -15.11 -3.15 O2 + Sulfur -71.24 -67.33 3.92 S + +Reaction step 50. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.87 -4.87 1.000e+00 1.988e+00 9.884e-01 + Gypsum -0.16 -4.87 -4.71 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.121e-02 1.162e-02 + S 1.121e-02 1.162e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.539 Charge balance + pe = 7.717 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.905e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 74.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.755268e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.741e-07 6.439e-07 -6.111 -6.191 -0.080 + H+ 3.347e-07 2.893e-07 -6.475 -6.539 -0.063 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.121e-02 + Ca+2 7.263e-03 3.693e-03 -2.139 -2.433 -0.294 + CaSO4 3.950e-03 3.976e-03 -2.403 -2.401 0.003 + CaHSO4+ 1.878e-08 1.572e-08 -7.726 -7.803 -0.077 + CaOH+ 2.530e-09 2.118e-09 -8.597 -8.674 -0.077 +H(0) 2.852e-32 + H2 1.426e-32 1.436e-32 -31.846 -31.843 0.003 +O(0) 1.531e-15 + O2 7.657e-16 7.709e-16 -15.116 -15.113 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -95.513 -95.593 -0.080 + H2S 0.000e+00 0.000e+00 -95.576 -95.573 0.003 + S-2 0.000e+00 0.000e+00 -100.421 -100.720 -0.299 +S(6) 1.121e-02 + SO4-2 7.262e-03 3.642e-03 -2.139 -2.439 -0.300 + CaSO4 3.950e-03 3.976e-03 -2.403 -2.401 0.003 + HSO4- 4.230e-07 3.541e-07 -6.374 -6.451 -0.077 + CaHSO4+ 1.878e-08 1.572e-08 -7.726 -7.803 -0.077 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.87 -4.87 CaSO4 + Gypsum -0.16 -4.87 -4.71 CaSO4:2H2O + H2(g) -28.51 -31.84 -3.33 H2 + H2O(g) -0.42 -0.00 0.42 H2O + H2S(g) -94.10 -95.57 -1.47 H2S + O2(g) -11.96 -15.11 -3.15 O2 + Sulfur -70.96 -67.06 3.90 S + +Reaction step 51. + +Using solution 1. Pure water +Using pure phase assemblage 1. +Using temperature 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Anhydrite 0.00 -4.89 -4.89 1.000e+00 1.989e+00 9.887e-01 + Gypsum -0.17 -4.89 -4.72 1.000e+00 -1.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Ca 1.094e-02 1.134e-02 + S 1.094e-02 1.134e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.530 Charge balance + pe = 7.664 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.841e-02 + Mass of water (kg) = 1.036e+00 + Total alkalinity (eq/kg) = 1.044e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 75.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 17 + Total H = 1.150124e+02 + Total O = 5.755156e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.935e-07 6.609e-07 -6.100 -6.180 -0.079 + H+ 3.412e-07 2.952e-07 -6.467 -6.530 -0.063 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Ca 1.094e-02 + Ca+2 7.104e-03 3.627e-03 -2.149 -2.440 -0.292 + CaSO4 3.838e-03 3.863e-03 -2.416 -2.413 0.003 + CaHSO4+ 1.900e-08 1.592e-08 -7.721 -7.798 -0.077 + CaOH+ 2.432e-09 2.039e-09 -8.614 -8.691 -0.077 +H(0) 3.754e-32 + H2 1.877e-32 1.889e-32 -31.727 -31.724 0.003 +O(0) 1.528e-15 + O2 7.641e-16 7.691e-16 -15.117 -15.114 0.003 +S(-2) 0.000e+00 + HS- 0.000e+00 0.000e+00 -95.131 -95.211 -0.079 + H2S 0.000e+00 0.000e+00 -95.188 -95.185 0.003 + S-2 0.000e+00 0.000e+00 -100.028 -100.325 -0.297 +S(6) 1.094e-02 + SO4-2 7.103e-03 3.579e-03 -2.149 -2.446 -0.298 + CaSO4 3.838e-03 3.863e-03 -2.416 -2.413 0.003 + HSO4- 4.356e-07 3.651e-07 -6.361 -6.438 -0.077 + CaHSO4+ 1.900e-08 1.592e-08 -7.721 -7.798 -0.077 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite 0.00 -4.89 -4.89 CaSO4 + Gypsum -0.17 -4.89 -4.72 CaSO4:2H2O + H2(g) -28.39 -31.72 -3.34 H2 + H2O(g) -0.40 -0.00 0.40 H2O + H2S(g) -93.71 -95.19 -1.48 H2S + O2(g) -11.96 -15.11 -3.15 O2 + Sulfur -70.68 -66.80 3.88 S + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex2.sel b/Sun/examples/ex2.sel new file mode 100644 index 00000000..6c7eed43 --- /dev/null +++ b/Sun/examples/ex2.sel @@ -0,0 +1,53 @@ + sim state soln dist_x time step pH pe temp si_anhydrite si_gypsum + 1 i_soln 1 -99 -99 -99 7 4 25.000 -999.9990 -999.9990 + 1 react 1 -99 0 1 7.06676 10.6862 25.000 -0.2197 0.0000 + 1 react 1 -99 0 2 7.05329 10.6168 26.000 -0.2157 0.0000 + 1 react 1 -99 0 3 7.03993 10.5719 27.000 -0.2115 0.0000 + 1 react 1 -99 0 4 7.02667 10.4793 28.000 -0.2071 0.0000 + 1 react 1 -99 0 5 7.01353 10.4109 29.000 -0.2025 0.0000 + 1 react 1 -99 0 6 7.00051 10.3439 30.000 -0.1977 0.0000 + 1 react 1 -99 0 7 6.9876 10.2766 31.000 -0.1928 0.0000 + 1 react 1 -99 0 8 6.97482 10.2099 32.000 -0.1877 0.0000 + 1 react 1 -99 0 9 6.96217 10.149 33.000 -0.1824 0.0000 + 1 react 1 -99 0 10 6.94965 10.0785 34.000 -0.1769 0.0000 + 1 react 1 -99 0 11 6.93726 10.0131 35.000 -0.1713 0.0000 + 1 react 1 -99 0 12 6.925 9.94603 36.000 -0.1655 0.0000 + 1 react 1 -99 0 13 6.91288 9.88397 37.000 -0.1595 0.0000 + 1 react 1 -99 0 14 6.90089 9.86516 38.000 -0.1533 0.0000 + 1 react 1 -99 0 15 6.88905 9.75536 39.000 -0.1470 0.0000 + 1 react 1 -99 0 16 6.87734 9.69233 40.000 -0.1406 0.0000 + 1 react 1 -99 0 17 6.86578 9.62865 41.000 -0.1340 0.0000 + 1 react 1 -99 0 18 6.85435 9.56448 42.000 -0.1272 0.0000 + 1 react 1 -99 0 19 6.84307 9.50323 43.000 -0.1203 0.0000 + 1 react 1 -99 0 20 6.83193 9.44484 44.000 -0.1132 0.0000 + 1 react 1 -99 0 21 6.82093 9.37869 45.000 -0.1060 0.0000 + 1 react 1 -99 0 22 6.81008 9.31598 46.000 -0.0986 0.0000 + 1 react 1 -99 0 23 6.79936 9.25548 47.000 -0.0911 0.0000 + 1 react 1 -99 0 24 6.78879 9.19236 48.000 -0.0835 0.0000 + 1 react 1 -99 0 25 6.77836 9.14193 49.000 -0.0757 0.0000 + 1 react 1 -99 0 26 6.76807 9.07059 50.000 -0.0678 0.0000 + 1 react 1 -99 0 27 6.75793 9.01241 51.000 -0.0597 0.0000 + 1 react 1 -99 0 28 6.74792 8.95269 52.000 -0.0515 0.0000 + 1 react 1 -99 0 29 6.73806 8.89104 53.000 -0.0432 0.0000 + 1 react 1 -99 0 30 6.72833 8.83437 54.000 -0.0347 0.0000 + 1 react 1 -99 0 31 6.71874 8.77256 55.000 -0.0261 0.0000 + 1 react 1 -99 0 32 6.7093 8.71589 56.000 -0.0174 0.0000 + 1 react 1 -99 0 33 6.69999 8.65867 57.000 -0.0085 0.0000 + 1 react 1 -99 0 34 6.69076 8.59025 58.000 0.0000 -0.0004 + 1 react 1 -99 0 35 6.68054 8.53312 59.000 0.0000 -0.0095 + 1 react 1 -99 0 36 6.67043 8.4773 60.000 0.0000 -0.0187 + 1 react 1 -99 0 37 6.66041 8.42236 61.000 0.0000 -0.0280 + 1 react 1 -99 0 38 6.65049 8.36458 62.000 0.0000 -0.0375 + 1 react 1 -99 0 39 6.64066 8.22145 63.000 0.0000 -0.0471 + 1 react 1 -99 0 40 6.63093 8.25388 64.000 0.0000 -0.0567 + 1 react 1 -99 0 41 6.62129 8.1986 65.000 0.0000 -0.0665 + 1 react 1 -99 0 42 6.61175 8.05474 66.000 0.0000 -0.0764 + 1 react 1 -99 0 43 6.6023 8.09202 67.000 0.0000 -0.0864 + 1 react 1 -99 0 44 6.59294 8.03836 68.000 0.0000 -0.0966 + 1 react 1 -99 0 45 6.58367 7.98491 69.000 0.0000 -0.1068 + 1 react 1 -99 0 46 6.57449 7.93039 70.000 0.0000 -0.1171 + 1 react 1 -99 0 47 6.5654 7.87729 71.000 0.0000 -0.1276 + 1 react 1 -99 0 48 6.55641 7.82446 72.000 0.0000 -0.1381 + 1 react 1 -99 0 49 6.5475 7.76904 73.000 0.0000 -0.1488 + 1 react 1 -99 0 50 6.53867 7.71679 74.000 0.0000 -0.1595 + 1 react 1 -99 0 51 6.52994 7.66434 75.000 0.0000 -0.1704 diff --git a/Sun/examples/ex3.log b/Sun/examples/ex3.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex3.out b/Sun/examples/ex3.out new file mode 100644 index 00000000..c04b11b6 --- /dev/null +++ b/Sun/examples/ex3.out @@ -0,0 +1,789 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex3 + Output file: ex3.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 3, part A.--Calcite equilibrium at log Pco2 = -2.0 and 25C. + SOLUTION 1 Pure water + pH 7.0 + temp 25.0 + EQUILIBRIUM_PHASES + CO2(g) -2.0 + Calcite 0.0 + SAVE solution 1 + END +----- +TITLE +----- + + Example 3, part A.--Calcite equilibrium at log Pco2 = -2.0 and 25C. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Pure water + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Pure water + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.082e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.002e-07 1.001e-07 -6.999 -6.999 -0.000 + H+ 1.001e-07 1.000e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 0.000 0.000 +H(0) 1.416e-25 + H2 7.079e-26 7.079e-26 -25.150 -25.150 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.080 -42.080 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 0.00 1.51 H2O + O2(g) -39.12 -42.08 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Pure water +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.998e+00 -1.646e-03 + CO2(g) -2.00 -20.15 -18.15 1.000e+01 9.998e+00 -1.976e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 3.622e-03 3.622e-03 + Ca 1.646e-03 1.646e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.297 Charge balance + pe = -0.987 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.826e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.291e-03 + Total CO2 (mol/kg) = 3.622e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.110124e+02 + Total O = 5.551511e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.137e-07 1.982e-07 -6.670 -6.703 -0.033 + H+ 5.403e-08 5.050e-08 -7.267 -7.297 -0.029 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 2.799e-30 + CH4 2.799e-30 2.802e-30 -29.553 -29.552 0.000 +C(4) 3.622e-03 + HCO3- 3.224e-03 2.998e-03 -2.492 -2.523 -0.032 + CO2 3.401e-04 3.405e-04 -3.468 -3.468 0.000 + CaHCO3+ 4.894e-05 4.551e-05 -4.310 -4.342 -0.032 + CaCO3 5.559e-06 5.565e-06 -5.255 -5.255 0.000 + CO3-2 3.721e-06 2.784e-06 -5.429 -5.555 -0.126 +Ca 1.646e-03 + Ca+2 1.591e-03 1.190e-03 -2.798 -2.925 -0.126 + CaHCO3+ 4.894e-05 4.551e-05 -4.310 -4.342 -0.032 + CaCO3 5.559e-06 5.565e-06 -5.255 -5.255 0.000 + CaOH+ 4.212e-09 3.910e-09 -8.376 -8.408 -0.032 +H(0) 3.403e-16 + H2 1.701e-16 1.703e-16 -15.769 -15.769 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -60.843 -60.843 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -26.69 -29.55 -2.86 CH4 + CO2(g) -2.00 -3.47 -1.47 CO2 + H2(g) -12.62 -15.77 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -57.88 -60.84 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + TITLE Example 3, part B.--Definition of seawater. + SOLUTION 2 Seawater + units ppm + pH 8.22 + pe 8.451 + density 1.023 + temp 25.0 + Ca 412.3 + Mg 1291.8 + Na 10768.0 + K 399.1 + Si 4.28 + Cl 19353.0 + Alkalinity 141.682 as HCO3 + S(6) 2712.0 + END +----- +TITLE +----- + + Example 3, part B.--Definition of seawater. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 2. Seawater + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Alkalinity 2.406e-03 2.406e-03 + Ca 1.066e-02 1.066e-02 + Cl 5.657e-01 5.657e-01 + K 1.058e-02 1.058e-02 + Mg 5.507e-02 5.507e-02 + Na 4.854e-01 4.854e-01 + S(6) 2.926e-02 2.926e-02 + Si 7.382e-05 7.382e-05 + +----------------------------Description of solution---------------------------- + + pH = 8.220 + pe = 8.451 + Activity of water = 0.981 + Ionic strength = 6.748e-01 + Mass of water (kg) = 1.000e+00 + Total carbon (mol/kg) = 2.180e-03 + Total CO2 (mol/kg) = 2.180e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.967e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.07 + Iterations = 7 + Total H = 1.110147e+02 + Total O = 5.563008e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.674e-06 1.629e-06 -5.573 -5.788 -0.215 + H+ 7.981e-09 6.026e-09 -8.098 -8.220 -0.122 + H2O 5.551e+01 9.806e-01 1.744 -0.009 0.000 +C(4) 2.180e-03 + HCO3- 1.514e-03 1.023e-03 -2.820 -2.990 -0.170 + MgHCO3+ 2.196e-04 1.640e-04 -3.658 -3.785 -0.127 + NaHCO3 1.668e-04 1.948e-04 -3.778 -3.710 0.067 + MgCO3 8.914e-05 1.041e-04 -4.050 -3.982 0.067 + NaCO3- 6.719e-05 5.020e-05 -4.173 -4.299 -0.127 + CaHCO3+ 4.598e-05 3.106e-05 -4.337 -4.508 -0.170 + CO3-2 3.821e-05 7.960e-06 -4.418 -5.099 -0.681 + CaCO3 2.725e-05 3.183e-05 -4.565 -4.497 0.067 + CO2 1.210e-05 1.413e-05 -4.917 -4.850 0.067 +Ca 1.066e-02 + Ca+2 9.504e-03 2.380e-03 -2.022 -2.623 -0.601 + CaSO4 1.083e-03 1.266e-03 -2.965 -2.898 0.067 + CaHCO3+ 4.598e-05 3.106e-05 -4.337 -4.508 -0.170 + CaCO3 2.725e-05 3.183e-05 -4.565 -4.497 0.067 + CaOH+ 8.604e-08 6.429e-08 -7.065 -7.192 -0.127 + CaHSO4+ 5.979e-11 4.467e-11 -10.223 -10.350 -0.127 +Cl 5.657e-01 + Cl- 5.657e-01 3.528e-01 -0.247 -0.452 -0.205 +H(0) 5.515e-37 + H2 2.757e-37 3.221e-37 -36.559 -36.492 0.067 +K 1.058e-02 + K+ 1.041e-02 6.495e-03 -1.982 -2.187 -0.205 + KSO4- 1.627e-04 1.216e-04 -3.789 -3.915 -0.127 + KOH 3.137e-09 3.665e-09 -8.503 -8.436 0.067 +Mg 5.507e-02 + Mg+2 4.742e-02 1.371e-02 -1.324 -1.863 -0.539 + MgSO4 7.330e-03 8.562e-03 -2.135 -2.067 0.067 + MgHCO3+ 2.196e-04 1.640e-04 -3.658 -3.785 -0.127 + MgCO3 8.914e-05 1.041e-04 -4.050 -3.982 0.067 + MgOH+ 1.084e-05 8.100e-06 -4.965 -5.092 -0.127 +Na 4.854e-01 + Na+ 4.791e-01 3.387e-01 -0.320 -0.470 -0.151 + NaSO4- 6.053e-03 4.523e-03 -2.218 -2.345 -0.127 + NaHCO3 1.668e-04 1.948e-04 -3.778 -3.710 0.067 + NaCO3- 6.719e-05 5.020e-05 -4.173 -4.299 -0.127 + NaOH 3.117e-07 3.641e-07 -6.506 -6.439 0.067 +O(0) 6.614e-20 + O2 3.307e-20 3.863e-20 -19.481 -19.413 0.067 +S(6) 2.926e-02 + SO4-2 1.463e-02 2.664e-03 -1.835 -2.574 -0.740 + MgSO4 7.330e-03 8.562e-03 -2.135 -2.067 0.067 + NaSO4- 6.053e-03 4.523e-03 -2.218 -2.345 -0.127 + CaSO4 1.083e-03 1.266e-03 -2.965 -2.898 0.067 + KSO4- 1.627e-04 1.216e-04 -3.789 -3.915 -0.127 + HSO4- 2.089e-09 1.561e-09 -8.680 -8.807 -0.127 + CaHSO4+ 5.979e-11 4.467e-11 -10.223 -10.350 -0.127 +Si 7.382e-05 + H4SiO4 7.110e-05 8.306e-05 -4.148 -4.081 0.067 + H3SiO4- 2.720e-06 2.032e-06 -5.565 -5.692 -0.127 + H2SiO4-2 7.362e-11 2.294e-11 -10.133 -10.639 -0.506 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.84 -5.20 -4.36 CaSO4 + Aragonite 0.61 -7.72 -8.34 CaCO3 + Calcite 0.76 -7.72 -8.48 CaCO3 + Chalcedony -0.51 -4.06 -3.55 SiO2 + Chrysotile 3.36 35.56 32.20 Mg3Si2O5(OH)4 + CO2(g) -3.38 -4.85 -1.47 CO2 + Dolomite 2.41 -14.68 -17.09 CaMg(CO3)2 + Gypsum -0.63 -5.21 -4.58 CaSO4:2H2O + H2(g) -33.34 -36.49 -3.15 H2 + H2O(g) -1.52 -0.01 1.51 H2O + Halite -2.50 -0.92 1.58 NaCl + O2(g) -16.45 -19.41 -2.96 O2 + Quartz -0.08 -4.06 -3.98 SiO2 + Sepiolite 1.16 16.92 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -1.74 16.92 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -1.35 -4.06 -2.71 SiO2 + Talc 6.04 27.44 21.40 Mg3Si4O10(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + TITLE Example 3, part C.--Mix 70% ground water, 30% seawater. + MIX 1 + 1 0.7 + 2 0.3 + SAVE solution 3 + END +----- +TITLE +----- + + Example 3, part C.--Mix 70% ground water, 30% seawater. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using mix 1. + +Mixture 1. + + 7.000e-01 Solution 1 Solution after simulation 1. + 3.000e-01 Solution 2 Seawater + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 3.189e-03 3.189e-03 + Ca 4.350e-03 4.350e-03 + Cl 1.697e-01 1.697e-01 + K 3.173e-03 3.173e-03 + Mg 1.652e-02 1.652e-02 + Na 1.456e-01 1.456e-01 + S 8.777e-03 8.777e-03 + Si 2.215e-05 2.215e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.351 Charge balance + pe = -1.717 Adjusted to redox equilibrium + Activity of water = 0.994 + Ionic strength = 2.087e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.026e-03 + Total CO2 (mol/kg) = 3.189e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.390e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.06 + Iterations = 13 + Total H = 1.110131e+02 + Total O = 5.554960e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.170e-07 2.231e-07 -6.499 -6.651 -0.153 + H+ 5.603e-08 4.460e-08 -7.252 -7.351 -0.099 + H2O 5.551e+01 9.941e-01 1.744 -0.003 0.000 +C(-4) 4.007e-25 + CH4 4.007e-25 4.204e-25 -24.397 -24.376 0.021 +C(4) 3.189e-03 + HCO3- 2.662e-03 1.980e-03 -2.575 -2.703 -0.129 + CO2 1.904e-04 1.998e-04 -3.720 -3.699 0.021 + MgHCO3+ 1.545e-04 1.151e-04 -3.811 -3.939 -0.128 + NaHCO3 1.137e-04 1.192e-04 -3.944 -3.924 0.021 + CaHCO3+ 4.245e-05 3.158e-05 -4.372 -4.501 -0.129 + MgCO3 9.408e-06 9.871e-06 -5.027 -5.006 0.021 + CO3-2 6.803e-06 2.082e-06 -5.167 -5.682 -0.514 + NaCO3- 5.572e-06 4.151e-06 -5.254 -5.382 -0.128 + CaCO3 4.166e-06 4.371e-06 -5.380 -5.359 0.021 +Ca 4.350e-03 + Ca+2 3.928e-03 1.250e-03 -2.406 -2.903 -0.497 + CaSO4 3.753e-04 3.938e-04 -3.426 -3.405 0.021 + CaHCO3+ 4.245e-05 3.158e-05 -4.372 -4.501 -0.129 + CaCO3 4.166e-06 4.371e-06 -5.380 -5.359 0.021 + CaOH+ 6.204e-09 4.622e-09 -8.207 -8.335 -0.128 + CaHSO4+ 1.381e-10 1.029e-10 -9.860 -9.988 -0.128 +Cl 1.697e-01 + Cl- 1.697e-01 1.203e-01 -0.770 -0.920 -0.149 +H(0) 7.279e-15 + H2 3.640e-15 3.819e-15 -14.439 -14.418 0.021 +K 3.173e-03 + K+ 3.140e-03 2.226e-03 -2.503 -2.652 -0.149 + KSO4- 3.316e-05 2.470e-05 -4.479 -4.607 -0.128 + KOH 1.639e-10 1.720e-10 -9.785 -9.764 0.021 +Mg 1.652e-02 + Mg+2 1.460e-02 4.968e-03 -1.836 -2.304 -0.468 + MgSO4 1.753e-03 1.839e-03 -2.756 -2.735 0.021 + MgHCO3+ 1.545e-04 1.151e-04 -3.811 -3.939 -0.128 + MgCO3 9.408e-06 9.871e-06 -5.027 -5.006 0.021 + MgOH+ 5.396e-07 4.020e-07 -6.268 -6.396 -0.128 +Na 1.456e-01 + Na+ 1.444e-01 1.071e-01 -0.841 -0.970 -0.130 + NaSO4- 1.138e-03 8.476e-04 -2.944 -3.072 -0.128 + NaHCO3 1.137e-04 1.192e-04 -3.944 -3.924 0.021 + NaCO3- 5.572e-06 4.151e-06 -5.254 -5.382 -0.128 + NaOH 1.503e-08 1.577e-08 -7.823 -7.802 0.021 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -63.570 -63.549 0.021 +S(-2) 4.890e-22 + HS- 3.876e-22 2.728e-22 -21.412 -21.564 -0.153 + H2S 1.014e-22 1.064e-22 -21.994 -21.973 0.021 + S-2 2.513e-27 7.386e-28 -26.600 -27.132 -0.532 +S(6) 8.777e-03 + SO4-2 5.478e-03 1.579e-03 -2.261 -2.802 -0.540 + MgSO4 1.753e-03 1.839e-03 -2.756 -2.735 0.021 + NaSO4- 1.138e-03 8.476e-04 -2.944 -3.072 -0.128 + CaSO4 3.753e-04 3.938e-04 -3.426 -3.405 0.021 + KSO4- 3.316e-05 2.470e-05 -4.479 -4.607 -0.128 + HSO4- 9.193e-09 6.849e-09 -8.037 -8.164 -0.128 + CaHSO4+ 1.381e-10 1.029e-10 -9.860 -9.988 -0.128 +Si 2.215e-05 + H4SiO4 2.204e-05 2.313e-05 -4.657 -4.636 0.021 + H3SiO4- 1.026e-07 7.646e-08 -6.989 -7.117 -0.128 + H2SiO4-2 3.784e-13 1.166e-13 -12.422 -12.933 -0.511 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -1.34 -5.70 -4.36 CaSO4 + Aragonite -0.25 -8.58 -8.34 CaCO3 + Calcite -0.10 -8.58 -8.48 CaCO3 + CH4(g) -21.52 -24.38 -2.86 CH4 + Chalcedony -1.08 -4.63 -3.55 SiO2 + Chrysotile -4.28 27.92 32.20 Mg3Si2O5(OH)4 + CO2(g) -2.23 -3.70 -1.47 CO2 + Dolomite 0.52 -16.57 -17.09 CaMg(CO3)2 + Gypsum -1.13 -5.71 -4.58 CaSO4:2H2O + H2(g) -11.27 -14.42 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -20.98 -21.97 -1.00 H2S + Halite -3.47 -1.89 1.58 NaCl + O2(g) -60.59 -63.55 -2.96 O2 + Quartz -0.65 -4.63 -3.98 SiO2 + Sepiolite -4.87 10.89 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -7.77 10.89 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -1.92 -4.63 -2.71 SiO2 + Sulfur -15.59 -10.71 4.88 S + Talc -2.74 18.66 21.40 Mg3Si4O10(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + TITLE Example 3, part D.--Equilibrate mixture with calcite and dolomite. + EQUILIBRIUM_PHASES 1 + Calcite 0.0 + Dolomite 0.0 + USE solution 3 + END +----- +TITLE +----- + + Example 3, part D.--Equilibrate mixture with calcite and dolomite. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 3. Solution after simulation 3. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.984e+00 -1.571e-02 + Dolomite 0.00 -17.09 -17.09 1.000e+01 1.001e+01 7.935e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 3.029e-03 3.029e-03 + Ca 1.213e-02 1.212e-02 + Cl 1.697e-01 1.697e-01 + K 3.173e-03 3.173e-03 + Mg 8.585e-03 8.585e-03 + Na 1.456e-01 1.456e-01 + S 8.777e-03 8.777e-03 + Si 2.215e-05 2.215e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.056 Charge balance + pe = -1.421 Adjusted to redox equilibrium + Activity of water = 0.994 + Ionic strength = 2.087e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.704e-03 + Total CO2 (mol/kg) = 3.029e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.390e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.06 + Iterations = 5 + Total H = 1.110131e+02 + Total O = 5.554912e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.609e-07 1.132e-07 -6.793 -6.946 -0.153 + H+ 1.104e-07 8.788e-08 -6.957 -7.056 -0.099 + H2O 5.551e+01 9.941e-01 1.744 -0.003 0.000 +C(-4) 6.977e-25 + CH4 6.977e-25 7.320e-25 -24.156 -24.135 0.021 +C(4) 3.029e-03 + HCO3- 2.397e-03 1.783e-03 -2.620 -2.749 -0.129 + CO2 3.377e-04 3.543e-04 -3.471 -3.451 0.021 + CaHCO3+ 1.065e-04 7.920e-05 -3.973 -4.101 -0.129 + NaHCO3 1.023e-04 1.073e-04 -3.990 -3.969 0.021 + MgHCO3+ 7.221e-05 5.380e-05 -4.141 -4.269 -0.128 + CaCO3 5.304e-06 5.565e-06 -5.275 -5.255 0.021 + CO3-2 3.109e-06 9.513e-07 -5.507 -6.022 -0.514 + NaCO3- 2.546e-06 1.897e-06 -5.594 -5.722 -0.128 + MgCO3 2.232e-06 2.341e-06 -5.651 -5.631 0.021 +Ca 1.213e-02 + Ca+2 1.095e-02 3.482e-03 -1.961 -2.458 -0.497 + CaSO4 1.067e-03 1.119e-03 -2.972 -2.951 0.021 + CaHCO3+ 1.065e-04 7.920e-05 -3.973 -4.101 -0.129 + CaCO3 5.304e-06 5.565e-06 -5.275 -5.255 0.021 + CaOH+ 8.774e-09 6.537e-09 -8.057 -8.185 -0.128 + CaHSO4+ 7.734e-10 5.762e-10 -9.112 -9.239 -0.128 +Cl 1.697e-01 + Cl- 1.697e-01 1.203e-01 -0.770 -0.920 -0.149 +H(0) 7.246e-15 + H2 3.623e-15 3.801e-15 -14.441 -14.420 0.021 +K 3.173e-03 + K+ 3.140e-03 2.225e-03 -2.503 -2.653 -0.149 + KSO4- 3.381e-05 2.519e-05 -4.471 -4.599 -0.128 + KOH 8.319e-11 8.729e-11 -10.080 -10.059 0.021 +Mg 8.585e-03 + Mg+2 7.582e-03 2.579e-03 -2.120 -2.588 -0.468 + MgSO4 9.283e-04 9.740e-04 -3.032 -3.011 0.021 + MgHCO3+ 7.221e-05 5.380e-05 -4.141 -4.269 -0.128 + MgCO3 2.232e-06 2.341e-06 -5.651 -5.631 0.021 + MgOH+ 1.422e-07 1.059e-07 -6.847 -6.975 -0.128 +Na 1.456e-01 + Na+ 1.444e-01 1.071e-01 -0.841 -0.970 -0.130 + NaSO4- 1.160e-03 8.644e-04 -2.935 -3.063 -0.128 + NaHCO3 1.023e-04 1.073e-04 -3.990 -3.969 0.021 + NaCO3- 2.546e-06 1.897e-06 -5.594 -5.722 -0.128 + NaOH 7.627e-09 8.002e-09 -8.118 -8.097 0.021 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -63.566 -63.545 0.021 +S(-2) 1.159e-21 + HS- 7.648e-22 5.382e-22 -21.116 -21.269 -0.153 + H2S 3.941e-22 4.136e-22 -21.404 -21.383 0.021 + S-2 2.517e-27 7.397e-28 -26.599 -27.131 -0.532 +S(6) 8.777e-03 + SO4-2 5.588e-03 1.611e-03 -2.253 -2.793 -0.540 + NaSO4- 1.160e-03 8.644e-04 -2.935 -3.063 -0.128 + CaSO4 1.067e-03 1.119e-03 -2.972 -2.951 0.021 + MgSO4 9.283e-04 9.740e-04 -3.032 -3.011 0.021 + KSO4- 3.381e-05 2.519e-05 -4.471 -4.599 -0.128 + HSO4- 1.847e-08 1.376e-08 -7.733 -7.861 -0.128 + CaHSO4+ 7.734e-10 5.762e-10 -9.112 -9.239 -0.128 +Si 2.215e-05 + H4SiO4 2.210e-05 2.318e-05 -4.656 -4.635 0.021 + H3SiO4- 5.221e-08 3.890e-08 -7.282 -7.410 -0.128 + H2SiO4-2 9.772e-14 3.011e-14 -13.010 -13.521 -0.511 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.89 -5.25 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -21.28 -24.14 -2.86 CH4 + Chalcedony -1.08 -4.63 -3.55 SiO2 + Chrysotile -6.90 25.30 32.20 Mg3Si2O5(OH)4 + CO2(g) -1.98 -3.45 -1.47 CO2 + Dolomite 0.00 -17.09 -17.09 CaMg(CO3)2 + Gypsum -0.68 -5.26 -4.58 CaSO4:2H2O + H2(g) -11.27 -14.42 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -20.39 -21.38 -1.00 H2S + Halite -3.47 -1.89 1.58 NaCl + O2(g) -60.58 -63.54 -2.96 O2 + Quartz -0.65 -4.63 -3.98 SiO2 + Sepiolite -6.62 9.14 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -9.52 9.14 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -1.92 -4.63 -2.71 SiO2 + Sulfur -15.00 -10.11 4.88 S + Talc -5.36 16.04 21.40 Mg3Si4O10(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 5. +------------------------------------ + + TITLE Example 3, part E.--Equilibrate mixture with calcite only. + EQUILIBRIUM_PHASES 2 + Calcite 0.0 + USE solution 3 + END +----- +TITLE +----- + + Example 3, part E.--Equilibrate mixture with calcite only. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 3. Solution after simulation 3. +Using pure phase assemblage 2. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 1.000e+01 -3.992e-05 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 3.229e-03 3.229e-03 + Ca 4.390e-03 4.390e-03 + Cl 1.697e-01 1.697e-01 + K 3.173e-03 3.173e-03 + Mg 1.652e-02 1.652e-02 + Na 1.456e-01 1.456e-01 + S 8.777e-03 8.777e-03 + Si 2.215e-05 2.215e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.442 Charge balance + pe = -1.861 Adjusted to redox equilibrium + Activity of water = 0.994 + Ionic strength = 2.088e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.106e-03 + Total CO2 (mol/kg) = 3.229e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.390e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.06 + Iterations = 6 + Total H = 1.110131e+02 + Total O = 5.554972e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.915e-07 2.755e-07 -6.407 -6.560 -0.153 + H+ 4.537e-08 3.612e-08 -7.343 -7.442 -0.099 + H2O 5.551e+01 9.941e-01 1.744 -0.003 0.000 +C(-4) 8.842e-25 + CH4 8.842e-25 9.278e-25 -24.053 -24.033 0.021 +C(4) 3.229e-03 + HCO3- 2.721e-03 2.024e-03 -2.565 -2.694 -0.129 + MgHCO3+ 1.579e-04 1.176e-04 -3.802 -3.930 -0.128 + CO2 1.576e-04 1.653e-04 -3.803 -3.782 0.021 + NaHCO3 1.161e-04 1.219e-04 -3.935 -3.914 0.021 + CaHCO3+ 4.376e-05 3.255e-05 -4.359 -4.487 -0.129 + MgCO3 1.187e-05 1.245e-05 -4.926 -4.905 0.021 + CO3-2 8.587e-06 2.628e-06 -5.066 -5.580 -0.514 + NaCO3- 7.033e-06 5.240e-06 -5.153 -5.281 -0.128 + CaCO3 5.304e-06 5.565e-06 -5.275 -5.255 0.021 +Ca 4.390e-03 + Ca+2 3.963e-03 1.261e-03 -2.402 -2.899 -0.497 + CaSO4 3.784e-04 3.971e-04 -3.422 -3.401 0.021 + CaHCO3+ 4.376e-05 3.255e-05 -4.359 -4.487 -0.129 + CaCO3 5.304e-06 5.565e-06 -5.275 -5.255 0.021 + CaOH+ 7.728e-09 5.758e-09 -8.112 -8.240 -0.128 + CaHSO4+ 1.128e-10 8.402e-11 -9.948 -10.076 -0.128 +Cl 1.697e-01 + Cl- 1.697e-01 1.203e-01 -0.770 -0.920 -0.149 +H(0) 9.302e-15 + H2 4.651e-15 4.880e-15 -14.332 -14.312 0.021 +K 3.173e-03 + K+ 3.140e-03 2.226e-03 -2.503 -2.652 -0.149 + KSO4- 3.314e-05 2.469e-05 -4.480 -4.607 -0.128 + KOH 2.025e-10 2.124e-10 -9.694 -9.673 0.021 +Mg 1.652e-02 + Mg+2 1.460e-02 4.966e-03 -1.836 -2.304 -0.468 + MgSO4 1.752e-03 1.838e-03 -2.757 -2.736 0.021 + MgHCO3+ 1.579e-04 1.176e-04 -3.802 -3.930 -0.128 + MgCO3 1.187e-05 1.245e-05 -4.926 -4.905 0.021 + MgOH+ 6.661e-07 4.963e-07 -6.176 -6.304 -0.128 +Na 1.456e-01 + Na+ 1.444e-01 1.071e-01 -0.841 -0.970 -0.130 + NaSO4- 1.137e-03 8.472e-04 -2.944 -3.072 -0.128 + NaHCO3 1.161e-04 1.219e-04 -3.935 -3.914 0.021 + NaCO3- 7.033e-06 5.240e-06 -5.153 -5.281 -0.128 + NaOH 1.856e-08 1.947e-08 -7.731 -7.711 0.021 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -63.783 -63.762 0.021 +S(-2) 1.014e-21 + HS- 8.367e-22 5.888e-22 -21.077 -21.230 -0.153 + H2S 1.772e-22 1.860e-22 -21.751 -21.731 0.021 + S-2 6.701e-27 1.969e-27 -26.174 -26.706 -0.532 +S(6) 8.777e-03 + SO4-2 5.477e-03 1.579e-03 -2.261 -2.802 -0.540 + MgSO4 1.752e-03 1.838e-03 -2.757 -2.736 0.021 + NaSO4- 1.137e-03 8.472e-04 -2.944 -3.072 -0.128 + CaSO4 3.784e-04 3.971e-04 -3.422 -3.401 0.021 + KSO4- 3.314e-05 2.469e-05 -4.480 -4.607 -0.128 + HSO4- 7.441e-09 5.544e-09 -8.128 -8.256 -0.128 + CaHSO4+ 1.128e-10 8.402e-11 -9.948 -10.076 -0.128 +Si 2.215e-05 + H4SiO4 2.202e-05 2.311e-05 -4.657 -4.636 0.021 + H3SiO4- 1.266e-07 9.432e-08 -6.898 -7.025 -0.128 + H2SiO4-2 5.766e-13 1.776e-13 -12.239 -12.750 -0.511 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -1.34 -5.70 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -21.17 -24.03 -2.86 CH4 + Chalcedony -1.08 -4.63 -3.55 SiO2 + Chrysotile -3.73 28.47 32.20 Mg3Si2O5(OH)4 + CO2(g) -2.31 -3.78 -1.47 CO2 + Dolomite 0.73 -16.36 -17.09 CaMg(CO3)2 + Gypsum -1.13 -5.71 -4.58 CaSO4:2H2O + H2(g) -11.16 -14.31 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -20.73 -21.73 -1.00 H2S + Halite -3.47 -1.89 1.58 NaCl + O2(g) -60.80 -63.76 -2.96 O2 + Quartz -0.65 -4.63 -3.98 SiO2 + Sepiolite -4.51 11.25 15.76 Mg2Si3O7.5OH:3H2O + Sepiolite(d) -7.41 11.25 18.66 Mg2Si3O7.5OH:3H2O + SiO2(a) -1.92 -4.63 -2.71 SiO2 + Sulfur -15.45 -10.57 4.88 S + Talc -2.19 19.21 21.40 Mg3Si4O10(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 6. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex4.log b/Sun/examples/ex4.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex4.out b/Sun/examples/ex4.out new file mode 100644 index 00000000..146247a6 --- /dev/null +++ b/Sun/examples/ex4.out @@ -0,0 +1,478 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex4 + Output file: ex4.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 4a.--Rain water evaporation + SOLUTION 1 Precipitation from Central Oklahoma + units mg/L + pH 4.5 # estimated + temp 25.0 + Ca .384 + Mg .043 + Na .141 + K .036 + Cl .236 + C(4) .1 CO2(g) -3.5 + S(6) 1.3 + N(-3) .208 + N(5) .237 + REACTION 1 + H2O -1.0 + 52.73 moles + SAVE solution 2 + END +----- +TITLE +----- + + Example 4a.--Rain water evaporation + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. Precipitation from Central Oklahoma + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C(4) 1.092e-05 1.092e-05 Equilibrium with CO2(g) + Ca 9.581e-06 9.581e-06 + Cl 6.657e-06 6.657e-06 + K 9.207e-07 9.207e-07 + Mg 1.769e-06 1.769e-06 + N(-3) 1.485e-05 1.485e-05 + N(5) 1.692e-05 1.692e-05 + Na 6.133e-06 6.133e-06 + S(6) 1.353e-05 1.353e-05 + +----------------------------Description of solution---------------------------- + + pH = 4.500 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 8.838e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.185e-05 + Total CO2 (mol/kg) = 1.092e-05 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.581e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 20.29 + Iterations = 3 + Total H = 1.110125e+02 + Total O = 5.550634e+01 + +---------------------------------Redox couples--------------------------------- + + Redox couple pe Eh (volts) + + N(-3)/N(5) 9.2667 0.5482 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.196e-05 3.162e-05 -4.495 -4.500 -0.005 + OH- 3.200e-10 3.166e-10 -9.495 -9.500 -0.005 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(4) 1.092e-05 + CO2 1.077e-05 1.077e-05 -4.968 -4.968 0.000 + HCO3- 1.531e-07 1.514e-07 -6.815 -6.820 -0.005 + CaHCO3+ 1.787e-11 1.768e-11 -10.748 -10.753 -0.005 + MgHCO3+ 3.025e-12 2.992e-12 -11.519 -11.524 -0.005 + NaHCO3 5.166e-13 5.166e-13 -12.287 -12.287 0.000 + CO3-2 2.345e-13 2.246e-13 -12.630 -12.649 -0.019 + CaCO3 3.452e-15 3.452e-15 -14.462 -14.462 0.000 + MgCO3 3.619e-16 3.619e-16 -15.441 -15.441 0.000 + NaCO3- 2.565e-17 2.537e-17 -16.591 -16.596 -0.005 +Ca 9.581e-06 + Ca+2 9.557e-06 9.151e-06 -5.020 -5.039 -0.019 + CaSO4 2.353e-08 2.353e-08 -7.628 -7.628 0.000 + CaHCO3+ 1.787e-11 1.768e-11 -10.748 -10.753 -0.005 + CaHSO4+ 4.408e-12 4.360e-12 -11.356 -11.361 -0.005 + CaOH+ 4.855e-14 4.803e-14 -13.314 -13.319 -0.005 + CaCO3 3.452e-15 3.452e-15 -14.462 -14.462 0.000 +Cl 6.657e-06 + Cl- 6.657e-06 6.585e-06 -5.177 -5.181 -0.005 +H(0) 1.416e-20 + H2 7.079e-21 7.079e-21 -20.150 -20.150 0.000 +K 9.207e-07 + K+ 9.206e-07 9.106e-07 -6.036 -6.041 -0.005 + KSO4- 8.337e-11 8.247e-11 -10.079 -10.084 -0.005 + KOH 9.984e-17 9.985e-17 -16.001 -16.001 0.000 +Mg 1.769e-06 + Mg+2 1.764e-06 1.689e-06 -5.754 -5.772 -0.019 + MgSO4 5.103e-09 5.103e-09 -8.292 -8.292 0.000 + MgHCO3+ 3.025e-12 2.992e-12 -11.519 -11.524 -0.005 + MgOH+ 1.960e-13 1.939e-13 -12.708 -12.712 -0.005 + MgCO3 3.619e-16 3.619e-16 -15.441 -15.441 0.000 +N(-3) 1.485e-05 + NH4+ 1.485e-05 1.469e-05 -4.828 -4.833 -0.005 + NH4SO4- 2.465e-09 2.438e-09 -8.608 -8.613 -0.005 + NH3 2.646e-10 2.647e-10 -9.577 -9.577 0.000 +N(5) 1.692e-05 + NO3- 1.692e-05 1.674e-05 -4.772 -4.776 -0.005 +Na 6.133e-06 + Na+ 6.133e-06 6.066e-06 -5.212 -5.217 -0.005 + NaSO4- 3.962e-10 3.919e-10 -9.402 -9.407 -0.005 + NaHCO3 5.166e-13 5.166e-13 -12.287 -12.287 0.000 + NaOH 1.267e-15 1.267e-15 -14.897 -14.897 0.000 + NaCO3- 2.565e-17 2.537e-17 -16.591 -16.596 -0.005 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -52.080 -52.080 0.000 +S(6) 1.353e-05 + SO4-2 1.346e-05 1.289e-05 -4.871 -4.890 -0.019 + HSO4- 4.006e-08 3.963e-08 -7.397 -7.402 -0.005 + CaSO4 2.353e-08 2.353e-08 -7.628 -7.628 0.000 + MgSO4 5.103e-09 5.103e-09 -8.292 -8.292 0.000 + NH4SO4- 2.465e-09 2.438e-09 -8.608 -8.613 -0.005 + NaSO4- 3.962e-10 3.919e-10 -9.402 -9.407 -0.005 + KSO4- 8.337e-11 8.247e-11 -10.079 -10.084 -0.005 + CaHSO4+ 4.408e-12 4.360e-12 -11.356 -11.361 -0.005 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -5.57 -9.93 -4.36 CaSO4 + Aragonite -9.35 -17.69 -8.34 CaCO3 + Calcite -9.21 -17.69 -8.48 CaCO3 + CO2(g) -3.50 -4.97 -1.47 CO2 + Dolomite -19.02 -36.11 -17.09 CaMg(CO3)2 + Gypsum -5.35 -9.93 -4.58 CaSO4:2H2O + H2(g) -17.00 -20.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -11.98 -10.40 1.58 NaCl + NH3(g) -11.35 -9.58 1.77 NH3 + O2(g) -49.12 -52.08 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Precipitation from Central Oklahoma +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 5.273e+01 moles of the following reaction have been added: + + Relative + Reactant moles + + H2O -1.00 + + Relative + Element moles + H -2.00 + O -1.00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.183e-04 1.092e-05 + Ca 1.916e-04 9.581e-06 + Cl 1.331e-04 6.657e-06 + K 1.841e-05 9.207e-07 + Mg 3.536e-05 1.769e-06 + N 6.352e-04 3.177e-05 + Na 1.226e-04 6.133e-06 + S 2.706e-04 1.353e-05 + +----------------------------Description of solution---------------------------- + + pH = 3.148 Charge balance + pe = 16.530 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.528e-03 + Mass of water (kg) = 5.002e-02 + Total alkalinity (eq/kg) = -7.555e-04 + Total CO2 (mol/kg) = 2.183e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.581e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 24.31 + Iterations = 20 + Total H = 5.552525e+00 + Total O = 2.776344e+00 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 7.406e-04 7.108e-04 -3.130 -3.148 -0.018 + OH- 1.472e-11 1.408e-11 -10.832 -10.851 -0.019 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -136.693 -136.693 0.000 +C(4) 2.183e-04 + CO2 2.182e-04 2.182e-04 -3.661 -3.661 0.000 + HCO3- 1.425e-07 1.366e-07 -6.846 -6.865 -0.019 + CaHCO3+ 2.834e-10 2.715e-10 -9.548 -9.566 -0.019 + MgHCO3+ 4.780e-11 4.576e-11 -10.321 -10.340 -0.019 + NaHCO3 9.005e-12 9.008e-12 -11.046 -11.045 0.000 + CO3-2 1.070e-14 9.010e-15 -13.971 -14.045 -0.074 + CaCO3 2.358e-15 2.359e-15 -14.627 -14.627 0.000 + MgCO3 2.461e-16 2.462e-16 -15.609 -15.609 0.000 + NaCO3- 2.056e-17 1.968e-17 -16.687 -16.706 -0.019 +Ca 1.916e-04 + Ca+2 1.851e-04 1.559e-04 -3.733 -3.807 -0.075 + CaSO4 6.474e-06 6.477e-06 -5.189 -5.189 0.000 + CaHSO4+ 2.817e-08 2.697e-08 -7.550 -7.569 -0.019 + CaHCO3+ 2.834e-10 2.715e-10 -9.548 -9.566 -0.019 + CaOH+ 3.801e-14 3.639e-14 -13.420 -13.439 -0.019 + CaCO3 2.358e-15 2.359e-15 -14.627 -14.627 0.000 +Cl 1.331e-04 + Cl- 1.331e-04 1.274e-04 -3.876 -3.895 -0.019 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.506 -42.506 0.000 +K 1.841e-05 + K+ 1.838e-05 1.759e-05 -4.736 -4.755 -0.019 + KSO4- 2.689e-08 2.575e-08 -7.570 -7.589 -0.019 + KOH 8.579e-17 8.582e-17 -16.067 -16.066 0.000 +Mg 3.536e-05 + Mg+2 3.396e-05 2.864e-05 -4.469 -4.543 -0.074 + MgSO4 1.398e-06 1.398e-06 -5.855 -5.854 0.000 + MgHCO3+ 4.780e-11 4.576e-11 -10.321 -10.340 -0.019 + MgOH+ 1.528e-13 1.463e-13 -12.816 -12.835 -0.019 + MgCO3 2.461e-16 2.462e-16 -15.609 -15.609 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -48.438 -48.457 -0.019 + NH4SO4- 0.000e+00 0.000e+00 -51.009 -51.028 -0.019 + NH3 0.000e+00 0.000e+00 -54.553 -54.553 0.000 +N(0) 4.751e-04 + N2 2.375e-04 2.376e-04 -3.624 -3.624 0.000 +N(3) 2.623e-15 + NO2- 2.623e-15 2.510e-15 -14.581 -14.600 -0.019 +N(5) 1.601e-04 + NO3- 1.601e-04 1.532e-04 -3.796 -3.815 -0.019 +Na 1.226e-04 + Na+ 1.225e-04 1.173e-04 -3.912 -3.931 -0.019 + NaSO4- 1.279e-07 1.224e-07 -6.893 -6.912 -0.019 + NaHCO3 9.005e-12 9.008e-12 -11.046 -11.045 0.000 + NaOH 1.090e-15 1.090e-15 -14.963 -14.962 0.000 + NaCO3- 2.056e-17 1.968e-17 -16.687 -16.706 -0.019 +O(0) 8.553e-08 + O2 4.277e-08 4.278e-08 -7.369 -7.369 0.000 +S(-2) 0.000e+00 + H2S 0.000e+00 0.000e+00 -126.809 -126.809 0.000 + HS- 0.000e+00 0.000e+00 -130.583 -130.602 -0.019 + S-2 0.000e+00 0.000e+00 -140.297 -140.372 -0.075 +S(6) 2.706e-04 + SO4-2 2.475e-04 2.083e-04 -3.606 -3.681 -0.075 + HSO4- 1.503e-05 1.439e-05 -4.823 -4.842 -0.019 + CaSO4 6.474e-06 6.477e-06 -5.189 -5.189 0.000 + MgSO4 1.398e-06 1.398e-06 -5.855 -5.854 0.000 + NaSO4- 1.279e-07 1.224e-07 -6.893 -6.912 -0.019 + CaHSO4+ 2.817e-08 2.697e-08 -7.550 -7.569 -0.019 + KSO4- 2.689e-08 2.575e-08 -7.570 -7.589 -0.019 + NH4SO4- 0.000e+00 0.000e+00 -51.009 -51.028 -0.019 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.13 -7.49 -4.36 CaSO4 + Aragonite -9.52 -17.85 -8.34 CaCO3 + Calcite -9.37 -17.85 -8.48 CaCO3 + CH4(g) -133.83 -136.69 -2.86 CH4 + CO2(g) -2.19 -3.66 -1.47 CO2 + Dolomite -19.35 -36.44 -17.09 CaMg(CO3)2 + Gypsum -2.91 -7.49 -4.58 CaSO4:2H2O + H2(g) -39.36 -42.51 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -125.81 -126.81 -1.00 H2S + Halite -9.41 -7.83 1.58 NaCl + N2(g) -0.36 -3.62 -3.26 N2 + NH3(g) -56.32 -54.55 1.77 NH3 + O2(g) -4.41 -7.37 -2.96 O2 + Sulfur -92.34 -87.45 4.88 S + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + TITLE Example 4b.--Factor of 20 more solution + MIX + 2 20. + SAVE solution 3 + END +----- +TITLE +----- + + Example 4b.--Factor of 20 more solution + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using mix 1. + +Mixture 1. + + 2.000e+01 Solution 2 Solution after simulation 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.183e-04 2.184e-04 + Ca 1.916e-04 1.916e-04 + Cl 1.331e-04 1.331e-04 + K 1.841e-05 1.841e-05 + Mg 3.536e-05 3.537e-05 + N 6.352e-04 6.354e-04 + Na 1.226e-04 1.227e-04 + S 2.706e-04 2.707e-04 + +----------------------------Description of solution---------------------------- + + pH = 3.148 Charge balance + pe = 16.530 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.528e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -7.555e-04 + Total CO2 (mol/kg) = 2.183e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 5.162e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 24.31 + Iterations = 0 + Total H = 1.110505e+02 + Total O = 5.552687e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 7.406e-04 7.108e-04 -3.130 -3.148 -0.018 + OH- 1.472e-11 1.408e-11 -10.832 -10.851 -0.019 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(-4) 0.000e+00 + CH4 0.000e+00 0.000e+00 -136.693 -136.693 0.000 +C(4) 2.183e-04 + CO2 2.182e-04 2.182e-04 -3.661 -3.661 0.000 + HCO3- 1.425e-07 1.366e-07 -6.846 -6.865 -0.019 + CaHCO3+ 2.834e-10 2.715e-10 -9.548 -9.566 -0.019 + MgHCO3+ 4.780e-11 4.576e-11 -10.321 -10.340 -0.019 + NaHCO3 9.005e-12 9.008e-12 -11.046 -11.045 0.000 + CO3-2 1.070e-14 9.010e-15 -13.971 -14.045 -0.074 + CaCO3 2.358e-15 2.359e-15 -14.627 -14.627 0.000 + MgCO3 2.461e-16 2.462e-16 -15.609 -15.609 0.000 + NaCO3- 2.056e-17 1.968e-17 -16.687 -16.706 -0.019 +Ca 1.916e-04 + Ca+2 1.851e-04 1.559e-04 -3.733 -3.807 -0.075 + CaSO4 6.474e-06 6.477e-06 -5.189 -5.189 0.000 + CaHSO4+ 2.817e-08 2.697e-08 -7.550 -7.569 -0.019 + CaHCO3+ 2.834e-10 2.715e-10 -9.548 -9.566 -0.019 + CaOH+ 3.801e-14 3.639e-14 -13.420 -13.439 -0.019 + CaCO3 2.358e-15 2.359e-15 -14.627 -14.627 0.000 +Cl 1.331e-04 + Cl- 1.331e-04 1.274e-04 -3.876 -3.895 -0.019 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.506 -42.506 0.000 +K 1.841e-05 + K+ 1.838e-05 1.759e-05 -4.736 -4.755 -0.019 + KSO4- 2.689e-08 2.575e-08 -7.570 -7.589 -0.019 + KOH 8.579e-17 8.582e-17 -16.067 -16.066 0.000 +Mg 3.536e-05 + Mg+2 3.396e-05 2.864e-05 -4.469 -4.543 -0.074 + MgSO4 1.398e-06 1.398e-06 -5.855 -5.854 0.000 + MgHCO3+ 4.780e-11 4.576e-11 -10.321 -10.340 -0.019 + MgOH+ 1.528e-13 1.463e-13 -12.816 -12.835 -0.019 + MgCO3 2.461e-16 2.462e-16 -15.609 -15.609 0.000 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -48.438 -48.457 -0.019 + NH4SO4- 0.000e+00 0.000e+00 -51.009 -51.028 -0.019 + NH3 0.000e+00 0.000e+00 -54.553 -54.553 0.000 +N(0) 4.751e-04 + N2 2.375e-04 2.376e-04 -3.624 -3.624 0.000 +N(3) 2.623e-15 + NO2- 2.623e-15 2.510e-15 -14.581 -14.600 -0.019 +N(5) 1.601e-04 + NO3- 1.601e-04 1.532e-04 -3.796 -3.815 -0.019 +Na 1.226e-04 + Na+ 1.225e-04 1.173e-04 -3.912 -3.931 -0.019 + NaSO4- 1.279e-07 1.224e-07 -6.893 -6.912 -0.019 + NaHCO3 9.005e-12 9.008e-12 -11.046 -11.045 0.000 + NaOH 1.090e-15 1.090e-15 -14.963 -14.962 0.000 + NaCO3- 2.056e-17 1.968e-17 -16.687 -16.706 -0.019 +O(0) 8.553e-08 + O2 4.277e-08 4.278e-08 -7.369 -7.369 0.000 +S(-2) 0.000e+00 + H2S 0.000e+00 0.000e+00 -126.809 -126.809 0.000 + HS- 0.000e+00 0.000e+00 -130.583 -130.602 -0.019 + S-2 0.000e+00 0.000e+00 -140.297 -140.372 -0.075 +S(6) 2.706e-04 + SO4-2 2.475e-04 2.083e-04 -3.606 -3.681 -0.075 + HSO4- 1.503e-05 1.439e-05 -4.823 -4.842 -0.019 + CaSO4 6.474e-06 6.477e-06 -5.189 -5.189 0.000 + MgSO4 1.398e-06 1.398e-06 -5.855 -5.854 0.000 + NaSO4- 1.279e-07 1.224e-07 -6.893 -6.912 -0.019 + CaHSO4+ 2.817e-08 2.697e-08 -7.550 -7.569 -0.019 + KSO4- 2.689e-08 2.575e-08 -7.570 -7.589 -0.019 + NH4SO4- 0.000e+00 0.000e+00 -51.009 -51.028 -0.019 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -3.13 -7.49 -4.36 CaSO4 + Aragonite -9.52 -17.85 -8.34 CaCO3 + Calcite -9.37 -17.85 -8.48 CaCO3 + CH4(g) -133.83 -136.69 -2.86 CH4 + CO2(g) -2.19 -3.66 -1.47 CO2 + Dolomite -19.35 -36.44 -17.09 CaMg(CO3)2 + Gypsum -2.91 -7.49 -4.58 CaSO4:2H2O + H2(g) -39.36 -42.51 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -125.81 -126.81 -1.00 H2S + Halite -9.41 -7.83 1.58 NaCl + N2(g) -0.36 -3.62 -3.26 N2 + NH3(g) -56.32 -54.55 1.77 NH3 + O2(g) -4.41 -7.37 -2.96 O2 + Sulfur -92.34 -87.45 4.88 S + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex5.log b/Sun/examples/ex5.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex5.out b/Sun/examples/ex5.out new file mode 100644 index 00000000..d335bbe5 --- /dev/null +++ b/Sun/examples/ex5.out @@ -0,0 +1,942 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex5 + Output file: ex5.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 5.--Add oxygen, equilibrate with pyrite, calcite, and goethite. + SOLUTION 1 PURE WATER + pH 7.0 + temp 25.0 + EQUILIBRIUM_PHASES 1 + Pyrite 0.0 + Goethite 0.0 + Calcite 0.0 + CO2(g) -3.5 + Gypsum 0.0 0.0 + REACTION 1 + O2 1.0 + NaCl 0.5 + 0.0 0.001 0.005 0.01 0.05 + SELECTED_OUTPUT + file ex5.sel + totals Cl + si Gypsum + equilibrium_phases pyrite goethite calcite CO2(g) gypsum + END +----- +TITLE +----- + + Example 5.--Add oxygen, equilibrate with pyrite, calcite, and goethite. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. PURE WATER + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Pure water + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.082e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.002e-07 1.001e-07 -6.999 -6.999 -0.000 + H+ 1.001e-07 1.000e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 0.000 0.000 +H(0) 1.416e-25 + H2 7.079e-26 7.079e-26 -25.150 -25.150 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.080 -42.080 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 0.00 1.51 H2O + O2(g) -39.12 -42.08 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 0.000e+00 moles of the following reaction have been added: + + Relative + Reactant moles + + O2 1.00 + NaCl 0.50 + + Relative + Element moles + Cl 0.50 + Na 0.50 + O 2.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 1.000e+01 -4.934e-04 + CO2(g) -3.50 -21.65 -18.15 1.000e+01 1.000e+01 -4.870e-04 + Goethite 0.00 12.02 12.02 1.000e+01 1.000e+01 1.105e-08 + Gypsum -6.13 -10.71 -4.58 0.000e+00 0.000e+00 + Pyrite 0.00 -85.78 -85.78 1.000e+01 1.000e+01 -3.154e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 9.804e-04 9.804e-04 + Ca 4.934e-04 4.934e-04 + Fe 2.049e-08 2.049e-08 + S 6.308e-08 6.308e-08 + +----------------------------Description of solution---------------------------- + + pH = 8.279 Charge balance + pe = -4.943 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.463e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.867e-04 + Total CO2 (mol/kg) = 9.803e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.550867e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.987e-06 1.903e-06 -5.702 -5.720 -0.019 + H+ 5.476e-09 5.260e-09 -8.262 -8.279 -0.018 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +C(-4) 5.403e-08 + CH4 5.403e-08 5.405e-08 -7.267 -7.267 0.000 +C(4) 9.803e-04 + HCO3- 9.494e-04 9.104e-04 -3.023 -3.041 -0.018 + CO2 1.076e-05 1.077e-05 -4.968 -4.968 0.000 + CO3-2 9.603e-06 8.117e-06 -5.018 -5.091 -0.073 + CaCO3 5.563e-06 5.565e-06 -5.255 -5.255 0.000 + CaHCO3+ 4.943e-06 4.740e-06 -5.306 -5.324 -0.018 + FeCO3 2.600e-09 2.601e-09 -8.585 -8.585 0.000 + FeHCO3+ 1.269e-09 1.216e-09 -8.896 -8.915 -0.019 +Ca 4.934e-04 + Ca+2 4.829e-04 4.081e-04 -3.316 -3.389 -0.073 + CaCO3 5.563e-06 5.565e-06 -5.255 -5.255 0.000 + CaHCO3+ 4.943e-06 4.740e-06 -5.306 -5.324 -0.018 + CaOH+ 1.344e-08 1.288e-08 -7.872 -7.890 -0.019 + CaSO4 3.896e-09 3.897e-09 -8.409 -8.409 0.000 + CaHSO4+ 1.253e-16 1.201e-16 -15.902 -15.920 -0.019 +Fe(2) 2.049e-08 + Fe+2 1.578e-08 1.336e-08 -7.802 -7.874 -0.072 + FeCO3 2.600e-09 2.601e-09 -8.585 -8.585 0.000 + FeHCO3+ 1.269e-09 1.216e-09 -8.896 -8.915 -0.019 + FeOH+ 8.381e-10 8.031e-10 -9.077 -9.095 -0.019 + FeSO4 1.137e-13 1.137e-13 -12.944 -12.944 0.000 + Fe(HS)2 6.287e-17 6.289e-17 -16.202 -16.201 0.000 + FeHSO4+ 4.102e-21 3.931e-21 -20.387 -20.406 -0.019 + Fe(HS)3- 1.643e-23 1.574e-23 -22.784 -22.803 -0.019 +Fe(3) 3.369e-14 + Fe(OH)3 2.753e-14 2.754e-14 -13.560 -13.560 0.000 + Fe(OH)4- 4.984e-15 4.776e-15 -14.302 -14.321 -0.019 + Fe(OH)2+ 1.174e-15 1.124e-15 -14.931 -14.949 -0.019 + FeOH+2 2.119e-20 1.786e-20 -19.674 -19.748 -0.074 + Fe+3 2.091e-26 1.455e-26 -25.680 -25.837 -0.158 + FeSO4+ 7.970e-30 7.637e-30 -29.099 -29.117 -0.019 + Fe(SO4)2- 8.346e-36 7.997e-36 -35.079 -35.097 -0.019 + FeHSO4+2 1.276e-37 1.076e-37 -36.894 -36.968 -0.074 + Fe2(OH)2+4 1.700e-38 8.587e-39 -37.769 -38.066 -0.297 + Fe3(OH)4+5 0.000e+00 0.000e+00 -50.232 -50.695 -0.464 +H(0) 3.009e-10 + H2 1.505e-10 1.505e-10 -9.823 -9.822 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -72.735 -72.735 0.000 +S(-2) 2.505e-09 + HS- 2.399e-09 2.298e-09 -8.620 -8.639 -0.019 + H2S 1.057e-10 1.057e-10 -9.976 -9.976 0.000 + S-2 6.249e-14 5.278e-14 -13.204 -13.278 -0.073 + Fe(HS)2 6.287e-17 6.289e-17 -16.202 -16.201 0.000 + Fe(HS)3- 1.643e-23 1.574e-23 -22.784 -22.803 -0.019 +S(6) 6.057e-08 + SO4-2 5.668e-08 4.786e-08 -7.247 -7.320 -0.073 + CaSO4 3.896e-09 3.897e-09 -8.409 -8.409 0.000 + FeSO4 1.137e-13 1.137e-13 -12.944 -12.944 0.000 + HSO4- 2.554e-14 2.448e-14 -13.593 -13.611 -0.019 + CaHSO4+ 1.253e-16 1.201e-16 -15.902 -15.920 -0.019 + FeHSO4+ 4.102e-21 3.931e-21 -20.387 -20.406 -0.019 + FeSO4+ 7.970e-30 7.637e-30 -29.099 -29.117 -0.019 + Fe(SO4)2- 8.346e-36 7.997e-36 -35.079 -35.097 -0.019 + FeHSO4+2 1.276e-37 1.076e-37 -36.894 -36.968 -0.074 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -6.35 -10.71 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -4.41 -7.27 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Fe(OH)3(a) -5.89 -1.00 4.89 Fe(OH)3 + FeS(ppt) -4.32 -8.23 -3.92 FeS + Goethite 0.00 -1.00 -1.00 FeOOH + Gypsum -6.13 -10.71 -4.58 CaSO4:2H2O + H2(g) -6.67 -9.82 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -8.98 -9.98 -1.00 H2S + Hematite 2.01 -2.00 -4.01 Fe2O3 + Mackinawite -3.59 -8.23 -4.65 FeS + Melanterite -12.99 -15.19 -2.21 FeSO4:7H2O + O2(g) -69.78 -72.74 -2.96 O2 + Pyrite 0.00 -18.48 -18.48 FeS2 + Siderite -2.07 -12.96 -10.89 FeCO3 + Sulfur -8.19 -3.30 4.88 S + +Reaction step 2. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 1.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + O2 1.00 + NaCl 0.50 + + Relative + Element moles + Cl 0.50 + Na 0.50 + O 2.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.999e+00 -9.277e-04 + CO2(g) -3.50 -21.65 -18.15 1.000e+01 1.000e+01 1.418e-04 + Goethite 0.00 12.02 12.02 1.000e+01 1.000e+01 2.667e-04 + Gypsum -2.02 -6.60 -4.58 0.000e+00 0.000e+00 + Pyrite 0.00 -85.78 -85.78 1.000e+01 1.000e+01 -2.667e-04 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 7.859e-04 7.859e-04 + Ca 9.277e-04 9.277e-04 + Cl 5.000e-04 5.000e-04 + Fe 9.939e-09 9.939e-09 + Na 5.000e-04 5.000e-04 + S 5.333e-04 5.333e-04 + +----------------------------Description of solution---------------------------- + + pH = 8.171 Charge balance + pe = -4.287 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.591e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 7.887e-04 + Total CO2 (mol/kg) = 7.859e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 24 + Total H = 1.110122e+02 + Total O = 5.551018e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.585e-06 1.484e-06 -5.800 -5.829 -0.029 + H+ 7.160e-09 6.745e-09 -8.145 -8.171 -0.026 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 2.240e-12 + CH4 2.240e-12 2.242e-12 -11.650 -11.649 0.000 +C(4) 7.859e-04 + HCO3- 7.565e-04 7.099e-04 -3.121 -3.149 -0.028 + CO2 1.076e-05 1.077e-05 -4.968 -4.968 0.000 + CaHCO3+ 6.477e-06 6.078e-06 -5.189 -5.216 -0.028 + CO3-2 6.364e-06 4.936e-06 -5.196 -5.307 -0.110 + CaCO3 5.560e-06 5.565e-06 -5.255 -5.255 0.000 + NaHCO3 1.865e-07 1.867e-07 -6.729 -6.729 0.000 + NaCO3- 4.587e-08 4.298e-08 -7.338 -7.367 -0.028 + FeCO3 7.363e-10 7.369e-10 -9.133 -9.133 0.000 + FeHCO3+ 4.715e-10 4.418e-10 -9.327 -9.355 -0.028 +Ca 9.277e-04 + Ca+2 8.657e-04 6.711e-04 -3.063 -3.173 -0.111 + CaSO4 4.996e-05 5.000e-05 -4.301 -4.301 0.000 + CaHCO3+ 6.477e-06 6.078e-06 -5.189 -5.216 -0.028 + CaCO3 5.560e-06 5.565e-06 -5.255 -5.255 0.000 + CaOH+ 1.762e-08 1.651e-08 -7.754 -7.782 -0.028 + CaHSO4+ 2.108e-12 1.976e-12 -11.676 -11.704 -0.028 +Cl 5.000e-04 + Cl- 5.000e-04 4.682e-04 -3.301 -3.330 -0.029 + FeCl+ 4.293e-12 4.023e-12 -11.367 -11.396 -0.028 + FeCl+2 5.629e-28 4.339e-28 -27.250 -27.363 -0.113 + FeCl2+ 9.686e-31 9.076e-31 -30.014 -30.042 -0.028 + FeCl3 4.246e-35 4.250e-35 -34.372 -34.372 0.000 +Fe(2) 9.939e-09 + Fe+2 8.002e-09 6.223e-09 -8.097 -8.206 -0.109 + FeCO3 7.363e-10 7.369e-10 -9.133 -9.133 0.000 + FeHCO3+ 4.715e-10 4.418e-10 -9.327 -9.355 -0.028 + FeSO4 4.129e-10 4.132e-10 -9.384 -9.384 0.000 + FeOH+ 3.114e-10 2.918e-10 -9.507 -9.535 -0.028 + FeCl+ 4.293e-12 4.023e-12 -11.367 -11.396 -0.028 + FeHSO4+ 1.955e-17 1.832e-17 -16.709 -16.737 -0.028 + Fe(HS)2 5.043e-18 5.047e-18 -17.297 -17.297 0.000 + Fe(HS)3- 5.596e-25 5.243e-25 -24.252 -24.280 -0.028 +Fe(3) 3.303e-14 + Fe(OH)3 2.752e-14 2.754e-14 -13.560 -13.560 0.000 + Fe(OH)4- 3.974e-15 3.724e-15 -14.401 -14.429 -0.028 + Fe(OH)2+ 1.539e-15 1.442e-15 -14.813 -14.841 -0.028 + FeOH+2 3.810e-20 2.937e-20 -19.419 -19.532 -0.113 + FeSO4+ 1.341e-25 1.256e-25 -24.873 -24.901 -0.028 + Fe+3 5.252e-26 3.069e-26 -25.280 -25.513 -0.233 + Fe(SO4)2- 1.095e-27 1.026e-27 -26.960 -26.989 -0.028 + FeCl+2 5.629e-28 4.339e-28 -27.250 -27.363 -0.113 + FeCl2+ 9.686e-31 9.076e-31 -30.014 -30.042 -0.028 + FeHSO4+2 2.943e-33 2.269e-33 -32.531 -32.644 -0.113 + FeCl3 4.246e-35 4.250e-35 -34.372 -34.372 0.000 + Fe2(OH)2+4 6.575e-38 2.322e-38 -37.182 -37.634 -0.452 + Fe3(OH)4+5 0.000e+00 0.000e+00 -49.449 -50.155 -0.706 +H(0) 2.414e-11 + H2 1.207e-11 1.208e-11 -10.918 -10.918 0.000 +Na 5.000e-04 + Na+ 4.988e-04 4.677e-04 -3.302 -3.330 -0.028 + NaSO4- 9.340e-07 8.752e-07 -6.030 -6.058 -0.028 + NaHCO3 1.865e-07 1.867e-07 -6.729 -6.729 0.000 + NaCO3- 4.587e-08 4.298e-08 -7.338 -7.367 -0.028 + NaOH 4.577e-10 4.581e-10 -9.339 -9.339 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -70.545 -70.544 0.000 +S(-2) 1.075e-09 + HS- 1.019e-09 9.540e-10 -8.992 -9.020 -0.029 + H2S 5.621e-11 5.626e-11 -10.250 -10.250 0.000 + S-2 2.207e-14 1.708e-14 -13.656 -13.767 -0.111 + Fe(HS)2 5.043e-18 5.047e-18 -17.297 -17.297 0.000 + Fe(HS)3- 5.596e-25 5.243e-25 -24.252 -24.280 -0.028 +S(6) 5.333e-04 + SO4-2 4.824e-04 3.734e-04 -3.317 -3.428 -0.111 + CaSO4 4.996e-05 5.000e-05 -4.301 -4.301 0.000 + NaSO4- 9.340e-07 8.752e-07 -6.030 -6.058 -0.028 + FeSO4 4.129e-10 4.132e-10 -9.384 -9.384 0.000 + HSO4- 2.613e-10 2.449e-10 -9.583 -9.611 -0.028 + CaHSO4+ 2.108e-12 1.976e-12 -11.676 -11.704 -0.028 + FeHSO4+ 1.955e-17 1.832e-17 -16.709 -16.737 -0.028 + FeSO4+ 1.341e-25 1.256e-25 -24.873 -24.901 -0.028 + Fe(SO4)2- 1.095e-27 1.026e-27 -26.960 -26.989 -0.028 + FeHSO4+2 2.943e-33 2.269e-33 -32.531 -32.644 -0.113 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -2.24 -6.60 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -8.79 -11.65 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Fe(OH)3(a) -5.89 -1.00 4.89 Fe(OH)3 + FeS(ppt) -5.14 -9.06 -3.92 FeS + Goethite -0.00 -1.00 -1.00 FeOOH + Gypsum -2.02 -6.60 -4.58 CaSO4:2H2O + H2(g) -7.77 -10.92 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -9.25 -10.25 -1.00 H2S + Halite -8.24 -6.66 1.58 NaCl + Hematite 2.01 -2.00 -4.01 Fe2O3 + Mackinawite -4.41 -9.06 -4.65 FeS + Melanterite -9.42 -11.63 -2.21 FeSO4:7H2O + O2(g) -67.58 -70.54 -2.96 O2 + Pyrite -0.00 -18.48 -18.48 FeS2 + Siderite -2.62 -13.51 -10.89 FeCO3 + Sulfur -7.36 -2.48 4.88 S + +Reaction step 3. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 5.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + O2 1.00 + NaCl 0.50 + + Relative + Element moles + Cl 0.50 + Na 0.50 + O 2.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.997e+00 -2.937e-03 + CO2(g) -3.50 -21.65 -18.15 1.000e+01 1.000e+01 2.395e-03 + Goethite 0.00 12.02 12.02 1.000e+01 1.000e+01 1.333e-03 + Gypsum -1.06 -5.64 -4.58 0.000e+00 0.000e+00 + Pyrite 0.00 -85.78 -85.78 1.000e+01 9.999e+00 -1.333e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.424e-04 5.424e-04 + Ca 2.937e-03 2.937e-03 + Cl 2.500e-03 2.500e-03 + Fe 2.124e-08 2.124e-08 + Na 2.500e-03 2.500e-03 + S 2.667e-03 2.667e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.982 Charge balance + pe = -3.970 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.210e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.415e-04 + Total CO2 (mol/kg) = 5.424e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 25 + Total H = 1.110111e+02 + Total O = 5.551757e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.077e-06 9.604e-07 -5.968 -6.018 -0.050 + H+ 1.149e-08 1.042e-08 -7.940 -7.982 -0.042 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 2.129e-13 + CH4 2.129e-13 2.135e-13 -12.672 -12.671 0.001 +C(4) 5.424e-04 + HCO3- 5.118e-04 4.594e-04 -3.291 -3.338 -0.047 + CO2 1.074e-05 1.077e-05 -4.969 -4.968 0.001 + CaHCO3+ 1.046e-05 9.392e-06 -4.980 -5.027 -0.047 + CaCO3 5.549e-06 5.565e-06 -5.256 -5.255 0.001 + CO3-2 3.184e-06 2.067e-06 -5.497 -5.685 -0.188 + NaHCO3 5.724e-07 5.740e-07 -6.242 -6.241 0.001 + NaCO3- 9.566e-08 8.553e-08 -7.019 -7.068 -0.049 + FeHCO3+ 5.691e-10 5.088e-10 -9.245 -9.293 -0.049 + FeCO3 5.477e-10 5.493e-10 -9.261 -9.260 0.001 +Ca 2.937e-03 + Ca+2 2.469e-03 1.602e-03 -2.607 -2.795 -0.188 + CaSO4 4.520e-04 4.532e-04 -3.345 -3.344 0.001 + CaHCO3+ 1.046e-05 9.392e-06 -4.980 -5.027 -0.047 + CaCO3 5.549e-06 5.565e-06 -5.256 -5.255 0.001 + CaOH+ 2.854e-08 2.551e-08 -7.545 -7.593 -0.049 + CaHSO4+ 3.095e-11 2.767e-11 -10.509 -10.558 -0.049 +Cl 2.500e-03 + Cl- 2.500e-03 2.230e-03 -2.602 -2.652 -0.050 + FeCl+ 3.814e-11 3.410e-11 -10.419 -10.467 -0.049 + FeCl+2 1.194e-26 7.627e-27 -25.923 -26.118 -0.194 + FeCl2+ 8.499e-29 7.599e-29 -28.071 -28.119 -0.049 + FeCl3 1.690e-32 1.695e-32 -31.772 -31.771 0.001 +Fe(2) 2.124e-08 + Fe+2 1.693e-08 1.108e-08 -7.771 -7.956 -0.184 + FeSO4 2.784e-09 2.792e-09 -8.555 -8.554 0.001 + FeHCO3+ 5.691e-10 5.088e-10 -9.245 -9.293 -0.049 + FeCO3 5.477e-10 5.493e-10 -9.261 -9.260 0.001 + FeOH+ 3.758e-10 3.360e-10 -9.425 -9.474 -0.049 + FeCl+ 3.814e-11 3.410e-11 -10.419 -10.467 -0.049 + FeHSO4+ 2.139e-16 1.913e-16 -15.670 -15.718 -0.049 + Fe(HS)2 2.796e-18 2.804e-18 -17.553 -17.552 0.001 + Fe(HS)3- 1.820e-25 1.627e-25 -24.740 -24.789 -0.049 +Fe(3) 3.265e-14 + Fe(OH)3 2.746e-14 2.754e-14 -13.561 -13.560 0.001 + Fe(OH)4- 2.695e-15 2.409e-15 -14.569 -14.618 -0.049 + Fe(OH)2+ 2.492e-15 2.228e-15 -14.603 -14.652 -0.049 + FeOH+2 1.098e-19 7.014e-20 -18.960 -19.154 -0.194 + FeSO4+ 1.968e-24 1.760e-24 -23.706 -23.755 -0.049 + Fe+3 2.720e-25 1.132e-25 -24.566 -24.946 -0.381 + Fe(SO4)2- 6.105e-26 5.458e-26 -25.214 -25.263 -0.049 + FeCl+2 1.194e-26 7.627e-27 -25.923 -26.118 -0.194 + FeCl2+ 8.499e-29 7.599e-29 -28.071 -28.119 -0.049 + FeHSO4+2 7.686e-32 4.911e-32 -31.114 -31.309 -0.194 + FeCl3 1.690e-32 1.695e-32 -31.772 -31.771 0.001 + Fe2(OH)2+4 7.941e-37 1.324e-37 -36.100 -36.878 -0.778 + Fe3(OH)4+5 0.000e+00 0.000e+00 -47.995 -49.210 -1.216 +H(0) 1.338e-11 + H2 6.691e-12 6.710e-12 -11.174 -11.173 0.001 +Na 2.500e-03 + Na+ 2.482e-03 2.222e-03 -2.605 -2.653 -0.048 + NaSO4- 1.766e-05 1.579e-05 -4.753 -4.802 -0.049 + NaHCO3 5.724e-07 5.740e-07 -6.242 -6.241 0.001 + NaCO3- 9.566e-08 8.553e-08 -7.019 -7.068 -0.049 + NaOH 1.404e-09 1.408e-09 -8.853 -8.851 0.001 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -70.035 -70.034 0.001 +S(-2) 6.460e-10 + HS- 5.976e-10 5.329e-10 -9.224 -9.273 -0.050 + H2S 4.843e-11 4.856e-11 -10.315 -10.314 0.001 + S-2 9.562e-15 6.176e-15 -14.019 -14.209 -0.190 + Fe(HS)2 2.796e-18 2.804e-18 -17.553 -17.552 0.001 + Fe(HS)3- 1.820e-25 1.627e-25 -24.740 -24.789 -0.049 +S(6) 2.667e-03 + SO4-2 2.197e-03 1.418e-03 -2.658 -2.848 -0.190 + CaSO4 4.520e-04 4.532e-04 -3.345 -3.344 0.001 + NaSO4- 1.766e-05 1.579e-05 -4.753 -4.802 -0.049 + FeSO4 2.784e-09 2.792e-09 -8.555 -8.554 0.001 + HSO4- 1.606e-09 1.436e-09 -8.794 -8.843 -0.049 + CaHSO4+ 3.095e-11 2.767e-11 -10.509 -10.558 -0.049 + FeHSO4+ 2.139e-16 1.913e-16 -15.670 -15.718 -0.049 + FeSO4+ 1.968e-24 1.760e-24 -23.706 -23.755 -0.049 + Fe(SO4)2- 6.105e-26 5.458e-26 -25.214 -25.263 -0.049 + FeHSO4+2 7.686e-32 4.911e-32 -31.114 -31.309 -0.194 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -1.28 -5.64 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -9.81 -12.67 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Fe(OH)3(a) -5.89 -1.00 4.89 Fe(OH)3 + FeS(ppt) -5.33 -9.25 -3.92 FeS + Goethite -0.00 -1.00 -1.00 FeOOH + Gypsum -1.06 -5.64 -4.58 CaSO4:2H2O + H2(g) -8.02 -11.17 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -9.32 -10.31 -1.00 H2S + Halite -6.89 -5.30 1.58 NaCl + Hematite 2.01 -2.00 -4.01 Fe2O3 + Mackinawite -4.60 -9.25 -4.65 FeS + Melanterite -8.60 -10.80 -2.21 FeSO4:7H2O + O2(g) -67.07 -70.03 -2.96 O2 + Pyrite -0.00 -18.48 -18.48 FeS2 + Siderite -2.75 -13.64 -10.89 FeCO3 + Sulfur -7.17 -2.29 4.88 S + +Reaction step 4. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 1.000e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + O2 1.00 + NaCl 0.50 + + Relative + Element moles + Cl 0.50 + Na 0.50 + O 2.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.994e+00 -5.559e-03 + CO2(g) -3.50 -21.65 -18.15 1.000e+01 1.001e+01 5.105e-03 + Goethite 0.00 12.02 12.02 1.000e+01 1.000e+01 2.667e-03 + Gypsum -0.65 -5.23 -4.58 0.000e+00 0.000e+00 + Pyrite -0.00 -85.78 -85.78 1.000e+01 9.997e+00 -2.667e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.540e-04 4.540e-04 + Ca 5.560e-03 5.559e-03 + Cl 5.000e-03 5.000e-03 + Fe 3.429e-08 3.429e-08 + Na 5.000e-03 5.000e-03 + S 5.333e-03 5.333e-03 + +----------------------------Description of solution---------------------------- + + pH = 7.884 Charge balance + pe = -3.817 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.218e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.522e-04 + Total CO2 (mol/kg) = 4.540e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 25 + Total H = 1.110098e+02 + Total O = 5.552735e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 8.898e-07 7.665e-07 -6.051 -6.115 -0.065 + H+ 1.474e-08 1.306e-08 -7.832 -7.884 -0.053 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +C(-4) 7.696e-14 + CH4 7.696e-14 7.735e-14 -13.114 -13.112 0.002 +C(4) 4.540e-04 + HCO3- 4.210e-04 3.666e-04 -3.376 -3.436 -0.060 + CaHCO3+ 1.351e-05 1.177e-05 -4.869 -4.929 -0.060 + CO2 1.071e-05 1.077e-05 -4.970 -4.968 0.002 + CaCO3 5.536e-06 5.565e-06 -5.257 -5.255 0.002 + CO3-2 2.289e-06 1.317e-06 -5.640 -5.880 -0.240 + NaHCO3 8.791e-07 8.836e-07 -6.056 -6.054 0.002 + NaCO3- 1.214e-07 1.051e-07 -6.916 -6.978 -0.063 + FeHCO3+ 6.487e-10 5.616e-10 -9.188 -9.251 -0.063 + FeCO3 4.814e-10 4.839e-10 -9.317 -9.315 0.002 +Ca 5.560e-03 + Ca+2 4.373e-03 2.515e-03 -2.359 -2.599 -0.240 + CaSO4 1.168e-03 1.174e-03 -2.933 -2.930 0.002 + CaHCO3+ 1.351e-05 1.177e-05 -4.869 -4.929 -0.060 + CaCO3 5.536e-06 5.565e-06 -5.257 -5.255 0.002 + CaOH+ 3.692e-08 3.196e-08 -7.433 -7.495 -0.063 + CaHSO4+ 1.037e-10 8.977e-11 -9.984 -10.047 -0.063 +Cl 5.000e-03 + Cl- 5.000e-03 4.311e-03 -2.301 -2.365 -0.064 + FeCl+ 1.053e-10 9.114e-11 -9.978 -10.040 -0.063 + FeCl+2 5.162e-26 2.899e-26 -25.287 -25.538 -0.251 + FeCl2+ 6.449e-28 5.583e-28 -27.191 -27.253 -0.063 + FeCl3 2.394e-31 2.406e-31 -30.621 -30.619 0.002 +Fe(2) 3.429e-08 + Fe+2 2.629e-08 1.532e-08 -7.580 -7.815 -0.235 + FeSO4 6.337e-09 6.369e-09 -8.198 -8.196 0.002 + FeHCO3+ 6.487e-10 5.616e-10 -9.188 -9.251 -0.063 + FeCO3 4.814e-10 4.839e-10 -9.317 -9.315 0.002 + FeOH+ 4.284e-10 3.708e-10 -9.368 -9.431 -0.063 + FeCl+ 1.053e-10 9.114e-11 -9.978 -10.040 -0.063 + FeHSO4+ 6.314e-16 5.466e-16 -15.200 -15.262 -0.063 + Fe(HS)2 2.164e-18 2.175e-18 -17.665 -17.663 0.002 + Fe(HS)3- 1.092e-25 9.454e-26 -24.962 -25.024 -0.063 +Fe(3) 3.284e-14 + Fe(OH)3 2.739e-14 2.753e-14 -13.562 -13.560 0.002 + Fe(OH)2+ 3.224e-15 2.791e-15 -14.492 -14.554 -0.063 + Fe(OH)4- 2.221e-15 1.923e-15 -14.653 -14.716 -0.063 + FeOH+2 1.960e-19 1.101e-19 -18.708 -18.958 -0.251 + FeSO4+ 6.596e-24 5.710e-24 -23.181 -23.243 -0.063 + Fe+3 6.635e-25 2.227e-25 -24.178 -24.652 -0.474 + Fe(SO4)2- 3.374e-25 2.921e-25 -24.472 -24.534 -0.063 + FeCl+2 5.162e-26 2.899e-26 -25.287 -25.538 -0.251 + FeCl2+ 6.449e-28 5.583e-28 -27.191 -27.253 -0.063 + FeHSO4+2 3.555e-31 1.996e-31 -30.449 -30.700 -0.251 + FeCl3 2.394e-31 2.406e-31 -30.621 -30.619 0.002 + Fe2(OH)2+4 3.279e-36 3.263e-37 -35.484 -36.486 -1.002 + Fe3(OH)4+5 0.000e+00 0.000e+00 -47.155 -48.721 -1.566 +H(0) 1.036e-11 + H2 5.179e-12 5.205e-12 -11.286 -11.284 0.002 +Na 5.000e-03 + Na+ 4.941e-03 4.286e-03 -2.306 -2.368 -0.062 + NaSO4- 5.802e-05 5.023e-05 -4.236 -4.299 -0.063 + NaHCO3 8.791e-07 8.836e-07 -6.056 -6.054 0.002 + NaCO3- 1.214e-07 1.051e-07 -6.916 -6.978 -0.063 + NaOH 2.157e-09 2.168e-09 -8.666 -8.664 0.002 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -69.815 -69.813 0.002 +S(-2) 5.087e-10 + HS- 4.634e-10 3.992e-10 -9.334 -9.399 -0.065 + H2S 4.533e-11 4.557e-11 -10.344 -10.341 0.002 + S-2 6.474e-15 3.693e-15 -14.189 -14.433 -0.244 + Fe(HS)2 2.164e-18 2.175e-18 -17.665 -17.663 0.002 + Fe(HS)3- 1.092e-25 9.454e-26 -24.962 -25.024 -0.063 +S(6) 5.333e-03 + SO4-2 4.108e-03 2.338e-03 -2.386 -2.631 -0.245 + CaSO4 1.168e-03 1.174e-03 -2.933 -2.930 0.002 + NaSO4- 5.802e-05 5.023e-05 -4.236 -4.299 -0.063 + FeSO4 6.337e-09 6.369e-09 -8.198 -8.196 0.002 + HSO4- 3.429e-09 2.968e-09 -8.465 -8.527 -0.063 + CaHSO4+ 1.037e-10 8.977e-11 -9.984 -10.047 -0.063 + FeHSO4+ 6.314e-16 5.466e-16 -15.200 -15.262 -0.063 + FeSO4+ 6.596e-24 5.710e-24 -23.181 -23.243 -0.063 + Fe(SO4)2- 3.374e-25 2.921e-25 -24.472 -24.534 -0.063 + FeHSO4+2 3.555e-31 1.996e-31 -30.449 -30.700 -0.251 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.87 -5.23 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -10.25 -13.11 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Fe(OH)3(a) -5.89 -1.00 4.89 Fe(OH)3 + FeS(ppt) -5.41 -9.33 -3.92 FeS + Goethite -0.00 -1.00 -1.00 FeOOH + Gypsum -0.65 -5.23 -4.58 CaSO4:2H2O + H2(g) -8.13 -11.28 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -9.34 -10.34 -1.00 H2S + Halite -6.32 -4.73 1.58 NaCl + Hematite 2.01 -2.00 -4.01 Fe2O3 + Mackinawite -4.68 -9.33 -4.65 FeS + Melanterite -8.24 -10.45 -2.21 FeSO4:7H2O + O2(g) -66.85 -69.81 -2.96 O2 + Pyrite -0.00 -18.48 -18.48 FeS2 + Siderite -2.81 -13.70 -10.89 FeCO3 + Sulfur -7.09 -2.21 4.88 S + +Reaction step 5. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 1. + + 5.000e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + O2 1.00 + NaCl 0.50 + + Relative + Element moles + Cl 0.50 + Na 0.50 + O 2.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.973e+00 -2.684e-02 + CO2(g) -3.50 -21.65 -18.15 1.000e+01 1.003e+01 2.649e-02 + Goethite 0.00 12.02 12.02 1.000e+01 1.001e+01 1.333e-02 + Gypsum 0.00 -4.58 -4.58 0.000e+00 9.002e-03 9.002e-03 + Pyrite -0.00 -85.78 -85.78 1.000e+01 9.987e+00 -1.333e-02 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 3.526e-04 3.524e-04 + Ca 1.785e-02 1.784e-02 + Cl 2.501e-02 2.500e-02 + Fe 8.735e-08 8.732e-08 + Na 2.501e-02 2.500e-02 + S 1.767e-02 1.766e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.719 Charge balance + pe = -3.565 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 7.432e-02 + Mass of water (kg) = 9.996e-01 + Total alkalinity (eq/kg) = 3.499e-04 + Total CO2 (mol/kg) = 3.526e-04 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -4.778e-11 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 25 + Total H = 1.109631e+02 + Total O = 5.555309e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.681e-07 5.237e-07 -6.175 -6.281 -0.106 + H+ 2.279e-08 1.909e-08 -7.642 -7.719 -0.077 + H2O 5.551e+01 9.986e-01 1.744 -0.001 0.000 +C(-4) 1.534e-14 + CH4 1.534e-14 1.561e-14 -13.814 -13.807 0.007 +C(4) 3.526e-04 + HCO3- 3.108e-04 2.505e-04 -3.508 -3.601 -0.094 + CaHCO3+ 2.134e-05 1.720e-05 -4.671 -4.764 -0.094 + CO2 1.058e-05 1.077e-05 -4.975 -4.968 0.007 + CaCO3 5.470e-06 5.565e-06 -5.262 -5.255 0.007 + NaHCO3 2.706e-06 2.752e-06 -5.568 -5.560 0.007 + CO3-2 1.458e-06 6.155e-07 -5.836 -6.211 -0.374 + NaCO3- 2.804e-07 2.239e-07 -6.552 -6.650 -0.098 + FeHCO3+ 8.424e-10 6.727e-10 -9.074 -9.172 -0.098 + FeCO3 3.897e-10 3.964e-10 -9.409 -9.402 0.007 +Ca 1.785e-02 + Ca+2 1.266e-02 5.382e-03 -1.898 -2.269 -0.371 + CaSO4 5.162e-03 5.251e-03 -2.287 -2.280 0.007 + CaHCO3+ 2.134e-05 1.720e-05 -4.671 -4.764 -0.094 + CaCO3 5.470e-06 5.565e-06 -5.262 -5.255 0.007 + CaOH+ 5.853e-08 4.673e-08 -7.233 -7.330 -0.098 + CaHSO4+ 7.355e-10 5.872e-10 -9.133 -9.231 -0.098 +Cl 2.501e-02 + Cl- 2.501e-02 1.966e-02 -1.602 -1.706 -0.105 + FeCl+ 9.125e-10 7.286e-10 -9.040 -9.138 -0.098 + FeCl+2 1.019e-24 4.140e-25 -23.992 -24.383 -0.391 + FeCl2+ 4.553e-26 3.635e-26 -25.342 -25.439 -0.098 + FeCl3 7.025e-29 7.146e-29 -28.153 -28.146 0.007 +Fe(2) 8.735e-08 + Fe+2 6.170e-08 2.685e-08 -7.210 -7.571 -0.361 + FeSO4 2.295e-08 2.335e-08 -7.639 -7.632 0.007 + FeCl+ 9.125e-10 7.286e-10 -9.040 -9.138 -0.098 + FeHCO3+ 8.424e-10 6.727e-10 -9.074 -9.172 -0.098 + FeOH+ 5.563e-10 4.442e-10 -9.255 -9.352 -0.098 + FeCO3 3.897e-10 3.964e-10 -9.409 -9.402 0.007 + FeHSO4+ 3.669e-15 2.930e-15 -14.435 -14.533 -0.098 + Fe(HS)2 1.432e-18 1.457e-18 -17.844 -17.837 0.007 + Fe(HS)3- 4.903e-26 3.915e-26 -25.310 -25.407 -0.098 +Fe(3) 3.379e-14 + Fe(OH)3 2.704e-14 2.750e-14 -13.568 -13.561 0.007 + Fe(OH)2+ 5.111e-15 4.081e-15 -14.291 -14.389 -0.098 + Fe(OH)4- 1.644e-15 1.312e-15 -14.784 -14.882 -0.098 + FeOH+2 5.796e-19 2.356e-19 -18.237 -18.628 -0.391 + FeSO4+ 4.683e-23 3.739e-23 -22.329 -22.427 -0.098 + Fe(SO4)2- 5.010e-24 4.000e-24 -23.300 -23.398 -0.098 + Fe+3 3.432e-24 6.974e-25 -23.464 -24.156 -0.692 + FeCl+2 1.019e-24 4.140e-25 -23.992 -24.383 -0.391 + FeCl2+ 4.553e-26 3.635e-26 -25.342 -25.439 -0.098 + FeCl3 7.025e-29 7.146e-29 -28.153 -28.146 0.007 + FeHSO4+2 4.703e-30 1.911e-30 -29.328 -29.719 -0.391 + Fe2(OH)2+4 5.473e-35 1.494e-36 -34.262 -35.826 -1.564 + Fe3(OH)4+5 0.000e+00 0.000e+00 -45.451 -47.895 -2.444 +H(0) 6.856e-12 + H2 3.428e-12 3.487e-12 -11.465 -11.458 0.007 +Na 2.501e-02 + Na+ 2.441e-02 1.954e-02 -1.612 -1.709 -0.097 + NaSO4- 5.997e-04 4.788e-04 -3.222 -3.320 -0.098 + NaHCO3 2.706e-06 2.752e-06 -5.568 -5.560 0.007 + NaCO3- 2.804e-07 2.239e-07 -6.552 -6.650 -0.098 + NaOH 6.639e-09 6.753e-09 -8.178 -8.170 0.007 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -69.474 -69.466 0.007 +S(-2) 3.552e-10 + HS- 3.148e-10 2.467e-10 -9.502 -9.608 -0.106 + H2S 4.048e-11 4.118e-11 -10.393 -10.385 0.007 + S-2 3.777e-15 1.561e-15 -14.423 -14.807 -0.384 + Fe(HS)2 1.432e-18 1.457e-18 -17.844 -17.837 0.007 + Fe(HS)3- 4.903e-26 3.915e-26 -25.310 -25.407 -0.098 +S(6) 1.767e-02 + SO4-2 1.191e-02 4.890e-03 -1.924 -2.311 -0.387 + CaSO4 5.162e-03 5.251e-03 -2.287 -2.280 0.007 + NaSO4- 5.997e-04 4.788e-04 -3.222 -3.320 -0.098 + FeSO4 2.295e-08 2.335e-08 -7.639 -7.632 0.007 + HSO4- 1.137e-08 9.075e-09 -7.944 -8.042 -0.098 + CaHSO4+ 7.355e-10 5.872e-10 -9.133 -9.231 -0.098 + FeHSO4+ 3.669e-15 2.930e-15 -14.435 -14.533 -0.098 + FeSO4+ 4.683e-23 3.739e-23 -22.329 -22.427 -0.098 + Fe(SO4)2- 5.010e-24 4.000e-24 -23.300 -23.398 -0.098 + FeHSO4+2 4.703e-30 1.911e-30 -29.328 -29.719 -0.391 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Anhydrite -0.22 -4.58 -4.36 CaSO4 + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -10.95 -13.81 -2.86 CH4 + CO2(g) -3.50 -4.97 -1.47 CO2 + Fe(OH)3(a) -5.89 -1.00 4.89 Fe(OH)3 + FeS(ppt) -5.54 -9.46 -3.92 FeS + Goethite 0.00 -1.00 -1.00 FeOOH + Gypsum 0.00 -4.58 -4.58 CaSO4:2H2O + H2(g) -8.31 -11.46 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + H2S(g) -9.39 -10.39 -1.00 H2S + Halite -5.00 -3.42 1.58 NaCl + Hematite 2.01 -2.00 -4.01 Fe2O3 + Mackinawite -4.81 -9.46 -4.65 FeS + Melanterite -7.68 -9.89 -2.21 FeSO4:7H2O + O2(g) -66.51 -69.47 -2.96 O2 + Pyrite -0.00 -18.48 -18.48 FeS2 + Siderite -2.89 -13.78 -10.89 FeCO3 + Sulfur -6.96 -2.08 4.88 S + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex5.sel b/Sun/examples/ex5.sel new file mode 100644 index 00000000..a017da32 --- /dev/null +++ b/Sun/examples/ex5.sel @@ -0,0 +1,7 @@ + sim state soln dist_x time step pH pe Cl pyrite d_pyrite goethite d_goethite calcite d_calcite CO2(g) d_CO2(g) gypsum d_gypsum si_Gypsum + 1 i_soln 1 -99 -99 -99 7 4 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -999.9990 + 1 react 1 -99 0 1 8.27904 -4.94284 0.0000e+00 1.0000e+01 -3.1538e-08 1.0000e+01 1.1047e-08 9.9995e+00 -4.9340e-04 9.9995e+00 -4.8697e-04 0.0000e+00 0.0000e+00 -6.1283 + 1 react 1 -99 0 2 8.17103 -4.28707 5.0000e-04 9.9997e+00 -2.6667e-04 1.0000e+01 2.6666e-04 9.9991e+00 -9.2766e-04 1.0000e+01 1.4180e-04 0.0000e+00 0.0000e+00 -2.0202 + 1 react 1 -99 0 3 7.98207 -3.97043 2.5000e-03 9.9987e+00 -1.3333e-03 1.0001e+01 1.3333e-03 9.9971e+00 -2.9374e-03 1.0002e+01 2.3951e-03 0.0000e+00 0.0000e+00 -1.0629 + 1 react 1 -99 0 4 7.88418 -3.81741 5.0001e-03 9.9973e+00 -2.6667e-03 1.0003e+01 2.6666e-03 9.9944e+00 -5.5594e-03 1.0005e+01 5.1054e-03 0.0000e+00 0.0000e+00 -0.6499 + 1 react 1 -99 0 5 7.71922 -3.56545 2.5011e-02 9.9867e+00 -1.3333e-02 1.0013e+01 1.3333e-02 9.9732e+00 -2.6841e-02 1.0026e+01 2.6489e-02 9.0018e-03 9.0018e-03 0.0000 diff --git a/Sun/examples/ex6.log b/Sun/examples/ex6.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex6.out b/Sun/examples/ex6.out new file mode 100644 index 00000000..49aa2d56 --- /dev/null +++ b/Sun/examples/ex6.out @@ -0,0 +1,3053 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex6 + Output file: ex6.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 6A.--React to phase boundaries. + SOLUTION 1 PURE WATER + pH 7.0 charge + temp 25.0 + PHASES + Gibbsite + Al(OH)3 + 3 H+ = Al+3 + 3 H2O + log_k 8.049 + delta_h -22.792 kcal + Kaolinite + Al2Si2O5(OH)4 + 6 H+ = H2O + 2 H4SiO4 + 2 Al+3 + log_k 5.708 + delta_h -35.306 kcal + K-mica + KAl3Si3O10(OH)2 + 10 H+ = 3 Al+3 + 3 H4SiO4 + K+ + log_k 12.970 + delta_h -59.377 kcal + K-feldspar + KAlSi3O8 + 4 H2O + 4 H+ = Al+3 + 3 H4SiO4 + K+ + log_k 0.875 + delta_h -12.467 kcal + SELECTED_OUTPUT + file ex6A-B.sel + activities K+ H+ H4SiO4 + si Gibbsite Kaolinite K-mica K-feldspar + equilibrium_phases Gibbsite Kaolinite K-mica K-feldspar + END +----- +TITLE +----- + + Example 6A.--React to phase boundaries. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. PURE WATER + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Pure water + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.121e-18 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.121e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 2 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.001e-07 1.001e-07 -7.000 -7.000 -0.000 + H+ 1.001e-07 1.001e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +H(0) 1.417e-25 + H2 7.087e-26 7.087e-26 -25.150 -25.150 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.081 -42.081 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -39.12 -42.08 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + TITLE Example 6A1.--Find amount of K-feldspar dissolved to + reach gibbsite saturation. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 KAlSi3O8 10.0 + Kaolinite 0.0 0.0 + K-mica 0.0 0.0 + K-feldspar 0.0 0.0 + END +----- +TITLE +----- + + Example 6A1.--Find amount of K-feldspar dissolved to + reach gibbsite saturation. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -2.671e-08 + K-feldspar -14.68 -13.81 0.88 0.000e+00 0.000e+00 + K-mica -10.68 2.29 12.97 0.000e+00 0.000e+00 + Kaolinite -3.80 1.90 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 2.671e-08 2.671e-08 + K 2.671e-08 2.671e-08 + Si 8.013e-08 8.013e-08 + +----------------------------Description of solution---------------------------- + + pH = 7.006 Charge balance + pe = 11.468 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.262e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.068e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.300e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.016e-07 1.015e-07 -6.993 -6.993 -0.000 + H+ 9.865e-08 9.861e-08 -7.006 -7.006 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 2.671e-08 + Al(OH)4- 2.455e-08 2.454e-08 -7.610 -7.610 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 8.597e-10 8.594e-10 -9.066 -9.066 -0.000 + AlOH+2 1.083e-11 1.081e-11 -10.965 -10.966 -0.001 + Al+3 1.077e-13 1.073e-13 -12.968 -12.969 -0.002 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.099 -40.099 0.000 +K 2.671e-08 + K+ 2.671e-08 2.670e-08 -7.573 -7.574 -0.000 + KOH 9.388e-16 9.388e-16 -15.027 -15.027 0.000 +O(0) 1.314e-12 + O2 6.572e-13 6.572e-13 -12.182 -12.182 0.000 +Si 8.013e-08 + H4SiO4 8.001e-08 8.001e-08 -7.097 -7.097 0.000 + H3SiO4- 1.197e-10 1.196e-10 -9.922 -9.922 -0.000 + H2SiO4-2 8.267e-17 8.253e-17 -16.083 -16.083 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -3.55 -7.10 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -36.95 -40.10 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -14.68 -13.81 0.88 KAlSi3O8 + K-mica -10.68 2.29 12.97 KAl3Si3O10(OH)2 + Kaolinite -3.80 1.90 5.71 Al2Si2O5(OH)4 + O2(g) -9.22 -12.18 -2.96 O2 + Quartz -3.12 -7.10 -3.98 SiO2 + SiO2(a) -4.39 -7.10 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + TITLE Example 6A2.--Find amount of K-feldspar dissolved to + reach kaolinite saturation. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 0.0 + Kaolinite 0.0 KAlSi3O8 10.0 + K-mica 0.0 0.0 + K-feldspar 0.0 0.0 + END +----- +TITLE +----- + + Example 6A2.--Find amount of K-feldspar dissolved to + reach kaolinite saturation. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.00 8.05 8.05 0.000e+00 1.782e-06 1.782e-06 + K-feldspar -5.86 -4.99 0.88 0.000e+00 0.000e+00 + K-mica -1.86 11.11 12.97 0.000e+00 0.000e+00 + Kaolinite -0.00 5.71 5.71 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -2.179e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 3.968e-07 3.968e-07 + K 2.179e-06 2.179e-06 + Si 6.536e-06 6.536e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.212 Charge balance + pe = 9.894 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.185e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.369e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.876e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550623e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.636e-06 1.633e-06 -5.786 -5.787 -0.001 + H+ 6.141e-09 6.131e-09 -8.212 -8.212 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 3.968e-07 + Al(OH)4- 3.955e-07 3.948e-07 -6.403 -6.404 -0.001 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 5.352e-11 5.343e-11 -10.271 -10.272 -0.001 + AlOH+2 4.208e-14 4.179e-14 -13.376 -13.379 -0.003 + Al+3 2.620e-17 2.579e-17 -16.582 -16.588 -0.007 +H(0) 8.674e-40 + H2 4.337e-40 4.337e-40 -39.363 -39.363 0.000 +K 2.179e-06 + K+ 2.179e-06 2.175e-06 -5.662 -5.663 -0.001 + KOH 1.230e-12 1.230e-12 -11.910 -11.910 0.000 +O(0) 4.433e-14 + O2 2.216e-14 2.216e-14 -13.654 -13.654 0.000 +Si 6.536e-06 + H4SiO4 6.383e-06 6.383e-06 -5.195 -5.195 0.000 + H3SiO4- 1.538e-07 1.535e-07 -6.813 -6.814 -0.001 + H2SiO4-2 1.715e-12 1.703e-12 -11.766 -11.769 -0.003 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -1.64 -5.20 -3.55 SiO2 + Gibbsite -0.00 8.05 8.05 Al(OH)3 + H2(g) -36.21 -39.36 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -5.86 -4.99 0.88 KAlSi3O8 + K-mica -1.86 11.11 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -10.69 -13.65 -2.96 O2 + Quartz -1.21 -5.20 -3.98 SiO2 + SiO2(a) -2.48 -5.20 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + TITLE Example 6A3.--Find amount of K-feldspar dissolved to + reach K-mica saturation. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 0.0 + Kaolinite 0.0 0.0 + K-mica 0.0 KAlSi3O8 10.0 + K-feldspar 0.0 0.0 + END +----- +TITLE +----- + + Example 6A3.--Find amount of K-feldspar dissolved to + reach K-mica saturation. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.73 7.32 8.05 0.000e+00 0.000e+00 + K-feldspar -2.55 -1.67 0.88 0.000e+00 0.000e+00 + K-mica -0.00 12.97 12.97 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -2.001e-05 + Kaolinite 0.00 5.71 5.71 0.000e+00 9.715e-06 9.715e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.851e-07 5.851e-07 + K 2.001e-05 2.001e-05 + Si 4.062e-05 4.061e-05 + +----------------------------Description of solution---------------------------- + + pH = 9.109 Charge balance + pe = 9.063 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.002e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.177e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.710e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550629e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.293e-05 1.286e-05 -4.888 -4.891 -0.002 + H+ 7.822e-10 7.782e-10 -9.107 -9.109 -0.002 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.851e-07 + Al(OH)4- 5.849e-07 5.818e-07 -6.233 -6.235 -0.002 + Al(OH)3 2.402e-10 2.402e-10 -9.619 -9.619 0.000 + Al(OH)2+ 1.275e-12 1.269e-12 -11.894 -11.897 -0.002 + AlOH+2 1.286e-16 1.260e-16 -15.891 -15.900 -0.009 + Al+3 1.034e-20 9.870e-21 -19.985 -20.006 -0.020 +H(0) 6.411e-40 + H2 3.206e-40 3.206e-40 -39.494 -39.494 0.000 +K 2.001e-05 + K+ 2.001e-05 1.991e-05 -4.699 -4.701 -0.002 + KOH 8.871e-11 8.872e-11 -10.052 -10.052 0.000 +O(0) 8.113e-14 + O2 4.057e-14 4.057e-14 -13.392 -13.392 0.000 +Si 4.062e-05 + H4SiO4 3.412e-05 3.412e-05 -4.467 -4.467 0.000 + H3SiO4- 6.498e-06 6.464e-06 -5.187 -5.189 -0.002 + H2SiO4-2 5.770e-10 5.651e-10 -9.239 -9.248 -0.009 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.48 7.32 10.80 Al(OH)3 + Chalcedony -0.92 -4.47 -3.55 SiO2 + Gibbsite -0.73 7.32 8.05 Al(OH)3 + H2(g) -36.34 -39.49 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -2.55 -1.67 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite 0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -10.43 -13.39 -2.96 O2 + Quartz -0.49 -4.47 -3.98 SiO2 + SiO2(a) -1.76 -4.47 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 5. +------------------------------------ + + TITLE Example 6A4.--Find amount of K-feldspar dissolved to + reach K-feldspar saturation. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 0.0 + Kaolinite 0.0 0.0 + K-mica 0.0 0.0 + K-feldspar 0.0 KAlSi3O8 10.0 + END +----- +TITLE +----- + + Example 6A4.--Find amount of K-feldspar dissolved to + reach K-feldspar saturation. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -2.00 6.05 8.05 0.000e+00 0.000e+00 + K-feldspar -0.00 0.87 0.88 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -1.909e-04 + K-mica -0.00 12.97 12.97 0.000e+00 6.361e-05 6.361e-05 + Kaolinite -0.72 4.99 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.990e-08 5.989e-08 + K 1.273e-04 1.273e-04 + Si 3.818e-04 3.818e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.389 Charge balance + pe = 8.719 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.273e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.275e-04 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.063e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.110123e+02 + Total O = 5.550698e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.486e-05 2.453e-05 -4.605 -4.610 -0.006 + H+ 4.133e-10 4.080e-10 -9.384 -9.389 -0.006 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.990e-08 + Al(OH)4- 5.988e-08 5.911e-08 -7.223 -7.228 -0.006 + Al(OH)3 1.280e-11 1.280e-11 -10.893 -10.893 0.000 + Al(OH)2+ 3.590e-14 3.544e-14 -13.445 -13.451 -0.006 + AlOH+2 1.944e-18 1.845e-18 -17.711 -17.734 -0.023 + Al+3 8.505e-23 7.579e-23 -22.070 -22.120 -0.050 +H(0) 8.588e-40 + H2 4.294e-40 4.294e-40 -39.367 -39.367 0.000 +K 1.273e-04 + K+ 1.273e-04 1.256e-04 -3.895 -3.901 -0.006 + KOH 1.067e-09 1.067e-09 -8.972 -8.972 0.000 +O(0) 4.521e-14 + O2 2.261e-14 2.261e-14 -13.646 -13.646 0.000 +Si 3.818e-04 + H4SiO4 2.795e-04 2.795e-04 -3.554 -3.554 0.000 + H3SiO4- 1.023e-04 1.010e-04 -3.990 -3.996 -0.006 + H2SiO4-2 1.774e-08 1.684e-08 -7.751 -7.774 -0.023 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.75 6.05 10.80 Al(OH)3 + Chalcedony -0.00 -3.55 -3.55 SiO2 + Gibbsite -2.00 6.05 8.05 Al(OH)3 + H2(g) -36.22 -39.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -0.00 0.87 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.72 4.99 5.71 Al2Si2O5(OH)4 + O2(g) -10.69 -13.65 -2.96 O2 + Quartz 0.43 -3.55 -3.98 SiO2 + SiO2(a) -0.84 -3.55 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 6. +------------------------------------ + + TITLE Example 6A5.--Find point with kaolinite present, + but no gibbsite. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 KAlSi3O8 10.0 + Kaolinite 0.0 1.0 + END +----- +TITLE +----- + + Example 6A5.--Find point with kaolinite present, + but no gibbsite. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -3.023e-06 + Kaolinite -0.00 5.71 5.71 1.000e+00 1.000e+00 1.237e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.493e-07 5.493e-07 + K 3.023e-06 3.023e-06 + Si 6.596e-06 6.596e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.354 Charge balance + pe = 9.786 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.028e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.671e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.021e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550623e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.267e-06 2.262e-06 -5.645 -5.646 -0.001 + H+ 4.435e-09 4.426e-09 -8.353 -8.354 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.493e-07 + Al(OH)4- 5.480e-07 5.469e-07 -6.261 -6.262 -0.001 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 3.865e-11 3.857e-11 -10.413 -10.414 -0.001 + AlOH+2 2.196e-14 2.178e-14 -13.658 -13.662 -0.004 + Al+3 9.882e-18 9.704e-18 -17.005 -17.013 -0.008 +H(0) 7.444e-40 + H2 3.722e-40 3.722e-40 -39.429 -39.429 0.000 +K 3.023e-06 + K+ 3.023e-06 3.017e-06 -5.520 -5.520 -0.001 + KOH 2.364e-12 2.364e-12 -11.626 -11.626 0.000 +O(0) 6.019e-14 + O2 3.009e-14 3.009e-14 -13.522 -13.522 0.000 +Si 6.596e-06 + H4SiO4 6.383e-06 6.383e-06 -5.195 -5.195 0.000 + H3SiO4- 2.131e-07 2.127e-07 -6.671 -6.672 -0.001 + H2SiO4-2 3.295e-12 3.269e-12 -11.482 -11.486 -0.004 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -1.64 -5.20 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -36.28 -39.43 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -5.58 -4.70 0.88 KAlSi3O8 + K-mica -1.57 11.40 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -10.56 -13.52 -2.96 O2 + Quartz -1.21 -5.20 -3.98 SiO2 + SiO2(a) -2.48 -5.20 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 7. +------------------------------------ + + TITLE Example 6A6.--Find point with K-mica present, + but no kaolinite + USE solution 1 + EQUILIBRIUM_PHASES 1 + Kaolinite 0.0 KAlSi3O8 10.0 + K-mica 0.0 1.0 + END +----- +TITLE +----- + + Example 6A6.--Find point with K-mica present, + but no kaolinite + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + K-mica 0.00 12.97 12.97 1.000e+00 1.000e+00 1.079e-05 + Kaolinite 0.00 5.71 5.71 + KAlSi3O8 is reactant 1.000e+01 1.000e+01 -3.268e-05 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 3.263e-07 3.263e-07 + K 2.190e-05 2.190e-05 + Si 6.569e-05 6.569e-05 + +----------------------------Description of solution---------------------------- + + pH = 9.070 Charge balance + pe = 8.836 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.190e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.288e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.154e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550635e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.183e-05 1.176e-05 -4.927 -4.930 -0.002 + H+ 8.558e-10 8.512e-10 -9.068 -9.070 -0.002 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 3.263e-07 + Al(OH)4- 3.262e-07 3.244e-07 -6.487 -6.489 -0.002 + Al(OH)3 1.465e-10 1.465e-10 -9.834 -9.834 0.000 + Al(OH)2+ 8.509e-13 8.463e-13 -12.070 -12.072 -0.002 + AlOH+2 9.393e-17 9.191e-17 -16.027 -16.037 -0.009 + Al+3 8.269e-21 7.876e-21 -20.083 -20.104 -0.021 +H(0) 2.179e-39 + H2 1.089e-39 1.089e-39 -38.963 -38.963 0.000 +K 2.190e-05 + K+ 2.190e-05 2.178e-05 -4.660 -4.662 -0.002 + KOH 8.871e-11 8.872e-11 -10.052 -10.052 0.000 +O(0) 7.024e-15 + O2 3.512e-15 3.512e-15 -14.454 -14.454 0.000 +Si 6.569e-05 + H4SiO4 5.595e-05 5.595e-05 -4.252 -4.252 0.000 + H3SiO4- 9.745e-06 9.692e-06 -5.011 -5.014 -0.002 + H2SiO4-2 7.916e-10 7.745e-10 -9.101 -9.111 -0.009 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.69 7.11 10.80 Al(OH)3 + Chalcedony -0.70 -4.25 -3.55 SiO2 + Gibbsite -0.94 7.11 8.05 Al(OH)3 + H2(g) -35.81 -38.96 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -2.12 -1.24 0.88 KAlSi3O8 + K-mica 0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite 0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -11.49 -14.45 -2.96 O2 + Quartz -0.27 -4.25 -3.98 SiO2 + SiO2(a) -1.54 -4.25 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 8. +------------------------------------ + + TITLE Example 6B.--Path between phase boundaries. + USE solution 1 + EQUILIBRIUM_PHASES 1 + Kaolinite 0.0 0.0 + Gibbsite 0.0 0.0 + K-mica 0.0 0.0 + K-feldspar 0.0 0.0 + REACTION 1 + K-feldspar 1.0 + 0.04 0.08 0.16 0.32 0.64 1.0 2.0 4.0 + 8.0 16.0 32.0 64.0 100 200 umol + END +----- +TITLE +----- + + Example 6B.--Path between phase boundaries. + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 4.000e-08 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.00 8.05 8.05 0.000e+00 1.187e-08 1.187e-08 + K-feldspar -13.96 -13.08 0.88 0.000e+00 0.000e+00 + K-mica -9.95 3.02 12.97 0.000e+00 0.000e+00 + Kaolinite -3.45 2.25 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 2.813e-08 2.813e-08 + K 4.000e-08 4.000e-08 + Si 1.200e-07 1.200e-07 + +----------------------------Description of solution---------------------------- + + pH = 7.031 Charge balance + pe = 11.457 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.339e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.244e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.761e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.077e-07 1.076e-07 -6.968 -6.968 -0.000 + H+ 9.306e-08 9.302e-08 -7.031 -7.031 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 2.813e-08 + Al(OH)4- 2.603e-08 2.602e-08 -7.585 -7.585 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 8.110e-10 8.107e-10 -9.091 -9.091 -0.000 + AlOH+2 9.638e-12 9.621e-12 -11.016 -11.017 -0.001 + Al+3 9.044e-14 9.009e-14 -13.044 -13.045 -0.002 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.127 -40.127 0.000 +K 4.000e-08 + K+ 4.000e-08 3.998e-08 -7.398 -7.398 -0.000 + KOH 1.490e-15 1.490e-15 -14.827 -14.827 0.000 +O(0) 1.494e-12 + O2 7.470e-13 7.470e-13 -12.127 -12.127 0.000 +Si 1.200e-07 + H4SiO4 1.198e-07 1.198e-07 -6.922 -6.922 0.000 + H3SiO4- 1.900e-10 1.899e-10 -9.721 -9.721 -0.000 + H2SiO4-2 1.391e-16 1.389e-16 -15.857 -15.857 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -3.37 -6.92 -3.55 SiO2 + Gibbsite -0.00 8.05 8.05 Al(OH)3 + H2(g) -36.98 -40.13 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -13.96 -13.08 0.88 KAlSi3O8 + K-mica -9.95 3.02 12.97 KAl3Si3O10(OH)2 + Kaolinite -3.45 2.25 5.71 Al2Si2O5(OH)4 + O2(g) -9.17 -12.13 -2.96 O2 + Quartz -2.94 -6.92 -3.98 SiO2 + SiO2(a) -4.21 -6.92 -2.71 SiO2 + +Reaction step 2. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 8.000e-08 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.00 8.05 8.05 0.000e+00 4.713e-08 4.713e-08 + K-feldspar -12.68 -11.80 0.88 0.000e+00 0.000e+00 + K-mica -8.68 4.29 12.97 0.000e+00 0.000e+00 + Kaolinite -2.85 2.86 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 3.287e-08 3.287e-08 + K 8.000e-08 8.000e-08 + Si 2.400e-07 2.400e-07 + +----------------------------Description of solution---------------------------- + + pH = 7.106 Charge balance + pe = 11.288 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.591e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.786e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.120e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.278e-07 1.277e-07 -6.894 -6.894 -0.000 + H+ 7.842e-08 7.838e-08 -7.106 -7.106 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 3.287e-08 + Al(OH)4- 3.089e-08 3.088e-08 -7.510 -7.510 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 6.834e-10 6.831e-10 -9.165 -9.166 -0.000 + AlOH+2 6.845e-12 6.832e-12 -11.165 -11.165 -0.001 + Al+3 5.414e-14 5.391e-14 -13.267 -13.268 -0.002 +H(0) 2.308e-40 + H2 1.154e-40 1.154e-40 -39.938 -39.938 0.000 +K 8.000e-08 + K+ 8.000e-08 7.996e-08 -7.097 -7.097 -0.000 + KOH 3.537e-15 3.537e-15 -14.451 -14.451 0.000 +O(0) 6.262e-13 + O2 3.131e-13 3.131e-13 -12.504 -12.504 0.000 +Si 2.400e-07 + H4SiO4 2.395e-07 2.395e-07 -6.621 -6.621 0.000 + H3SiO4- 4.508e-10 4.506e-10 -9.346 -9.346 -0.000 + H2SiO4-2 3.918e-16 3.911e-16 -15.407 -15.408 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -3.07 -6.62 -3.55 SiO2 + Gibbsite -0.00 8.05 8.05 Al(OH)3 + H2(g) -36.79 -39.94 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -12.68 -11.80 0.88 KAlSi3O8 + K-mica -8.68 4.29 12.97 KAl3Si3O10(OH)2 + Kaolinite -2.85 2.86 5.71 Al2Si2O5(OH)4 + O2(g) -9.54 -12.50 -2.96 O2 + Quartz -2.64 -6.62 -3.98 SiO2 + SiO2(a) -3.91 -6.62 -2.71 SiO2 + +Reaction step 3. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 1.600e-07 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 0.000e+00 1.160e-07 1.160e-07 + K-feldspar -11.34 -10.47 0.88 0.000e+00 0.000e+00 + K-mica -7.34 5.63 12.97 0.000e+00 0.000e+00 + Kaolinite -2.25 3.46 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 4.398e-08 4.398e-08 + K 1.600e-07 1.600e-07 + Si 4.800e-07 4.800e-07 + +----------------------------Description of solution---------------------------- + + pH = 7.241 Charge balance + pe = 11.241 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.179e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.919e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.323e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.745e-07 1.744e-07 -6.758 -6.758 -0.000 + H+ 5.743e-08 5.740e-08 -7.241 -7.241 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 4.398e-08 + Al(OH)4- 4.219e-08 4.217e-08 -7.375 -7.375 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 5.005e-10 5.002e-10 -9.301 -9.301 -0.000 + AlOH+2 3.671e-12 3.663e-12 -11.435 -11.436 -0.001 + Al+3 2.127e-14 2.117e-14 -13.672 -13.674 -0.002 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.113 -40.113 0.000 +K 1.600e-07 + K+ 1.600e-07 1.599e-07 -6.796 -6.796 -0.000 + KOH 9.661e-15 9.661e-15 -14.015 -14.015 0.000 +O(0) 1.405e-12 + O2 7.025e-13 7.025e-13 -12.153 -12.153 0.000 +Si 4.800e-07 + H4SiO4 4.788e-07 4.788e-07 -6.320 -6.320 0.000 + H3SiO4- 1.231e-09 1.230e-09 -8.910 -8.910 -0.000 + H2SiO4-2 1.461e-15 1.458e-15 -14.835 -14.836 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -2.77 -6.32 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -36.96 -40.11 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -11.34 -10.47 0.88 KAlSi3O8 + K-mica -7.34 5.63 12.97 KAl3Si3O10(OH)2 + Kaolinite -2.25 3.46 5.71 Al2Si2O5(OH)4 + O2(g) -9.19 -12.15 -2.96 O2 + Quartz -2.34 -6.32 -3.98 SiO2 + SiO2(a) -3.61 -6.32 -2.71 SiO2 + +Reaction step 4. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 3.200e-07 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.00 8.05 8.05 0.000e+00 2.499e-07 2.499e-07 + K-feldspar -9.93 -9.05 0.88 0.000e+00 0.000e+00 + K-mica -5.93 7.04 12.97 0.000e+00 0.000e+00 + Kaolinite -1.65 4.06 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 7.007e-08 7.007e-08 + K 3.200e-07 3.200e-07 + Si 9.600e-07 9.600e-07 + +----------------------------Description of solution---------------------------- + + pH = 7.451 Charge balance + pe = 11.188 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 3.557e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.302e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.281e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.832e-07 2.830e-07 -6.548 -6.548 -0.000 + H+ 3.539e-08 3.537e-08 -7.451 -7.451 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 7.007e-08 + Al(OH)4- 6.848e-08 6.843e-08 -7.164 -7.165 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 3.085e-10 3.082e-10 -9.511 -9.511 -0.000 + AlOH+2 1.395e-12 1.391e-12 -11.855 -11.857 -0.001 + Al+3 4.984e-15 4.953e-15 -14.302 -14.305 -0.003 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.429 -40.429 0.000 +K 3.200e-07 + K+ 3.200e-07 3.198e-07 -6.495 -6.495 -0.000 + KOH 3.135e-14 3.135e-14 -13.504 -13.504 0.000 +O(0) 6.000e-12 + O2 3.000e-12 3.000e-12 -11.523 -11.523 0.000 +Si 9.600e-07 + H4SiO4 9.560e-07 9.560e-07 -6.020 -6.020 0.000 + H3SiO4- 3.988e-09 3.986e-09 -8.399 -8.400 -0.000 + H2SiO4-2 7.687e-15 7.665e-15 -14.114 -14.115 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -2.47 -6.02 -3.55 SiO2 + Gibbsite -0.00 8.05 8.05 Al(OH)3 + H2(g) -37.28 -40.43 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -9.93 -9.05 0.88 KAlSi3O8 + K-mica -5.93 7.04 12.97 KAl3Si3O10(OH)2 + Kaolinite -1.65 4.06 5.71 Al2Si2O5(OH)4 + O2(g) -8.56 -11.52 -2.96 O2 + Quartz -2.04 -6.02 -3.98 SiO2 + SiO2(a) -3.31 -6.02 -2.71 SiO2 + +Reaction step 5. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 6.400e-07 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 0.000e+00 5.130e-07 5.130e-07 + K-feldspar -8.47 -7.59 0.88 0.000e+00 0.000e+00 + K-mica -4.46 8.51 12.97 0.000e+00 0.000e+00 + Kaolinite -1.05 4.66 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.270e-07 1.270e-07 + K 6.400e-07 6.400e-07 + Si 1.920e-06 1.920e-06 + +----------------------------Description of solution---------------------------- + + pH = 7.715 Charge balance + pe = 10.994 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 6.595e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.021e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.096e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 5.193e-07 5.189e-07 -6.285 -6.285 -0.000 + H+ 1.931e-08 1.929e-08 -7.714 -7.715 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.270e-07 + Al(OH)4- 1.256e-07 1.254e-07 -6.901 -6.902 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 1.683e-10 1.681e-10 -9.774 -9.774 -0.000 + AlOH+2 4.155e-13 4.139e-13 -12.381 -12.383 -0.002 + Al+3 8.109e-16 8.040e-16 -15.091 -15.095 -0.004 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.567 -40.567 0.000 +K 6.400e-07 + K+ 6.400e-07 6.394e-07 -6.194 -6.194 -0.000 + KOH 1.149e-13 1.149e-13 -12.940 -12.940 0.000 +O(0) 1.135e-11 + O2 5.673e-12 5.673e-12 -11.246 -11.246 0.000 +Si 1.920e-06 + H4SiO4 1.905e-06 1.905e-06 -5.720 -5.720 0.000 + H3SiO4- 1.458e-08 1.456e-08 -7.836 -7.837 -0.000 + H2SiO4-2 5.153e-14 5.134e-14 -13.288 -13.290 -0.002 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -2.17 -5.72 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -37.42 -40.57 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -8.47 -7.59 0.88 KAlSi3O8 + K-mica -4.46 8.51 12.97 KAl3Si3O10(OH)2 + Kaolinite -1.05 4.66 5.71 Al2Si2O5(OH)4 + O2(g) -8.29 -11.25 -2.96 O2 + Quartz -1.74 -5.72 -3.98 SiO2 + SiO2(a) -3.01 -5.72 -2.71 SiO2 + +Reaction step 6. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 1.000e-06 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 0.000e+00 8.081e-07 8.081e-07 + K-feldspar -7.51 -6.64 0.88 0.000e+00 0.000e+00 + K-mica -3.51 9.46 12.97 0.000e+00 0.000e+00 + Kaolinite -0.67 5.04 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.919e-07 1.919e-07 + K 1.000e-06 1.000e-06 + Si 3.000e-06 3.000e-06 + +----------------------------Description of solution---------------------------- + + pH = 7.896 Charge balance + pe = 10.790 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.013e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.576e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.467e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 11 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.879e-07 7.870e-07 -6.104 -6.104 -0.001 + H+ 1.274e-08 1.272e-08 -7.895 -7.896 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.919e-07 + Al(OH)4- 1.905e-07 1.903e-07 -6.720 -6.721 -0.001 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 1.110e-10 1.109e-10 -9.955 -9.955 -0.001 + AlOH+2 1.808e-13 1.799e-13 -12.743 -12.745 -0.002 + Al+3 2.328e-16 2.304e-16 -15.633 -15.638 -0.005 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.520 -40.520 0.000 +K 1.000e-06 + K+ 1.000e-06 9.988e-07 -6.000 -6.001 -0.001 + KOH 2.723e-13 2.723e-13 -12.565 -12.565 0.000 +O(0) 9.161e-12 + O2 4.580e-12 4.580e-12 -11.339 -11.339 0.000 +Si 3.000e-06 + H4SiO4 2.966e-06 2.966e-06 -5.528 -5.528 0.000 + H3SiO4- 3.442e-08 3.438e-08 -7.463 -7.464 -0.001 + H2SiO4-2 1.847e-13 1.838e-13 -12.734 -12.736 -0.002 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -1.98 -5.53 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -37.37 -40.52 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -7.51 -6.64 0.88 KAlSi3O8 + K-mica -3.51 9.46 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.67 5.04 5.71 Al2Si2O5(OH)4 + O2(g) -8.38 -11.34 -2.96 O2 + Quartz -1.55 -5.53 -3.98 SiO2 + SiO2(a) -2.82 -5.53 -2.71 SiO2 + +Reaction step 7. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 2.000e-06 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 0.000e+00 1.633e-06 1.633e-06 + K-feldspar -6.04 -5.17 0.88 0.000e+00 0.000e+00 + K-mica -2.04 10.93 12.97 0.000e+00 0.000e+00 + Kaolinite -0.07 5.64 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 3.666e-07 3.666e-07 + K 2.000e-06 2.000e-06 + Si 6.000e-06 6.000e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.178 Charge balance + pe = 10.498 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.007e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.100e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.114e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 12 + Total H = 1.110124e+02 + Total O = 5.550623e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.511e-06 1.508e-06 -5.821 -5.822 -0.001 + H+ 6.648e-09 6.637e-09 -8.177 -8.178 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 3.666e-07 + Al(OH)4- 3.653e-07 3.647e-07 -6.437 -6.438 -0.001 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 5.794e-11 5.784e-11 -10.237 -10.238 -0.001 + AlOH+2 4.931e-14 4.898e-14 -13.307 -13.310 -0.003 + Al+3 3.322e-17 3.273e-17 -16.479 -16.485 -0.006 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -40.501 -40.501 0.000 +K 2.000e-06 + K+ 2.000e-06 1.997e-06 -5.699 -5.700 -0.001 + KOH 1.043e-12 1.043e-12 -11.982 -11.982 0.000 +O(0) 8.387e-12 + O2 4.194e-12 4.194e-12 -11.377 -11.377 0.000 +Si 6.000e-06 + H4SiO4 5.869e-06 5.869e-06 -5.231 -5.231 0.000 + H3SiO4- 1.306e-07 1.304e-07 -6.884 -6.885 -0.001 + H2SiO4-2 1.345e-12 1.336e-12 -11.871 -11.874 -0.003 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -1.68 -5.23 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -37.35 -40.50 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -6.04 -5.17 0.88 KAlSi3O8 + K-mica -2.04 10.93 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.07 5.64 5.71 Al2Si2O5(OH)4 + O2(g) -8.42 -11.38 -2.96 O2 + Quartz -1.25 -5.23 -3.98 SiO2 + SiO2(a) -2.52 -5.23 -2.71 SiO2 + +Reaction step 8. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 4.000e-06 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.11 7.94 8.05 0.000e+00 0.000e+00 + K-feldspar -5.11 -4.23 0.88 0.000e+00 0.000e+00 + K-mica -1.32 11.65 12.97 0.000e+00 0.000e+00 + Kaolinite -0.00 5.71 5.71 0.000e+00 1.712e-06 1.712e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.761e-07 5.761e-07 + K 4.000e-06 4.000e-06 + Si 8.576e-06 8.576e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.484 Charge balance + pe = 9.390 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.003e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.728e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.241e-17 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 12 + Total H = 1.110124e+02 + Total O = 5.550623e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.059e-06 3.051e-06 -5.514 -5.516 -0.001 + H+ 3.288e-09 3.281e-09 -8.483 -8.484 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.761e-07 + Al(OH)4- 5.751e-07 5.737e-07 -6.240 -6.241 -0.001 + Al(OH)3 9.987e-10 9.987e-10 -9.001 -9.001 0.000 + Al(OH)2+ 2.229e-11 2.224e-11 -10.652 -10.653 -0.001 + AlOH+2 9.396e-15 9.309e-15 -14.027 -14.031 -0.004 + Al+3 3.140e-18 3.074e-18 -17.503 -17.512 -0.009 +H(0) 2.529e-39 + H2 1.264e-39 1.264e-39 -38.898 -38.898 0.000 +K 4.000e-06 + K+ 4.000e-06 3.991e-06 -5.398 -5.399 -0.001 + KOH 4.218e-12 4.218e-12 -11.375 -11.375 0.000 +O(0) 5.215e-15 + O2 2.607e-15 2.607e-15 -14.584 -14.584 0.000 +Si 8.576e-06 + H4SiO4 8.206e-06 8.206e-06 -5.086 -5.086 0.000 + H3SiO4- 3.697e-07 3.688e-07 -6.432 -6.433 -0.001 + H2SiO4-2 7.719e-12 7.647e-12 -11.112 -11.116 -0.004 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.86 7.94 10.80 Al(OH)3 + Chalcedony -1.53 -5.09 -3.55 SiO2 + Gibbsite -0.11 7.94 8.05 Al(OH)3 + H2(g) -35.75 -38.90 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -5.11 -4.23 0.88 KAlSi3O8 + K-mica -1.32 11.65 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -11.62 -14.58 -2.96 O2 + Quartz -1.11 -5.09 -3.98 SiO2 + SiO2(a) -2.37 -5.09 -2.71 SiO2 + +Reaction step 9. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 8.000e-06 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.38 7.67 8.05 0.000e+00 0.000e+00 + K-feldspar -3.97 -3.10 0.88 0.000e+00 0.000e+00 + K-mica -0.73 12.24 12.97 0.000e+00 0.000e+00 + Kaolinite -0.00 5.71 5.71 0.000e+00 3.695e-06 3.695e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 6.110e-07 6.110e-07 + K 8.000e-06 8.000e-06 + Si 1.661e-05 1.661e-05 + +----------------------------Description of solution---------------------------- + + pH = 8.779 Charge balance + pe = 9.506 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.002e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.833e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.133e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550625e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.035e-06 6.015e-06 -5.219 -5.221 -0.001 + H+ 1.670e-09 1.664e-09 -8.777 -8.779 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 6.110e-07 + Al(OH)4- 6.105e-07 6.084e-07 -6.214 -6.216 -0.001 + Al(OH)3 5.373e-10 5.373e-10 -9.270 -9.270 0.000 + Al(OH)2+ 6.089e-12 6.069e-12 -11.215 -11.217 -0.001 + AlOH+2 1.306e-15 1.289e-15 -14.884 -14.890 -0.006 + Al+3 2.224e-19 2.159e-19 -18.653 -18.666 -0.013 +H(0) 3.823e-40 + H2 1.911e-40 1.911e-40 -39.719 -39.719 0.000 +K 8.000e-06 + K+ 8.000e-06 7.974e-06 -5.097 -5.098 -0.001 + KOH 1.661e-11 1.661e-11 -10.780 -10.780 0.000 +O(0) 2.282e-13 + O2 1.141e-13 1.141e-13 -12.943 -12.943 0.000 +Si 1.661e-05 + H4SiO4 1.525e-05 1.525e-05 -4.817 -4.817 0.000 + H3SiO4- 1.356e-06 1.352e-06 -5.868 -5.869 -0.001 + H2SiO4-2 5.598e-11 5.524e-11 -10.252 -10.258 -0.006 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.13 7.67 10.80 Al(OH)3 + Chalcedony -1.27 -4.82 -3.55 SiO2 + Gibbsite -0.38 7.67 8.05 Al(OH)3 + H2(g) -36.57 -39.72 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -3.97 -3.10 0.88 KAlSi3O8 + K-mica -0.73 12.24 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -9.98 -12.94 -2.96 O2 + Quartz -0.84 -4.82 -3.98 SiO2 + SiO2(a) -2.10 -4.82 -2.71 SiO2 + +Reaction step 10. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 1.600e-05 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.64 7.41 8.05 0.000e+00 0.000e+00 + K-feldspar -2.89 -2.01 0.88 0.000e+00 0.000e+00 + K-mica -0.17 12.80 12.97 0.000e+00 0.000e+00 + Kaolinite 0.00 5.71 5.71 0.000e+00 7.701e-06 7.701e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.987e-07 5.987e-07 + K 1.600e-05 1.600e-05 + Si 3.260e-05 3.260e-05 + +----------------------------Description of solution---------------------------- + + pH = 9.035 Charge balance + pe = 8.801 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.600e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.780e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.512e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550628e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.089e-05 1.084e-05 -4.963 -4.965 -0.002 + H+ 9.275e-10 9.232e-10 -9.033 -9.035 -0.002 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.987e-07 + Al(OH)4- 5.984e-07 5.956e-07 -6.223 -6.225 -0.002 + Al(OH)3 2.918e-10 2.918e-10 -9.535 -9.535 0.000 + Al(OH)2+ 1.837e-12 1.828e-12 -11.736 -11.738 -0.002 + AlOH+2 2.194e-16 2.153e-16 -15.659 -15.667 -0.008 + Al+3 2.087e-20 2.001e-20 -19.681 -19.699 -0.018 +H(0) 3.011e-39 + H2 1.505e-39 1.505e-39 -38.822 -38.822 0.000 +K 1.600e-05 + K+ 1.600e-05 1.593e-05 -4.796 -4.798 -0.002 + KOH 5.981e-11 5.981e-11 -10.223 -10.223 0.000 +O(0) 3.679e-15 + O2 1.840e-15 1.840e-15 -14.735 -14.735 0.000 +Si 3.260e-05 + H4SiO4 2.809e-05 2.809e-05 -4.551 -4.551 0.000 + H3SiO4- 4.508e-06 4.487e-06 -5.346 -5.348 -0.002 + H2SiO4-2 3.368e-10 3.306e-10 -9.473 -9.481 -0.008 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.39 7.41 10.80 Al(OH)3 + Chalcedony -1.00 -4.55 -3.55 SiO2 + Gibbsite -0.64 7.41 8.05 Al(OH)3 + H2(g) -35.67 -38.82 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -2.89 -2.01 0.88 KAlSi3O8 + K-mica -0.17 12.80 12.97 KAl3Si3O10(OH)2 + Kaolinite 0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -11.78 -14.74 -2.96 O2 + Quartz -0.57 -4.55 -3.98 SiO2 + SiO2(a) -1.84 -4.55 -2.71 SiO2 + +Reaction step 11. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 3.200e-05 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.93 7.12 8.05 0.000e+00 0.000e+00 + K-feldspar -2.14 -1.26 0.88 0.000e+00 0.000e+00 + K-mica -0.00 12.97 12.97 0.000e+00 1.020e-05 1.020e-05 + Kaolinite 0.00 5.71 5.71 0.000e+00 5.270e-07 5.270e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 3.349e-07 3.349e-07 + K 2.180e-05 2.180e-05 + Si 6.434e-05 6.433e-05 + +----------------------------Description of solution---------------------------- + + pH = 9.072 Charge balance + pe = 8.977 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.180e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.280e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 2.694e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 13 + Total H = 1.110124e+02 + Total O = 5.550635e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.188e-05 1.182e-05 -4.925 -4.928 -0.002 + H+ 8.519e-10 8.473e-10 -9.070 -9.072 -0.002 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 3.349e-07 + Al(OH)4- 3.348e-07 3.330e-07 -6.475 -6.478 -0.002 + Al(OH)3 1.497e-10 1.497e-10 -9.825 -9.825 0.000 + Al(OH)2+ 8.654e-13 8.607e-13 -12.063 -12.065 -0.002 + AlOH+2 9.510e-17 9.305e-17 -16.022 -16.031 -0.009 + Al+3 8.332e-21 7.937e-21 -20.079 -20.100 -0.021 +H(0) 1.127e-39 + H2 5.637e-40 5.637e-40 -39.249 -39.249 0.000 +K 2.180e-05 + K+ 2.180e-05 2.168e-05 -4.662 -4.664 -0.002 + KOH 8.871e-11 8.872e-11 -10.052 -10.052 0.000 +O(0) 2.624e-14 + O2 1.312e-14 1.312e-14 -13.882 -13.882 0.000 +Si 6.434e-05 + H4SiO4 5.475e-05 5.475e-05 -4.262 -4.262 0.000 + H3SiO4- 9.581e-06 9.529e-06 -5.019 -5.021 -0.002 + H2SiO4-2 7.819e-10 7.650e-10 -9.107 -9.116 -0.009 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.68 7.12 10.80 Al(OH)3 + Chalcedony -0.71 -4.26 -3.55 SiO2 + Gibbsite -0.93 7.12 8.05 Al(OH)3 + H2(g) -36.10 -39.25 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -2.14 -1.26 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite 0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -10.92 -13.88 -2.96 O2 + Quartz -0.28 -4.26 -3.98 SiO2 + SiO2(a) -1.55 -4.26 -2.71 SiO2 + +Reaction step 12. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 6.400e-05 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -1.35 6.69 8.05 0.000e+00 0.000e+00 + K-feldspar -1.29 -0.42 0.88 0.000e+00 0.000e+00 + K-mica 0.00 12.97 12.97 0.000e+00 2.127e-05 2.127e-05 + Kaolinite -0.30 5.41 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.812e-07 1.812e-07 + K 4.273e-05 4.273e-05 + Si 1.282e-04 1.282e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.225 Charge balance + pe = 8.690 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 4.273e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.327e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.000e-13 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 21 + Total H = 1.110124e+02 + Total O = 5.550647e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.694e-05 1.681e-05 -4.771 -4.774 -0.003 + H+ 5.999e-10 5.954e-10 -9.222 -9.225 -0.003 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.812e-07 + Al(OH)4- 1.812e-07 1.798e-07 -6.742 -6.745 -0.003 + Al(OH)3 5.680e-11 5.680e-11 -10.246 -10.246 0.000 + Al(OH)2+ 2.313e-13 2.295e-13 -12.636 -12.639 -0.003 + AlOH+2 1.797e-17 1.744e-17 -16.745 -16.759 -0.013 + Al+3 1.118e-21 1.045e-21 -20.951 -20.981 -0.029 +H(0) 2.093e-39 + H2 1.046e-39 1.046e-39 -38.980 -38.980 0.000 +K 4.273e-05 + K+ 4.273e-05 4.240e-05 -4.369 -4.373 -0.003 + KOH 2.469e-10 2.469e-10 -9.607 -9.607 0.000 +O(0) 7.616e-15 + O2 3.808e-15 3.808e-15 -14.419 -14.419 0.000 +Si 1.282e-04 + H4SiO4 1.026e-04 1.026e-04 -3.989 -3.989 0.000 + H3SiO4- 2.560e-05 2.540e-05 -4.592 -4.595 -0.003 + H2SiO4-2 2.992e-09 2.902e-09 -8.524 -8.537 -0.013 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.11 6.69 10.80 Al(OH)3 + Chalcedony -0.44 -3.99 -3.55 SiO2 + Gibbsite -1.35 6.69 8.05 Al(OH)3 + H2(g) -35.83 -38.98 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -1.29 -0.42 0.88 KAlSi3O8 + K-mica 0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.30 5.41 5.71 Al2Si2O5(OH)4 + O2(g) -11.46 -14.42 -2.96 O2 + Quartz -0.01 -3.99 -3.98 SiO2 + SiO2(a) -1.28 -3.99 -2.71 SiO2 + +Reaction step 13. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 1.000e-04 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -1.62 6.43 8.05 0.000e+00 0.000e+00 + K-feldspar -0.76 0.11 0.88 0.000e+00 0.000e+00 + K-mica 0.00 12.97 12.97 0.000e+00 3.329e-05 3.329e-05 + Kaolinite -0.48 5.23 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.179e-07 1.179e-07 + K 6.671e-05 6.671e-05 + Si 2.001e-04 2.001e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.305 Charge balance + pe = 8.570 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 6.671e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 6.706e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.012e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.550662e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.038e-05 2.019e-05 -4.691 -4.695 -0.004 + H+ 5.006e-10 4.959e-10 -9.301 -9.305 -0.004 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.179e-07 + Al(OH)4- 1.179e-07 1.167e-07 -6.929 -6.933 -0.004 + Al(OH)3 3.072e-11 3.072e-11 -10.513 -10.513 0.000 + Al(OH)2+ 1.044e-13 1.034e-13 -12.981 -12.985 -0.004 + AlOH+2 6.796e-18 6.543e-18 -17.168 -17.184 -0.016 + Al+3 3.554e-22 3.267e-22 -21.449 -21.486 -0.037 +H(0) 2.521e-39 + H2 1.260e-39 1.260e-39 -38.899 -38.899 0.000 +K 6.671e-05 + K+ 6.671e-05 6.608e-05 -4.176 -4.180 -0.004 + KOH 4.620e-10 4.620e-10 -9.335 -9.335 0.000 +O(0) 5.248e-15 + O2 2.624e-15 2.624e-15 -14.581 -14.581 0.000 +Si 2.001e-04 + H4SiO4 1.539e-04 1.539e-04 -3.813 -3.813 0.000 + H3SiO4- 4.620e-05 4.576e-05 -4.335 -4.339 -0.004 + H2SiO4-2 6.519e-09 6.277e-09 -8.186 -8.202 -0.016 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.37 6.43 10.80 Al(OH)3 + Chalcedony -0.26 -3.81 -3.55 SiO2 + Gibbsite -1.62 6.43 8.05 Al(OH)3 + H2(g) -35.75 -38.90 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -0.76 0.11 0.88 KAlSi3O8 + K-mica 0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.48 5.23 5.71 Al2Si2O5(OH)4 + O2(g) -11.62 -14.58 -2.96 O2 + Quartz 0.17 -3.81 -3.98 SiO2 + SiO2(a) -1.10 -3.81 -2.71 SiO2 + +Reaction step 14. + +Using solution 1. PURE WATER +Using pure phase assemblage 1. +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 8. + + 2.000e-04 moles of the following reaction have been added: + + Relative + Reactant moles + + K-feldspar 1.00 + + Relative + Element moles + Al 1.00 + K 1.00 + O 8.00 + Si 3.00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -2.00 6.05 8.05 0.000e+00 0.000e+00 + K-feldspar 0.00 0.88 0.88 0.000e+00 9.120e-06 9.120e-06 + K-mica -0.00 12.97 12.97 0.000e+00 6.361e-05 6.361e-05 + Kaolinite -0.72 4.99 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.990e-08 5.989e-08 + K 1.273e-04 1.273e-04 + Si 3.818e-04 3.818e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.389 Charge balance + pe = 8.947 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.273e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.275e-04 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.728e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 15 + Total H = 1.110123e+02 + Total O = 5.550698e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.486e-05 2.453e-05 -4.605 -4.610 -0.006 + H+ 4.133e-10 4.080e-10 -9.384 -9.389 -0.006 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.990e-08 + Al(OH)4- 5.988e-08 5.911e-08 -7.223 -7.228 -0.006 + Al(OH)3 1.280e-11 1.280e-11 -10.893 -10.893 0.000 + Al(OH)2+ 3.590e-14 3.544e-14 -13.445 -13.451 -0.006 + AlOH+2 1.944e-18 1.845e-18 -17.711 -17.734 -0.023 + Al+3 8.505e-23 7.579e-23 -22.070 -22.120 -0.050 +H(0) 3.013e-40 + H2 1.507e-40 1.507e-40 -39.822 -39.822 0.000 +K 1.273e-04 + K+ 1.273e-04 1.256e-04 -3.895 -3.901 -0.006 + KOH 1.067e-09 1.067e-09 -8.972 -8.972 0.000 +O(0) 3.673e-13 + O2 1.836e-13 1.836e-13 -12.736 -12.736 0.000 +Si 3.818e-04 + H4SiO4 2.795e-04 2.795e-04 -3.554 -3.554 0.000 + H3SiO4- 1.023e-04 1.010e-04 -3.990 -3.996 -0.006 + H2SiO4-2 1.774e-08 1.684e-08 -7.751 -7.774 -0.023 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.75 6.05 10.80 Al(OH)3 + Chalcedony -0.00 -3.55 -3.55 SiO2 + Gibbsite -2.00 6.05 8.05 Al(OH)3 + H2(g) -36.67 -39.82 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar 0.00 0.88 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.72 4.99 5.71 Al2Si2O5(OH)4 + O2(g) -9.78 -12.74 -2.96 O2 + Quartz 0.43 -3.55 -3.98 SiO2 + SiO2(a) -0.84 -3.55 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 9. +------------------------------------ + + TITLE Example 6C.--kinetic calculation + SOLUTION 1 + units mol/kgw + Al 1.e-13 + K 1.e-13 + Si 3.e-13 + EQUILIBRIUM_PHASES 1 + Gibbsite 0.0 0.0 + Kaolinite 0.0 0.0 + K-mica 0.0 0.0 + KINETICS 1 + K-feldspar + parms 1.36e-11 + m0 2.16 + m 1.94 + step_divide 1e-6 + steps 1e2 1e3 1e4 1e5 1e6 1e7 1e8 + INCREMENTAL_REACTIONS true + RATES + K-feldspar + start + 10 REM store the initial amount of K-feldspar + 20 IF EXISTS(1) = 0 THEN PUT(M, 1) + 30 REM calculate moles of reaction + 40 SR_kfld = SR("K-feldspar") + 50 moles = PARM(1) * (M/M0)^0.67 * (1 - SR_kfld) * TIME + 60 REM The following is for printout of phase transitions + 80 REM Start Gibbsite + 90 if ABS(SI("Gibbsite")) > 1e-3 THEN GOTO 150 + 100 i = 2 + 110 GOSUB 1500 + 150 REM Start Gibbsite -> Kaolinite + 160 if ABS(SI("Kaolinite")) > 1e-3 THEN GOTO 200 + 170 i = 3 + 180 GOSUB 1500 + 200 REM End Gibbsite -> Kaolinite + 210 if ABS(SI("Kaolinite")) > 1e-3 OR EQUI("Gibbsite") > 0 THEN GOTO 250 + 220 i = 4 + 230 GOSUB 1500 + 250 REM Start Kaolinite -> K-mica + 260 if ABS(SI("K-mica")) > 1e-3 THEN GOTO 300 + 270 i = 5 + 280 GOSUB 1500 + 300 REM End Kaolinite -> K-mica + 310 if ABS(SI("K-mica")) > 1e-3 OR EQUI("Kaolinite") > 0 THEN GOTO 350 + 320 i = 6 + 330 GOSUB 1500 + 350 REM Start K-mica -> K-feldspar + 360 if ABS(SI("K-feldspar")) > 1e-3 THEN GOTO 1000 + 370 i = 7 + 380 GOSUB 1500 + 1000 SAVE moles + 1010 END + 1500 REM subroutine to store data + 1510 if GET(i) >= M THEN RETURN + 1520 PUT(M, i) + 1530 PUT(TOTAL_TIME, i, 1) + 1540 PUT(LA("K+")-LA("H+"), i, 2) + 1550 PUT(LA("H4SiO4"), i, 3) + 1560 RETURN + end + USER_PRINT + 10 DATA "A: Gibbsite ", "B: Gibbsite -> Kaolinite ", "C: Gibbsite -> Kaolinite ", "D: Kaolinite -> K-mica ", "E: Kaolinite -> K-mica ", "F: K-mica -> K-feldspar" + 20 PRINT " Transition Time K-feldspar LA(K/H) LA(H4SiO4)" + 30 PRINT " reacted" + 40 PRINT " (moles)" + 50 FOR i = 2 TO 7 + 60 READ s$ + 70 IF EXISTS(i) THEN PRINT s$, GET(i,1), GET(1) - GET(i), GET(i,2), GET(i,3) + 80 NEXT i + SELECTED_OUTPUT + file ex6C.sel + reset false + USER_PUNCH + heading pH+log[K] log[H4SiO4] + 10 PUNCH LA("K+")-LA("H+") LA("H4SiO4") + END +----- +TITLE +----- + + Example 6C.--kinetic calculation + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.000e-13 1.000e-13 + K 1.000e-13 1.000e-13 + Si 3.000e-13 3.000e-13 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.086e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 3 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.001e-07 1.001e-07 -6.999 -7.000 -0.000 + H+ 1.000e-07 1.000e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.000e-13 + Al(OH)4- 9.178e-14 9.175e-14 -13.037 -13.037 -0.000 + Al(OH)3 4.868e-15 4.868e-15 -14.313 -14.313 0.000 + Al(OH)2+ 3.305e-15 3.304e-15 -14.481 -14.481 -0.000 + AlOH+2 4.222e-17 4.215e-17 -16.375 -16.375 -0.001 + Al+3 4.258e-19 4.244e-19 -18.371 -18.372 -0.001 +H(0) 1.416e-25 + H2 7.079e-26 7.079e-26 -25.150 -25.150 0.000 +K 1.000e-13 + K+ 1.000e-13 9.996e-14 -13.000 -13.000 -0.000 + KOH 3.466e-21 3.466e-21 -20.460 -20.460 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.080 -42.080 0.000 +Si 3.000e-13 + H4SiO4 2.996e-13 2.996e-13 -12.524 -12.524 0.000 + H3SiO4- 4.419e-16 4.417e-16 -15.355 -15.355 -0.000 + H2SiO4-2 3.009e-22 3.005e-22 -21.522 -21.522 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -8.17 2.63 10.80 Al(OH)3 + Chalcedony -8.97 -12.52 -3.55 SiO2 + Gibbsite -5.42 2.63 8.05 Al(OH)3 + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -41.82 -40.94 0.88 KAlSi3O8 + K-mica -48.66 -35.69 12.97 KAl3Si3O10(OH)2 + Kaolinite -25.50 -19.79 5.71 Al2Si2O5(OH)4 + O2(g) -39.12 -42.08 -2.96 O2 + Quartz -8.54 -12.52 -3.98 SiO2 + SiO2(a) -9.81 -12.52 -2.71 SiO2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 100 seconds (Incremented time: 100 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.266e-09 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -1.32 6.73 8.05 0.000e+00 0.000e+00 + K-mica -19.94 -6.97 12.97 0.000e+00 0.000e+00 + Kaolinite -9.09 -3.38 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.266e-09 1.266e-09 + K 1.266e-09 1.266e-09 + Si 3.797e-09 3.797e-09 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 11.049 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.013e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.171e-09 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 35 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.002e-07 1.002e-07 -6.999 -6.999 -0.000 + H+ 9.997e-08 9.993e-08 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.266e-09 + Al(OH)4- 1.162e-09 1.161e-09 -8.935 -8.935 -0.000 + Al(OH)3 6.157e-11 6.157e-11 -10.211 -10.211 0.000 + Al(OH)2+ 4.178e-11 4.176e-11 -10.379 -10.379 -0.000 + AlOH+2 5.332e-13 5.324e-13 -12.273 -12.274 -0.001 + Al+3 5.375e-15 5.356e-15 -14.270 -14.271 -0.001 +H(0) 1.128e-39 + H2 5.642e-40 5.642e-40 -39.249 -39.249 0.000 +K 1.266e-09 + K+ 1.266e-09 1.265e-09 -8.898 -8.898 -0.000 + KOH 4.390e-17 4.390e-17 -16.358 -16.358 0.000 +O(0) 2.619e-14 + O2 1.309e-14 1.309e-14 -13.883 -13.883 0.000 +Si 3.797e-09 + H4SiO4 3.791e-09 3.791e-09 -8.421 -8.421 0.000 + H3SiO4- 5.596e-12 5.594e-12 -11.252 -11.252 -0.000 + H2SiO4-2 3.814e-18 3.808e-18 -17.419 -17.419 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.07 6.73 10.80 Al(OH)3 + Chalcedony -4.87 -8.42 -3.55 SiO2 + Gibbsite -1.32 6.73 8.05 Al(OH)3 + H2(g) -36.10 -39.25 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -21.31 -20.43 0.88 KAlSi3O8 + K-mica -19.94 -6.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -9.09 -3.38 5.71 Al2Si2O5(OH)4 + O2(g) -10.92 -13.88 -2.96 O2 + Quartz -4.44 -8.42 -3.98 SiO2 + SiO2(a) -5.71 -8.42 -2.71 SiO2 + +Reaction step 2. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 1000 seconds (Incremented time: 1100 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.266e-08 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.28 7.77 8.05 0.000e+00 0.000e+00 + K-mica -12.66 0.31 12.97 0.000e+00 0.000e+00 + Kaolinite -4.93 0.78 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 1.392e-08 1.392e-08 + K 1.392e-08 1.392e-08 + Si 4.176e-08 4.176e-08 + +----------------------------Description of solution---------------------------- + + pH = 7.003 Charge balance + pe = 11.058 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.137e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.579e-08 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 7 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.009e-07 1.009e-07 -6.996 -6.996 -0.000 + H+ 9.928e-08 9.924e-08 -7.003 -7.003 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 1.392e-08 + Al(OH)4- 1.279e-08 1.278e-08 -7.893 -7.893 -0.000 + Al(OH)3 6.731e-10 6.731e-10 -9.172 -9.172 0.000 + Al(OH)2+ 4.535e-10 4.533e-10 -9.343 -9.344 -0.000 + AlOH+2 5.749e-12 5.740e-12 -11.240 -11.241 -0.001 + Al+3 5.755e-14 5.734e-14 -13.240 -13.242 -0.002 +H(0) 1.070e-39 + H2 5.349e-40 5.349e-40 -39.272 -39.272 0.000 +K 1.392e-08 + K+ 1.392e-08 1.392e-08 -7.856 -7.856 -0.000 + KOH 4.862e-16 4.862e-16 -15.313 -15.313 0.000 +O(0) 2.914e-14 + O2 1.457e-14 1.457e-14 -13.837 -13.837 0.000 +Si 4.176e-08 + H4SiO4 4.170e-08 4.170e-08 -7.380 -7.380 0.000 + H3SiO4- 6.199e-11 6.196e-11 -10.208 -10.208 -0.000 + H2SiO4-2 4.254e-17 4.247e-17 -16.371 -16.372 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.03 7.77 10.80 Al(OH)3 + Chalcedony -3.83 -7.38 -3.55 SiO2 + Gibbsite -0.28 7.77 8.05 Al(OH)3 + H2(g) -36.12 -39.27 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -16.10 -15.22 0.88 KAlSi3O8 + K-mica -12.66 0.31 12.97 KAl3Si3O10(OH)2 + Kaolinite -4.93 0.78 5.71 Al2Si2O5(OH)4 + O2(g) -10.88 -13.84 -2.96 O2 + Quartz -3.40 -7.38 -3.98 SiO2 + SiO2(a) -4.67 -7.38 -2.71 SiO2 + +Reaction step 3. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 10000 seconds (Incremented time: 11100 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.266e-07 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) +A: Gibbsite 1100 1.4048e-07 3.5755e-01 -6.3763e+00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 0.000e+00 9.936e-08 9.936e-08 + K-mica -7.59 5.38 12.97 0.000e+00 0.000e+00 + Kaolinite -2.36 3.35 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 4.111e-08 4.111e-08 + K 1.405e-07 1.405e-07 + Si 4.214e-07 4.214e-07 + +----------------------------Description of solution---------------------------- + + pH = 7.210 Charge balance + pe = 10.821 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 2.027e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.639e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.03 + Iterations = 8 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.625e-07 1.624e-07 -6.789 -6.789 -0.000 + H+ 6.167e-08 6.164e-08 -7.210 -7.210 -0.000 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 4.111e-08 + Al(OH)4- 3.929e-08 3.927e-08 -7.406 -7.406 -0.000 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 5.374e-10 5.372e-10 -9.270 -9.270 -0.000 + AlOH+2 4.233e-12 4.224e-12 -11.373 -11.374 -0.001 + Al+3 2.634e-14 2.621e-14 -13.579 -13.582 -0.002 +H(0) 1.226e-39 + H2 6.128e-40 6.128e-40 -39.213 -39.213 0.000 +K 1.405e-07 + K+ 1.405e-07 1.404e-07 -6.852 -6.853 -0.000 + KOH 7.899e-15 7.899e-15 -14.102 -14.102 0.000 +O(0) 2.220e-14 + O2 1.110e-14 1.110e-14 -13.955 -13.955 0.000 +Si 4.214e-07 + H4SiO4 4.204e-07 4.204e-07 -6.376 -6.376 0.000 + H3SiO4- 1.006e-09 1.006e-09 -8.997 -8.997 -0.000 + H2SiO4-2 1.112e-15 1.110e-15 -14.954 -14.955 -0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -2.82 -6.38 -3.55 SiO2 + Gibbsite -0.00 8.05 8.05 Al(OH)3 + H2(g) -36.06 -39.21 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -11.60 -10.72 0.88 KAlSi3O8 + K-mica -7.59 5.38 12.97 KAl3Si3O10(OH)2 + Kaolinite -2.36 3.35 5.71 Al2Si2O5(OH)4 + O2(g) -10.99 -13.95 -2.96 O2 + Quartz -2.40 -6.38 -3.98 SiO2 + SiO2(a) -3.66 -6.38 -2.71 SiO2 + +Reaction step 4. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 100000 seconds (Incremented time: 111100 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.266e-06 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) +A: Gibbsite 1100 1.4048e-07 3.5755e-01 -6.3763e+00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite 0.00 8.05 8.05 9.936e-08 1.142e-06 1.043e-06 + K-mica -2.79 10.18 12.97 0.000e+00 0.000e+00 + Kaolinite -0.37 5.33 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 2.640e-07 2.640e-07 + K 1.406e-06 1.406e-06 + Si 4.218e-06 4.218e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.035 Charge balance + pe = 10.027 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.415e-06 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.198e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 65 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.086e-06 1.085e-06 -5.964 -5.965 -0.001 + H+ 9.240e-09 9.228e-09 -8.034 -8.035 -0.001 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 2.640e-07 + Al(OH)4- 2.626e-07 2.623e-07 -6.581 -6.581 -0.001 + Al(OH)3 1.284e-09 1.284e-09 -8.891 -8.891 0.000 + Al(OH)2+ 8.053e-11 8.042e-11 -10.094 -10.095 -0.001 + AlOH+2 9.521e-14 9.468e-14 -13.021 -13.024 -0.002 + Al+3 8.906e-17 8.796e-17 -16.050 -16.056 -0.005 +H(0) 1.066e-39 + H2 5.332e-40 5.332e-40 -39.273 -39.273 0.000 +K 1.406e-06 + K+ 1.406e-06 1.404e-06 -5.852 -5.853 -0.001 + KOH 5.276e-13 5.276e-13 -12.278 -12.278 0.000 +O(0) 2.932e-14 + O2 1.466e-14 1.466e-14 -13.834 -13.834 0.000 +Si 4.218e-06 + H4SiO4 4.152e-06 4.152e-06 -5.382 -5.382 0.000 + H3SiO4- 6.643e-08 6.634e-08 -7.178 -7.178 -0.001 + H2SiO4-2 4.918e-13 4.890e-13 -12.308 -12.311 -0.002 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -2.75 8.05 10.80 Al(OH)3 + Chalcedony -1.83 -5.38 -3.55 SiO2 + Gibbsite 0.00 8.05 8.05 Al(OH)3 + H2(g) -36.12 -39.27 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -6.79 -5.91 0.88 KAlSi3O8 + K-mica -2.79 10.18 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.37 5.33 5.71 Al2Si2O5(OH)4 + O2(g) -10.87 -13.83 -2.96 O2 + Quartz -1.40 -5.38 -3.98 SiO2 + SiO2(a) -2.67 -5.38 -2.71 SiO2 + +Reaction step 5. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 1e+06 seconds (Incremented time: 1.1111e+06 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.265e-05 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) +A: Gibbsite 1100 1.4048e-07 3.5755e-01 -6.3763e+00 +B: Gibbsite -> Kaolinite 1.7434e+05 2.2064e-06 2.5609e+00 -5.1950e+00 +C: Gibbsite -> Kaolinite 2.3929e+05 3.0284e-06 2.8352e+00 -5.1943e+00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -0.59 7.45 8.05 1.142e-06 -1.142e-06 + K-mica -0.27 12.70 12.97 0.000e+00 0.000e+00 + Kaolinite 0.00 5.71 5.71 0.000e+00 6.727e-06 6.727e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 6.045e-07 6.045e-07 + K 1.406e-05 1.406e-05 + Si 2.872e-05 2.872e-05 + +----------------------------Description of solution---------------------------- + + pH = 8.990 Charge balance + pe = 9.170 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.406e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.587e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 467 + Total H = 1.110124e+02 + Total O = 5.550627e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 9.825e-06 9.782e-06 -5.008 -5.010 -0.002 + H+ 1.028e-09 1.023e-09 -8.988 -8.990 -0.002 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 6.045e-07 + Al(OH)4- 6.042e-07 6.015e-07 -6.219 -6.221 -0.002 + Al(OH)3 3.266e-10 3.266e-10 -9.486 -9.486 0.000 + Al(OH)2+ 2.279e-12 2.269e-12 -11.642 -11.644 -0.002 + AlOH+2 3.015e-16 2.963e-16 -15.521 -15.528 -0.008 + Al+3 3.174e-20 3.052e-20 -19.498 -19.515 -0.017 +H(0) 6.790e-40 + H2 3.395e-40 3.395e-40 -39.469 -39.469 0.000 +K 1.406e-05 + K+ 1.406e-05 1.400e-05 -4.852 -4.854 -0.002 + KOH 4.742e-11 4.742e-11 -10.324 -10.324 0.000 +O(0) 7.232e-14 + O2 3.616e-14 3.616e-14 -13.442 -13.442 0.000 +Si 2.872e-05 + H4SiO4 2.509e-05 2.509e-05 -4.600 -4.600 0.000 + H3SiO4- 3.631e-06 3.615e-06 -5.440 -5.442 -0.002 + H2SiO4-2 2.445e-10 2.403e-10 -9.612 -9.619 -0.008 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -3.35 7.45 10.80 Al(OH)3 + Chalcedony -1.05 -4.60 -3.55 SiO2 + Gibbsite -0.59 7.45 8.05 Al(OH)3 + H2(g) -36.32 -39.47 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -3.09 -2.21 0.88 KAlSi3O8 + K-mica -0.27 12.70 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.00 5.71 5.71 Al2Si2O5(OH)4 + O2(g) -10.48 -13.44 -2.96 O2 + Quartz -0.62 -4.60 -3.98 SiO2 + SiO2(a) -1.89 -4.60 -2.71 SiO2 + +Reaction step 6. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 1e+07 seconds (Incremented time: 1.11111e+07 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -1.126e-04 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) +A: Gibbsite 1100 1.4048e-07 3.5755e-01 -6.3763e+00 +B: Gibbsite -> Kaolinite 1.7434e+05 2.2064e-06 2.5609e+00 -5.1950e+00 +C: Gibbsite -> Kaolinite 2.3929e+05 3.0284e-06 2.8352e+00 -5.1943e+00 +D: Kaolinite -> K-mica 1.5869e+06 2.0070e-05 4.4080e+00 -4.4659e+00 +E: Kaolinite -> K-mica 2.5972e+06 3.2791e-05 4.4103e+00 -4.2509e+00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -1.76 6.29 8.05 0.000e+00 0.000e+00 + K-mica -0.00 12.97 12.97 0.000e+00 4.218e-05 4.218e-05 + Kaolinite -0.57 5.14 5.71 6.727e-06 -6.727e-06 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 9.274e-08 9.274e-08 + K 8.444e-05 8.444e-05 + Si 2.533e-04 2.533e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.339 Charge balance + pe = -4.518 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.445e-05 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.472e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.113e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 3145 + Total H = 1.110123e+02 + Total O = 5.550672e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.211e-05 2.187e-05 -4.655 -4.660 -0.005 + H+ 4.625e-10 4.577e-10 -9.335 -9.339 -0.005 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 9.274e-08 + Al(OH)4- 9.272e-08 9.174e-08 -7.033 -7.037 -0.005 + Al(OH)3 2.228e-11 2.228e-11 -10.652 -10.652 0.000 + Al(OH)2+ 6.994e-14 6.920e-14 -13.155 -13.160 -0.005 + AlOH+2 4.217e-18 4.041e-18 -17.375 -17.393 -0.018 + Al+3 2.046e-22 1.862e-22 -21.689 -21.730 -0.041 +H(0) 3.219e-13 + H2 1.610e-13 1.610e-13 -12.793 -12.793 0.000 +K 8.444e-05 + K+ 8.444e-05 8.355e-05 -4.073 -4.078 -0.005 + KOH 6.329e-10 6.329e-10 -9.199 -9.199 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -66.794 -66.794 0.000 +Si 2.533e-04 + H4SiO4 1.911e-04 1.911e-04 -3.719 -3.719 0.000 + H3SiO4- 6.222e-05 6.157e-05 -4.206 -4.211 -0.005 + H2SiO4-2 9.548e-09 9.150e-09 -8.020 -8.039 -0.018 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.51 6.29 10.80 Al(OH)3 + Chalcedony -0.17 -3.72 -3.55 SiO2 + Gibbsite -1.76 6.29 8.05 Al(OH)3 + H2(g) -9.64 -12.79 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -0.48 0.39 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.57 5.14 5.71 Al2Si2O5(OH)4 + O2(g) -63.83 -66.79 -2.96 O2 + Quartz 0.26 -3.72 -3.98 SiO2 + SiO2(a) -1.01 -3.72 -2.71 SiO2 + +Reaction step 7. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 9. + +Kinetics 1. Kinetics defined in simulation 9. + + Time step: 1e+08 seconds (Incremented time: 1.11111e+08 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + K-feldspar -6.426e-05 1.940e+00 K-feldspar 1 + +----------------------------------User print----------------------------------- + + Transition Time K-feldspar LA(K/H) LA(H4SiO4) + reacted + (moles) +A: Gibbsite 1100 1.4048e-07 3.5755e-01 -6.3763e+00 +B: Gibbsite -> Kaolinite 1.7434e+05 2.2064e-06 2.5609e+00 -5.1950e+00 +C: Gibbsite -> Kaolinite 2.3929e+05 3.0284e-06 2.8352e+00 -5.1943e+00 +D: Kaolinite -> K-mica 1.5869e+06 2.0070e-05 4.4080e+00 -4.4659e+00 +E: Kaolinite -> K-mica 2.5972e+06 3.2791e-05 4.4103e+00 -4.2509e+00 +F: K-mica -> K-feldspar 4.7840e+07 1.9072e-04 5.4879e+00 -3.5540e+00 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Gibbsite -2.00 6.05 8.05 0.000e+00 0.000e+00 + K-mica 0.00 12.97 12.97 4.218e-05 6.361e-05 2.143e-05 + Kaolinite -0.72 4.99 5.71 0.000e+00 0.000e+00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Al 5.990e-08 5.989e-08 + K 1.273e-04 1.273e-04 + Si 3.818e-04 3.818e-04 + +----------------------------Description of solution---------------------------- + + pH = 9.389 Charge balance + pe = -4.454 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.273e-04 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.275e-04 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.114e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 1788 + Total H = 1.110123e+02 + Total O = 5.550698e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.486e-05 2.453e-05 -4.605 -4.610 -0.006 + H+ 4.133e-10 4.080e-10 -9.384 -9.389 -0.006 + H2O 5.551e+01 1.000e+00 1.744 -0.000 0.000 +Al 5.990e-08 + Al(OH)4- 5.988e-08 5.911e-08 -7.223 -7.228 -0.006 + Al(OH)3 1.280e-11 1.280e-11 -10.893 -10.893 0.000 + Al(OH)2+ 3.590e-14 3.544e-14 -13.445 -13.451 -0.006 + AlOH+2 1.944e-18 1.845e-18 -17.711 -17.734 -0.023 + Al+3 8.505e-23 7.579e-23 -22.070 -22.120 -0.050 +H(0) 1.911e-13 + H2 9.553e-14 9.553e-14 -13.020 -13.020 0.000 +K 1.273e-04 + K+ 1.273e-04 1.256e-04 -3.895 -3.901 -0.006 + KOH 1.067e-09 1.067e-09 -8.972 -8.972 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -66.340 -66.340 0.000 +Si 3.818e-04 + H4SiO4 2.795e-04 2.795e-04 -3.554 -3.554 0.000 + H3SiO4- 1.023e-04 1.010e-04 -3.990 -3.996 -0.006 + H2SiO4-2 1.774e-08 1.684e-08 -7.751 -7.774 -0.023 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Al(OH)3(a) -4.75 6.05 10.80 Al(OH)3 + Chalcedony -0.00 -3.55 -3.55 SiO2 + Gibbsite -2.00 6.05 8.05 Al(OH)3 + H2(g) -9.87 -13.02 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + K-feldspar -0.00 0.87 0.88 KAlSi3O8 + K-mica -0.00 12.97 12.97 KAl3Si3O10(OH)2 + Kaolinite -0.72 4.99 5.71 Al2Si2O5(OH)4 + O2(g) -63.38 -66.34 -2.96 O2 + Quartz 0.43 -3.55 -3.98 SiO2 + SiO2(a) -0.84 -3.55 -2.71 SiO2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 10. +------------------------------------- + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex6A-B.sel b/Sun/examples/ex6A-B.sel new file mode 100644 index 00000000..a623a401 --- /dev/null +++ b/Sun/examples/ex6A-B.sel @@ -0,0 +1,22 @@ + sim state soln dist_x time step pH pe la_K+ la_H+ la_H4SiO4 Gibbsite d_Gibbsite Kaolinite d_Kaolinite K-mica d_K-mica K-feldspar d_K-feldspar si_Gibbsite si_Kaolinite si_K-mica si_K-feldspar + 1 i_soln 1 -99 -99 -99 6.99977 4 -1.0000e+03 -6.9998e+00 -1.0000e+03 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -999.9990 -999.9990 -999.9990 -999.9990 + 2 react 1 -99 0 1 7.00609 11.4683 -7.5735e+00 -7.0061e+00 -7.0969e+00 1.0000e+01 -2.6709e-08 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -3.8037 -10.6810 -14.6840 + 3 react 1 -99 0 1 8.2125 9.89391 -5.6625e+00 -8.2125e+00 -5.1950e+00 1.7820e-06 1.7820e-06 1.0000e+01 -2.1788e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.0000 -0.0000 -1.8580 -5.8610 + 4 react 1 -99 0 1 9.10891 9.06313 -4.7009e+00 -9.1089e+00 -4.4670e+00 0.0000e+00 0.0000e+00 9.7149e-06 9.7149e-06 1.0000e+01 -2.0015e-05 0.0000e+00 0.0000e+00 -0.7280 0.0000 -0.0000 -2.5471 + 5 react 1 -99 0 1 9.3893 8.71926 -3.9009e+00 -9.3893e+00 -3.5536e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 6.3607e-05 6.3607e-05 9.9998e+00 -1.9088e-04 -2.0015 -0.7202 -0.0000 -0.0000 + 6 react 1 -99 0 1 8.35402 9.7856 -5.5204e+00 -8.3540e+00 -5.1950e+00 1.0000e+01 -3.0232e-06 1.0000e+00 1.2370e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -0.0000 -1.5744 -5.5774 + 7 react 1 -99 0 1 9.06998 8.8364 -4.6620e+00 -9.0700e+00 -4.2522e+00 0.0000e+00 0.0000e+00 1.0000e+01 -3.2683e-05 1.0000e+00 1.0785e-05 0.0000e+00 0.0000e+00 -0.9428 0.0000 0.0000 -2.1175 + 8 react 1 -99 0 1 7.03143 11.4569 -7.3981e+00 -7.0314e+00 -6.9215e+00 1.1865e-08 1.1865e-08 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.0000 -3.4530 -9.9542 -13.9572 + 8 react 1 -99 0 2 7.10578 11.2881 -7.0971e+00 -7.1058e+00 -6.6206e+00 4.7135e-08 4.7135e-08 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.0000 -2.8512 -8.6762 -12.6792 + 8 react 1 -99 0 3 7.24112 11.2405 -6.7961e+00 -7.2411e+00 -6.3199e+00 1.1602e-07 1.1602e-07 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -2.2497 -7.3376 -11.3406 + 8 react 1 -99 0 4 7.45138 11.1879 -6.4952e+00 -7.4514e+00 -6.0195e+00 2.4993e-07 2.4993e-07 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.0000 -1.6491 -5.9254 -9.9284 + 8 react 1 -99 0 5 7.71458 10.9939 -6.1942e+00 -7.7146e+00 -5.7200e+00 5.1299e-07 5.1299e-07 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -1.0500 -4.4627 -8.4657 + 8 react 1 -99 0 6 7.89551 10.7897 -6.0005e+00 -7.8955e+00 -5.5279e+00 8.0811e-07 8.0811e-07 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -0.6658 -3.5117 -7.5147 + 8 react 1 -99 0 7 8.17803 10.4976 -5.6997e+00 -8.1780e+00 -5.2314e+00 1.6334e-06 1.6334e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000 -0.0728 -2.0389 -6.0419 + 8 react 1 -99 0 8 8.48402 9.39003 -5.3990e+00 -8.4840e+00 -5.0858e+00 0.0000e+00 0.0000e+00 1.7119e-06 1.7119e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.1092 -0.0000 -1.3229 -5.1076 + 8 react 1 -99 0 9 8.77878 9.50556 -5.0983e+00 -8.7788e+00 -4.8166e+00 0.0000e+00 0.0000e+00 3.6945e-06 3.6945e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.3784 -0.0000 -0.7276 -3.9737 + 8 react 1 -99 0 10 9.0347 8.80148 -4.7979e+00 -9.0347e+00 -4.5514e+00 0.0000e+00 0.0000e+00 7.7006e-06 7.7006e-06 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 -0.6436 0.0000 -0.1712 -2.8871 + 8 react 1 -99 0 11 9.07198 8.97748 -4.6640e+00 -9.0720e+00 -4.2616e+00 0.0000e+00 0.0000e+00 5.2701e-07 5.2701e-07 1.0204e-05 1.0204e-05 0.0000e+00 0.0000e+00 -0.9334 0.0000 -0.0000 -2.1362 + 8 react 1 -99 0 12 9.2252 8.68998 -4.3726e+00 -9.2252e+00 -3.9889e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 2.1273e-05 2.1273e-05 0.0000e+00 0.0000e+00 -1.3543 -0.2964 0.0000 -1.2945 + 8 react 1 -99 0 13 9.30457 8.57016 -4.1800e+00 -9.3046e+00 -3.8127e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 3.3294e-05 3.3294e-05 0.0000e+00 0.0000e+00 -1.6212 -0.4777 0.0000 -0.7607 + 8 react 1 -99 0 14 9.3893 8.9467 -3.9009e+00 -9.3893e+00 -3.5536e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 6.3607e-05 6.3607e-05 9.1200e-06 9.1200e-06 -2.0015 -0.7202 -0.0000 0.0000 diff --git a/Sun/examples/ex6C.sel b/Sun/examples/ex6C.sel new file mode 100644 index 00000000..efc12a6c --- /dev/null +++ b/Sun/examples/ex6C.sel @@ -0,0 +1,9 @@ + pH+log[K] log[H4SiO4] + -6.0002e+00 -1.2524e+01 + -1.8975e+00 -8.4212e+00 + -8.5316e-01 -7.3798e+00 + 3.5755e-01 -6.3763e+00 + 2.1823e+00 -5.3818e+00 + 4.1360e+00 -4.6005e+00 + 5.2614e+00 -3.7187e+00 + 5.4884e+00 -3.5536e+00 diff --git a/Sun/examples/ex7.log b/Sun/examples/ex7.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex7.out b/Sun/examples/ex7.out new file mode 100644 index 00000000..8e79de41 --- /dev/null +++ b/Sun/examples/ex7.out @@ -0,0 +1,2819 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex7 + Output file: ex7.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 7.--Organic decomposition with fixed-pressure and + fixed-volume gas phases + SOLUTION 1 + EQUILIBRIUM_PHASES 1 + Calcite + CO2(g) -1.5 + SAVE solution 1 + SELECTED_OUTPUT + reset false + file ex7.sel + simulation true + state true + reaction true + si CO2(g) CH4(g) N2(g) NH3(g) + gases CO2(g) CH4(g) N2(g) NH3(g) + END +----- +TITLE +----- + + Example 7.--Organic decomposition with fixed-pressure and + fixed-volume gas phases + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Pure water + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 4.000 + Activity of water = 1.000 + Ionic strength = 1.001e-07 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.082e-10 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.082e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 0 + Total H = 1.110124e+02 + Total O = 5.550622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.002e-07 1.001e-07 -6.999 -6.999 -0.000 + H+ 1.001e-07 1.000e-07 -7.000 -7.000 -0.000 + H2O 5.551e+01 1.000e+00 1.744 0.000 0.000 +H(0) 1.416e-25 + H2 7.079e-26 7.079e-26 -25.150 -25.150 0.000 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -42.080 -42.080 0.000 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -22.00 -25.15 -3.15 H2 + H2O(g) -1.51 0.00 1.51 H2O + O2(g) -39.12 -42.08 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Calcite 0.00 -8.48 -8.48 1.000e+01 9.997e+00 -2.502e-03 + CO2(g) -1.50 -19.65 -18.15 1.000e+01 9.996e+00 -3.568e-03 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 6.071e-03 6.071e-03 + Ca 2.502e-03 2.502e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.971 Charge balance + pe = -0.653 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.282e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.004e-03 + Total CO2 (mol/kg) = 6.071e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 16 + Total H = 1.110124e+02 + Total O = 5.552086e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.159e-07 1.070e-07 -6.936 -6.971 -0.035 + OH- 1.025e-07 9.358e-08 -6.989 -7.029 -0.040 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 7.589e-30 + CH4 7.589e-30 7.602e-30 -29.120 -29.119 0.001 +C(4) 6.071e-03 + HCO3- 4.883e-03 4.476e-03 -2.311 -2.349 -0.038 + CO2 1.075e-03 1.077e-03 -2.969 -2.968 0.001 + CaHCO3+ 1.052e-04 9.640e-05 -3.978 -4.016 -0.038 + CaCO3 5.556e-06 5.565e-06 -5.255 -5.255 0.001 + CO3-2 2.778e-06 1.962e-06 -5.556 -5.707 -0.151 +Ca 2.502e-03 + Ca+2 2.391e-03 1.688e-03 -2.621 -2.773 -0.151 + CaHCO3+ 1.052e-04 9.640e-05 -3.978 -4.016 -0.038 + CaCO3 5.556e-06 5.565e-06 -5.255 -5.255 0.001 + CaOH+ 2.864e-09 2.619e-09 -8.543 -8.582 -0.039 +H(0) 3.273e-16 + H2 1.636e-16 1.639e-16 -15.786 -15.785 0.001 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -60.810 -60.809 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite 0.00 -8.48 -8.48 CaCO3 + CH4(g) -26.26 -29.12 -2.86 CH4 + CO2(g) -1.50 -2.97 -1.47 CO2 + H2(g) -12.64 -15.79 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -57.85 -60.81 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + USE solution 1 + GAS_PHASE 1 Fixed-pressure gas phase + fixed_pressure + pressure 1.1 + CO2(g) 0.0 + CH4(g) 0.0 + N2(g) 0.0 + NH3(g) 0.0 + REACTION 1 + CH2O(NH3)0.07 1.0 + 1. 2. 3. 4. 8. 16. 32 64. 125. 250. 500. 1000. mmol + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 1.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 7.071e-03 7.071e-03 + Ca 2.502e-03 2.502e-03 + N 7.000e-05 7.000e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.831 Charge balance + pe = -3.723 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.353e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.074e-03 + Total CO2 (mol/kg) = 6.571e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.110146e+02 + Total O = 5.552186e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.597e-07 1.474e-07 -6.797 -6.831 -0.035 + OH- 7.440e-08 6.789e-08 -7.128 -7.168 -0.040 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 5.001e-04 + CH4 5.001e-04 5.009e-04 -3.301 -3.300 0.001 +C(4) 6.571e-03 + HCO3- 4.955e-03 4.541e-03 -2.305 -2.343 -0.038 + CO2 1.503e-03 1.505e-03 -2.823 -2.822 0.001 + CaHCO3+ 1.066e-04 9.766e-05 -3.972 -4.010 -0.038 + CaCO3 4.083e-06 4.090e-06 -5.389 -5.388 0.001 + CO3-2 2.048e-06 1.445e-06 -5.689 -5.840 -0.152 +Ca 2.502e-03 + Ca+2 2.392e-03 1.686e-03 -2.621 -2.773 -0.152 + CaHCO3+ 1.066e-04 9.766e-05 -3.972 -4.010 -0.038 + CaCO3 4.083e-06 4.090e-06 -5.389 -5.388 0.001 + CaOH+ 2.076e-09 1.897e-09 -8.683 -8.722 -0.039 +H(0) 8.575e-10 + H2 4.287e-10 4.295e-10 -9.368 -9.367 0.001 +N(-3) 6.986e-05 + NH4+ 6.962e-05 6.338e-05 -4.157 -4.198 -0.041 + NH3 2.446e-07 2.450e-07 -6.612 -6.611 0.001 +N(0) 1.394e-07 + N2 6.970e-08 6.981e-08 -7.157 -7.156 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.351 -62.391 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.704 -84.744 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.647 -73.646 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.28 -8.61 -8.34 CaCO3 + Calcite -0.13 -8.61 -8.48 CaCO3 + CH4(g) -0.44 -3.30 -2.86 CH4 + CO2(g) -1.35 -2.82 -1.47 CO2 + H2(g) -6.22 -9.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.90 -7.16 -3.26 N2 + NH3(g) -8.38 -6.61 1.77 NH3 + O2(g) -70.69 -73.65 -2.96 O2 + +Reaction step 2. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 2.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 8.071e-03 8.071e-03 + Ca 2.502e-03 2.502e-03 + N 1.400e-04 1.400e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.728 Charge balance + pe = -3.644 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.422e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.144e-03 + Total CO2 (mol/kg) = 7.071e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 20 + Total H = 1.110169e+02 + Total O = 5.552286e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.026e-07 1.869e-07 -6.693 -6.728 -0.035 + OH- 5.871e-08 5.355e-08 -7.231 -7.271 -0.040 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 1.000e-03 + CH4 1.000e-03 1.002e-03 -3.000 -2.999 0.001 +C(4) 7.071e-03 + HCO3- 5.026e-03 4.604e-03 -2.299 -2.337 -0.038 + CO2 1.932e-03 1.935e-03 -2.714 -2.713 0.001 + CaHCO3+ 1.079e-04 9.886e-05 -3.967 -4.005 -0.038 + CaCO3 3.261e-06 3.266e-06 -5.487 -5.486 0.001 + CO3-2 1.640e-06 1.155e-06 -5.785 -5.937 -0.152 +Ca 2.502e-03 + Ca+2 2.391e-03 1.683e-03 -2.621 -2.774 -0.153 + CaHCO3+ 1.079e-04 9.886e-05 -3.967 -4.005 -0.038 + CaCO3 3.261e-06 3.266e-06 -5.487 -5.486 0.001 + CaOH+ 1.635e-09 1.494e-09 -8.786 -8.826 -0.039 +H(0) 9.576e-10 + H2 4.788e-10 4.796e-10 -9.320 -9.319 0.001 +N(-3) 1.398e-04 + NH4+ 1.394e-04 1.268e-04 -3.856 -3.897 -0.041 + NH3 3.860e-07 3.867e-07 -6.413 -6.413 0.001 +N(0) 2.493e-07 + N2 1.247e-07 1.249e-07 -6.904 -6.904 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.399 -62.440 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.800 -84.841 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.743 -73.742 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.38 -8.71 -8.34 CaCO3 + Calcite -0.23 -8.71 -8.48 CaCO3 + CH4(g) -0.14 -3.00 -2.86 CH4 + CO2(g) -1.25 -2.71 -1.47 CO2 + H2(g) -6.17 -9.32 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.64 -6.90 -3.26 N2 + NH3(g) -8.18 -6.41 1.77 NH3 + O2(g) -70.78 -73.74 -2.96 O2 + +Reaction step 3. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 3.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 1.91e-03 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) 0.01 1.030e+00 0.000e+00 8.036e-05 8.036e-05 +CO2(g) -1.16 6.932e-02 0.000e+00 5.406e-06 5.406e-06 +N2(g) -3.50 3.151e-04 0.000e+00 2.458e-08 2.458e-08 +NH3(g) -8.09 8.187e-09 0.000e+00 6.386e-13 6.386e-13 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 8.985e-03 8.985e-03 + Ca 2.502e-03 2.502e-03 + N 2.100e-04 2.100e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.648 Charge balance + pe = -3.572 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.491e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.214e-03 + Total CO2 (mol/kg) = 7.565e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 23 + Total H = 1.110187e+02 + Total O = 5.552385e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.438e-07 2.249e-07 -6.613 -6.648 -0.035 + OH- 4.882e-08 4.451e-08 -7.311 -7.352 -0.040 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 1.420e-03 + CH4 1.420e-03 1.422e-03 -2.848 -2.847 0.001 +C(4) 7.565e-03 + HCO3- 5.096e-03 4.667e-03 -2.293 -2.331 -0.038 + CO2 2.356e-03 2.360e-03 -2.628 -2.627 0.001 + CaHCO3+ 1.092e-04 1.000e-04 -3.962 -4.000 -0.038 + CaCO3 2.742e-06 2.747e-06 -5.562 -5.561 0.001 + CO3-2 1.384e-06 9.733e-07 -5.859 -6.012 -0.153 +Ca 2.502e-03 + Ca+2 2.390e-03 1.680e-03 -2.622 -2.775 -0.153 + CaHCO3+ 1.092e-04 1.000e-04 -3.962 -4.000 -0.038 + CaCO3 2.742e-06 2.747e-06 -5.562 -5.561 0.001 + CaOH+ 1.357e-09 1.240e-09 -8.867 -8.907 -0.039 +H(0) 9.947e-10 + H2 4.974e-10 4.982e-10 -9.303 -9.303 0.001 +N(-3) 2.096e-04 + NH4+ 2.091e-04 1.902e-04 -3.680 -3.721 -0.041 + NH3 4.813e-07 4.821e-07 -6.318 -6.317 0.001 +N(0) 3.457e-07 + N2 1.729e-07 1.732e-07 -6.762 -6.762 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.433 -62.474 -0.041 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.851 -84.891 -0.041 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.776 -73.775 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.45 -8.79 -8.34 CaCO3 + Calcite -0.31 -8.79 -8.48 CaCO3 + CH4(g) 0.01 -2.85 -2.86 CH4 + CO2(g) -1.16 -2.63 -1.47 CO2 + H2(g) -6.15 -9.30 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.50 -6.76 -3.26 N2 + NH3(g) -8.09 -6.32 1.77 NH3 + O2(g) -70.81 -73.77 -2.96 O2 + +Reaction step 4. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 4.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 1.43e-02 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) 0.01 1.019e+00 0.000e+00 5.966e-04 5.966e-04 +CO2(g) -1.09 8.074e-02 0.000e+00 4.728e-05 4.728e-05 +N2(g) -3.32 4.773e-04 0.000e+00 2.795e-07 2.795e-07 +NH3(g) -8.02 9.476e-09 0.000e+00 5.549e-12 5.549e-12 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 9.427e-03 9.427e-03 + Ca 2.502e-03 2.502e-03 + N 2.795e-04 2.794e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.588 Charge balance + pe = -3.502 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.558e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 5.283e-03 + Total CO2 (mol/kg) = 8.023e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 23 + Total H = 1.110189e+02 + Total O = 5.552477e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.803e-07 2.585e-07 -6.552 -6.588 -0.035 + OH- 4.248e-08 3.872e-08 -7.372 -7.412 -0.040 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 1.404e-03 + CH4 1.404e-03 1.406e-03 -2.853 -2.852 0.001 +C(4) 8.023e-03 + HCO3- 5.165e-03 4.728e-03 -2.287 -2.325 -0.038 + CO2 2.744e-03 2.749e-03 -2.562 -2.561 0.001 + CaHCO3+ 1.105e-04 1.012e-04 -3.957 -3.995 -0.038 + CaCO3 2.412e-06 2.417e-06 -5.618 -5.617 0.001 + CO3-2 1.221e-06 8.579e-07 -5.913 -6.067 -0.153 +Ca 2.502e-03 + Ca+2 2.389e-03 1.677e-03 -2.622 -2.775 -0.154 + CaHCO3+ 1.105e-04 1.012e-04 -3.957 -3.995 -0.038 + CaCO3 2.412e-06 2.417e-06 -5.618 -5.617 0.001 + CaOH+ 1.179e-09 1.076e-09 -8.928 -8.968 -0.040 +H(0) 9.548e-10 + H2 4.774e-10 4.782e-10 -9.321 -9.320 0.001 +N(-3) 2.789e-04 + NH4+ 2.784e-04 2.531e-04 -3.555 -3.597 -0.041 + NH3 5.570e-07 5.580e-07 -6.254 -6.253 0.001 +N(0) 5.237e-07 + N2 2.619e-07 2.623e-07 -6.582 -6.581 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.377 -62.418 -0.041 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.777 -84.817 -0.041 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.740 -73.739 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.51 -8.84 -8.34 CaCO3 + Calcite -0.36 -8.84 -8.48 CaCO3 + CH4(g) 0.01 -2.85 -2.86 CH4 + CO2(g) -1.09 -2.56 -1.47 CO2 + H2(g) -6.17 -9.32 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.32 -6.58 -3.26 N2 + NH3(g) -8.02 -6.25 1.77 NH3 + O2(g) -70.78 -73.74 -2.96 O2 + +Reaction step 5. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 8.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 6.67e-02 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.01 9.758e-01 0.000e+00 2.659e-03 2.659e-03 +CO2(g) -0.91 1.230e-01 0.000e+00 3.351e-04 3.351e-04 +N2(g) -2.90 1.257e-03 0.000e+00 3.425e-06 3.425e-06 +NH3(g) -7.89 1.292e-08 0.000e+00 3.520e-11 3.520e-11 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.108e-02 1.108e-02 + Ca 2.502e-03 2.502e-03 + N 5.532e-04 5.532e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.426 Charge balance + pe = -3.316 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.823e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 5.556e-03 + Total CO2 (mol/kg) = 9.733e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.074e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.110195e+02 + Total O = 5.552819e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 4.068e-07 3.747e-07 -6.391 -6.426 -0.036 + OH- 2.935e-08 2.671e-08 -7.532 -7.573 -0.041 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 1.344e-03 + CH4 1.344e-03 1.347e-03 -2.871 -2.871 0.001 +C(4) 9.733e-03 + HCO3- 5.435e-03 4.969e-03 -2.265 -2.304 -0.039 + CO2 4.180e-03 4.187e-03 -2.379 -2.378 0.001 + CaHCO3+ 1.155e-04 1.056e-04 -3.938 -3.977 -0.039 + CaCO3 1.736e-06 1.740e-06 -5.760 -5.760 0.001 + CO3-2 8.902e-07 6.219e-07 -6.051 -6.206 -0.156 +Ca 2.502e-03 + Ca+2 2.385e-03 1.665e-03 -2.623 -2.779 -0.156 + CaHCO3+ 1.155e-04 1.056e-04 -3.938 -3.977 -0.039 + CaCO3 1.736e-06 1.740e-06 -5.760 -5.760 0.001 + CaOH+ 8.088e-10 7.373e-10 -9.092 -9.132 -0.040 +H(0) 8.501e-10 + H2 4.251e-10 4.258e-10 -9.372 -9.371 0.001 +N(-3) 5.518e-04 + NH4+ 5.510e-04 5.003e-04 -3.259 -3.301 -0.042 + NH3 7.594e-07 7.608e-07 -6.120 -6.119 0.001 +N(0) 1.379e-06 + N2 6.895e-07 6.907e-07 -6.161 -6.161 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.252 -62.293 -0.041 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.601 -84.642 -0.041 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.639 -73.639 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.65 -8.98 -8.34 CaCO3 + Calcite -0.51 -8.98 -8.48 CaCO3 + CH4(g) -0.01 -2.87 -2.86 CH4 + CO2(g) -0.91 -2.38 -1.47 CO2 + H2(g) -6.22 -9.37 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.90 -6.16 -3.26 N2 + NH3(g) -7.89 -6.12 1.77 NH3 + O2(g) -70.68 -73.64 -2.96 O2 + +Reaction step 6. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 1.600e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 1.83e-01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.04 9.042e-01 0.000e+00 6.775e-03 6.775e-03 +CO2(g) -0.72 1.925e-01 0.000e+00 1.442e-03 1.442e-03 +N2(g) -2.47 3.359e-03 0.000e+00 2.517e-05 2.517e-05 +NH3(g) -7.76 1.735e-08 0.000e+00 1.300e-10 1.300e-10 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.385e-02 1.385e-02 + Ca 2.502e-03 2.502e-03 + N 1.070e-03 1.070e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.269 Charge balance + pe = -3.131 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.320e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.070e-03 + Total CO2 (mol/kg) = 1.261e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 20 + Total H = 1.110207e+02 + Total O = 5.553398e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 5.850e-07 5.377e-07 -6.233 -6.269 -0.037 + OH- 2.050e-08 1.861e-08 -7.688 -7.730 -0.042 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +C(-4) 1.246e-03 + CH4 1.246e-03 1.248e-03 -2.905 -2.904 0.001 +C(4) 1.261e-02 + CO2 6.541e-03 6.553e-03 -2.184 -2.184 0.001 + HCO3- 5.941e-03 5.419e-03 -2.226 -2.266 -0.040 + CaHCO3+ 1.246e-04 1.136e-04 -3.905 -3.945 -0.040 + CaCO3 1.302e-06 1.304e-06 -5.885 -5.885 0.001 + CO3-2 6.830e-07 4.726e-07 -6.166 -6.326 -0.160 +Ca 2.502e-03 + Ca+2 2.376e-03 1.643e-03 -2.624 -2.784 -0.160 + CaHCO3+ 1.246e-04 1.136e-04 -3.905 -3.945 -0.040 + CaCO3 1.302e-06 1.304e-06 -5.885 -5.885 0.001 + CaOH+ 5.575e-10 5.070e-10 -9.254 -9.295 -0.041 +H(0) 7.456e-10 + H2 3.728e-10 3.735e-10 -9.429 -9.428 0.001 +N(-3) 1.066e-03 + NH4+ 1.065e-03 9.641e-04 -2.973 -3.016 -0.043 + NH3 1.020e-06 1.022e-06 -5.991 -5.991 0.001 +N(0) 3.685e-06 + N2 1.842e-06 1.846e-06 -5.735 -5.734 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -62.109 -62.151 -0.043 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.401 -84.444 -0.043 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.526 -73.525 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.77 -9.11 -8.34 CaCO3 + Calcite -0.63 -9.11 -8.48 CaCO3 + CH4(g) -0.04 -2.90 -2.86 CH4 + CO2(g) -0.72 -2.18 -1.47 CO2 + H2(g) -6.28 -9.43 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.47 -5.73 -3.26 N2 + NH3(g) -7.76 -5.99 1.77 NH3 + O2(g) -70.56 -73.52 -2.96 O2 + +Reaction step 7. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 3.200e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 4.56e-01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.09 8.051e-01 0.000e+00 1.502e-02 1.502e-02 +CO2(g) -0.54 2.859e-01 0.000e+00 5.333e-03 5.333e-03 +N2(g) -2.05 8.992e-03 0.000e+00 1.677e-04 1.677e-04 +NH3(g) -7.63 2.343e-08 0.000e+00 4.372e-10 4.372e-10 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.772e-02 1.772e-02 + Ca 2.502e-03 2.502e-03 + N 1.905e-03 1.905e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.152 Charge balance + pe = -2.985 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.121e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 6.899e-03 + Total CO2 (mol/kg) = 1.661e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.110231e+02 + Total O = 5.554219e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 7.692e-07 7.048e-07 -6.114 -6.152 -0.038 + OH- 1.571e-08 1.420e-08 -7.804 -7.848 -0.044 + H2O 5.551e+01 9.996e-01 1.744 -0.000 0.000 +C(-4) 1.109e-03 + CH4 1.109e-03 1.111e-03 -2.955 -2.954 0.001 +C(4) 1.661e-02 + CO2 9.712e-03 9.733e-03 -2.013 -2.012 0.001 + HCO3- 6.756e-03 6.139e-03 -2.170 -2.212 -0.042 + CaHCO3+ 1.387e-04 1.261e-04 -3.858 -3.899 -0.042 + CaCO3 1.102e-06 1.104e-06 -5.958 -5.957 0.001 + CO3-2 5.992e-07 4.085e-07 -6.222 -6.389 -0.166 +Ca 2.502e-03 + Ca+2 2.362e-03 1.609e-03 -2.627 -2.793 -0.167 + CaHCO3+ 1.387e-04 1.261e-04 -3.858 -3.899 -0.042 + CaCO3 1.102e-06 1.104e-06 -5.958 -5.957 0.001 + CaOH+ 4.182e-10 3.788e-10 -9.379 -9.422 -0.043 +H(0) 6.560e-10 + H2 3.280e-10 3.287e-10 -9.484 -9.483 0.001 +N(-3) 1.895e-03 + NH4+ 1.893e-03 1.707e-03 -2.723 -2.768 -0.045 + NH3 1.377e-06 1.380e-06 -5.861 -5.860 0.001 +N(0) 9.862e-06 + N2 4.931e-06 4.941e-06 -5.307 -5.306 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.927 -61.972 -0.044 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -84.164 -84.209 -0.044 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.415 -73.414 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.85 -9.18 -8.34 CaCO3 + Calcite -0.70 -9.18 -8.48 CaCO3 + CH4(g) -0.09 -2.95 -2.86 CH4 + CO2(g) -0.54 -2.01 -1.47 CO2 + H2(g) -6.33 -9.48 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.05 -5.31 -3.26 N2 + NH3(g) -7.63 -5.86 1.77 NH3 + O2(g) -70.45 -73.41 -2.96 O2 + +Reaction step 8. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 6.400e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 1.10e+00 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.15 7.052e-01 0.000e+00 3.167e-02 3.167e-02 +CO2(g) -0.42 3.760e-01 0.000e+00 1.689e-02 1.689e-02 +N2(g) -1.73 1.883e-02 0.000e+00 8.456e-04 8.456e-04 +NH3(g) -7.54 2.911e-08 0.000e+00 1.307e-09 1.307e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.151e-02 2.151e-02 + Ca 2.502e-03 2.502e-03 + N 2.789e-03 2.789e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.083 Charge balance + pe = -2.895 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 9.965e-03 + Mass of water (kg) = 9.999e-01 + Total alkalinity (eq/kg) = 7.773e-03 + Total CO2 (mol/kg) = 2.054e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.110272e+02 + Total O = 5.555108e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.035e-07 8.254e-07 -6.044 -6.083 -0.039 + OH- 1.346e-08 1.212e-08 -7.871 -7.916 -0.046 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +C(-4) 9.712e-04 + CH4 9.712e-04 9.734e-04 -3.013 -3.012 0.001 +C(4) 2.054e-02 + CO2 1.277e-02 1.280e-02 -1.894 -1.893 0.001 + HCO3- 7.616e-03 6.895e-03 -2.118 -2.161 -0.043 + CaHCO3+ 1.532e-04 1.387e-04 -3.815 -3.858 -0.043 + CaCO3 1.035e-06 1.037e-06 -5.985 -5.984 0.001 + CO3-2 5.831e-07 3.917e-07 -6.234 -6.407 -0.173 +Ca 2.502e-03 + Ca+2 2.348e-03 1.576e-03 -2.629 -2.802 -0.173 + CaHCO3+ 1.532e-04 1.387e-04 -3.815 -3.858 -0.043 + CaCO3 1.035e-06 1.037e-06 -5.985 -5.984 0.001 + CaOH+ 3.511e-10 3.168e-10 -9.455 -9.499 -0.045 +H(0) 5.924e-10 + H2 2.962e-10 2.969e-10 -9.528 -9.527 0.001 +N(-3) 2.768e-03 + NH4+ 2.767e-03 2.483e-03 -2.558 -2.605 -0.047 + NH3 1.710e-06 1.714e-06 -5.767 -5.766 0.001 +N(0) 2.065e-05 + N2 1.032e-05 1.035e-05 -4.986 -4.985 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.767 -61.814 -0.046 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.960 -84.006 -0.046 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.327 -73.326 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.87 -9.21 -8.34 CaCO3 + Calcite -0.73 -9.21 -8.48 CaCO3 + CH4(g) -0.15 -3.01 -2.86 CH4 + CO2(g) -0.42 -1.89 -1.47 CO2 + H2(g) -6.38 -9.53 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.73 -4.99 -3.26 N2 + NH3(g) -7.54 -5.77 1.77 NH3 + O2(g) -70.37 -73.33 -2.96 O2 + +Reaction step 9. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 1.250e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 2.44e+00 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.20 6.377e-01 0.000e+00 6.367e-02 6.367e-02 +CO2(g) -0.36 4.352e-01 0.000e+00 4.345e-02 4.345e-02 +N2(g) -1.57 2.715e-02 0.000e+00 2.711e-03 2.711e-03 +NH3(g) -7.50 3.187e-08 0.000e+00 3.182e-09 3.182e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.396e-02 2.396e-02 + Ca 2.502e-03 2.502e-03 + N 3.328e-03 3.328e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.048 Charge balance + pe = -2.846 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 1.048e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.302e-03 + Total CO2 (mol/kg) = 2.308e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.107e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 19 + Total H = 1.110340e+02 + Total O = 5.555897e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.825e-07 8.960e-07 -6.008 -6.048 -0.040 + OH- 1.243e-08 1.117e-08 -7.905 -7.952 -0.047 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +C(-4) 8.781e-04 + CH4 8.781e-04 8.802e-04 -3.056 -3.055 0.001 +C(4) 2.308e-02 + CO2 1.478e-02 1.482e-02 -1.830 -1.829 0.001 + HCO3- 8.137e-03 7.351e-03 -2.090 -2.134 -0.044 + CaHCO3+ 1.616e-04 1.460e-04 -3.791 -3.836 -0.044 + CaCO3 1.004e-06 1.006e-06 -5.998 -5.997 0.001 + CO3-2 5.776e-07 3.847e-07 -6.238 -6.415 -0.177 +Ca 2.502e-03 + Ca+2 2.339e-03 1.557e-03 -2.631 -2.808 -0.177 + CaHCO3+ 1.616e-04 1.460e-04 -3.791 -3.836 -0.044 + CaCO3 1.004e-06 1.006e-06 -5.998 -5.997 0.001 + CaOH+ 3.202e-10 2.883e-10 -9.495 -9.540 -0.046 +H(0) 5.569e-10 + H2 2.784e-10 2.791e-10 -9.555 -9.554 0.001 +N(-3) 3.298e-03 + NH4+ 3.296e-03 2.951e-03 -2.482 -2.530 -0.048 + NH3 1.872e-06 1.877e-06 -5.728 -5.727 0.001 +N(0) 2.977e-05 + N2 1.489e-05 1.492e-05 -4.827 -4.826 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.682 -61.730 -0.047 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.848 -83.896 -0.047 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.273 -73.272 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.89 -9.22 -8.34 CaCO3 + Calcite -0.74 -9.22 -8.48 CaCO3 + CH4(g) -0.20 -3.06 -2.86 CH4 + CO2(g) -0.36 -1.83 -1.47 CO2 + H2(g) -6.40 -9.55 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.57 -4.83 -3.26 N2 + NH3(g) -7.50 -5.73 1.77 NH3 + O2(g) -70.31 -73.27 -2.96 O2 + +Reaction step 10. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 2.500e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 5.29e+00 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.22 5.988e-01 0.000e+00 1.294e-01 1.294e-01 +CO2(g) -0.33 4.690e-01 0.000e+00 1.013e-01 1.013e-01 +N2(g) -1.49 3.216e-02 0.000e+00 6.949e-03 6.949e-03 +NH3(g) -7.48 3.294e-08 0.000e+00 7.117e-09 7.117e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.532e-02 2.532e-02 + Ca 2.502e-03 2.502e-03 + N 3.602e-03 3.602e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.029 Charge balance + pe = -2.819 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 1.074e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.570e-03 + Total CO2 (mol/kg) = 2.450e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 23 + Total H = 1.110473e+02 + Total O = 5.556816e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.028e-06 9.364e-07 -5.988 -6.029 -0.040 + OH- 1.191e-08 1.069e-08 -7.924 -7.971 -0.047 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +C(-4) 8.246e-04 + CH4 8.246e-04 8.266e-04 -3.084 -3.083 0.001 +C(4) 2.450e-02 + CO2 1.593e-02 1.597e-02 -1.798 -1.797 0.001 + HCO3- 8.400e-03 7.581e-03 -2.076 -2.120 -0.045 + CaHCO3+ 1.659e-04 1.497e-04 -3.780 -3.825 -0.045 + CaCO3 9.846e-07 9.870e-07 -6.007 -6.006 0.001 + CO3-2 5.724e-07 3.797e-07 -6.242 -6.421 -0.178 +Ca 2.502e-03 + Ca+2 2.335e-03 1.548e-03 -2.632 -2.810 -0.179 + CaHCO3+ 1.659e-04 1.497e-04 -3.780 -3.825 -0.045 + CaCO3 9.846e-07 9.870e-07 -6.007 -6.006 0.001 + CaOH+ 3.049e-10 2.741e-10 -9.516 -9.562 -0.046 +H(0) 5.380e-10 + H2 2.690e-10 2.697e-10 -9.570 -9.569 0.001 +N(-3) 3.566e-03 + NH4+ 3.564e-03 3.187e-03 -2.448 -2.497 -0.049 + NH3 1.935e-06 1.939e-06 -5.713 -5.712 0.001 +N(0) 3.526e-05 + N2 1.763e-05 1.767e-05 -4.754 -4.753 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.642 -61.690 -0.048 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.793 -83.841 -0.048 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.243 -73.242 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.89 -9.23 -8.34 CaCO3 + Calcite -0.75 -9.23 -8.48 CaCO3 + CH4(g) -0.22 -3.08 -2.86 CH4 + CO2(g) -0.33 -1.80 -1.47 CO2 + H2(g) -6.42 -9.57 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.49 -4.75 -3.26 N2 + NH3(g) -7.48 -5.71 1.77 NH3 + O2(g) -70.28 -73.24 -2.96 O2 + +Reaction step 11. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 5.000e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 1.10e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.24 5.791e-01 0.000e+00 2.609e-01 2.609e-01 +CO2(g) -0.31 4.862e-01 0.000e+00 2.191e-01 2.191e-01 +N2(g) -1.46 3.469e-02 0.000e+00 1.563e-02 1.563e-02 +NH3(g) -7.48 3.333e-08 0.000e+00 1.502e-08 1.502e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.600e-02 2.601e-02 + Ca 2.501e-03 2.502e-03 + N 3.730e-03 3.731e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.019 Charge balance + pe = -2.806 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 1.086e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 8.694e-03 + Total CO2 (mol/kg) = 2.520e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.094e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 23 + Total H = 1.110737e+02 + Total O = 5.558262e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.051e-06 9.573e-07 -5.978 -6.019 -0.041 + OH- 1.166e-08 1.045e-08 -7.933 -7.981 -0.047 + H2O 5.551e+01 9.995e-01 1.744 -0.000 0.000 +C(-4) 7.973e-04 + CH4 7.973e-04 7.993e-04 -3.098 -3.097 0.001 +C(4) 2.520e-02 + CO2 1.651e-02 1.655e-02 -1.782 -1.781 0.001 + HCO3- 8.522e-03 7.687e-03 -2.069 -2.114 -0.045 + CaHCO3+ 1.678e-04 1.513e-04 -3.775 -3.820 -0.045 + CaCO3 9.737e-07 9.761e-07 -6.012 -6.011 0.001 + CO3-2 5.689e-07 3.766e-07 -6.245 -6.424 -0.179 +Ca 2.501e-03 + Ca+2 2.333e-03 1.543e-03 -2.632 -2.812 -0.179 + CaHCO3+ 1.678e-04 1.513e-04 -3.775 -3.820 -0.045 + CaCO3 9.737e-07 9.761e-07 -6.012 -6.011 0.001 + CaOH+ 2.975e-10 2.673e-10 -9.527 -9.573 -0.046 +H(0) 5.287e-10 + H2 2.643e-10 2.650e-10 -9.578 -9.577 0.001 +N(-3) 3.691e-03 + NH4+ 3.690e-03 3.297e-03 -2.433 -2.482 -0.049 + NH3 1.958e-06 1.962e-06 -5.708 -5.707 0.001 +N(0) 3.804e-05 + N2 1.902e-05 1.907e-05 -4.721 -4.720 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.623 -61.671 -0.048 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.767 -83.815 -0.048 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.228 -73.227 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.90 -9.24 -8.34 CaCO3 + Calcite -0.76 -9.24 -8.48 CaCO3 + CH4(g) -0.24 -3.10 -2.86 CH4 + CO2(g) -0.31 -1.78 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.46 -4.72 -3.26 N2 + NH3(g) -7.48 -5.71 1.77 NH3 + O2(g) -70.27 -73.23 -2.96 O2 + +Reaction step 12. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed-pressure gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 2. + + 1.000e+00 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1000 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.24 5.692e-01 0.000e+00 5.241e-01 5.241e-01 +CO2(g) -0.31 4.949e-01 0.000e+00 4.557e-01 4.557e-01 +N2(g) -1.44 3.595e-02 0.000e+00 3.310e-02 3.310e-02 +NH3(g) -7.48 3.349e-08 0.000e+00 3.083e-08 3.083e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.634e-02 2.636e-02 + Ca 2.500e-03 2.502e-03 + N 3.791e-03 3.794e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.014 Charge balance + pe = -2.799 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 1.091e-02 + Mass of water (kg) = 1.001e+00 + Total alkalinity (eq/kg) = 8.752e-03 + Total CO2 (mol/kg) = 2.556e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.077e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 24 + Total H = 1.111262e+02 + Total O = 5.560955e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.063e-06 9.680e-07 -5.973 -6.014 -0.041 + OH- 1.153e-08 1.034e-08 -7.938 -7.986 -0.047 + H2O 5.551e+01 9.994e-01 1.744 -0.000 0.000 +C(-4) 7.837e-04 + CH4 7.837e-04 7.857e-04 -3.106 -3.105 0.001 +C(4) 2.556e-02 + CO2 1.681e-02 1.685e-02 -1.775 -1.773 0.001 + HCO3- 8.579e-03 7.737e-03 -2.067 -2.111 -0.045 + CaHCO3+ 1.686e-04 1.520e-04 -3.773 -3.818 -0.045 + CaCO3 9.674e-07 9.698e-07 -6.014 -6.013 0.001 + CO3-2 5.667e-07 3.748e-07 -6.247 -6.426 -0.180 +Ca 2.500e-03 + Ca+2 2.331e-03 1.540e-03 -2.633 -2.812 -0.180 + CaHCO3+ 1.686e-04 1.520e-04 -3.773 -3.818 -0.045 + CaCO3 9.674e-07 9.698e-07 -6.014 -6.013 0.001 + CaOH+ 2.937e-10 2.639e-10 -9.532 -9.579 -0.047 +H(0) 5.241e-10 + H2 2.621e-10 2.627e-10 -9.582 -9.581 0.001 +N(-3) 3.752e-03 + NH4+ 3.750e-03 3.350e-03 -2.426 -2.475 -0.049 + NH3 1.967e-06 1.972e-06 -5.706 -5.705 0.001 +N(0) 3.942e-05 + N2 1.971e-05 1.976e-05 -4.705 -4.704 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.614 -61.663 -0.048 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.754 -83.802 -0.048 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.221 -73.219 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.90 -9.24 -8.34 CaCO3 + Calcite -0.76 -9.24 -8.48 CaCO3 + CH4(g) -0.24 -3.10 -2.86 CH4 + CO2(g) -0.31 -1.77 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.44 -4.70 -3.26 N2 + NH3(g) -7.48 -5.71 1.77 NH3 + O2(g) -70.26 -73.22 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + USE solution 1 + USE reaction 1 + GAS_PHASE 1 Fixed volume gas phase + fixed_volume + volume 22.5 + CO2(g) 0.0 + CH4(g) 0.0 + N2(g) 0.0 + NH3(g) 0.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 1.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0024 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -3.24 5.712e-04 0.000e+00 5.253e-04 5.253e-04 +CO2(g) -2.76 1.756e-03 0.000e+00 1.615e-03 1.615e-03 +N2(g) -4.42 3.775e-05 0.000e+00 3.472e-05 3.472e-05 +NH3(g) -9.17 6.759e-10 0.000e+00 6.216e-10 6.216e-10 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.930e-03 4.930e-03 + Ca 2.502e-03 2.502e-03 + N 5.596e-07 5.596e-07 + +----------------------------Description of solution---------------------------- + + pH = 8.204 Charge balance + pe = -4.921 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.093e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.005e-03 + Total CO2 (mol/kg) = 4.930e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110125e+02 + Total O = 5.551863e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.754e-06 1.603e-06 -5.756 -5.795 -0.039 + H+ 6.760e-09 6.246e-09 -8.170 -8.204 -0.034 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 7.871e-07 + CH4 7.871e-07 7.884e-07 -6.104 -6.103 0.001 +C(4) 4.930e-03 + HCO3- 4.640e-03 4.258e-03 -2.334 -2.371 -0.037 + CaHCO3+ 9.719e-05 8.918e-05 -4.012 -4.050 -0.037 + CaCO3 8.803e-05 8.818e-05 -4.055 -4.055 0.001 + CO2 5.969e-05 5.979e-05 -4.224 -4.223 0.001 + CO3-2 4.508e-05 3.197e-05 -4.346 -4.495 -0.149 +Ca 2.502e-03 + Ca+2 2.317e-03 1.642e-03 -2.635 -2.785 -0.150 + CaHCO3+ 9.719e-05 8.918e-05 -4.012 -4.050 -0.037 + CaCO3 8.803e-05 8.818e-05 -4.055 -4.055 0.001 + CaOH+ 4.766e-08 4.362e-08 -7.322 -7.360 -0.038 +H(0) 3.826e-10 + H2 1.913e-10 1.916e-10 -9.718 -9.718 0.001 +N(-3) 5.182e-07 + NH4+ 4.784e-07 4.362e-07 -6.320 -6.360 -0.040 + NH3 3.974e-08 3.980e-08 -7.401 -7.400 0.001 +N(0) 4.143e-08 + N2 2.071e-08 2.075e-08 -7.684 -7.683 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.716 -60.756 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -82.719 -82.758 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -72.946 -72.945 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 1.06 -7.28 -8.34 CaCO3 + Calcite 1.20 -7.28 -8.48 CaCO3 + CH4(g) -3.24 -6.10 -2.86 CH4 + CO2(g) -2.76 -4.22 -1.47 CO2 + H2(g) -6.57 -9.72 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.42 -7.68 -3.26 N2 + NH3(g) -9.17 -7.40 1.77 NH3 + O2(g) -69.98 -72.94 -2.96 O2 + +Reaction step 2. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 2.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0034 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -2.94 1.142e-03 0.000e+00 1.051e-03 1.051e-03 +CO2(g) -2.65 2.226e-03 0.000e+00 2.047e-03 2.047e-03 +N2(g) -4.12 7.549e-05 0.000e+00 6.942e-05 6.942e-05 +NH3(g) -8.95 1.134e-09 0.000e+00 1.043e-09 1.043e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 4.973e-03 4.973e-03 + Ca 2.502e-03 2.502e-03 + N 1.156e-06 1.156e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.106 Charge balance + pe = -4.847 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.132e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.005e-03 + Total CO2 (mol/kg) = 4.972e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110127e+02 + Total O = 5.551877e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.399e-06 1.278e-06 -5.854 -5.893 -0.039 + H+ 8.478e-09 7.832e-09 -8.072 -8.106 -0.034 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 1.574e-06 + CH4 1.574e-06 1.577e-06 -5.803 -5.802 0.001 +C(4) 4.972e-03 + HCO3- 4.690e-03 4.303e-03 -2.329 -2.366 -0.037 + CaHCO3+ 9.880e-05 9.064e-05 -4.005 -4.043 -0.037 + CO2 7.565e-05 7.577e-05 -4.121 -4.120 0.001 + CaCO3 7.135e-05 7.146e-05 -4.147 -4.146 0.001 + CO3-2 3.636e-05 2.576e-05 -4.439 -4.589 -0.150 +Ca 2.502e-03 + Ca+2 2.332e-03 1.651e-03 -2.632 -2.782 -0.150 + CaHCO3+ 9.880e-05 9.064e-05 -4.005 -4.043 -0.037 + CaCO3 7.135e-05 7.146e-05 -4.147 -4.146 0.001 + CaOH+ 3.823e-08 3.498e-08 -7.418 -7.456 -0.039 +H(0) 4.288e-10 + H2 2.144e-10 2.148e-10 -9.669 -9.668 0.001 +N(-3) 1.074e-06 + NH4+ 1.007e-06 9.178e-07 -5.997 -6.037 -0.040 + NH3 6.667e-08 6.678e-08 -7.176 -7.175 0.001 +N(0) 8.283e-08 + N2 4.142e-08 4.148e-08 -7.383 -7.382 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.738 -60.778 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -82.790 -82.830 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.045 -73.044 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.96 -7.37 -8.34 CaCO3 + Calcite 1.11 -7.37 -8.48 CaCO3 + CH4(g) -2.94 -5.80 -2.86 CH4 + CO2(g) -2.65 -4.12 -1.47 CO2 + H2(g) -6.52 -9.67 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.12 -7.38 -3.26 N2 + NH3(g) -8.95 -7.18 1.77 NH3 + O2(g) -70.08 -73.04 -2.96 O2 + +Reaction step 3. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 3.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0045 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -2.77 1.713e-03 0.000e+00 1.576e-03 1.576e-03 +CO2(g) -2.57 2.703e-03 0.000e+00 2.486e-03 2.486e-03 +N2(g) -3.95 1.132e-04 0.000e+00 1.041e-04 1.041e-04 +NH3(g) -8.82 1.503e-09 0.000e+00 1.382e-09 1.382e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.009e-03 5.009e-03 + Ca 2.502e-03 2.502e-03 + N 1.822e-06 1.822e-06 + +----------------------------Description of solution---------------------------- + + pH = 8.025 Charge balance + pe = -4.777 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.159e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.006e-03 + Total CO2 (mol/kg) = 5.006e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.101e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 8 + Total H = 1.110128e+02 + Total O = 5.551889e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.160e-06 1.060e-06 -5.936 -5.975 -0.039 + H+ 1.023e-08 9.445e-09 -7.990 -8.025 -0.034 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 2.361e-06 + CH4 2.361e-06 2.365e-06 -5.627 -5.626 0.001 +C(4) 5.006e-03 + HCO3- 4.724e-03 4.334e-03 -2.326 -2.363 -0.037 + CaHCO3+ 9.991e-05 9.166e-05 -4.000 -4.038 -0.037 + CO2 9.189e-05 9.204e-05 -4.037 -4.036 0.001 + CaCO3 5.983e-05 5.992e-05 -4.223 -4.222 0.001 + CO3-2 3.039e-05 2.152e-05 -4.517 -4.667 -0.150 +Ca 2.502e-03 + Ca+2 2.342e-03 1.658e-03 -2.630 -2.781 -0.150 + CaHCO3+ 9.991e-05 9.166e-05 -4.000 -4.038 -0.037 + CaCO3 5.983e-05 5.992e-05 -4.223 -4.222 0.001 + CaOH+ 3.183e-08 2.912e-08 -7.497 -7.536 -0.039 +H(0) 4.521e-10 + H2 2.260e-10 2.264e-10 -9.646 -9.645 0.001 +N(-3) 1.698e-06 + NH4+ 1.609e-06 1.467e-06 -5.793 -5.834 -0.040 + NH3 8.836e-08 8.851e-08 -7.054 -7.053 0.001 +N(0) 1.242e-07 + N2 6.210e-08 6.220e-08 -7.207 -7.206 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.766 -60.806 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -82.841 -82.881 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.091 -73.090 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.89 -7.45 -8.34 CaCO3 + Calcite 1.03 -7.45 -8.48 CaCO3 + CH4(g) -2.77 -5.63 -2.86 CH4 + CO2(g) -2.57 -4.04 -1.47 CO2 + H2(g) -6.50 -9.65 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.95 -7.21 -3.26 N2 + NH3(g) -8.82 -7.05 1.77 NH3 + O2(g) -70.13 -73.09 -2.96 O2 + +Reaction step 4. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 4.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0056 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -2.64 2.285e-03 0.000e+00 2.101e-03 2.101e-03 +CO2(g) -2.50 3.186e-03 0.000e+00 2.930e-03 2.930e-03 +N2(g) -3.82 1.508e-04 0.000e+00 1.387e-04 1.387e-04 +NH3(g) -8.74 1.817e-09 0.000e+00 1.671e-09 1.671e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.040e-03 5.039e-03 + Ca 2.502e-03 2.502e-03 + N 2.554e-06 2.554e-06 + +----------------------------Description of solution---------------------------- + + pH = 7.956 Charge balance + pe = -4.715 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.179e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.007e-03 + Total CO2 (mol/kg) = 5.036e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.089e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 8 + Total H = 1.110129e+02 + Total O = 5.551900e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 9.896e-07 9.039e-07 -6.005 -6.044 -0.039 + H+ 1.199e-08 1.107e-08 -7.921 -7.956 -0.035 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 3.148e-06 + CH4 3.148e-06 3.154e-06 -5.502 -5.501 0.001 +C(4) 5.036e-03 + HCO3- 4.750e-03 4.357e-03 -2.323 -2.361 -0.038 + CO2 1.083e-04 1.085e-04 -3.965 -3.965 0.001 + CaHCO3+ 1.007e-04 9.240e-05 -3.997 -4.034 -0.038 + CaCO3 5.144e-05 5.153e-05 -4.289 -4.288 0.001 + CO3-2 2.607e-05 1.845e-05 -4.584 -4.734 -0.150 +Ca 2.502e-03 + Ca+2 2.350e-03 1.662e-03 -2.629 -2.779 -0.150 + CaHCO3+ 1.007e-04 9.240e-05 -3.997 -4.034 -0.038 + CaCO3 5.144e-05 5.153e-05 -4.289 -4.288 0.001 + CaOH+ 2.723e-08 2.491e-08 -7.565 -7.604 -0.039 +H(0) 4.662e-10 + H2 2.331e-10 2.335e-10 -9.632 -9.632 0.001 +N(-3) 2.389e-06 + NH4+ 2.282e-06 2.079e-06 -5.642 -5.682 -0.040 + NH3 1.068e-07 1.070e-07 -6.971 -6.971 0.001 +N(0) 1.655e-07 + N2 8.276e-08 8.289e-08 -7.082 -7.081 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.793 -60.833 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -82.881 -82.921 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.117 -73.117 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.82 -7.51 -8.34 CaCO3 + Calcite 0.97 -7.51 -8.48 CaCO3 + CH4(g) -2.64 -5.50 -2.86 CH4 + CO2(g) -2.50 -3.96 -1.47 CO2 + H2(g) -6.48 -9.63 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.82 -7.08 -3.26 N2 + NH3(g) -8.74 -6.97 1.77 NH3 + O2(g) -70.16 -73.12 -2.96 O2 + +Reaction step 5. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 8.000e-03 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0100 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -2.34 4.569e-03 0.000e+00 4.202e-03 4.202e-03 +CO2(g) -2.29 5.141e-03 0.000e+00 4.728e-03 4.728e-03 +N2(g) -3.52 3.012e-04 0.000e+00 2.770e-04 2.770e-04 +NH3(g) -8.56 2.783e-09 0.000e+00 2.559e-09 2.559e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.141e-03 5.141e-03 + Ca 2.502e-03 2.502e-03 + N 6.067e-06 6.067e-06 + +----------------------------Description of solution---------------------------- + + pH = 7.753 Charge balance + pe = -4.524 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.225e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.010e-03 + Total CO2 (mol/kg) = 5.135e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.182e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 8 + Total H = 1.110133e+02 + Total O = 5.551940e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 6.208e-07 5.669e-07 -6.207 -6.246 -0.039 + H+ 1.912e-08 1.766e-08 -7.718 -7.753 -0.035 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 6.296e-06 + CH4 6.296e-06 6.307e-06 -5.201 -5.200 0.001 +C(4) 5.135e-03 + HCO3- 4.808e-03 4.409e-03 -2.318 -2.356 -0.038 + CO2 1.748e-04 1.750e-04 -3.758 -3.757 0.001 + CaHCO3+ 1.026e-04 9.408e-05 -3.989 -4.027 -0.038 + CaCO3 3.285e-05 3.290e-05 -4.483 -4.483 0.001 + CO3-2 1.656e-05 1.171e-05 -4.781 -4.931 -0.150 +Ca 2.502e-03 + Ca+2 2.367e-03 1.673e-03 -2.626 -2.777 -0.151 + CaHCO3+ 1.026e-04 9.408e-05 -3.989 -4.027 -0.038 + CaCO3 3.285e-05 3.290e-05 -4.483 -4.483 0.001 + CaOH+ 1.719e-08 1.572e-08 -7.765 -7.804 -0.039 +H(0) 4.919e-10 + H2 2.459e-10 2.464e-10 -9.609 -9.608 0.001 +N(-3) 5.737e-06 + NH4+ 5.573e-06 5.077e-06 -5.254 -5.294 -0.040 + NH3 1.636e-07 1.639e-07 -6.786 -6.785 0.001 +N(0) 3.305e-07 + N2 1.652e-07 1.655e-07 -6.782 -6.781 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.880 -60.920 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -82.992 -83.032 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.164 -73.163 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.63 -7.71 -8.34 CaCO3 + Calcite 0.77 -7.71 -8.48 CaCO3 + CH4(g) -2.34 -5.20 -2.86 CH4 + CO2(g) -2.29 -3.76 -1.47 CO2 + H2(g) -6.46 -9.61 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.52 -6.78 -3.26 N2 + NH3(g) -8.56 -6.79 1.77 NH3 + O2(g) -70.20 -73.16 -2.96 O2 + +Reaction step 6. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 1.600e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0188 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -2.04 9.136e-03 0.000e+00 8.402e-03 8.402e-03 +CO2(g) -2.04 9.088e-03 0.000e+00 8.358e-03 8.358e-03 +N2(g) -3.22 6.006e-04 0.000e+00 5.523e-04 5.523e-04 +NH3(g) -8.39 4.116e-09 0.000e+00 3.786e-09 3.786e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.311e-03 5.311e-03 + Ca 2.502e-03 2.502e-03 + N 1.533e-05 1.533e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.510 Charge balance + pe = -4.288 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.265e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.019e-03 + Total CO2 (mol/kg) = 5.299e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 8 + Total H = 1.110142e+02 + Total O = 5.552014e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 3.548e-07 3.239e-07 -6.450 -6.490 -0.040 + H+ 3.347e-08 3.090e-08 -7.475 -7.510 -0.035 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 1.259e-05 + CH4 1.259e-05 1.261e-05 -4.900 -4.899 0.001 +C(4) 5.299e-03 + HCO3- 4.857e-03 4.453e-03 -2.314 -2.351 -0.038 + CO2 3.089e-04 3.094e-04 -3.510 -3.509 0.001 + CaHCO3+ 1.041e-04 9.544e-05 -3.983 -4.020 -0.038 + CaCO3 1.904e-05 1.907e-05 -4.720 -4.720 0.001 + CO3-2 9.566e-06 6.759e-06 -5.019 -5.170 -0.151 +Ca 2.502e-03 + Ca+2 2.379e-03 1.680e-03 -2.624 -2.775 -0.151 + CaHCO3+ 1.041e-04 9.544e-05 -3.983 -4.020 -0.038 + CaCO3 1.904e-05 1.907e-05 -4.720 -4.720 0.001 + CaOH+ 9.866e-09 9.021e-09 -8.006 -8.045 -0.039 +H(0) 5.073e-10 + H2 2.536e-10 2.541e-10 -9.596 -9.595 0.001 +N(-3) 1.467e-05 + NH4+ 1.443e-05 1.314e-05 -4.841 -4.881 -0.041 + NH3 2.420e-07 2.424e-07 -6.616 -6.615 0.001 +N(0) 6.590e-07 + N2 3.295e-07 3.301e-07 -6.482 -6.481 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -60.993 -61.033 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.118 -83.158 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.191 -73.190 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.39 -7.94 -8.34 CaCO3 + Calcite 0.53 -7.94 -8.48 CaCO3 + CH4(g) -2.04 -4.90 -2.86 CH4 + CO2(g) -2.04 -3.51 -1.47 CO2 + H2(g) -6.45 -9.60 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.22 -6.48 -3.26 N2 + NH3(g) -8.39 -6.62 1.77 NH3 + O2(g) -70.23 -73.19 -2.96 O2 + +Reaction step 7. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 3.200e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0365 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -1.74 1.827e-02 0.000e+00 1.680e-02 1.680e-02 +CO2(g) -1.77 1.701e-02 0.000e+00 1.564e-02 1.564e-02 +N2(g) -2.92 1.196e-03 0.000e+00 1.100e-03 1.100e-03 +NH3(g) -8.23 5.955e-09 0.000e+00 5.476e-09 5.476e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 5.630e-03 5.630e-03 + Ca 2.502e-03 2.502e-03 + N 4.035e-05 4.035e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.242 Charge balance + pe = -4.023 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.308e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.043e-03 + Total CO2 (mol/kg) = 5.605e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110160e+02 + Total O = 5.552158e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.915e-07 1.748e-07 -6.718 -6.757 -0.040 + H+ 6.203e-08 5.726e-08 -7.207 -7.242 -0.035 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 2.517e-05 + CH4 2.517e-05 2.522e-05 -4.599 -4.598 0.001 +C(4) 5.605e-03 + HCO3- 4.906e-03 4.497e-03 -2.309 -2.347 -0.038 + CO2 5.780e-04 5.790e-04 -3.238 -3.237 0.001 + CaHCO3+ 1.054e-04 9.659e-05 -3.977 -4.015 -0.038 + CaCO3 1.040e-05 1.042e-05 -4.983 -4.982 0.001 + CO3-2 5.218e-06 3.683e-06 -5.283 -5.434 -0.151 +Ca 2.502e-03 + Ca+2 2.386e-03 1.683e-03 -2.622 -2.774 -0.152 + CaHCO3+ 1.054e-04 9.659e-05 -3.977 -4.015 -0.038 + CaCO3 1.040e-05 1.042e-05 -4.983 -4.982 0.001 + CaOH+ 5.337e-09 4.879e-09 -8.273 -8.312 -0.039 +H(0) 5.158e-10 + H2 2.579e-10 2.583e-10 -9.589 -9.588 0.001 +N(-3) 3.904e-05 + NH4+ 3.869e-05 3.523e-05 -4.412 -4.453 -0.041 + NH3 3.501e-07 3.506e-07 -6.456 -6.455 0.001 +N(0) 1.312e-06 + N2 6.561e-07 6.572e-07 -6.183 -6.182 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.122 -61.162 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.254 -83.295 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.205 -73.204 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite 0.13 -8.21 -8.34 CaCO3 + Calcite 0.27 -8.21 -8.48 CaCO3 + CH4(g) -1.74 -4.60 -2.86 CH4 + CO2(g) -1.77 -3.24 -1.47 CO2 + H2(g) -6.44 -9.59 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.92 -6.18 -3.26 N2 + NH3(g) -8.23 -6.46 1.77 NH3 + O2(g) -70.24 -73.20 -2.96 O2 + +Reaction step 8. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 6.400e-02 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.0718 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -1.44 3.653e-02 0.000e+00 3.359e-02 3.359e-02 +CO2(g) -1.48 3.285e-02 0.000e+00 3.021e-02 3.021e-02 +N2(g) -2.62 2.377e-03 0.000e+00 2.186e-03 2.186e-03 +NH3(g) -8.07 8.504e-09 0.000e+00 7.820e-09 7.820e-09 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 6.268e-03 6.268e-03 + Ca 2.502e-03 2.502e-03 + N 1.082e-04 1.082e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.963 Charge balance + pe = -3.746 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.383e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.110e-03 + Total CO2 (mol/kg) = 6.217e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 12 + Total H = 1.110195e+02 + Total O = 5.552443e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.180e-07 1.089e-07 -6.928 -6.963 -0.035 + OH- 1.008e-07 9.192e-08 -6.997 -7.037 -0.040 + H2O 5.551e+01 9.999e-01 1.744 -0.000 0.000 +C(-4) 5.033e-05 + CH4 5.033e-05 5.042e-05 -4.298 -4.297 0.001 +C(4) 6.217e-03 + HCO3- 4.985e-03 4.568e-03 -2.302 -2.340 -0.038 + CO2 1.117e-03 1.118e-03 -2.952 -2.951 0.001 + CaHCO3+ 1.071e-04 9.809e-05 -3.970 -4.008 -0.038 + CaCO3 5.553e-06 5.563e-06 -5.255 -5.255 0.001 + CO3-2 2.791e-06 1.967e-06 -5.554 -5.706 -0.152 +Ca 2.502e-03 + Ca+2 2.389e-03 1.683e-03 -2.622 -2.774 -0.152 + CaHCO3+ 1.071e-04 9.809e-05 -3.970 -4.008 -0.038 + CaCO3 5.553e-06 5.563e-06 -5.255 -5.255 0.001 + CaOH+ 2.807e-09 2.565e-09 -8.552 -8.591 -0.039 +H(0) 5.202e-10 + H2 2.601e-10 2.605e-10 -9.585 -9.584 0.001 +N(-3) 1.056e-04 + NH4+ 1.051e-04 9.568e-05 -3.978 -4.019 -0.041 + NH3 4.999e-07 5.007e-07 -6.301 -6.300 0.001 +N(0) 2.608e-06 + N2 1.304e-06 1.306e-06 -5.885 -5.884 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.258 -61.298 -0.040 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.394 -83.434 -0.040 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.213 -73.212 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.14 -8.48 -8.34 CaCO3 + Calcite -0.00 -8.48 -8.48 CaCO3 + CH4(g) -1.44 -4.30 -2.86 CH4 + CO2(g) -1.48 -2.95 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.62 -5.88 -3.26 N2 + NH3(g) -8.07 -6.30 1.77 NH3 + O2(g) -70.25 -73.21 -2.96 O2 + +Reaction step 9. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 1.250e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.1390 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -1.15 7.131e-02 0.000e+00 6.558e-02 6.558e-02 +CO2(g) -1.20 6.304e-02 0.000e+00 5.798e-02 5.798e-02 +N2(g) -2.34 4.605e-03 0.000e+00 4.235e-03 4.235e-03 +NH3(g) -7.92 1.191e-08 0.000e+00 1.096e-08 1.096e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 7.514e-03 7.514e-03 + Ca 2.502e-03 2.502e-03 + N 2.794e-04 2.794e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.694 Charge balance + pe = -3.478 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.551e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.278e-03 + Total CO2 (mol/kg) = 7.416e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 18 + Total H = 1.110264e+02 + Total O = 5.552991e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.192e-07 2.021e-07 -6.659 -6.694 -0.035 + OH- 5.433e-08 4.952e-08 -7.265 -7.305 -0.040 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 9.827e-05 + CH4 9.827e-05 9.844e-05 -4.008 -4.007 0.001 +C(4) 7.416e-03 + HCO3- 5.158e-03 4.722e-03 -2.288 -2.326 -0.038 + CO2 2.143e-03 2.146e-03 -2.669 -2.668 0.001 + CaHCO3+ 1.103e-04 1.010e-04 -3.957 -3.996 -0.038 + CaCO3 3.080e-06 3.086e-06 -5.511 -5.511 0.001 + CO3-2 1.560e-06 1.096e-06 -5.807 -5.960 -0.153 +Ca 2.502e-03 + Ca+2 2.388e-03 1.677e-03 -2.622 -2.776 -0.154 + CaHCO3+ 1.103e-04 1.010e-04 -3.957 -3.996 -0.038 + CaCO3 3.080e-06 3.086e-06 -5.511 -5.511 0.001 + CaOH+ 1.508e-09 1.376e-09 -8.822 -8.861 -0.040 +H(0) 5.224e-10 + H2 2.612e-10 2.617e-10 -9.583 -9.582 0.001 +N(-3) 2.744e-04 + NH4+ 2.737e-04 2.488e-04 -3.563 -3.604 -0.041 + NH3 7.003e-07 7.015e-07 -6.155 -6.154 0.001 +N(0) 5.053e-06 + N2 2.526e-06 2.531e-06 -5.597 -5.597 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.385 -61.426 -0.041 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.523 -83.564 -0.041 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.216 -73.216 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.40 -8.74 -8.34 CaCO3 + Calcite -0.26 -8.74 -8.48 CaCO3 + CH4(g) -1.15 -4.01 -2.86 CH4 + CO2(g) -1.20 -2.67 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.34 -5.60 -3.26 N2 + NH3(g) -7.92 -6.15 1.77 NH3 + O2(g) -70.26 -73.22 -2.96 O2 + +Reaction step 10. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 2.500e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.2765 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.85 1.426e-01 0.000e+00 1.311e-01 1.311e-01 +CO2(g) -0.90 1.249e-01 0.000e+00 1.148e-01 1.148e-01 +N2(g) -2.04 9.123e-03 0.000e+00 8.390e-03 8.390e-03 +NH3(g) -7.77 1.683e-08 0.000e+00 1.547e-08 1.547e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.015e-02 1.015e-02 + Ca 2.502e-03 2.502e-03 + N 7.205e-04 7.206e-04 + +----------------------------Description of solution---------------------------- + + pH = 6.432 Charge balance + pe = -3.216 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 7.974e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.714e-03 + Total CO2 (mol/kg) = 9.953e-03 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.110405e+02 + Total O = 5.554122e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 4.021e-07 3.702e-07 -6.396 -6.432 -0.036 + OH- 2.973e-08 2.704e-08 -7.527 -7.568 -0.041 + H2O 5.551e+01 9.998e-01 1.744 -0.000 0.000 +C(-4) 1.964e-04 + CH4 1.964e-04 1.968e-04 -3.707 -3.706 0.001 +C(4) 9.953e-03 + HCO3- 5.589e-03 5.106e-03 -2.253 -2.292 -0.039 + CO2 4.243e-03 4.251e-03 -2.372 -2.372 0.001 + CaHCO3+ 1.182e-04 1.080e-04 -3.927 -3.967 -0.039 + CaCO3 1.798e-06 1.802e-06 -5.745 -5.744 0.001 + CO3-2 9.288e-07 6.469e-07 -6.032 -6.189 -0.157 +Ca 2.502e-03 + Ca+2 2.382e-03 1.658e-03 -2.623 -2.780 -0.157 + CaHCO3+ 1.182e-04 1.080e-04 -3.927 -3.967 -0.039 + CaCO3 1.798e-06 1.802e-06 -5.745 -5.744 0.001 + CaOH+ 8.158e-10 7.431e-10 -9.088 -9.129 -0.041 +H(0) 5.236e-10 + H2 2.618e-10 2.623e-10 -9.582 -9.581 0.001 +N(-3) 7.105e-04 + NH4+ 7.095e-04 6.436e-04 -3.149 -3.191 -0.042 + NH3 9.890e-07 9.908e-07 -6.005 -6.004 0.001 +N(0) 1.001e-05 + N2 5.004e-06 5.013e-06 -5.301 -5.300 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.500 -61.542 -0.042 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.639 -83.681 -0.042 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.219 -73.218 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.63 -8.97 -8.34 CaCO3 + Calcite -0.49 -8.97 -8.48 CaCO3 + CH4(g) -0.85 -3.71 -2.86 CH4 + CO2(g) -0.90 -2.37 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.04 -5.30 -3.26 N2 + NH3(g) -7.77 -6.00 1.77 NH3 + O2(g) -70.26 -73.22 -2.96 O2 + +Reaction step 11. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 5.000e-01 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 0.5515 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.55 2.850e-01 0.000e+00 2.621e-01 2.621e-01 +CO2(g) -0.60 2.484e-01 0.000e+00 2.284e-01 2.284e-01 +N2(g) -1.74 1.809e-02 0.000e+00 1.663e-02 1.663e-02 +NH3(g) -7.62 2.373e-08 0.000e+00 2.183e-08 2.183e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 1.554e-02 1.555e-02 + Ca 2.501e-03 2.502e-03 + N 1.731e-03 1.732e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.201 Charge balance + pe = -2.986 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 8.940e-03 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 6.713e-03 + Total CO2 (mol/kg) = 1.515e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 10 + Total H = 1.110691e+02 + Total O = 5.556400e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.859e-07 6.290e-07 -6.164 -6.201 -0.038 + OH- 1.758e-08 1.591e-08 -7.755 -7.798 -0.043 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +C(-4) 3.926e-04 + CH4 3.926e-04 3.934e-04 -3.406 -3.405 0.001 +C(4) 1.515e-02 + CO2 8.439e-03 8.457e-03 -2.074 -2.073 0.001 + HCO3- 6.573e-03 5.978e-03 -2.182 -2.223 -0.041 + CaHCO3+ 1.355e-04 1.233e-04 -3.868 -3.909 -0.041 + CaCO3 1.208e-06 1.210e-06 -5.918 -5.917 0.001 + CO3-2 6.516e-07 4.457e-07 -6.186 -6.351 -0.165 +Ca 2.501e-03 + Ca+2 2.364e-03 1.616e-03 -2.626 -2.792 -0.165 + CaHCO3+ 1.355e-04 1.233e-04 -3.868 -3.909 -0.041 + CaCO3 1.208e-06 1.210e-06 -5.918 -5.917 0.001 + CaOH+ 4.702e-10 4.262e-10 -9.328 -9.370 -0.043 +H(0) 5.241e-10 + H2 2.620e-10 2.626e-10 -9.582 -9.581 0.001 +N(-3) 1.711e-03 + NH4+ 1.710e-03 1.543e-03 -2.767 -2.812 -0.045 + NH3 1.395e-06 1.398e-06 -5.856 -5.855 0.001 +N(0) 1.984e-05 + N2 9.920e-06 9.940e-06 -5.004 -5.003 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.580 -61.624 -0.044 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.719 -83.764 -0.044 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.220 -73.219 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.81 -9.14 -8.34 CaCO3 + Calcite -0.66 -9.14 -8.48 CaCO3 + CH4(g) -0.55 -3.41 -2.86 CH4 + CO2(g) -0.60 -2.07 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.74 -5.00 -3.26 N2 + NH3(g) -7.62 -5.85 1.77 NH3 + O2(g) -70.26 -73.22 -2.96 O2 + +Reaction step 12. + +Using solution 1. Solution after simulation 1. +Using gas phase 1. Fixed volume gas phase +Using reaction 1. + +Reaction 1. Irreversible reaction defined in simulation 3. + + 1.000e+00 moles of the following reaction have been added: + + Relative + Reactant moles + + CH2O(NH3)0.07 1.00 + + Relative + Element moles + C 1.00 + H 2.21 + N 0.07 + O 1.00 + +-----------------------------------Gas phase----------------------------------- + + +Total pressure: 1.1013 atmospheres + Gas volume: 2.25e+01 liters + + Moles in gas + ---------------------------------- +Component log P P Initial Final Delta +CH4(g) -0.24 5.698e-01 0.000e+00 5.241e-01 5.241e-01 +CO2(g) -0.31 4.954e-01 0.000e+00 4.556e-01 4.556e-01 +N2(g) -1.44 3.599e-02 0.000e+00 3.310e-02 3.310e-02 +NH3(g) -7.47 3.351e-08 0.000e+00 3.081e-08 3.081e-08 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + C 2.636e-02 2.638e-02 + Ca 2.500e-03 2.502e-03 + N 3.796e-03 3.799e-03 + +----------------------------Description of solution---------------------------- + + pH = 6.014 Charge balance + pe = -2.799 Adjusted to redox equilibrium + Activity of water = 0.999 + Ionic strength = 1.092e-02 + Mass of water (kg) = 1.001e+00 + Total alkalinity (eq/kg) = 8.756e-03 + Total CO2 (mol/kg) = 2.558e-02 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.075e-10 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 13 + Total H = 1.111262e+02 + Total O = 5.560960e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.064e-06 9.687e-07 -5.973 -6.014 -0.041 + OH- 1.152e-08 1.033e-08 -7.938 -7.986 -0.048 + H2O 5.551e+01 9.994e-01 1.744 -0.000 0.000 +C(-4) 7.846e-04 + CH4 7.846e-04 7.866e-04 -3.105 -3.104 0.001 +C(4) 2.558e-02 + CO2 1.683e-02 1.687e-02 -1.774 -1.773 0.001 + HCO3- 8.584e-03 7.741e-03 -2.066 -2.111 -0.045 + CaHCO3+ 1.687e-04 1.521e-04 -3.773 -3.818 -0.045 + CaCO3 9.672e-07 9.696e-07 -6.014 -6.013 0.001 + CO3-2 5.667e-07 3.748e-07 -6.247 -6.426 -0.180 +Ca 2.500e-03 + Ca+2 2.330e-03 1.540e-03 -2.633 -2.812 -0.180 + CaHCO3+ 1.687e-04 1.521e-04 -3.773 -3.818 -0.045 + CaCO3 9.672e-07 9.696e-07 -6.014 -6.013 0.001 + CaOH+ 2.935e-10 2.637e-10 -9.532 -9.579 -0.047 +H(0) 5.241e-10 + H2 2.621e-10 2.627e-10 -9.582 -9.581 0.001 +N(-3) 3.756e-03 + NH4+ 3.754e-03 3.354e-03 -2.425 -2.474 -0.049 + NH3 1.968e-06 1.973e-06 -5.706 -5.705 0.001 +N(0) 3.946e-05 + N2 1.973e-05 1.978e-05 -4.705 -4.704 0.001 +N(3) 0.000e+00 + NO2- 0.000e+00 0.000e+00 -61.615 -61.663 -0.048 +N(5) 0.000e+00 + NO3- 0.000e+00 0.000e+00 -83.754 -83.802 -0.048 +O(0) 0.000e+00 + O2 0.000e+00 0.000e+00 -73.221 -73.219 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Aragonite -0.90 -9.24 -8.34 CaCO3 + Calcite -0.76 -9.24 -8.48 CaCO3 + CH4(g) -0.24 -3.10 -2.86 CH4 + CO2(g) -0.31 -1.77 -1.47 CO2 + H2(g) -6.43 -9.58 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -1.44 -4.70 -3.26 N2 + NH3(g) -7.47 -5.70 1.77 NH3 + O2(g) -70.26 -73.22 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex7.sel b/Sun/examples/ex7.sel new file mode 100644 index 00000000..e4582478 --- /dev/null +++ b/Sun/examples/ex7.sel @@ -0,0 +1,27 @@ + sim state reaction si_CO2(g) si_CH4(g) si_N2(g) si_NH3(g) pressure total mol volume g_CO2(g) g_CH4(g) g_N2(g) g_NH3(g) + 1 i_soln -99 -999.9990 -999.9990 -999.9990 -999.9990 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 1 react -99 -1.5000 -26.2591 -999.9990 -999.9990 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 2 react 1.0000e-03 -1.3544 -0.4402 -3.8961 -8.3809 1.1000e+00 1.0000e-25 2.2242e-24 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 2 react 2.0000e-03 -1.2453 -0.1392 -3.6436 -8.1826 1.1000e+00 1.0000e-25 2.2242e-24 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 2 react 3.0000e-03 -1.1592 0.0130 -3.5015 -8.0869 1.1000e+00 8.5793e-05 1.9082e-03 5.4061e-06 8.0362e-05 2.4578e-08 6.3856e-13 + 2 react 4.0000e-03 -1.0929 0.0081 -3.3212 -8.0234 1.1000e+00 6.4416e-04 1.4327e-02 4.7279e-05 5.9660e-04 2.7953e-07 5.5492e-12 + 2 react 8.0000e-03 -0.9101 -0.0107 -2.9007 -7.8887 1.1000e+00 2.9972e-03 6.6664e-02 3.3511e-04 2.6587e-03 3.4247e-06 3.5204e-11 + 2 react 1.6000e-02 -0.7156 -0.0438 -2.4738 -7.7606 1.1000e+00 8.2421e-03 1.8332e-01 1.4423e-03 6.7746e-03 2.5169e-05 1.3002e-10 + 2 react 3.2000e-02 -0.5438 -0.0941 -2.0462 -7.6302 1.1000e+00 2.0521e-02 4.5644e-01 5.3332e-03 1.5021e-02 1.6775e-04 4.3718e-10 + 2 react 6.4000e-02 -0.4248 -0.1517 -1.7252 -7.5359 1.1000e+00 4.9404e-02 1.0988e+00 1.6888e-02 3.1671e-02 8.4558e-04 1.3075e-09 + 2 react 1.2500e-01 -0.3613 -0.1954 -1.5662 -7.4966 1.1000e+00 1.0982e-01 2.4427e+00 4.3447e-02 6.3666e-02 2.7111e-03 3.1820e-09 + 2 react 2.5000e-01 -0.3288 -0.2227 -1.4927 -7.4823 1.1000e+00 2.3770e-01 5.2868e+00 1.0135e-01 1.2940e-01 6.9491e-03 7.1171e-09 + 2 react 5.0000e-01 -0.3131 -0.2373 -1.4597 -7.4772 1.1000e+00 4.9570e-01 1.1025e+01 2.1912e-01 2.6094e-01 1.5635e-02 1.5019e-08 + 2 react 1.0000e+00 -0.3055 -0.2448 -1.4443 -7.4751 1.1000e+00 1.0128e+00 2.2527e+01 4.5565e-01 5.2406e-01 3.3103e-02 3.0832e-08 + 3 react 1.0000e-03 -2.7554 -3.2432 -4.4230 -9.1701 2.3652e-03 2.1751e-03 2.2500e+01 1.6151e-03 5.2527e-04 3.4720e-05 6.2162e-10 + 3 react 2.0000e-03 -2.6525 -2.9422 -4.1221 -8.9453 3.4435e-03 3.1668e-03 2.2500e+01 2.0468e-03 1.0505e-03 6.9421e-05 1.0430e-09 + 3 react 3.0000e-03 -2.5681 -2.7661 -3.9462 -8.8230 4.5301e-03 4.1661e-03 2.2500e+01 2.4862e-03 1.5758e-03 1.0409e-04 1.3823e-09 + 3 react 4.0000e-03 -2.4967 -2.6412 -3.8215 -8.7406 5.6217e-03 5.1699e-03 2.2500e+01 2.9303e-03 2.1010e-03 1.3872e-04 1.6713e-09 + 3 react 8.0000e-03 -2.2889 -2.3402 -3.5212 -8.5555 1.0011e-02 9.2068e-03 2.2500e+01 4.7283e-03 4.2016e-03 2.7697e-04 2.5595e-09 + 3 react 1.6000e-02 -2.0415 -2.0392 -3.2214 -8.3855 1.8825e-02 1.7312e-02 2.2500e+01 8.3576e-03 8.4019e-03 5.5233e-04 3.7856e-09 + 3 react 3.2000e-02 -1.7694 -1.7383 -2.9223 -8.2251 3.6471e-02 3.3540e-02 2.2500e+01 1.5640e-02 1.6800e-02 1.0998e-03 5.4762e-09 + 3 react 6.4000e-02 -1.4834 -1.4374 -2.6240 -8.0704 7.1755e-02 6.5989e-02 2.2500e+01 3.0213e-02 3.3590e-02 2.1859e-03 7.8205e-09 + 3 react 1.2500e-01 -1.2004 -1.1468 -2.3367 -7.9240 1.3896e-01 1.2779e-01 2.2500e+01 5.7976e-02 6.5580e-02 4.2353e-03 1.0956e-08 + 3 react 2.5000e-01 -0.9036 -0.8460 -2.0399 -7.7740 2.7653e-01 2.5431e-01 2.2500e+01 1.1482e-01 1.3110e-01 8.3897e-03 1.5474e-08 + 3 react 5.0000e-01 -0.6049 -0.5452 -1.7426 -7.6246 5.5147e-01 5.0716e-01 2.2500e+01 2.2843e-01 2.6209e-01 1.6634e-02 2.1827e-08 + 3 react 1.0000e+00 -0.3050 -0.2442 -1.4438 -7.4749 1.1013e+00 1.0128e+00 2.2500e+01 4.5563e-01 5.2406e-01 3.3101e-02 3.0813e-08 diff --git a/Sun/examples/ex8.log b/Sun/examples/ex8.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex8.out b/Sun/examples/ex8.out new file mode 100644 index 00000000..5afdec15 --- /dev/null +++ b/Sun/examples/ex8.out @@ -0,0 +1,3612 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex8 + Output file: ex8.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 8.--Sorption of zinc on hydrous + iron oxides. + SURFACE_SPECIES + Hfo_sOH + H+ = Hfo_sOH2+ + log_k 7.18 + Hfo_sOH = Hfo_sO- + H+ + log_k -8.82 + Hfo_sOH + Zn+2 = Hfo_sOZn+ + H+ + log_k 0.66 + Hfo_wOH + H+ = Hfo_wOH2+ + log_k 7.18 + Hfo_wOH = Hfo_wO- + H+ + log_k -8.82 + Hfo_wOH + Zn+2 = Hfo_wOZn+ + H+ + log_k -2.32 + SURFACE 1 + Hfo_sOH 5e-6 600. 0.09 + Hfo_wOH 2e-4 + SOLUTION 1 + units mmol/kgw + pH 8.0 + Zn 0.0001 + Na 100. charge + N(5) 100. + SOLUTION 2 + units mmol/kgw + pH 8.0 + Zn 0.1 + Na 100. charge + N(5) 100. + USE solution none + PHASES + Fix_H+ + H+ = H+ + log_k 0.0 + END +----- +TITLE +----- + + Example 8.--Sorption of zinc on hydrous + iron oxides. + +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N(5) 1.000e-01 1.000e-01 + Na 1.000e-01 1.000e-01 Charge balance + Zn 1.000e-07 1.000e-07 + +----------------------------Description of solution---------------------------- + + pH = 8.000 + pe = 4.000 + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.361e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.936e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 9 + Total H = 1.110124e+02 + Total O = 5.580622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-06 9.977e-07 -5.883 -6.001 -0.118 + H+ 1.211e-08 1.000e-08 -7.917 -8.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 1.384e-27 + H2 6.918e-28 7.079e-28 -27.160 -27.150 0.010 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 1.000e-01 + Na+ 1.000e-01 7.829e-02 -1.000 -1.106 -0.106 + NaOH 5.038e-08 5.155e-08 -7.298 -7.288 0.010 +O(0) 1.615e-38 + O2 8.073e-39 8.261e-39 -38.093 -38.083 0.010 +Zn 1.000e-07 + Zn+2 9.102e-08 3.428e-08 -7.041 -7.465 -0.424 + ZnOH+ 4.793e-09 3.746e-09 -8.319 -8.426 -0.107 + Zn(OH)2 4.189e-09 4.286e-09 -8.378 -8.368 0.010 + Zn(OH)3- 1.729e-12 1.351e-12 -11.762 -11.869 -0.107 + Zn(OH)4-2 5.721e-17 2.134e-17 -16.243 -16.671 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -8.00 -8.00 0.00 H+ + H2(g) -24.00 -27.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -35.12 -38.08 -2.96 O2 + Zn(OH)2(e) -2.97 8.53 11.50 Zn(OH)2 + +Initial solution 2. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N(5) 1.000e-01 1.000e-01 + Na 9.981e-02 9.981e-02 Charge balance + Zn 1.000e-04 1.000e-04 + +----------------------------Description of solution---------------------------- + + pH = 8.000 + pe = 4.000 + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.452e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 7.433e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 9 + Total H = 1.110124e+02 + Total O = 5.580623e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-06 9.977e-07 -5.883 -6.001 -0.118 + H+ 1.211e-08 1.000e-08 -7.917 -8.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 1.384e-27 + H2 6.918e-28 7.079e-28 -27.160 -27.150 0.010 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.981e-02 + Na+ 9.981e-02 7.814e-02 -1.001 -1.107 -0.106 + NaOH 5.028e-08 5.145e-08 -7.299 -7.289 0.010 +O(0) 1.615e-38 + O2 8.073e-39 8.261e-39 -38.093 -38.083 0.010 +Zn 1.000e-04 + Zn+2 9.102e-05 3.427e-05 -4.041 -4.465 -0.424 + ZnOH+ 4.792e-06 3.745e-06 -5.319 -5.427 -0.107 + Zn(OH)2 4.187e-06 4.285e-06 -5.378 -5.368 0.010 + Zn(OH)3- 1.728e-09 1.350e-09 -8.762 -8.870 -0.107 + Zn(OH)4-2 5.721e-14 2.133e-14 -13.243 -13.671 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -8.00 -8.00 0.00 H+ + H2(g) -24.00 -27.15 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + O2(g) -35.12 -38.08 -2.96 O2 + Zn(OH)2(e) 0.03 11.53 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SELECTED_OUTPUT + file ex8.sel + molalities Zn+2 Hfo_wOZn+ Hfo_sOZn+ + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.00 -5.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.273e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 1.123e-04 Surface charge, eq + 2.007e-01 sigma, C/m**2 + 1.228e-01 psi, V + -4.778e+00 -F*psi/RT + 8.410e-03 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH2+ 2.778e-06 0.556 2.778e-06 -5.556 + Hfo_sOH 2.182e-06 0.436 2.182e-06 -5.661 + Hfo_sO- 3.928e-08 0.008 3.928e-08 -7.406 + Hfo_sOZn+ 3.150e-10 0.000 3.150e-10 -9.502 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH2+ 1.111e-04 0.556 1.111e-04 -3.954 + Hfo_wOH 8.730e-05 0.437 8.730e-05 -4.059 + Hfo_wO- 1.571e-06 0.008 1.571e-06 -5.804 + Hfo_wOZn+ 1.319e-11 0.000 1.319e-11 -10.880 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.987e-02 9.987e-02 + Zn 9.967e-08 9.967e-08 + +----------------------------Description of solution---------------------------- + + pH = 5.000 Charge balance + pe = 15.095 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.994e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.211e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.123e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.06 + Iterations = 17 + Total H = 1.110122e+02 + Total O = 5.580609e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.211e-05 1.000e-05 -4.917 -5.000 -0.083 + OH- 1.309e-09 9.977e-10 -8.883 -9.001 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.349 -43.339 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -52.670 -52.798 -0.128 + NH3 0.000e+00 0.000e+00 -57.052 -57.042 0.010 +N(0) 1.543e-06 + N2 7.717e-07 7.897e-07 -6.113 -6.103 0.010 +N(3) 2.412e-13 + NO2- 2.412e-13 1.818e-13 -12.618 -12.740 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.987e-02 + Na+ 9.987e-02 7.819e-02 -1.001 -1.107 -0.106 + NaOH 5.032e-11 5.149e-11 -10.298 -10.288 0.010 +O(0) 3.859e-06 + O2 1.929e-06 1.974e-06 -5.715 -5.705 0.010 +Zn 9.967e-08 + Zn+2 9.967e-08 3.754e-08 -7.001 -7.425 -0.424 + ZnOH+ 5.250e-12 4.103e-12 -11.280 -11.387 -0.107 + Zn(OH)2 4.588e-15 4.695e-15 -14.338 -14.328 0.010 + Zn(OH)3- 1.893e-21 1.479e-21 -20.723 -20.830 -0.107 + Zn(OH)4-2 6.265e-29 2.337e-29 -28.203 -28.631 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.00 -5.00 0.00 H+ + H2(g) -40.19 -43.34 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.84 -6.10 -3.26 N2 + NH3(g) -58.81 -57.04 1.77 NH3 + O2(g) -2.74 -5.70 -2.96 O2 + Zn(OH)2(e) -8.93 2.57 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.25 -5.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.060e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 9.671e-05 Surface charge, eq + 1.728e-01 sigma, C/m**2 + 1.152e-01 psi, V + -4.485e+00 -F*psi/RT + 1.127e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 2.520e-06 0.504 2.520e-06 -5.599 + Hfo_sOH2+ 2.419e-06 0.484 2.419e-06 -5.616 + Hfo_sO- 6.017e-08 0.012 6.017e-08 -7.221 + Hfo_sOZn+ 8.622e-10 0.000 8.622e-10 -9.064 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.008e-04 0.504 1.008e-04 -3.996 + Hfo_wOH2+ 9.676e-05 0.484 9.676e-05 -4.014 + Hfo_wO- 2.407e-06 0.012 2.407e-06 -5.618 + Hfo_wOZn+ 3.612e-11 0.000 3.612e-11 -10.442 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.990e-02 9.990e-02 + Zn 9.910e-08 9.910e-08 + +----------------------------Description of solution---------------------------- + + pH = 5.250 Charge balance + pe = 14.809 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.995e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.809e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -9.671e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 17 + Total H = 1.110122e+02 + Total O = 5.580611e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.812e-06 5.623e-06 -5.167 -5.250 -0.083 + OH- 2.329e-09 1.774e-09 -8.633 -8.751 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.278 -43.268 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -52.884 -53.012 -0.128 + NH3 0.000e+00 0.000e+00 -57.017 -57.007 0.010 +N(0) 1.111e-06 + N2 5.554e-07 5.683e-07 -6.255 -6.245 0.010 +N(3) 2.843e-13 + NO2- 2.843e-13 2.143e-13 -12.546 -12.669 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.990e-02 + Na+ 9.990e-02 7.821e-02 -1.000 -1.107 -0.106 + NaOH 8.949e-11 9.158e-11 -10.048 -10.038 0.010 +O(0) 2.777e-06 + O2 1.388e-06 1.421e-06 -5.857 -5.847 0.010 +Zn 9.910e-08 + Zn+2 9.909e-08 3.733e-08 -7.004 -7.428 -0.424 + ZnOH+ 9.281e-12 7.254e-12 -11.032 -11.139 -0.107 + Zn(OH)2 1.442e-14 1.476e-14 -13.841 -13.831 0.010 + Zn(OH)3- 1.058e-20 8.272e-21 -19.975 -20.082 -0.107 + Zn(OH)4-2 6.228e-28 2.323e-28 -27.206 -27.634 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.25 -5.25 0.00 H+ + H2(g) -40.12 -43.27 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.99 -6.25 -3.26 N2 + NH3(g) -58.78 -57.01 1.77 NH3 + O2(g) -2.89 -5.85 -2.96 O2 + Zn(OH)2(e) -8.43 3.07 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 4. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.50 -5.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 8.815e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 8.217e-05 Surface charge, eq + 1.468e-01 sigma, C/m**2 + 1.071e-01 psi, V + -4.168e+00 -F*psi/RT + 1.549e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 2.820e-06 0.564 2.820e-06 -5.550 + Hfo_sOH2+ 2.090e-06 0.418 2.090e-06 -5.680 + Hfo_sO- 8.716e-08 0.017 8.716e-08 -7.060 + Hfo_sOZn+ 2.320e-09 0.000 2.320e-09 -8.635 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.129e-04 0.564 1.129e-04 -3.947 + Hfo_wOH2+ 8.365e-05 0.418 8.365e-05 -4.078 + Hfo_wO- 3.488e-06 0.017 3.488e-06 -5.457 + Hfo_wOZn+ 9.722e-11 0.000 9.722e-11 -10.012 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.991e-02 9.991e-02 + Zn 9.758e-08 9.758e-08 + +----------------------------Description of solution---------------------------- + + pH = 5.500 Charge balance + pe = 14.523 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.996e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.826e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -8.217e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.04 + Iterations = 16 + Total H = 1.110123e+02 + Total O = 5.580613e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.830e-06 3.162e-06 -5.417 -5.500 -0.083 + OH- 4.141e-09 3.155e-09 -8.383 -8.501 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.206 -43.196 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.099 -53.227 -0.128 + NH3 0.000e+00 0.000e+00 -56.981 -56.971 0.010 +N(0) 7.994e-07 + N2 3.997e-07 4.090e-07 -6.398 -6.388 0.010 +N(3) 3.351e-13 + NO2- 3.351e-13 2.526e-13 -12.475 -12.598 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.991e-02 + Na+ 9.991e-02 7.822e-02 -1.000 -1.107 -0.106 + NaOH 1.592e-10 1.629e-10 -9.798 -9.788 0.010 +O(0) 1.998e-06 + O2 9.992e-07 1.023e-06 -6.000 -5.990 0.010 +Zn 9.758e-08 + Zn+2 9.757e-08 3.675e-08 -7.011 -7.435 -0.424 + ZnOH+ 1.625e-11 1.270e-11 -10.789 -10.896 -0.107 + Zn(OH)2 4.491e-14 4.595e-14 -13.348 -13.338 0.010 + Zn(OH)3- 5.860e-20 4.580e-20 -19.232 -19.339 -0.107 + Zn(OH)4-2 6.133e-27 2.288e-27 -26.212 -26.641 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.50 -5.50 0.00 H+ + H2(g) -40.05 -43.20 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.13 -6.39 -3.26 N2 + NH3(g) -58.74 -56.97 1.77 NH3 + O2(g) -3.03 -5.99 -2.96 O2 + Zn(OH)2(e) -7.94 3.56 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 5. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.75 -5.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 7.298e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 6.891e-05 Surface charge, eq + 1.231e-01 sigma, C/m**2 + 9.836e-02 psi, V + -3.829e+00 -F*psi/RT + 2.174e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.075e-06 0.615 3.075e-06 -5.512 + Hfo_sOH2+ 1.799e-06 0.360 1.799e-06 -5.745 + Hfo_sO- 1.204e-07 0.024 1.204e-07 -6.919 + Hfo_sOZn+ 6.061e-09 0.001 6.061e-09 -8.217 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.231e-04 0.616 1.231e-04 -3.910 + Hfo_wOH2+ 7.205e-05 0.360 7.205e-05 -4.142 + Hfo_wO- 4.821e-06 0.024 4.821e-06 -5.317 + Hfo_wOZn+ 2.542e-10 0.000 2.542e-10 -9.595 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.993e-02 9.993e-02 + Zn 9.368e-08 9.368e-08 + +----------------------------Description of solution---------------------------- + + pH = 5.750 Charge balance + pe = 14.237 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.997e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -2.146e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.891e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.03 + Iterations = 15 + Total H = 1.110123e+02 + Total O = 5.580615e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.154e-06 1.778e-06 -5.667 -5.750 -0.083 + OH- 7.364e-09 5.610e-09 -8.133 -8.251 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.135 -43.125 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.313 -53.441 -0.128 + NH3 0.000e+00 0.000e+00 -56.945 -56.935 0.010 +N(0) 5.753e-07 + N2 2.877e-07 2.944e-07 -6.541 -6.531 0.010 +N(3) 3.950e-13 + NO2- 3.950e-13 2.977e-13 -12.403 -12.526 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.993e-02 + Na+ 9.993e-02 7.824e-02 -1.000 -1.107 -0.106 + NaOH 2.831e-10 2.897e-10 -9.548 -9.538 0.010 +O(0) 1.438e-06 + O2 7.191e-07 7.359e-07 -6.143 -6.133 0.010 +Zn 9.368e-08 + Zn+2 9.366e-08 3.528e-08 -7.028 -7.452 -0.424 + ZnOH+ 2.774e-11 2.168e-11 -10.557 -10.664 -0.107 + Zn(OH)2 1.363e-13 1.395e-13 -12.865 -12.855 0.010 + Zn(OH)3- 3.163e-19 2.472e-19 -18.500 -18.607 -0.107 + Zn(OH)4-2 5.887e-26 2.196e-26 -25.230 -25.658 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.75 -5.75 0.00 H+ + H2(g) -39.97 -43.12 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.27 -6.53 -3.26 N2 + NH3(g) -58.71 -56.94 1.77 NH3 + O2(g) -3.17 -6.13 -2.96 O2 + Zn(OH)2(e) -7.46 4.04 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 6. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.00 -6.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 5.997e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 5.703e-05 Surface charge, eq + 1.019e-01 sigma, C/m**2 + 8.913e-02 psi, V + -3.469e+00 -F*psi/RT + 3.114e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.280e-06 0.656 3.280e-06 -5.484 + Hfo_sOH2+ 1.546e-06 0.309 1.546e-06 -5.811 + Hfo_sO- 1.594e-07 0.032 1.594e-07 -6.797 + Hfo_sOZn+ 1.486e-08 0.003 1.486e-08 -7.828 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.316e-04 0.658 1.316e-04 -3.881 + Hfo_wOH2+ 6.202e-05 0.310 6.202e-05 -4.207 + Hfo_wO- 6.395e-06 0.032 6.395e-06 -5.194 + Hfo_wOZn+ 6.241e-10 0.000 6.241e-10 -9.205 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.994e-02 9.994e-02 + Zn 8.452e-08 8.452e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.000 Charge balance + pe = 13.952 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.997e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.198e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.703e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.03 + Iterations = 15 + Total H = 1.110123e+02 + Total O = 5.580616e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.211e-06 1.000e-06 -5.917 -6.000 -0.083 + OH- 1.310e-08 9.977e-09 -7.883 -8.001 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.063 -43.053 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.527 -53.655 -0.128 + NH3 0.000e+00 0.000e+00 -56.909 -56.899 0.010 +N(0) 4.140e-07 + N2 2.070e-07 2.118e-07 -6.684 -6.674 0.010 +N(3) 4.656e-13 + NO2- 4.656e-13 3.509e-13 -12.332 -12.455 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.994e-02 + Na+ 9.994e-02 7.824e-02 -1.000 -1.107 -0.106 + NaOH 5.035e-10 5.152e-10 -9.298 -9.288 0.010 +O(0) 1.035e-06 + O2 5.176e-07 5.296e-07 -6.286 -6.276 0.010 +Zn 8.452e-08 + Zn+2 8.448e-08 3.182e-08 -7.073 -7.497 -0.424 + ZnOH+ 4.449e-11 3.477e-11 -10.352 -10.459 -0.107 + Zn(OH)2 3.888e-13 3.979e-13 -12.410 -12.400 0.010 + Zn(OH)3- 1.604e-18 1.254e-18 -17.795 -17.902 -0.107 + Zn(OH)4-2 5.310e-25 1.981e-25 -24.275 -24.703 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.00 -6.00 0.00 H+ + H2(g) -39.90 -43.05 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.41 -6.67 -3.26 N2 + NH3(g) -58.67 -56.90 1.77 NH3 + O2(g) -3.32 -6.28 -2.96 O2 + Zn(OH)2(e) -7.00 4.50 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 7. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.25 -6.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 4.875e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 4.650e-05 Surface charge, eq + 8.309e-02 sigma, C/m**2 + 7.940e-02 psi, V + -3.091e+00 -F*psi/RT + 4.547e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.435e-06 0.687 3.435e-06 -5.464 + Hfo_sOH2+ 1.330e-06 0.266 1.330e-06 -5.876 + Hfo_sO- 2.033e-07 0.041 2.033e-07 -6.692 + Hfo_sOZn+ 3.190e-08 0.006 3.190e-08 -7.496 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.383e-04 0.691 1.383e-04 -3.859 + Hfo_wOH2+ 5.352e-05 0.268 5.352e-05 -4.271 + Hfo_wO- 8.186e-06 0.041 8.186e-06 -5.087 + Hfo_wOZn+ 1.345e-09 0.000 1.345e-09 -8.871 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.995e-02 9.995e-02 + Zn 6.676e-08 6.676e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.250 Charge balance + pe = 13.666 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.998e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.569e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -4.650e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 14 + Total H = 1.110123e+02 + Total O = 5.580617e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.812e-07 5.623e-07 -6.167 -6.250 -0.083 + OH- 2.329e-08 1.774e-08 -7.633 -7.751 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.992 -42.982 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.742 -53.869 -0.128 + NH3 0.000e+00 0.000e+00 -56.874 -56.864 0.010 +N(0) 2.980e-07 + N2 1.490e-07 1.525e-07 -6.827 -6.817 0.010 +N(3) 5.488e-13 + NO2- 5.488e-13 4.137e-13 -12.261 -12.383 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.995e-02 + Na+ 9.995e-02 7.825e-02 -1.000 -1.106 -0.106 + NaOH 8.954e-10 9.163e-10 -9.048 -9.038 0.010 +O(0) 7.449e-07 + O2 3.725e-07 3.811e-07 -6.429 -6.419 0.010 +Zn 6.676e-08 + Zn+2 6.670e-08 2.512e-08 -7.176 -7.600 -0.424 + ZnOH+ 6.247e-11 4.882e-11 -10.204 -10.311 -0.107 + Zn(OH)2 9.707e-13 9.933e-13 -12.013 -12.003 0.010 + Zn(OH)3- 7.123e-18 5.567e-18 -17.147 -17.254 -0.107 + Zn(OH)4-2 4.192e-24 1.564e-24 -23.378 -23.806 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.25 -6.25 0.00 H+ + H2(g) -39.83 -42.98 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.56 -6.82 -3.26 N2 + NH3(g) -58.63 -56.86 1.77 NH3 + O2(g) -3.46 -6.42 -2.96 O2 + Zn(OH)2(e) -6.60 4.90 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 8. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.50 -6.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 3.904e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 3.724e-05 Surface charge, eq + 6.654e-02 sigma, C/m**2 + 6.920e-02 psi, V + -2.694e+00 -F*psi/RT + 6.764e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.546e-06 0.709 3.546e-06 -5.450 + Hfo_sOH2+ 1.148e-06 0.230 1.148e-06 -5.940 + Hfo_sO- 2.509e-07 0.050 2.509e-07 -6.600 + Hfo_sOZn+ 5.526e-08 0.011 5.526e-08 -7.258 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.434e-04 0.717 1.434e-04 -3.843 + Hfo_wOH2+ 4.643e-05 0.232 4.643e-05 -4.333 + Hfo_wO- 1.015e-05 0.051 1.015e-05 -4.994 + Hfo_wOZn+ 2.341e-09 0.000 2.341e-09 -8.631 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.996e-02 9.996e-02 + Zn 4.239e-08 4.239e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.500 Charge balance + pe = 13.380 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.998e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.400e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.724e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580618e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.831e-07 3.162e-07 -6.417 -6.500 -0.083 + OH- 4.141e-08 3.155e-08 -7.383 -7.501 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.921 -42.911 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.956 -54.084 -0.128 + NH3 0.000e+00 0.000e+00 -56.838 -56.828 0.010 +N(0) 2.145e-07 + N2 1.072e-07 1.097e-07 -6.970 -6.960 0.010 +N(3) 6.470e-13 + NO2- 6.470e-13 4.876e-13 -12.189 -12.312 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.996e-02 + Na+ 9.996e-02 7.826e-02 -1.000 -1.106 -0.106 + NaOH 1.592e-09 1.630e-09 -8.798 -8.788 0.010 +O(0) 5.361e-07 + O2 2.681e-07 2.743e-07 -6.572 -6.562 0.010 +Zn 4.239e-08 + Zn+2 4.232e-08 1.594e-08 -7.373 -7.797 -0.424 + ZnOH+ 7.049e-11 5.509e-11 -10.152 -10.259 -0.107 + Zn(OH)2 1.948e-12 1.993e-12 -11.710 -11.700 0.010 + Zn(OH)3- 2.542e-17 1.986e-17 -16.595 -16.702 -0.107 + Zn(OH)4-2 2.660e-23 9.922e-24 -22.575 -23.003 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.50 -6.50 0.00 H+ + H2(g) -39.76 -42.91 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.70 -6.96 -3.26 N2 + NH3(g) -58.60 -56.83 1.77 NH3 + O2(g) -3.60 -6.56 -2.96 O2 + Zn(OH)2(e) -6.30 5.20 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 9. +------------------------------------ + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.75 -6.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 3.063e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.913e-05 Surface charge, eq + 5.205e-02 sigma, C/m**2 + 5.854e-02 psi, V + -2.278e+00 -F*psi/RT + 1.024e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.624e-06 0.725 3.624e-06 -5.441 + Hfo_sOH2+ 9.992e-07 0.200 9.992e-07 -6.000 + Hfo_sO- 3.011e-07 0.060 3.011e-07 -6.521 + Hfo_sOZn+ 7.566e-08 0.015 7.566e-08 -7.121 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.472e-04 0.736 1.472e-04 -3.832 + Hfo_wOH2+ 4.058e-05 0.203 4.058e-05 -4.392 + Hfo_wO- 1.223e-05 0.061 1.223e-05 -4.913 + Hfo_wOZn+ 3.218e-09 0.000 3.218e-09 -8.492 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.997e-02 9.997e-02 + Zn 2.112e-08 2.112e-08 + +----------------------------Description of solution---------------------------- + + pH = 6.750 Charge balance + pe = 13.095 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.999e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.389e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.913e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580619e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.154e-07 1.778e-07 -6.667 -6.750 -0.083 + OH- 7.364e-08 5.610e-08 -7.133 -7.251 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.849 -42.839 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.170 -54.298 -0.128 + NH3 0.000e+00 0.000e+00 -56.802 -56.792 0.010 +N(0) 1.543e-07 + N2 7.717e-08 7.897e-08 -7.113 -7.103 0.010 +N(3) 7.626e-13 + NO2- 7.626e-13 5.748e-13 -12.118 -12.240 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.997e-02 + Na+ 9.997e-02 7.827e-02 -1.000 -1.106 -0.106 + NaOH 2.832e-09 2.898e-09 -8.548 -8.538 0.010 +O(0) 3.858e-07 + O2 1.929e-07 1.974e-07 -6.715 -6.705 0.010 +Zn 2.112e-08 + Zn+2 2.105e-08 7.929e-09 -7.677 -8.101 -0.424 + ZnOH+ 6.235e-11 4.872e-11 -10.205 -10.312 -0.107 + Zn(OH)2 3.064e-12 3.135e-12 -11.514 -11.504 0.010 + Zn(OH)3- 7.110e-17 5.556e-17 -16.148 -16.255 -0.107 + Zn(OH)4-2 1.323e-22 4.935e-23 -21.878 -22.307 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.75 -6.75 0.00 H+ + H2(g) -39.69 -42.84 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.84 -7.10 -3.26 N2 + NH3(g) -58.56 -56.79 1.77 NH3 + O2(g) -3.74 -6.70 -2.96 O2 + Zn(OH)2(e) -6.10 5.40 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 10. +------------------------------------- + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.00 -7.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 2.330e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.203e-05 Surface charge, eq + 3.936e-02 sigma, C/m**2 + 4.744e-02 psi, V + -1.847e+00 -F*psi/RT + 1.578e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.681e-06 0.736 3.681e-06 -5.434 + Hfo_sOH2+ 8.789e-07 0.176 8.789e-07 -6.056 + Hfo_sO- 3.531e-07 0.071 3.531e-07 -6.452 + Hfo_sOZn+ 8.747e-08 0.017 8.747e-08 -7.058 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.498e-04 0.749 1.498e-04 -3.824 + Hfo_wOH2+ 3.578e-05 0.179 3.578e-05 -4.446 + Hfo_wO- 1.437e-05 0.072 1.437e-05 -4.842 + Hfo_wOZn+ 3.729e-09 0.000 3.729e-09 -8.428 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.998e-02 9.998e-02 + Zn 8.799e-09 8.799e-09 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 12.809 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.999e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.491e-08 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.203e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580619e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-07 9.977e-08 -6.883 -7.001 -0.118 + H+ 1.211e-07 1.000e-07 -6.917 -7.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.778 -42.768 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.384 -54.512 -0.128 + NH3 0.000e+00 0.000e+00 -56.767 -56.757 0.010 +N(0) 1.111e-07 + N2 5.554e-08 5.683e-08 -7.255 -7.245 0.010 +N(3) 8.990e-13 + NO2- 8.990e-13 6.775e-13 -12.046 -12.169 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.998e-02 + Na+ 9.998e-02 7.827e-02 -1.000 -1.106 -0.106 + NaOH 5.037e-09 5.154e-09 -8.298 -8.288 0.010 +O(0) 2.777e-07 + O2 1.388e-07 1.421e-07 -6.857 -6.847 0.010 +Zn 8.799e-09 + Zn+2 8.749e-09 3.295e-09 -8.058 -8.482 -0.424 + ZnOH+ 4.608e-11 3.601e-11 -10.336 -10.444 -0.107 + Zn(OH)2 4.027e-12 4.121e-12 -11.395 -11.385 0.010 + Zn(OH)3- 1.662e-16 1.299e-16 -15.779 -15.887 -0.107 + Zn(OH)4-2 5.499e-22 2.051e-22 -21.260 -21.688 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.00 -7.00 0.00 H+ + H2(g) -39.62 -42.77 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.99 -7.25 -3.26 N2 + NH3(g) -58.53 -56.76 1.77 NH3 + O2(g) -3.89 -6.85 -2.96 O2 + Zn(OH)2(e) -5.99 5.51 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 11. +------------------------------------- + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.25 -7.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.683e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 1.576e-05 Surface charge, eq + 2.816e-02 sigma, C/m**2 + 3.596e-02 psi, V + -1.400e+00 -F*psi/RT + 2.467e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.720e-06 0.744 3.720e-06 -5.429 + Hfo_sOH2+ 7.810e-07 0.156 7.810e-07 -6.107 + Hfo_sO- 4.060e-07 0.081 4.060e-07 -6.392 + Hfo_sOZn+ 9.271e-08 0.019 9.271e-08 -7.033 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.516e-04 0.758 1.516e-04 -3.819 + Hfo_wOH2+ 3.183e-05 0.159 3.183e-05 -4.497 + Hfo_wO- 1.655e-05 0.083 1.655e-05 -4.781 + Hfo_wOZn+ 3.956e-09 0.000 3.956e-09 -8.403 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.998e-02 9.998e-02 + Zn 3.336e-09 3.336e-09 + +----------------------------Description of solution---------------------------- + + pH = 7.250 Charge balance + pe = 12.523 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 9.999e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.738e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.576e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580620e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.329e-07 1.774e-07 -6.633 -6.751 -0.118 + H+ 6.812e-08 5.623e-08 -7.167 -7.250 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.706 -42.696 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.599 -54.727 -0.128 + NH3 0.000e+00 0.000e+00 -56.731 -56.721 0.010 +N(0) 7.994e-08 + N2 3.997e-08 4.090e-08 -7.398 -7.388 0.010 +N(3) 1.060e-12 + NO2- 1.060e-12 7.987e-13 -11.975 -12.098 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.998e-02 + Na+ 9.998e-02 7.828e-02 -1.000 -1.106 -0.106 + NaOH 8.957e-09 9.166e-09 -8.048 -8.038 0.010 +O(0) 1.998e-07 + O2 9.992e-08 1.022e-07 -7.000 -6.990 0.010 +Zn 3.336e-09 + Zn+2 3.300e-09 1.243e-09 -8.481 -8.906 -0.424 + ZnOH+ 3.091e-11 2.415e-11 -10.510 -10.617 -0.107 + Zn(OH)2 4.803e-12 4.915e-12 -11.319 -11.309 0.010 + Zn(OH)3- 3.524e-16 2.754e-16 -15.453 -15.560 -0.107 + Zn(OH)4-2 2.074e-21 7.736e-22 -20.683 -21.111 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.25 -7.25 0.00 H+ + H2(g) -39.55 -42.70 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.13 -7.39 -3.26 N2 + NH3(g) -58.49 -56.72 1.77 NH3 + O2(g) -4.03 -6.99 -2.96 O2 + Zn(OH)2(e) -5.91 5.59 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 12. +------------------------------------- + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.50 -7.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.097e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 1.014e-05 Surface charge, eq + 1.812e-02 sigma, C/m**2 + 2.417e-02 psi, V + -9.409e-01 -F*psi/RT + 3.903e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.746e-06 0.749 3.746e-06 -5.426 + Hfo_sOH2+ 6.998e-07 0.140 6.998e-07 -6.155 + Hfo_sO- 4.594e-07 0.092 4.594e-07 -6.338 + Hfo_sOZn+ 9.474e-08 0.019 9.474e-08 -7.023 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.527e-04 0.764 1.527e-04 -3.816 + Hfo_wOH2+ 2.853e-05 0.143 2.853e-05 -4.545 + Hfo_wO- 1.873e-05 0.094 1.873e-05 -4.727 + Hfo_wOZn+ 4.045e-09 0.000 4.045e-09 -8.393 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.999e-02 9.999e-02 + Zn 1.216e-09 1.216e-09 + +----------------------------Description of solution---------------------------- + + pH = 7.500 Charge balance + pe = 12.237 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.918e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.014e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580621e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.141e-07 3.155e-07 -6.383 -6.501 -0.118 + H+ 3.831e-08 3.162e-08 -7.417 -7.500 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.635 -42.625 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.813 -54.941 -0.128 + NH3 0.000e+00 0.000e+00 -56.695 -56.685 0.010 +N(0) 5.753e-08 + N2 2.876e-08 2.943e-08 -7.541 -7.531 0.010 +N(3) 1.249e-12 + NO2- 1.249e-12 9.414e-13 -11.903 -12.026 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.999e-02 + Na+ 9.999e-02 7.828e-02 -1.000 -1.106 -0.106 + NaOH 1.593e-08 1.630e-08 -7.798 -7.788 0.010 +O(0) 1.438e-07 + O2 7.191e-08 7.359e-08 -7.143 -7.133 0.010 +Zn 1.216e-09 + Zn+2 1.190e-09 4.483e-10 -8.924 -9.348 -0.424 + ZnOH+ 1.982e-11 1.549e-11 -10.703 -10.810 -0.107 + Zn(OH)2 5.478e-12 5.606e-12 -11.261 -11.251 0.010 + Zn(OH)3- 7.149e-16 5.587e-16 -15.146 -15.253 -0.107 + Zn(OH)4-2 7.481e-21 2.790e-21 -20.126 -20.554 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.50 -7.50 0.00 H+ + H2(g) -39.47 -42.62 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.27 -7.53 -3.26 N2 + NH3(g) -58.46 -56.69 1.77 NH3 + O2(g) -4.17 -7.13 -2.96 O2 + Zn(OH)2(e) -5.85 5.65 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 13. +------------------------------------- + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.75 -7.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 5.425e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 4.965e-06 Surface charge, eq + 8.872e-03 sigma, C/m**2 + 1.217e-02 psi, V + -4.735e-01 -F*psi/RT + 6.228e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.760e-06 0.752 3.760e-06 -5.425 + Hfo_sOH2+ 6.303e-07 0.126 6.303e-07 -6.200 + Hfo_sO- 5.139e-07 0.103 5.139e-07 -6.289 + Hfo_sOZn+ 9.548e-08 0.019 9.548e-08 -7.020 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.533e-04 0.767 1.533e-04 -3.814 + Hfo_wOH2+ 2.570e-05 0.129 2.570e-05 -4.590 + Hfo_wO- 2.096e-05 0.105 2.096e-05 -4.679 + Hfo_wOZn+ 4.077e-09 0.000 4.077e-09 -8.390 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 1.000e-01 1.000e-01 + Zn 4.397e-10 4.397e-10 + +----------------------------Description of solution---------------------------- + + pH = 7.750 Charge balance + pe = 11.952 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 7.432e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -4.965e-06 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580621e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.364e-07 5.610e-07 -6.133 -6.251 -0.118 + H+ 2.154e-08 1.778e-08 -7.667 -7.750 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.563 -42.553 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -55.027 -55.155 -0.128 + NH3 0.000e+00 0.000e+00 -56.659 -56.649 0.010 +N(0) 4.140e-08 + N2 2.070e-08 2.118e-08 -7.684 -7.674 0.010 +N(3) 1.472e-12 + NO2- 1.472e-12 1.110e-12 -11.832 -11.955 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 1.000e-01 + Na+ 1.000e-01 7.829e-02 -1.000 -1.106 -0.106 + NaOH 2.833e-08 2.899e-08 -7.548 -7.538 0.010 +O(0) 1.035e-07 + O2 5.175e-08 5.296e-08 -7.286 -7.276 0.010 +Zn 4.397e-10 + Zn+2 4.211e-10 1.586e-10 -9.376 -9.800 -0.424 + ZnOH+ 1.247e-11 9.747e-12 -10.904 -11.011 -0.107 + Zn(OH)2 6.129e-12 6.272e-12 -11.213 -11.203 0.010 + Zn(OH)3- 1.422e-15 1.112e-15 -14.847 -14.954 -0.107 + Zn(OH)4-2 2.647e-20 9.873e-21 -19.577 -20.006 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.75 -7.75 0.00 H+ + H2(g) -39.40 -42.55 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.41 -7.67 -3.26 N2 + NH3(g) -58.42 -56.65 1.77 NH3 + O2(g) -4.32 -7.28 -2.96 O2 + Zn(OH)2(e) -5.80 5.70 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 14. +------------------------------------- + + USE solution 1 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -8.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 1. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -8.00 -8.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -1.388e-07 + +------------------------------Surface composition------------------------------ + +Hfo + 1.788e-08 Surface charge, eq + 3.195e-05 sigma, C/m**2 + 4.422e-05 psi, V + -1.721e-03 -F*psi/RT + 9.983e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 3.765e-06 0.753 3.765e-06 -5.424 + Hfo_sO- 5.708e-07 0.114 5.708e-07 -6.244 + Hfo_sOH2+ 5.688e-07 0.114 5.688e-07 -6.245 + Hfo_sOZn+ 9.575e-08 0.019 9.575e-08 -7.019 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.535e-04 0.768 1.535e-04 -3.814 + Hfo_wO- 2.328e-05 0.116 2.328e-05 -4.633 + Hfo_wOH2+ 2.320e-05 0.116 2.320e-05 -4.635 + Hfo_wOZn+ 4.089e-09 0.000 4.089e-09 -8.388 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 1.000e-01 1.000e-01 + Zn 1.626e-10 1.626e-10 + +----------------------------Description of solution---------------------------- + + pH = 8.000 Charge balance + pe = 11.666 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.348e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.788e-08 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 14 + Total H = 1.110124e+02 + Total O = 5.580622e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-06 9.977e-07 -5.883 -6.001 -0.118 + H+ 1.211e-08 1.000e-08 -7.917 -8.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.492 -42.482 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -55.242 -55.369 -0.128 + NH3 0.000e+00 0.000e+00 -56.624 -56.614 0.010 +N(0) 2.980e-08 + N2 1.490e-08 1.525e-08 -7.827 -7.817 0.010 +N(3) 1.736e-12 + NO2- 1.736e-12 1.308e-12 -11.761 -11.883 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 1.000e-01 + Na+ 1.000e-01 7.829e-02 -1.000 -1.106 -0.106 + NaOH 5.038e-08 5.155e-08 -7.298 -7.288 0.010 +O(0) 7.449e-08 + O2 3.725e-08 3.811e-08 -7.429 -7.419 0.010 +Zn 1.626e-10 + Zn+2 1.480e-10 5.574e-11 -9.830 -10.254 -0.424 + ZnOH+ 7.794e-12 6.091e-12 -11.108 -11.215 -0.107 + Zn(OH)2 6.811e-12 6.969e-12 -11.167 -11.157 0.010 + Zn(OH)3- 2.811e-15 2.196e-15 -14.551 -14.658 -0.107 + Zn(OH)4-2 9.302e-20 3.469e-20 -19.031 -19.460 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -8.00 -8.00 0.00 H+ + H2(g) -39.33 -42.48 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.56 -7.82 -3.26 N2 + NH3(g) -58.38 -56.61 1.77 NH3 + O2(g) -4.46 -7.42 -2.96 O2 + Zn(OH)2(e) -5.76 5.74 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 15. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.00 -5.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.399e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 1.124e-04 Surface charge, eq + 2.008e-01 sigma, C/m**2 + 1.228e-01 psi, V + -4.779e+00 -F*psi/RT + 8.404e-03 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH2+ 2.613e-06 0.523 2.613e-06 -5.583 + Hfo_sOH 2.054e-06 0.411 2.054e-06 -5.687 + Hfo_sOZn+ 2.962e-07 0.059 2.962e-07 -6.528 + Hfo_sO- 3.700e-08 0.007 3.700e-08 -7.432 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH2+ 1.111e-04 0.555 1.111e-04 -3.954 + Hfo_wOH 8.733e-05 0.437 8.733e-05 -4.059 + Hfo_wO- 1.573e-06 0.008 1.573e-06 -5.803 + Hfo_wOZn+ 1.319e-08 0.000 1.319e-08 -7.880 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.967e-02 9.967e-02 + Zn 9.969e-05 9.969e-05 + +----------------------------Description of solution---------------------------- + + pH = 5.000 Charge balance + pe = 15.095 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.211e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.124e-04 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.06 + Iterations = 21 + Total H = 1.110122e+02 + Total O = 5.580609e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.211e-05 1.000e-05 -4.917 -5.000 -0.083 + OH- 1.310e-09 9.977e-10 -8.883 -9.001 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.349 -43.339 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -52.670 -52.798 -0.128 + NH3 0.000e+00 0.000e+00 -57.052 -57.042 0.010 +N(0) 1.543e-06 + N2 7.716e-07 7.896e-07 -6.113 -6.103 0.010 +N(3) 2.412e-13 + NO2- 2.412e-13 1.818e-13 -12.618 -12.741 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.967e-02 + Na+ 9.967e-02 7.803e-02 -1.001 -1.108 -0.106 + NaOH 5.021e-11 5.138e-11 -10.299 -10.289 0.010 +O(0) 3.858e-06 + O2 1.929e-06 1.974e-06 -5.715 -5.705 0.010 +Zn 9.969e-05 + Zn+2 9.969e-05 3.754e-05 -4.001 -4.426 -0.424 + ZnOH+ 5.249e-09 4.102e-09 -8.280 -8.387 -0.107 + Zn(OH)2 4.587e-12 4.694e-12 -11.338 -11.328 0.010 + Zn(OH)3- 1.893e-18 1.479e-18 -17.723 -17.830 -0.107 + Zn(OH)4-2 6.266e-26 2.337e-26 -25.203 -25.631 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.00 -5.00 0.00 H+ + H2(g) -40.19 -43.34 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.84 -6.10 -3.26 N2 + NH3(g) -58.81 -57.04 1.77 NH3 + O2(g) -2.74 -5.70 -2.96 O2 + Zn(OH)2(e) -5.93 5.57 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 16. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.25 -5.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.178e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 9.693e-05 Surface charge, eq + 1.732e-01 sigma, C/m**2 + 1.153e-01 psi, V + -4.489e+00 -F*psi/RT + 1.124e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 2.154e-06 0.431 2.154e-06 -5.667 + Hfo_sOH2+ 2.060e-06 0.412 2.060e-06 -5.686 + Hfo_sOZn+ 7.349e-07 0.147 7.349e-07 -6.134 + Hfo_sO- 5.159e-08 0.010 5.159e-08 -7.287 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.010e-04 0.505 1.010e-04 -3.996 + Hfo_wOH2+ 9.657e-05 0.483 9.657e-05 -4.015 + Hfo_wO- 2.419e-06 0.012 2.419e-06 -5.616 + Hfo_wOZn+ 3.608e-08 0.000 3.608e-08 -7.443 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.970e-02 9.970e-02 + Zn 9.923e-05 9.923e-05 + +----------------------------Description of solution---------------------------- + + pH = 5.250 Charge balance + pe = 14.809 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -6.800e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -9.693e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.05 + Iterations = 21 + Total H = 1.110122e+02 + Total O = 5.580611e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.812e-06 5.623e-06 -5.167 -5.250 -0.083 + OH- 2.329e-09 1.774e-09 -8.633 -8.751 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.278 -43.268 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -52.884 -53.012 -0.128 + NH3 0.000e+00 0.000e+00 -57.017 -57.007 0.010 +N(0) 1.111e-06 + N2 5.553e-07 5.683e-07 -6.255 -6.245 0.010 +N(3) 2.843e-13 + NO2- 2.843e-13 2.142e-13 -12.546 -12.669 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.970e-02 + Na+ 9.970e-02 7.805e-02 -1.001 -1.108 -0.106 + NaOH 8.931e-11 9.139e-11 -10.049 -10.039 0.010 +O(0) 2.777e-06 + O2 1.388e-06 1.421e-06 -5.858 -5.848 0.010 +Zn 9.923e-05 + Zn+2 9.922e-05 3.736e-05 -4.003 -4.428 -0.424 + ZnOH+ 9.291e-09 7.261e-09 -8.032 -8.139 -0.107 + Zn(OH)2 1.444e-11 1.477e-11 -10.841 -10.831 0.010 + Zn(OH)3- 1.060e-17 8.280e-18 -16.975 -17.082 -0.107 + Zn(OH)4-2 6.236e-25 2.326e-25 -24.205 -24.633 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.25 -5.25 0.00 H+ + H2(g) -40.12 -43.27 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -2.99 -6.25 -3.26 N2 + NH3(g) -58.78 -57.01 1.77 NH3 + O2(g) -2.89 -5.85 -2.96 O2 + Zn(OH)2(e) -5.43 6.07 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 17. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.50 -5.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 9.839e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 8.263e-05 Surface charge, eq + 1.476e-01 sigma, C/m**2 + 1.073e-01 psi, V + -4.178e+00 -F*psi/RT + 1.533e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOH 1.934e-06 0.387 1.934e-06 -5.714 + Hfo_sOZn+ 1.587e-06 0.317 1.587e-06 -5.800 + Hfo_sOH2+ 1.419e-06 0.284 1.419e-06 -5.848 + Hfo_sO- 6.036e-08 0.012 6.036e-08 -7.219 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.132e-04 0.566 1.132e-04 -3.946 + Hfo_wOH2+ 8.312e-05 0.416 8.312e-05 -4.080 + Hfo_wO- 3.535e-06 0.018 3.535e-06 -5.452 + Hfo_wOZn+ 9.730e-08 0.000 9.730e-08 -7.012 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.972e-02 9.972e-02 + Zn 9.832e-05 9.832e-05 + +----------------------------Description of solution---------------------------- + + pH = 5.500 Charge balance + pe = 14.523 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -3.810e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -8.263e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.04 + Iterations = 21 + Total H = 1.110123e+02 + Total O = 5.580613e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.831e-06 3.162e-06 -5.417 -5.500 -0.083 + OH- 4.141e-09 3.155e-09 -8.383 -8.501 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.206 -43.196 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.099 -53.227 -0.128 + NH3 0.000e+00 0.000e+00 -56.981 -56.971 0.010 +N(0) 7.994e-07 + N2 3.997e-07 4.090e-07 -6.398 -6.388 0.010 +N(3) 3.351e-13 + NO2- 3.351e-13 2.525e-13 -12.475 -12.598 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.972e-02 + Na+ 9.972e-02 7.806e-02 -1.001 -1.108 -0.106 + NaOH 1.588e-10 1.625e-10 -9.799 -9.789 0.010 +O(0) 1.998e-06 + O2 9.991e-07 1.022e-06 -6.000 -5.990 0.010 +Zn 9.832e-05 + Zn+2 9.830e-05 3.702e-05 -4.007 -4.432 -0.424 + ZnOH+ 1.637e-08 1.279e-08 -7.786 -7.893 -0.107 + Zn(OH)2 4.523e-11 4.628e-11 -10.345 -10.335 0.010 + Zn(OH)3- 5.903e-17 4.613e-17 -16.229 -16.336 -0.107 + Zn(OH)4-2 6.178e-24 2.304e-24 -23.209 -23.638 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.50 -5.50 0.00 H+ + H2(g) -40.05 -43.20 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.13 -6.39 -3.26 N2 + NH3(g) -58.74 -56.97 1.77 NH3 + O2(g) -3.03 -5.99 -2.96 O2 + Zn(OH)2(e) -4.93 6.57 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 18. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -5.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -5.75 -5.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 8.089e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 6.973e-05 Surface charge, eq + 1.246e-01 sigma, C/m**2 + 9.892e-02 psi, V + -3.850e+00 -F*psi/RT + 2.127e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 2.766e-06 0.553 2.766e-06 -5.558 + Hfo_sOH 1.385e-06 0.277 1.385e-06 -5.858 + Hfo_sOH2+ 7.933e-07 0.159 7.933e-07 -6.101 + Hfo_sO- 5.543e-08 0.011 5.543e-08 -7.256 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.239e-04 0.619 1.239e-04 -3.907 + Hfo_wOH2+ 7.092e-05 0.355 7.092e-05 -4.149 + Hfo_wO- 4.955e-06 0.025 4.955e-06 -5.305 + Hfo_wOZn+ 2.589e-07 0.001 2.589e-07 -6.587 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.973e-02 9.973e-02 + Zn 9.698e-05 9.698e-05 + +----------------------------Description of solution---------------------------- + + pH = 5.750 Charge balance + pe = 14.237 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -2.117e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -6.973e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.03 + Iterations = 21 + Total H = 1.110123e+02 + Total O = 5.580615e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.154e-06 1.778e-06 -5.667 -5.750 -0.083 + OH- 7.365e-09 5.610e-09 -8.133 -8.251 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.135 -43.125 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.313 -53.441 -0.128 + NH3 0.000e+00 0.000e+00 -56.945 -56.935 0.010 +N(0) 5.754e-07 + N2 2.877e-07 2.944e-07 -6.541 -6.531 0.010 +N(3) 3.950e-13 + NO2- 3.950e-13 2.977e-13 -12.403 -12.526 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.973e-02 + Na+ 9.973e-02 7.808e-02 -1.001 -1.107 -0.106 + NaOH 2.825e-10 2.891e-10 -9.549 -9.539 0.010 +O(0) 1.438e-06 + O2 7.190e-07 7.358e-07 -6.143 -6.133 0.010 +Zn 9.698e-05 + Zn+2 9.695e-05 3.651e-05 -4.013 -4.438 -0.424 + ZnOH+ 2.871e-08 2.243e-08 -7.542 -7.649 -0.107 + Zn(OH)2 1.411e-10 1.443e-10 -9.851 -9.841 0.010 + Zn(OH)3- 3.274e-16 2.558e-16 -15.485 -15.592 -0.107 + Zn(OH)4-2 6.093e-23 2.272e-23 -22.215 -22.644 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -5.75 -5.75 0.00 H+ + H2(g) -39.97 -43.12 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.27 -6.53 -3.26 N2 + NH3(g) -58.71 -56.94 1.77 NH3 + O2(g) -3.17 -6.13 -2.96 O2 + Zn(OH)2(e) -4.44 7.06 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 19. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.00 -6.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 6.529e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 5.823e-05 Surface charge, eq + 1.041e-01 sigma, C/m**2 + 9.012e-02 psi, V + -3.508e+00 -F*psi/RT + 2.996e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 3.830e-06 0.766 3.830e-06 -5.417 + Hfo_sOH 7.781e-07 0.156 7.781e-07 -6.109 + Hfo_sOH2+ 3.529e-07 0.071 3.529e-07 -6.452 + Hfo_sO- 3.930e-08 0.008 3.930e-08 -7.406 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.325e-04 0.663 1.325e-04 -3.878 + Hfo_wOH2+ 6.010e-05 0.301 6.010e-05 -4.221 + Hfo_wO- 6.694e-06 0.033 6.694e-06 -5.174 + Hfo_wOZn+ 6.830e-07 0.003 6.830e-07 -6.166 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.975e-02 9.975e-02 + Zn 9.549e-05 9.549e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.000 Charge balance + pe = 13.952 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.147e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -5.823e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.03 + Iterations = 21 + Total H = 1.110123e+02 + Total O = 5.580617e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.211e-06 1.000e-06 -5.917 -6.000 -0.083 + OH- 1.310e-08 9.977e-09 -7.883 -8.001 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -43.063 -43.053 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.527 -53.655 -0.128 + NH3 0.000e+00 0.000e+00 -56.909 -56.899 0.010 +N(0) 4.143e-07 + N2 2.072e-07 2.120e-07 -6.684 -6.674 0.010 +N(3) 4.657e-13 + NO2- 4.657e-13 3.510e-13 -12.332 -12.455 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.975e-02 + Na+ 9.975e-02 7.809e-02 -1.001 -1.107 -0.106 + NaOH 5.025e-10 5.142e-10 -9.299 -9.289 0.010 +O(0) 1.035e-06 + O2 5.173e-07 5.294e-07 -6.286 -6.276 0.010 +Zn 9.549e-05 + Zn+2 9.544e-05 3.594e-05 -4.020 -4.444 -0.424 + ZnOH+ 5.025e-08 3.927e-08 -7.299 -7.406 -0.107 + Zn(OH)2 4.391e-10 4.493e-10 -9.357 -9.347 0.010 + Zn(OH)3- 1.812e-15 1.416e-15 -14.742 -14.849 -0.107 + Zn(OH)4-2 5.998e-22 2.237e-22 -21.222 -21.650 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.00 -6.00 0.00 H+ + H2(g) -39.90 -43.05 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.41 -6.67 -3.26 N2 + NH3(g) -58.67 -56.90 1.77 NH3 + O2(g) -3.32 -6.28 -2.96 O2 + Zn(OH)2(e) -3.95 7.55 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 20. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.25 -6.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 5.100e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 4.813e-05 Surface charge, eq + 8.601e-02 sigma, C/m**2 + 8.101e-02 psi, V + -3.153e+00 -F*psi/RT + 4.272e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.478e-06 0.896 4.478e-06 -5.349 + Hfo_sOH 3.657e-07 0.073 3.657e-07 -6.437 + Hfo_sOH2+ 1.330e-07 0.027 1.330e-07 -6.876 + Hfo_sO- 2.304e-08 0.005 2.304e-08 -7.637 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.389e-04 0.695 1.389e-04 -3.857 + Hfo_wOH2+ 5.052e-05 0.253 5.052e-05 -4.297 + Hfo_wO- 8.755e-06 0.044 8.755e-06 -5.058 + Hfo_wOZn+ 1.781e-06 0.009 1.781e-06 -5.749 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.976e-02 9.976e-02 + Zn 9.374e-05 9.374e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.250 Charge balance + pe = 13.666 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -5.666e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -4.813e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.580618e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.812e-07 5.623e-07 -6.167 -6.250 -0.083 + OH- 2.329e-08 1.774e-08 -7.633 -7.751 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.992 -42.982 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.742 -53.869 -0.128 + NH3 0.000e+00 0.000e+00 -56.874 -56.864 0.010 +N(0) 2.980e-07 + N2 1.490e-07 1.525e-07 -6.827 -6.817 0.010 +N(3) 5.489e-13 + NO2- 5.489e-13 4.136e-13 -12.261 -12.383 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.976e-02 + Na+ 9.976e-02 7.810e-02 -1.001 -1.107 -0.106 + NaOH 8.936e-10 9.145e-10 -9.049 -9.039 0.010 +O(0) 7.449e-07 + O2 3.724e-07 3.811e-07 -6.429 -6.419 0.010 +Zn 9.374e-05 + Zn+2 9.365e-05 3.526e-05 -4.028 -4.453 -0.424 + ZnOH+ 8.769e-08 6.853e-08 -7.057 -7.164 -0.107 + Zn(OH)2 1.363e-09 1.394e-09 -8.866 -8.856 0.010 + Zn(OH)3- 1.000e-14 7.814e-15 -14.000 -14.107 -0.107 + Zn(OH)4-2 5.886e-21 2.195e-21 -20.230 -20.659 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.25 -6.25 0.00 H+ + H2(g) -39.83 -42.98 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.56 -6.82 -3.26 N2 + NH3(g) -58.63 -56.86 1.77 NH3 + O2(g) -3.46 -6.42 -2.96 O2 + Zn(OH)2(e) -3.46 8.04 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 21. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.50 -6.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 3.598e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 3.959e-05 Surface charge, eq + 7.074e-02 sigma, C/m**2 + 7.194e-02 psi, V + -2.800e+00 -F*psi/RT + 6.079e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.781e-06 0.956 4.781e-06 -5.320 + Hfo_sOH 1.595e-07 0.032 1.595e-07 -6.797 + Hfo_sOH2+ 4.642e-08 0.009 4.642e-08 -7.333 + Hfo_sO- 1.256e-08 0.003 1.256e-08 -7.901 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.427e-04 0.714 1.427e-04 -3.845 + Hfo_wOH2+ 4.153e-05 0.208 4.153e-05 -4.382 + Hfo_wO- 1.124e-05 0.056 1.124e-05 -4.949 + Hfo_wOZn+ 4.480e-06 0.022 4.480e-06 -5.349 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.978e-02 9.978e-02 + Zn 9.074e-05 9.074e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.500 Charge balance + pe = 13.380 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = -1.809e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.959e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.580620e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.831e-07 3.162e-07 -6.417 -6.500 -0.083 + OH- 4.141e-08 3.155e-08 -7.383 -7.501 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.921 -42.911 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -53.956 -54.084 -0.128 + NH3 0.000e+00 0.000e+00 -56.838 -56.828 0.010 +N(0) 2.144e-07 + N2 1.072e-07 1.097e-07 -6.970 -6.960 0.010 +N(3) 6.470e-13 + NO2- 6.470e-13 4.876e-13 -12.189 -12.312 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.978e-02 + Na+ 9.978e-02 7.811e-02 -1.001 -1.107 -0.106 + NaOH 1.589e-09 1.626e-09 -8.799 -8.789 0.010 +O(0) 5.361e-07 + O2 2.680e-07 2.743e-07 -6.572 -6.562 0.010 +Zn 9.074e-05 + Zn+2 9.058e-05 3.411e-05 -4.043 -4.467 -0.424 + ZnOH+ 1.508e-07 1.179e-07 -6.822 -6.929 -0.107 + Zn(OH)2 4.168e-09 4.265e-09 -8.380 -8.370 0.010 + Zn(OH)3- 5.439e-14 4.250e-14 -13.264 -13.372 -0.107 + Zn(OH)4-2 5.693e-20 2.123e-20 -19.245 -19.673 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.50 -6.50 0.00 H+ + H2(g) -39.76 -42.91 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.70 -6.96 -3.26 N2 + NH3(g) -58.60 -56.83 1.77 NH3 + O2(g) -3.60 -6.56 -2.96 O2 + Zn(OH)2(e) -2.97 8.53 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 22. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -6.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -6.75 -6.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 1.709e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 3.290e-05 Surface charge, eq + 5.878e-02 sigma, C/m**2 + 6.370e-02 psi, V + -2.480e+00 -F*psi/RT + 8.378e-02 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.905e-06 0.981 4.905e-06 -5.309 + Hfo_sOH 7.153e-08 0.014 7.153e-08 -7.146 + Hfo_sOH2+ 1.613e-08 0.003 1.613e-08 -7.792 + Hfo_sO- 7.267e-09 0.001 7.267e-09 -8.139 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.430e-04 0.715 1.430e-04 -3.845 + Hfo_wOH2+ 3.224e-05 0.161 3.224e-05 -4.492 + Hfo_wO- 1.452e-05 0.073 1.452e-05 -4.838 + Hfo_wOZn+ 1.027e-05 0.051 1.027e-05 -4.989 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.980e-02 9.980e-02 + Zn 8.483e-05 8.483e-05 + +----------------------------Description of solution---------------------------- + + pH = 6.750 Charge balance + pe = 13.095 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.361e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -3.290e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.02 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.580621e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 2.154e-07 1.778e-07 -6.667 -6.750 -0.083 + OH- 7.365e-08 5.610e-08 -7.133 -7.251 -0.118 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.849 -42.839 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.170 -54.298 -0.128 + NH3 0.000e+00 0.000e+00 -56.802 -56.792 0.010 +N(0) 1.544e-07 + N2 7.718e-08 7.898e-08 -7.113 -7.102 0.010 +N(3) 7.627e-13 + NO2- 7.627e-13 5.748e-13 -12.118 -12.240 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.980e-02 + Na+ 9.980e-02 7.813e-02 -1.001 -1.107 -0.106 + NaOH 2.827e-09 2.893e-09 -8.549 -8.539 0.010 +O(0) 3.858e-07 + O2 1.929e-07 1.974e-07 -6.715 -6.705 0.010 +Zn 8.483e-05 + Zn+2 8.457e-05 3.184e-05 -4.073 -4.497 -0.424 + ZnOH+ 2.504e-07 1.957e-07 -6.601 -6.708 -0.107 + Zn(OH)2 1.230e-08 1.259e-08 -7.910 -7.900 0.010 + Zn(OH)3- 2.856e-13 2.231e-13 -12.544 -12.651 -0.107 + Zn(OH)4-2 5.315e-19 1.982e-19 -18.274 -18.703 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -6.75 -6.75 0.00 H+ + H2(g) -39.69 -42.84 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.84 -7.10 -3.26 N2 + NH3(g) -58.56 -56.79 1.77 NH3 + O2(g) -3.74 -6.70 -2.96 O2 + Zn(OH)2(e) -2.50 9.00 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 23. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.00 -7.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -7.621e-06 + +------------------------------Surface composition------------------------------ + +Hfo + 2.821e-05 Surface charge, eq + 5.040e-02 sigma, C/m**2 + 5.718e-02 psi, V + -2.226e+00 -F*psi/RT + 1.080e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.953e-06 0.991 4.953e-06 -5.305 + Hfo_sOH 3.573e-08 0.007 3.573e-08 -7.447 + Hfo_sOH2+ 5.840e-09 0.001 5.840e-09 -8.234 + Hfo_sO- 5.008e-09 0.001 5.008e-09 -8.300 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.380e-04 0.690 1.380e-04 -3.860 + Hfo_wOH2+ 2.256e-05 0.113 2.256e-05 -4.647 + Hfo_wOZn+ 2.004e-05 0.100 2.004e-05 -4.698 + Hfo_wO- 1.935e-05 0.097 1.935e-05 -4.713 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.982e-02 9.982e-02 + Zn 7.501e-05 7.501e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.000 Charge balance + pe = 12.809 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.001e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.762e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.821e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 22 + Total H = 1.110125e+02 + Total O = 5.580624e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-07 9.977e-08 -6.883 -7.001 -0.118 + H+ 1.211e-07 1.000e-07 -6.917 -7.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.778 -42.768 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.384 -54.512 -0.128 + NH3 0.000e+00 0.000e+00 -56.766 -56.756 0.010 +N(0) 1.112e-07 + N2 5.561e-08 5.691e-08 -7.255 -7.245 0.010 +N(3) 8.992e-13 + NO2- 8.992e-13 6.777e-13 -12.046 -12.169 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.982e-02 + Na+ 9.982e-02 7.815e-02 -1.001 -1.107 -0.106 + NaOH 5.028e-09 5.146e-09 -8.299 -8.289 0.010 +O(0) 2.775e-07 + O2 1.388e-07 1.420e-07 -6.858 -6.848 0.010 +Zn 7.501e-05 + Zn+2 7.458e-05 2.808e-05 -4.127 -4.552 -0.424 + ZnOH+ 3.927e-07 3.069e-07 -6.406 -6.513 -0.107 + Zn(OH)2 3.432e-08 3.512e-08 -7.465 -7.454 0.010 + Zn(OH)3- 1.416e-12 1.107e-12 -11.849 -11.956 -0.107 + Zn(OH)4-2 4.688e-18 1.748e-18 -17.329 -17.757 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.00 -7.00 0.00 H+ + H2(g) -39.62 -42.77 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -3.98 -7.24 -3.26 N2 + NH3(g) -58.53 -56.76 1.77 NH3 + O2(g) -3.89 -6.85 -2.96 O2 + Zn(OH)2(e) -2.05 9.45 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 24. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.25 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.25 -7.25 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -3.628e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.514e-05 Surface charge, eq + 4.492e-02 sigma, C/m**2 + 5.252e-02 psi, V + -2.044e+00 -F*psi/RT + 1.295e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.973e-06 0.995 4.973e-06 -5.303 + Hfo_sOH 2.031e-08 0.004 2.031e-08 -7.692 + Hfo_sO- 4.222e-09 0.001 4.222e-09 -8.375 + Hfo_sOH2+ 2.238e-09 0.000 2.238e-09 -8.650 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.270e-04 0.635 1.270e-04 -3.896 + Hfo_wOZn+ 3.257e-05 0.163 3.257e-05 -4.487 + Hfo_wO- 2.640e-05 0.132 2.640e-05 -4.578 + Hfo_wOH2+ 1.400e-05 0.070 1.400e-05 -4.854 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.985e-02 9.985e-02 + Zn 6.245e-05 6.245e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.250 Charge balance + pe = 12.523 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.321e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.514e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 22 + Total H = 1.110125e+02 + Total O = 5.580627e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 2.329e-07 1.774e-07 -6.633 -6.751 -0.118 + H+ 6.812e-08 5.623e-08 -7.167 -7.250 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.706 -42.696 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.596 -54.724 -0.128 + NH3 0.000e+00 0.000e+00 -56.729 -56.719 0.010 +N(0) 8.046e-08 + N2 4.023e-08 4.117e-08 -7.395 -7.385 0.010 +N(3) 1.061e-12 + NO2- 1.061e-12 7.997e-13 -11.974 -12.097 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.536e-02 -1.000 -1.123 -0.123 +Na 9.985e-02 + Na+ 9.985e-02 7.817e-02 -1.001 -1.107 -0.106 + NaOH 8.944e-09 9.153e-09 -8.048 -8.038 0.010 +O(0) 1.993e-07 + O2 9.966e-08 1.020e-07 -7.001 -6.991 0.010 +Zn 6.245e-05 + Zn+2 6.179e-05 2.327e-05 -4.209 -4.633 -0.424 + ZnOH+ 5.786e-07 4.521e-07 -6.238 -6.345 -0.107 + Zn(OH)2 8.990e-08 9.200e-08 -7.046 -7.036 0.010 + Zn(OH)3- 6.598e-12 5.156e-12 -11.181 -11.288 -0.107 + Zn(OH)4-2 3.883e-17 1.448e-17 -16.411 -16.839 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.25 -7.25 0.00 H+ + H2(g) -39.55 -42.70 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.13 -7.39 -3.26 N2 + NH3(g) -58.49 -56.72 1.77 NH3 + O2(g) -4.03 -6.99 -2.96 O2 + Zn(OH)2(e) -1.64 9.86 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 25. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.5 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.50 -7.50 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -6.533e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.290e-05 Surface charge, eq + 4.091e-02 sigma, C/m**2 + 4.889e-02 psi, V + -1.903e+00 -F*psi/RT + 1.491e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.982e-06 0.996 4.982e-06 -5.303 + Hfo_sOH 1.269e-08 0.003 1.269e-08 -7.897 + Hfo_sO- 4.073e-09 0.001 4.073e-09 -8.390 + Hfo_sOH2+ 9.054e-10 0.000 9.054e-10 -9.043 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 1.109e-04 0.554 1.109e-04 -3.955 + Hfo_wOZn+ 4.560e-05 0.228 4.560e-05 -4.341 + Hfo_wO- 3.560e-05 0.178 3.560e-05 -4.449 + Hfo_wOH2+ 7.913e-06 0.040 7.913e-06 -5.102 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.988e-02 9.988e-02 + Zn 4.942e-05 4.942e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.500 Charge balance + pe = 12.237 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.643e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.290e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 24 + Total H = 1.110126e+02 + Total O = 5.580630e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 4.141e-07 3.155e-07 -6.383 -6.501 -0.118 + H+ 3.831e-08 3.162e-08 -7.417 -7.500 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.635 -42.625 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -54.813 -54.941 -0.128 + NH3 0.000e+00 0.000e+00 -56.695 -56.685 0.010 +N(0) 5.753e-08 + N2 2.876e-08 2.943e-08 -7.541 -7.531 0.010 +N(3) 1.249e-12 + NO2- 1.249e-12 9.414e-13 -11.903 -12.026 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.988e-02 + Na+ 9.988e-02 7.819e-02 -1.001 -1.107 -0.106 + NaOH 1.591e-08 1.628e-08 -7.798 -7.788 0.010 +O(0) 1.438e-07 + O2 7.191e-08 7.359e-08 -7.143 -7.133 0.010 +Zn 4.942e-05 + Zn+2 4.839e-05 1.822e-05 -4.315 -4.739 -0.424 + ZnOH+ 8.058e-07 6.297e-07 -6.094 -6.201 -0.107 + Zn(OH)2 2.227e-07 2.278e-07 -6.652 -6.642 0.010 + Zn(OH)3- 2.906e-11 2.271e-11 -10.537 -10.644 -0.107 + Zn(OH)4-2 3.041e-16 1.134e-16 -15.517 -15.945 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.50 -7.50 0.00 H+ + H2(g) -39.47 -42.62 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.27 -7.53 -3.26 N2 + NH3(g) -58.46 -56.69 1.77 NH3 + O2(g) -4.17 -7.13 -2.96 O2 + Zn(OH)2(e) -1.24 10.26 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 26. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -7.75 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -7.75 -7.75 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -9.246e-05 + +------------------------------Surface composition------------------------------ + +Hfo + 2.082e-05 Surface charge, eq + 3.720e-02 sigma, C/m**2 + 4.536e-02 psi, V + -1.765e+00 -F*psi/RT + 1.711e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.987e-06 0.997 4.987e-06 -5.302 + Hfo_sOH 8.383e-09 0.002 8.383e-09 -8.077 + Hfo_sO- 4.170e-09 0.001 4.170e-09 -8.380 + Hfo_sOH2+ 3.861e-10 0.000 3.861e-10 -9.413 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 9.232e-05 0.462 9.232e-05 -4.035 + Hfo_wOZn+ 5.751e-05 0.288 5.751e-05 -4.240 + Hfo_wO- 4.592e-05 0.230 4.592e-05 -4.338 + Hfo_wOH2+ 4.251e-06 0.021 4.251e-06 -5.371 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.991e-02 9.991e-02 + Zn 3.750e-05 3.750e-05 + +----------------------------Description of solution---------------------------- + + pH = 7.750 Charge balance + pe = 11.952 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.853e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -2.082e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 23 + Total H = 1.110126e+02 + Total O = 5.580632e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 7.364e-07 5.610e-07 -6.133 -6.251 -0.118 + H+ 2.154e-08 1.778e-08 -7.667 -7.750 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.563 -42.553 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -55.027 -55.155 -0.128 + NH3 0.000e+00 0.000e+00 -56.659 -56.649 0.010 +N(0) 4.145e-08 + N2 2.072e-08 2.121e-08 -7.684 -7.674 0.010 +N(3) 1.473e-12 + NO2- 1.473e-12 1.110e-12 -11.832 -11.955 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.991e-02 + Na+ 9.991e-02 7.821e-02 -1.000 -1.107 -0.106 + NaOH 2.830e-08 2.896e-08 -7.548 -7.538 0.010 +O(0) 1.035e-07 + O2 5.173e-08 5.294e-08 -7.286 -7.276 0.010 +Zn 3.750e-05 + Zn+2 3.592e-05 1.353e-05 -4.445 -4.869 -0.424 + ZnOH+ 1.064e-06 8.312e-07 -5.973 -6.080 -0.107 + Zn(OH)2 5.227e-07 5.349e-07 -6.282 -6.272 0.010 + Zn(OH)3- 1.213e-10 9.479e-11 -9.916 -10.023 -0.107 + Zn(OH)4-2 2.258e-15 8.419e-16 -14.646 -15.075 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -7.75 -7.75 0.00 H+ + H2(g) -39.40 -42.55 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.41 -7.67 -3.26 N2 + NH3(g) -58.42 -56.65 1.77 NH3 + O2(g) -4.32 -7.28 -2.96 O2 + Zn(OH)2(e) -0.87 10.63 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 27. +------------------------------------- + + USE solution 2 + USE surface 1 + EQUILIBRIUM_PHASES 1 + Fix_H+ -8.0 NaOH 10.0 + END +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +Using solution 2. +Using surface 1. +Using pure phase assemblage 1. + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + Fix_H+ -8.00 -8.00 0.00 + NaOH is reactant 1.000e+01 1.000e+01 -1.167e-04 + +------------------------------Surface composition------------------------------ + +Hfo + 1.856e-05 Surface charge, eq + 3.316e-02 sigma, C/m**2 + 4.130e-02 psi, V + -1.607e+00 -F*psi/RT + 2.004e-01 exp(-F*psi/RT) + 6.000e+02 specific area, m**2/g + 5.400e+01 m**2 for 9.000e-02 g + + +Hfo_s + 5.000e-06 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_sOZn+ 4.990e-06 0.998 4.990e-06 -5.302 + Hfo_sOH 5.756e-09 0.001 5.756e-09 -8.240 + Hfo_sO- 4.347e-09 0.001 4.347e-09 -8.362 + Hfo_sOH2+ 1.746e-10 0.000 1.746e-10 -9.758 + +Hfo_w + 2.000e-04 moles + Mole Log + Species Moles Fraction Molality Molality + + Hfo_wOH 7.426e-05 0.371 7.426e-05 -4.129 + Hfo_wOZn+ 6.740e-05 0.337 6.740e-05 -4.171 + Hfo_wO- 5.608e-05 0.280 5.608e-05 -4.251 + Hfo_wOH2+ 2.252e-06 0.011 2.252e-06 -5.647 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + N 1.000e-01 1.000e-01 + Na 9.993e-02 9.993e-02 + Zn 2.761e-05 2.761e-05 + +----------------------------Description of solution---------------------------- + + pH = 8.000 Charge balance + pe = 11.666 Adjusted to redox equilibrium + Activity of water = 0.997 + Ionic strength = 1.000e-01 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 4.985e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.856e-05 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.01 + Iterations = 25 + Total H = 1.110127e+02 + Total O = 5.580635e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.310e-06 9.977e-07 -5.883 -6.001 -0.118 + H+ 1.211e-08 1.000e-08 -7.917 -8.000 -0.083 + H2O 5.551e+01 9.966e-01 1.744 -0.001 0.000 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -42.492 -42.482 0.010 +N(-3) 0.000e+00 + NH4+ 0.000e+00 0.000e+00 -55.242 -55.369 -0.128 + NH3 0.000e+00 0.000e+00 -56.624 -56.614 0.010 +N(0) 2.980e-08 + N2 1.490e-08 1.525e-08 -7.827 -7.817 0.010 +N(3) 1.736e-12 + NO2- 1.736e-12 1.308e-12 -11.761 -11.883 -0.123 +N(5) 1.000e-01 + NO3- 1.000e-01 7.537e-02 -1.000 -1.123 -0.123 +Na 9.993e-02 + Na+ 9.993e-02 7.823e-02 -1.000 -1.107 -0.106 + NaOH 5.034e-08 5.151e-08 -7.298 -7.288 0.010 +O(0) 7.449e-08 + O2 3.725e-08 3.811e-08 -7.429 -7.419 0.010 +Zn 2.761e-05 + Zn+2 2.513e-05 9.463e-06 -4.600 -5.024 -0.424 + ZnOH+ 1.323e-06 1.034e-06 -5.878 -5.985 -0.107 + Zn(OH)2 1.156e-06 1.183e-06 -5.937 -5.927 0.010 + Zn(OH)3- 4.772e-10 3.729e-10 -9.321 -9.428 -0.107 + Zn(OH)4-2 1.579e-14 5.890e-15 -13.802 -14.230 -0.428 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Fix_H+ -8.00 -8.00 0.00 H+ + H2(g) -39.33 -42.48 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + N2(g) -4.56 -7.82 -3.26 N2 + NH3(g) -58.38 -56.61 1.77 NH3 + O2(g) -4.46 -7.42 -2.96 O2 + Zn(OH)2(e) -0.53 10.97 11.50 Zn(OH)2 + +------------------ +End of simulation. +------------------ + +------------------------------------- +Reading input data for simulation 28. +------------------------------------- + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex8.sel b/Sun/examples/ex8.sel new file mode 100644 index 00000000..7bbafc65 --- /dev/null +++ b/Sun/examples/ex8.sel @@ -0,0 +1,27 @@ + sim state soln dist_x time step pH pe m_Zn+2 m_Hfo_wOZn+ m_Hfo_sOZn+ + 2 react 1 -99 0 1 5 15.0946 9.9667e-08 1.3194e-11 3.1498e-10 + 3 react 1 -99 0 1 5.25 14.8089 9.9093e-08 3.6118e-11 8.6216e-10 + 4 react 1 -99 0 1 5.5 14.5232 9.7567e-08 9.7221e-11 2.3200e-09 + 5 react 1 -99 0 1 5.75 14.2374 9.3657e-08 2.5418e-10 6.0611e-09 + 6 react 1 -99 0 1 6 13.9517 8.4476e-08 6.2406e-10 1.4855e-08 + 7 react 1 -99 0 1 6.25 13.666 6.6695e-08 1.3446e-09 3.1897e-08 + 8 react 1 -99 0 1 6.5 13.3803 4.2322e-08 2.3406e-09 5.5265e-08 + 9 react 1 -99 0 1 6.75 13.0946 2.1052e-08 3.2179e-09 7.5665e-08 + 10 react 1 -99 0 1 7 12.8089 8.7494e-09 3.7289e-09 8.7472e-08 + 11 react 1 -99 0 1 7.25 12.5232 3.3000e-09 3.9564e-09 9.2708e-08 + 12 react 1 -99 0 1 7.5 12.2374 1.1903e-09 4.0447e-09 9.4740e-08 + 13 react 1 -99 0 1 7.75 11.9517 4.2114e-10 4.0771e-09 9.5483e-08 + 14 react 1 -99 0 1 8 11.666 1.4799e-10 4.0887e-09 9.5749e-08 + 15 react 2 -99 0 1 5 15.0946 9.9686e-05 1.3187e-08 2.9620e-07 + 16 react 2 -99 0 1 5.25 14.8089 9.9220e-05 3.6081e-08 7.3494e-07 + 17 react 2 -99 0 1 5.5 14.5231 9.8300e-05 9.7297e-08 1.5866e-06 + 18 react 2 -99 0 1 5.75 14.2374 9.6947e-05 2.5891e-07 2.7658e-06 + 19 react 2 -99 0 1 6 13.9517 9.5437e-05 6.8302e-07 3.8297e-06 + 20 react 2 -99 0 1 6.25 13.666 9.3651e-05 1.7815e-06 4.4782e-06 + 21 react 2 -99 0 1 6.5 13.3803 9.0584e-05 4.4798e-06 4.7815e-06 + 22 react 2 -99 0 1 6.75 13.0946 8.4566e-05 1.0266e-05 4.9051e-06 + 23 react 2 -99 0 1 7 12.8088 7.4581e-05 2.0039e-05 4.9534e-06 + 24 react 2 -99 0 1 7.25 12.5229 6.1786e-05 3.2572e-05 4.9732e-06 + 25 react 2 -99 0 1 7.5 12.2374 4.8388e-05 4.5601e-05 4.9823e-06 + 26 react 2 -99 0 1 7.75 11.9517 3.5918e-05 5.7508e-05 4.9871e-06 + 27 react 2 -99 0 1 8 11.666 2.5127e-05 6.7404e-05 4.9897e-06 diff --git a/Sun/examples/ex9.log b/Sun/examples/ex9.log new file mode 100644 index 00000000..e69de29b diff --git a/Sun/examples/ex9.out b/Sun/examples/ex9.out new file mode 100644 index 00000000..e865b680 --- /dev/null +++ b/Sun/examples/ex9.out @@ -0,0 +1,1284 @@ + Input file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../examples/ex9 + Output file: ex9.out +Database file: /z/parkplace/home/dlpark/../../home/dlpark/programs/phreeqc/src/../src/Sun/../../database/phreeqc.dat + +------------------ +Reading data base. +------------------ + + SOLUTION_MASTER_SPECIES + SOLUTION_SPECIES + PHASES + EXCHANGE_MASTER_SPECIES + EXCHANGE_SPECIES + SURFACE_MASTER_SPECIES + SURFACE_SPECIES + RATES + END +------------------------------------ +Reading input data for simulation 1. +------------------------------------ + + TITLE Example 9.--Kinetically controlled oxidation of ferrous + iron. Decoupled valence states of iron. + SOLUTION_MASTER_SPECIES + Fe_di Fe_di+2 0.0 Fe_di 55.847 + Fe_tri Fe_tri+3 0.0 Fe_tri 55.847 + SOLUTION_SPECIES + Fe_di+2 = Fe_di+2 + log_k 0.0 + Fe_tri+3 = Fe_tri+3 + log_k 0.0 + Fe_di+2 + H2O = Fe_diOH+ + H+ + log_k -9.5 + delta_h 13.20 kcal + Fe_di+2 + Cl- = Fe_diCl+ + log_k 0.14 + Fe_di+2 + CO3-2 = Fe_diCO3 + log_k 4.38 + Fe_di+2 + HCO3- = Fe_diHCO3+ + log_k 2.0 + Fe_di+2 + SO4-2 = Fe_diSO4 + log_k 2.25 + delta_h 3.230 kcal + Fe_di+2 + HSO4- = Fe_diHSO4+ + log_k 1.08 + Fe_di+2 + 2HS- = Fe_di(HS)2 + log_k 8.95 + Fe_di+2 + 3HS- = Fe_di(HS)3- + log_k 10.987 + Fe_di+2 + HPO4-2 = Fe_diHPO4 + log_k 3.6 + Fe_di+2 + H2PO4- = Fe_diH2PO4+ + log_k 2.7 + Fe_di+2 + F- = Fe_diF+ + log_k 1.0 + Fe_tri+3 + H2O = Fe_triOH+2 + H+ + log_k -2.19 + delta_h 10.4 kcal + Fe_tri+3 + 2 H2O = Fe_tri(OH)2+ + 2 H+ + log_k -5.67 + delta_h 17.1 kcal + Fe_tri+3 + 3 H2O = Fe_tri(OH)3 + 3 H+ + log_k -12.56 + delta_h 24.8 kcal + Fe_tri+3 + 4 H2O = Fe_tri(OH)4- + 4 H+ + log_k -21.6 + delta_h 31.9 kcal + 2 Fe_tri+3 + 2 H2O = Fe_tri2(OH)2+4 + 2 H+ + log_k -2.95 + delta_h 13.5 kcal + 3 Fe_tri+3 + 4 H2O = Fe_tri3(OH)4+5 + 4 H+ + log_k -6.3 + delta_h 14.3 kcal + Fe_tri+3 + Cl- = Fe_triCl+2 + log_k 1.48 + delta_h 5.6 kcal + Fe_tri+3 + 2 Cl- = Fe_triCl2+ + log_k 2.13 + Fe_tri+3 + 3 Cl- = Fe_triCl3 + log_k 1.13 + Fe_tri+3 + SO4-2 = Fe_triSO4+ + log_k 4.04 + delta_h 3.91 kcal + Fe_tri+3 + HSO4- = Fe_triHSO4+2 + log_k 2.48 + Fe_tri+3 + 2 SO4-2 = Fe_tri(SO4)2- + log_k 5.38 + delta_h 4.60 kcal + Fe_tri+3 + HPO4-2 = Fe_triHPO4+ + log_k 5.43 + delta_h 5.76 kcal + Fe_tri+3 + H2PO4- = Fe_triH2PO4+2 + log_k 5.43 + Fe_tri+3 + F- = Fe_triF+2 + log_k 6.2 + delta_h 2.7 kcal + Fe_tri+3 + 2 F- = Fe_triF2+ + log_k 10.8 + delta_h 4.8 kcal + Fe_tri+3 + 3 F- = Fe_triF3 + log_k 14.0 + delta_h 5.4 kcal + PHASES + Goethite + Fe_triOOH + 3 H+ = Fe_tri+3 + 2 H2O + log_k -1.0 + END +----- +TITLE +----- + + Example 9.--Kinetically controlled oxidation of ferrous + iron. Decoupled valence states of iron. + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 2. +------------------------------------ + + SOLUTION 1 + pH 7.0 + pe 10.0 O2(g) -0.67 + Fe_di 0.1 + Na 10. + Cl 10. charge + EQUILIBRIUM_PHASES 1 + O2(g) -0.67 + RATES + Fe_di_ox + start + 10 Fe_di = TOT("Fe_di") + 20 if (Fe_di <= 0) then goto 200 + 30 p_o2 = 10^(SI("O2(g)")) + 40 moles = (2.91e-9 + 1.33e12 * (ACT("OH-"))^2 * p_o2) * Fe_di * TIME + 200 SAVE moles + end + KINETICS 1 + Fe_di_ox + formula Fe_di -1.0 Fe_tri 1.0 + steps 100 400 3100 10800 21600 5.04e4 8.64e4 1.728e5 1.728e5 1.728e5 1.728e5 + INCREMENTAL_REACTIONS true + SELECTED_OUTPUT + file ex9.sel + reset false + USER_PUNCH + headings Days Fe(2) Fe(3) pH si_goethite + 10 PUNCH SIM_TIME/3600/24 TOT("Fe_di")*1e6, TOT("Fe_tri")*1e6, -LA("H+"), SI("Goethite") + END +------------------------------------------- +Beginning of initial solution calculations. +------------------------------------------- + +Initial solution 1. + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 Charge balance + Fe_di 1.000e-04 1.000e-04 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 7.000 + pe = 13.613 Equilibrium with O2(g) + Activity of water = 1.000 + Ionic strength = 1.030e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.308e-07 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = -1.740e-18 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = -0.00 + Iterations = 9 + Total H = 1.110124e+02 + Total O = 5.550668e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + OH- 1.113e-07 1.001e-07 -6.953 -7.000 -0.046 + H+ 1.096e-07 1.000e-07 -6.960 -7.000 -0.040 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 9.149e-07 8.242e-07 -6.039 -6.084 -0.045 +Fe_di 1.000e-04 + Fe_di+2 9.886e-05 6.510e-05 -4.005 -4.186 -0.181 + Fe_diCl+ 9.149e-07 8.242e-07 -6.039 -6.084 -0.045 + Fe_diOH+ 2.285e-07 2.058e-07 -6.641 -6.687 -0.045 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 5.943e-10 5.957e-10 -9.226 -9.225 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +----------------------------------------- +Beginning of batch-reaction calculations. +----------------------------------------- + +Reaction step 1. + +WARNING: Element Fe_tri has negative moles in solution, -5.977583e-06. + Erroneous mole balance occurs as moles are added to produce zero moles. + Usually caused by KINETICS, REACTION, or diffuse layer calculation. + May be due to large time steps in early part of KINETICS simulation or negative concentrations in the diffuse layer. +WARNING: Element Fe_tri has negative moles in solution, -1.366855e-06. + Erroneous mole balance occurs as moles are added to produce zero moles. + Usually caused by KINETICS, REACTION, or diffuse layer calculation. + May be due to large time steps in early part of KINETICS simulation or negative concentrations in the diffuse layer. +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 100 seconds (Incremented time: 100 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.058e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -2.645e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.894e-05 9.894e-05 + Fe_tri 1.058e-06 1.058e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 6.048 Charge balance + pe = 14.565 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.030e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.289e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.530e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 206 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.821e-07 8.962e-07 -6.008 -6.048 -0.040 + OH- 1.242e-08 1.117e-08 -7.906 -7.952 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 9.071e-07 8.172e-07 -6.042 -6.088 -0.045 + Fe_triCl+2 1.330e-13 8.757e-14 -12.876 -13.058 -0.181 + Fe_triCl2+ 3.982e-15 3.587e-15 -14.400 -14.445 -0.045 + Fe_triCl3 3.282e-18 3.290e-18 -17.484 -17.483 0.001 +Fe_di 9.894e-05 + Fe_di+2 9.801e-05 6.455e-05 -4.009 -4.190 -0.181 + Fe_diCl+ 9.071e-07 8.172e-07 -6.042 -6.088 -0.045 + Fe_diOH+ 2.527e-08 2.277e-08 -7.597 -7.643 -0.045 +Fe_tri 1.058e-06 + Fe_tri(OH)2+ 9.336e-07 8.410e-07 -6.030 -6.075 -0.045 + Fe_tri(OH)3 1.206e-07 1.209e-07 -6.919 -6.918 0.001 + Fe_triOH+2 3.457e-09 2.277e-09 -8.461 -8.643 -0.181 + Fe_tri(OH)4- 1.365e-10 1.229e-10 -9.865 -9.910 -0.045 + Fe_tri+3 8.092e-13 3.162e-13 -12.092 -12.500 -0.408 + Fe_triCl+2 1.330e-13 8.757e-14 -12.876 -13.058 -0.181 + Fe_triCl2+ 3.982e-15 3.587e-15 -14.400 -14.445 -0.045 + Fe_tri2(OH)2+4 7.418e-16 1.396e-16 -15.130 -15.855 -0.726 + Fe_triCl3 3.282e-18 3.290e-18 -17.484 -17.483 0.001 + Fe_tri3(OH)4+5 3.336e-19 2.452e-20 -18.477 -19.610 -1.134 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 6.631e-11 6.647e-11 -10.178 -10.177 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.64 5.64 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 2. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 400 seconds (Incremented time: 500 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -7.364e-07 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -1.841e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.821e-05 9.821e-05 + Fe_tri 1.794e-06 1.794e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 5.810 Charge balance + pe = 14.803 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.030e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.025e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 8.635e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 25 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.699e-06 1.550e-06 -5.770 -5.810 -0.040 + OH- 7.183e-09 6.457e-09 -8.144 -8.190 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 9.005e-07 8.112e-07 -6.046 -6.091 -0.045 + Fe_triCl+2 7.069e-13 4.656e-13 -12.151 -12.332 -0.181 + Fe_triCl2+ 2.117e-14 1.907e-14 -13.674 -13.720 -0.045 + Fe_triCl3 1.745e-17 1.749e-17 -16.758 -16.757 0.001 +Fe_di 9.821e-05 + Fe_di+2 9.729e-05 6.408e-05 -4.012 -4.193 -0.181 + Fe_diCl+ 9.005e-07 8.112e-07 -6.046 -6.091 -0.045 + Fe_diOH+ 1.451e-08 1.307e-08 -7.838 -7.884 -0.045 +Fe_tri 1.794e-06 + Fe_tri(OH)2+ 1.660e-06 1.495e-06 -5.780 -5.825 -0.045 + Fe_tri(OH)3 1.239e-07 1.242e-07 -6.907 -6.906 0.001 + Fe_triOH+2 1.063e-08 7.000e-09 -7.974 -8.155 -0.181 + Fe_tri(OH)4- 8.110e-11 7.306e-11 -10.091 -10.136 -0.045 + Fe_tri+3 4.302e-12 1.681e-12 -11.366 -11.774 -0.408 + Fe_triCl+2 7.069e-13 4.656e-13 -12.151 -12.332 -0.181 + Fe_triCl2+ 2.117e-14 1.907e-14 -13.674 -13.720 -0.045 + Fe_tri2(OH)2+4 7.010e-15 1.319e-15 -14.154 -14.880 -0.726 + Fe_triCl3 1.745e-17 1.749e-17 -16.758 -16.757 0.001 + Fe_tri3(OH)4+5 5.604e-18 4.120e-19 -17.252 -18.385 -1.134 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 3.834e-11 3.843e-11 -10.416 -10.415 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.65 5.65 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 3. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 3100 seconds (Incremented time: 3600 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.614e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -4.036e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.659e-05 9.659e-05 + Fe_tri 3.408e-06 3.408e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 5.525 Charge balance + pe = 15.088 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.029e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 3.639e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 9.240e-16 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 65 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 3.274e-06 2.988e-06 -5.485 -5.525 -0.040 + OH- 3.726e-09 3.349e-09 -8.429 -8.475 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 8.857e-07 7.979e-07 -6.053 -6.098 -0.045 + Fe_triCl+2 5.132e-12 3.380e-12 -11.290 -11.471 -0.181 + Fe_triCl2+ 1.537e-13 1.385e-13 -12.813 -12.859 -0.045 + Fe_triCl3 1.267e-16 1.270e-16 -15.897 -15.896 0.001 +Fe_di 9.659e-05 + Fe_di+2 9.570e-05 6.303e-05 -4.019 -4.200 -0.181 + Fe_diCl+ 8.857e-07 7.979e-07 -6.053 -6.098 -0.045 + Fe_diOH+ 7.403e-09 6.669e-09 -8.131 -8.176 -0.045 +Fe_tri 3.408e-06 + Fe_tri(OH)2+ 3.242e-06 2.921e-06 -5.489 -5.534 -0.045 + Fe_tri(OH)3 1.256e-07 1.259e-07 -6.901 -6.900 0.001 + Fe_triOH+2 4.003e-08 2.636e-08 -7.398 -7.579 -0.181 + Fe_tri(OH)4- 4.265e-11 3.842e-11 -10.370 -10.415 -0.045 + Fe_tri+3 3.123e-11 1.220e-11 -10.505 -10.913 -0.408 + Fe_triCl+2 5.132e-12 3.380e-12 -11.290 -11.471 -0.181 + Fe_triCl2+ 1.537e-13 1.385e-13 -12.813 -12.859 -0.045 + Fe_tri2(OH)2+4 9.943e-14 1.871e-14 -13.002 -13.728 -0.725 + Fe_tri3(OH)4+5 1.553e-16 1.142e-17 -15.809 -16.942 -1.134 + Fe_triCl3 1.267e-16 1.270e-16 -15.897 -15.896 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 1.989e-11 1.994e-11 -10.701 -10.700 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 4. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 10800 seconds (Incremented time: 14400 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.953e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -4.883e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.464e-05 9.464e-05 + Fe_tri 5.361e-06 5.361e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 5.327 Charge balance + pe = 15.286 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.029e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 5.592e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.873e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 24 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 5.163e-06 4.711e-06 -5.287 -5.327 -0.040 + OH- 2.363e-09 2.124e-09 -8.627 -8.673 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 8.679e-07 7.819e-07 -6.062 -6.107 -0.045 + Fe_triCl+2 2.021e-11 1.331e-11 -10.694 -10.876 -0.181 + Fe_triCl2+ 6.053e-13 5.453e-13 -12.218 -12.263 -0.045 + Fe_triCl3 4.990e-16 5.001e-16 -15.302 -15.301 0.001 +Fe_di 9.464e-05 + Fe_di+2 9.377e-05 6.176e-05 -4.028 -4.209 -0.181 + Fe_diCl+ 8.679e-07 7.819e-07 -6.062 -6.107 -0.045 + Fe_diOH+ 4.600e-09 4.144e-09 -8.337 -8.383 -0.045 +Fe_tri 5.361e-06 + Fe_tri(OH)2+ 5.135e-06 4.626e-06 -5.289 -5.335 -0.045 + Fe_tri(OH)3 1.261e-07 1.264e-07 -6.899 -6.898 0.001 + Fe_triOH+2 9.996e-08 6.584e-08 -7.000 -7.182 -0.181 + Fe_tri+3 1.230e-10 4.806e-11 -9.910 -10.318 -0.408 + Fe_tri(OH)4- 2.716e-11 2.447e-11 -10.566 -10.611 -0.045 + Fe_triCl+2 2.021e-11 1.331e-11 -10.694 -10.876 -0.181 + Fe_tri2(OH)2+4 6.200e-13 1.167e-13 -12.208 -12.933 -0.725 + Fe_triCl2+ 6.053e-13 5.453e-13 -12.218 -12.263 -0.045 + Fe_tri3(OH)4+5 1.533e-15 1.128e-16 -14.814 -15.948 -1.133 + Fe_triCl3 4.990e-16 5.001e-16 -15.302 -15.301 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 1.261e-11 1.264e-11 -10.899 -10.898 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 5. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 21600 seconds (Incremented time: 36000 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.875e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -4.688e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.276e-05 9.276e-05 + Fe_tri 7.236e-06 7.236e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 5.197 Charge balance + pe = 15.415 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.029e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 7.467e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.886e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 6.954e-06 6.346e-06 -5.158 -5.197 -0.040 + OH- 1.754e-09 1.577e-09 -8.756 -8.802 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.171e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 8.507e-07 7.664e-07 -6.070 -6.116 -0.045 + Fe_triCl+2 4.947e-11 3.258e-11 -10.306 -10.487 -0.181 + Fe_triCl2+ 1.482e-12 1.335e-12 -11.829 -11.875 -0.045 + Fe_triCl3 1.221e-15 1.224e-15 -14.913 -14.912 0.001 +Fe_di 9.276e-05 + Fe_di+2 9.191e-05 6.054e-05 -4.037 -4.218 -0.181 + Fe_diCl+ 8.507e-07 7.664e-07 -6.070 -6.116 -0.045 + Fe_diOH+ 3.347e-09 3.016e-09 -8.475 -8.521 -0.045 +Fe_tri 7.236e-06 + Fe_tri(OH)2+ 6.928e-06 6.241e-06 -5.159 -5.205 -0.045 + Fe_triOH+2 1.817e-07 1.196e-07 -6.741 -6.922 -0.181 + Fe_tri(OH)3 1.263e-07 1.266e-07 -6.898 -6.897 0.001 + Fe_tri+3 3.010e-10 1.176e-10 -9.521 -9.929 -0.408 + Fe_triCl+2 4.947e-11 3.258e-11 -10.306 -10.487 -0.181 + Fe_tri(OH)4- 2.020e-11 1.819e-11 -10.695 -10.740 -0.045 + Fe_tri2(OH)2+4 2.047e-12 3.853e-13 -11.689 -12.414 -0.725 + Fe_triCl2+ 1.482e-12 1.335e-12 -11.829 -11.875 -0.045 + Fe_tri3(OH)4+5 6.830e-15 5.024e-16 -14.166 -15.299 -1.133 + Fe_triCl3 1.221e-15 1.224e-15 -14.913 -14.912 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.019e-03 -2.000 -2.045 -0.045 + NaOH 9.365e-12 9.387e-12 -11.029 -11.027 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 6. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 50400 seconds (Incremented time: 86400 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -2.406e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -6.016e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 9.036e-05 9.036e-05 + Fe_tri 9.642e-06 9.642e-06 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 5.075 Charge balance + pe = 15.538 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.029e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 9.873e-06 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.884e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 22 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 9.220e-06 8.414e-06 -5.035 -5.075 -0.040 + OH- 1.323e-09 1.189e-09 -8.878 -8.925 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 8.287e-07 7.466e-07 -6.082 -6.127 -0.045 + Fe_triCl+2 1.154e-10 7.603e-11 -9.938 -10.119 -0.181 + Fe_triCl2+ 3.457e-12 3.115e-12 -11.461 -11.507 -0.045 + Fe_triCl3 2.850e-15 2.857e-15 -14.545 -14.544 0.001 +Fe_di 9.036e-05 + Fe_di+2 8.953e-05 5.897e-05 -4.048 -4.229 -0.181 + Fe_diCl+ 8.287e-07 7.466e-07 -6.082 -6.127 -0.045 + Fe_diOH+ 2.459e-09 2.216e-09 -8.609 -8.655 -0.045 +Fe_tri 9.642e-06 + Fe_tri(OH)2+ 9.195e-06 8.284e-06 -5.036 -5.082 -0.045 + Fe_triOH+2 3.197e-07 2.106e-07 -6.495 -6.677 -0.181 + Fe_tri(OH)3 1.265e-07 1.268e-07 -6.898 -6.897 0.001 + Fe_tri+3 7.023e-10 2.745e-10 -9.153 -9.561 -0.408 + Fe_triCl+2 1.154e-10 7.603e-11 -9.938 -10.119 -0.181 + Fe_tri(OH)4- 1.525e-11 1.374e-11 -10.817 -10.862 -0.045 + Fe_tri2(OH)2+4 6.340e-12 1.193e-12 -11.198 -11.923 -0.725 + Fe_triCl2+ 3.457e-12 3.115e-12 -11.461 -11.507 -0.045 + Fe_tri3(OH)4+5 2.807e-14 2.065e-15 -13.552 -14.685 -1.133 + Fe_triCl3 2.850e-15 2.857e-15 -14.545 -14.544 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 7.063e-12 7.080e-12 -11.151 -11.150 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 7. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 86400 seconds (Incremented time: 172800 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -2.462e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -6.156e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 8.790e-05 8.790e-05 + Fe_tri 1.210e-05 1.210e-05 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 4.979 Charge balance + pe = 15.634 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.029e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.233e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.894e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 21 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.150e-05 1.050e-05 -4.939 -4.979 -0.040 + OH- 1.061e-09 9.534e-10 -8.974 -9.021 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 8.062e-07 7.263e-07 -6.094 -6.139 -0.045 + Fe_triCl+2 2.242e-10 1.477e-10 -9.649 -9.831 -0.181 + Fe_triCl2+ 6.716e-12 6.050e-12 -11.173 -11.218 -0.045 + Fe_triCl3 5.536e-15 5.549e-15 -14.257 -14.256 0.001 +Fe_di 8.790e-05 + Fe_di+2 8.709e-05 5.737e-05 -4.060 -4.241 -0.181 + Fe_diCl+ 8.062e-07 7.263e-07 -6.094 -6.139 -0.045 + Fe_diOH+ 1.918e-09 1.728e-09 -8.717 -8.763 -0.045 +Fe_tri 1.210e-05 + Fe_tri(OH)2+ 1.148e-05 1.034e-05 -4.940 -4.985 -0.045 + Fe_triOH+2 4.978e-07 3.279e-07 -6.303 -6.484 -0.181 + Fe_tri(OH)3 1.266e-07 1.269e-07 -6.898 -6.897 0.001 + Fe_tri+3 1.364e-09 5.332e-10 -8.865 -9.273 -0.408 + Fe_triCl+2 2.242e-10 1.477e-10 -9.649 -9.831 -0.181 + Fe_tri2(OH)2+4 1.537e-11 2.894e-12 -10.813 -11.539 -0.725 + Fe_tri(OH)4- 1.223e-11 1.102e-11 -10.912 -10.958 -0.045 + Fe_triCl2+ 6.716e-12 6.050e-12 -11.173 -11.218 -0.045 + Fe_tri3(OH)4+5 8.494e-14 6.251e-15 -13.071 -14.204 -1.133 + Fe_triCl3 5.536e-15 5.549e-15 -14.257 -14.256 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 5.662e-12 5.676e-12 -11.247 -11.246 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 8. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 172800 seconds (Incremented time: 345600 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -3.088e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -7.722e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 8.481e-05 8.481e-05 + Fe_tri 1.519e-05 1.519e-05 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 4.884 Charge balance + pe = 15.729 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.028e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.542e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 6.894e-15 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 21 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.431e-05 1.306e-05 -4.844 -4.884 -0.040 + OH- 8.523e-10 7.662e-10 -9.069 -9.116 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 7.779e-07 7.008e-07 -6.109 -6.154 -0.045 + Fe_triCl+2 4.323e-10 2.848e-10 -9.364 -9.546 -0.181 + Fe_triCl2+ 1.295e-11 1.167e-11 -10.888 -10.933 -0.045 + Fe_triCl3 1.068e-14 1.070e-14 -13.972 -13.971 0.001 +Fe_di 8.481e-05 + Fe_di+2 8.403e-05 5.535e-05 -4.076 -4.257 -0.181 + Fe_diCl+ 7.779e-07 7.008e-07 -6.109 -6.154 -0.045 + Fe_diOH+ 1.487e-09 1.340e-09 -8.828 -8.873 -0.045 +Fe_tri 1.519e-05 + Fe_tri(OH)2+ 1.429e-05 1.288e-05 -4.845 -4.890 -0.045 + Fe_triOH+2 7.712e-07 5.080e-07 -6.113 -6.294 -0.181 + Fe_tri(OH)3 1.266e-07 1.269e-07 -6.897 -6.896 0.001 + Fe_tri+3 2.630e-09 1.028e-09 -8.580 -8.988 -0.408 + Fe_triCl+2 4.323e-10 2.848e-10 -9.364 -9.546 -0.181 + Fe_tri2(OH)2+4 3.689e-11 6.947e-12 -10.433 -11.158 -0.725 + Fe_triCl2+ 1.295e-11 1.167e-11 -10.888 -10.933 -0.045 + Fe_tri(OH)4- 9.835e-12 8.861e-12 -11.007 -11.053 -0.045 + Fe_tri3(OH)4+5 2.539e-13 1.869e-14 -12.595 -13.728 -1.133 + Fe_triCl3 1.068e-14 1.070e-14 -13.972 -13.971 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 4.550e-12 4.561e-12 -11.342 -11.341 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 9. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 172800 seconds (Incremented time: 518400 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -2.157e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -5.393e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 8.265e-05 8.265e-05 + Fe_tri 1.735e-05 1.735e-05 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 4.829 Charge balance + pe = 15.784 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.028e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.758e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 5.287e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 18 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.624e-05 1.482e-05 -4.789 -4.829 -0.040 + OH- 7.509e-10 6.751e-10 -9.124 -9.171 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 7.581e-07 6.830e-07 -6.120 -6.166 -0.045 + Fe_triCl+2 6.322e-10 4.164e-10 -9.199 -9.380 -0.181 + Fe_triCl2+ 1.894e-11 1.706e-11 -10.723 -10.768 -0.045 + Fe_triCl3 1.561e-14 1.565e-14 -13.807 -13.806 0.001 +Fe_di 8.265e-05 + Fe_di+2 8.189e-05 5.395e-05 -4.087 -4.268 -0.181 + Fe_diCl+ 7.581e-07 6.830e-07 -6.120 -6.166 -0.045 + Fe_diOH+ 1.277e-09 1.150e-09 -8.894 -8.939 -0.045 +Fe_tri 1.735e-05 + Fe_tri(OH)2+ 1.622e-05 1.462e-05 -4.790 -4.835 -0.045 + Fe_triOH+2 9.937e-07 6.546e-07 -6.003 -6.184 -0.181 + Fe_tri(OH)3 1.267e-07 1.270e-07 -6.897 -6.896 0.001 + Fe_tri+3 3.845e-09 1.503e-09 -8.415 -8.823 -0.408 + Fe_triCl+2 6.322e-10 4.164e-10 -9.199 -9.380 -0.181 + Fe_tri2(OH)2+4 6.124e-11 1.153e-11 -10.213 -10.938 -0.725 + Fe_triCl2+ 1.894e-11 1.706e-11 -10.723 -10.768 -0.045 + Fe_tri(OH)4- 8.668e-12 7.809e-12 -11.062 -11.107 -0.045 + Fe_tri3(OH)4+5 4.783e-13 3.522e-14 -12.320 -13.453 -1.133 + Fe_triCl3 1.561e-14 1.565e-14 -13.807 -13.806 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 4.009e-12 4.019e-12 -11.397 -11.396 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 10. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 172800 seconds (Incremented time: 691200 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.711e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -4.279e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 8.094e-05 8.094e-05 + Fe_tri 1.906e-05 1.906e-05 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 4.790 Charge balance + pe = 15.822 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.028e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 1.929e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 5.594e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 18 + Total H = 1.110124e+02 + Total O = 5.550669e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.776e-05 1.621e-05 -4.751 -4.790 -0.040 + OH- 6.869e-10 6.175e-10 -9.163 -9.209 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 7.425e-07 6.689e-07 -6.129 -6.175 -0.045 + Fe_triCl+2 8.261e-10 5.442e-10 -9.083 -9.264 -0.181 + Fe_triCl2+ 2.475e-11 2.230e-11 -10.606 -10.652 -0.045 + Fe_triCl3 2.040e-14 2.045e-14 -13.690 -13.689 0.001 +Fe_di 8.094e-05 + Fe_di+2 8.020e-05 5.283e-05 -4.096 -4.277 -0.181 + Fe_diCl+ 7.425e-07 6.689e-07 -6.129 -6.175 -0.045 + Fe_diOH+ 1.144e-09 1.031e-09 -8.942 -8.987 -0.045 +Fe_tri 1.906e-05 + Fe_tri(OH)2+ 1.774e-05 1.598e-05 -4.751 -4.796 -0.045 + Fe_triOH+2 1.188e-06 7.825e-07 -5.925 -6.107 -0.181 + Fe_tri(OH)3 1.267e-07 1.270e-07 -6.897 -6.896 0.001 + Fe_tri+3 5.025e-09 1.965e-09 -8.299 -8.707 -0.408 + Fe_triCl+2 8.261e-10 5.442e-10 -9.083 -9.264 -0.181 + Fe_tri2(OH)2+4 8.749e-11 1.648e-11 -10.058 -10.783 -0.725 + Fe_triCl2+ 2.475e-11 2.230e-11 -10.606 -10.652 -0.045 + Fe_tri(OH)4- 7.930e-12 7.145e-12 -11.101 -11.146 -0.045 + Fe_tri3(OH)4+5 7.472e-13 5.503e-14 -12.127 -13.259 -1.133 + Fe_triCl3 2.040e-14 2.045e-14 -13.690 -13.689 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 3.667e-12 3.676e-12 -11.436 -11.435 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +Reaction step 11. + +Using solution 1. +Using pure phase assemblage 1. +Using kinetics 1. Kinetics defined in simulation 2. + +Kinetics 1. Kinetics defined in simulation 2. + + Time step: 172800 seconds (Incremented time: 864000 seconds) + + Rate name Delta Moles Total Moles Reactant Coefficient + + Fe_di_ox -1.441e-06 1.000e+00 Fe_di -1 + Fe_tri 1 + +-------------------------------Phase assemblage-------------------------------- + + Moles in assemblage + Phase SI log IAP log KT Initial Final Delta + + O2(g) -0.67 82.45 83.12 1.000e+01 1.000e+01 -3.603e-07 + +-----------------------------Solution composition------------------------------ + + Elements Molality Moles + + Cl 1.020e-02 1.020e-02 + Fe_di 7.950e-05 7.950e-05 + Fe_tri 2.050e-05 2.050e-05 + Na 1.000e-02 1.000e-02 + +----------------------------Description of solution---------------------------- + + pH = 4.760 Charge balance + pe = 15.852 Adjusted to redox equilibrium + Activity of water = 1.000 + Ionic strength = 1.028e-02 + Mass of water (kg) = 1.000e+00 + Total alkalinity (eq/kg) = 2.073e-05 + Total carbon (mol/kg) = 0.000e+00 + Total CO2 (mol/kg) = 0.000e+00 + Temperature (deg C) = 25.000 + Electrical balance (eq) = 5.638e-14 + Percent error, 100*(Cat-|An|)/(Cat+|An|) = 0.00 + Iterations = 18 + Total H = 1.110124e+02 + Total O = 5.550670e+01 + +----------------------------Distribution of species---------------------------- + + Log Log Log + Species Molality Activity Molality Activity Gamma + + H+ 1.902e-05 1.736e-05 -4.721 -4.760 -0.040 + OH- 6.413e-10 5.765e-10 -9.193 -9.239 -0.046 + H2O 5.551e+01 9.997e-01 1.744 -0.000 0.000 +Cl 1.020e-02 + Cl- 1.020e-02 9.172e-03 -1.991 -2.038 -0.046 + Fe_diCl+ 7.293e-07 6.570e-07 -6.137 -6.182 -0.045 + Fe_triCl+2 1.015e-09 6.689e-10 -8.993 -9.175 -0.181 + Fe_triCl2+ 3.042e-11 2.740e-11 -10.517 -10.562 -0.045 + Fe_triCl3 2.508e-14 2.513e-14 -13.601 -13.600 0.001 +Fe_di 7.950e-05 + Fe_di+2 7.877e-05 5.189e-05 -4.104 -4.285 -0.181 + Fe_diCl+ 7.293e-07 6.570e-07 -6.137 -6.182 -0.045 + Fe_diOH+ 1.049e-09 9.450e-10 -8.979 -9.025 -0.045 +Fe_tri 2.050e-05 + Fe_tri(OH)2+ 1.900e-05 1.712e-05 -4.721 -4.766 -0.045 + Fe_triOH+2 1.363e-06 8.979e-07 -5.866 -6.047 -0.181 + Fe_tri(OH)3 1.267e-07 1.270e-07 -6.897 -6.896 0.001 + Fe_tri+3 6.176e-09 2.415e-09 -8.209 -8.617 -0.408 + Fe_triCl+2 1.015e-09 6.689e-10 -8.993 -9.175 -0.181 + Fe_tri2(OH)2+4 1.152e-10 2.170e-11 -9.939 -10.664 -0.725 + Fe_triCl2+ 3.042e-11 2.740e-11 -10.517 -10.562 -0.045 + Fe_tri(OH)4- 7.405e-12 6.671e-12 -11.130 -11.176 -0.045 + Fe_tri3(OH)4+5 1.054e-12 7.762e-14 -11.977 -13.110 -1.133 + Fe_triCl3 2.508e-14 2.513e-14 -13.601 -13.600 0.001 +H(0) 0.000e+00 + H2 0.000e+00 0.000e+00 -44.376 -44.375 0.001 +Na 1.000e-02 + Na+ 1.000e-02 9.020e-03 -2.000 -2.045 -0.045 + NaOH 3.424e-12 3.432e-12 -11.465 -11.464 0.001 +O(0) 4.677e-04 + O2 2.339e-04 2.344e-04 -3.631 -3.630 0.001 + +------------------------------Saturation indices------------------------------- + + Phase SI log IAP log KT + + Goethite 6.66 5.66 -1.00 Fe_triOOH + H2(g) -41.23 -44.38 -3.15 H2 + H2O(g) -1.51 -0.00 1.51 H2O + Halite -5.66 -4.08 1.58 NaCl + O2(g) -0.67 -3.63 -2.96 O2 + +------------------ +End of simulation. +------------------ + +------------------------------------ +Reading input data for simulation 3. +------------------------------------ + +----------- +End of run. +----------- + +No memory leaks diff --git a/Sun/examples/ex9.sel b/Sun/examples/ex9.sel new file mode 100644 index 00000000..98dc3b1e --- /dev/null +++ b/Sun/examples/ex9.sel @@ -0,0 +1,13 @@ + Days Fe(2) Fe(3) pH si_goethite + 0.0000e+00 1.0000e+02 0.0000e+00 7.0000e+00 -9.9990e+01 + 1.1574e-03 9.8942e+01 1.0578e+00 6.0476e+00 6.6424e+00 + 5.7870e-03 9.8206e+01 1.7942e+00 5.8097e+00 6.6543e+00 + 4.1667e-02 9.6592e+01 3.4082e+00 5.5247e+00 6.6602e+00 + 1.6667e-01 9.4639e+01 5.3610e+00 5.3268e+00 6.6620e+00 + 4.1667e-01 9.2764e+01 7.2360e+00 5.1975e+00 6.6627e+00 + 1.0000e+00 9.0358e+01 9.6422e+00 5.0750e+00 6.6632e+00 + 2.0000e+00 8.7896e+01 1.2104e+01 4.9790e+00 6.6635e+00 + 4.0000e+00 8.4808e+01 1.5192e+01 4.8840e+00 6.6638e+00 + 6.0000e+00 8.2651e+01 1.7349e+01 4.8290e+00 6.6639e+00 + 8.0000e+00 8.0939e+01 1.9061e+01 4.7903e+00 6.6640e+00 + 1.0000e+01 7.9498e+01 2.0502e+01 4.7605e+00 6.6640e+00 diff --git a/SurfCharge.cxx b/SurfCharge.cxx new file mode 100644 index 00000000..1a0cf559 --- /dev/null +++ b/SurfCharge.cxx @@ -0,0 +1,493 @@ +// SurfCharge.cxx: implementation of the cxxSurfCharge class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "SurfCharge.h" +#define EXTERNAL extern +#include "global.h" +#include "output.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSurfCharge::cxxSurfCharge() + // + // default constructor for cxxSurfCharge + // +{ + name = NULL; + specific_area = 0.0; + grams = 0.0; + charge_balance = 0.0; + mass_water = 0.0; + la_psi = 0.0; + diffuse_layer_totals.type = cxxNameDouble::ND_ELT_MOLES; +} + +cxxSurfCharge::cxxSurfCharge(struct surface_charge *surf_charge_ptr) + // + // constructor for cxxSurfCharge from struct surface_charge + // +: +diffuse_layer_totals(surf_charge_ptr->diffuse_layer_totals) +{ + name = surf_charge_ptr->name; + specific_area = surf_charge_ptr->specific_area; + grams = surf_charge_ptr->grams; + charge_balance = surf_charge_ptr->charge_balance; + mass_water = surf_charge_ptr->mass_water; + la_psi = surf_charge_ptr->la_psi; +} + +cxxSurfCharge::~cxxSurfCharge() +{ +} + +struct master *cxxSurfCharge::get_psi_master() +{ + struct master *master_ptr = NULL; + std::string str = this->name; + + str.append("_psi"); + master_ptr = master_bsearch(str.c_str()); + if (master_ptr == NULL) { + std::ostringstream error_oss; + error_oss << "Surface charge psi_master not found." << this->name << std::endl; + //Utilities::error_msg(error_oss.str(), CONTINUE); + error_msg(error_oss.str().c_str(), CONTINUE); + } + return(master_ptr); +} + +struct surface_charge *cxxSurfCharge::cxxSurfCharge2surface_charge(std::list& el) + // + // Builds surface_charge structure from of cxxSurfCharge + // +{ + struct surface_charge *surf_charge_ptr = (struct surface_charge *) PHRQ_malloc((size_t) (el.size() * sizeof(struct surface_charge))); + if (surf_charge_ptr == NULL) malloc_error(); + + int i = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + surf_charge_ptr[i].name = it->name; + surf_charge_ptr[i].specific_area = it->specific_area; + surf_charge_ptr[i].grams = it->grams; + surf_charge_ptr[i].charge_balance = it->charge_balance; + surf_charge_ptr[i].mass_water = it->mass_water; + surf_charge_ptr[i].la_psi = it->la_psi; + surf_charge_ptr[i].diffuse_layer_totals = it->diffuse_layer_totals.elt_list(); + surf_charge_ptr[i].psi_master = it->get_psi_master(); + surf_charge_ptr[i].count_g = 0; + surf_charge_ptr[i].g = NULL; + i++; + } + return(surf_charge_ptr); +} + +void cxxSurfCharge::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surf_charge message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surf_Charge element and attributes + + s_oss << indent0 << "name=\"" << this->name << "\"" << std::endl; + s_oss << indent0 << "specific_area=\"" << this->specific_area << "\"" << std::endl; + s_oss << indent0 << "grams=\"" << this->grams << "\"" << std::endl; + s_oss << indent0 << "charge_balance=\"" << this->charge_balance << "\"" << std::endl; + s_oss << indent0 << "mass_water=\"" << this->mass_water << "\"" << std::endl; + s_oss << indent0 << "la_psi=\"" << this->la_psi << "\"" << std::endl; + + // totals + s_oss << indent0; + s_oss << "diffuse_layer_totals.dump_xml(s_oss, indent + 1); + +} + +void cxxSurfCharge::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surf_charge message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surf_Charge element and attributes + + s_oss << indent0 << "-name " << this->name << std::endl; + s_oss << indent0 << "-specific_area " << this->specific_area << std::endl; + s_oss << indent0 << "-grams " << this->grams << std::endl; + s_oss << indent0 << "-charge_balance " << this->charge_balance << std::endl; + s_oss << indent0 << "-mass_water " << this->mass_water << std::endl; + s_oss << indent0 << "-la_psi " << this->la_psi << std::endl; + + // totals + s_oss << indent0; + s_oss << "-diffuse_layer_totals" << std::endl; + this->diffuse_layer_totals.dump_raw(s_oss, indent + 1); + +} + +void cxxSurfCharge::read_raw(CParser& parser) +{ + std::string str; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("name"); // 0 + vopts.push_back("specific_area"); // 1 + vopts.push_back("grams"); // 2 + vopts.push_back("charge_balance"); // 3 + vopts.push_back("mass_water"); // 4 + vopts.push_back("la_psi"); // 5 + vopts.push_back("diffuse_layer_totals"); // 6 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool name_defined(false); + bool specific_area_defined(false); + bool grams_defined(false); + bool charge_balance_defined(false); + bool mass_water_defined(false); + bool la_psi_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Surface for more processing + //parser.error_msg("Unknown input in SURF_CHARGE read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // name + if (!(parser.get_iss() >> str)) + { + this->name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for name.", CParser::OT_CONTINUE); + } else { + this->name = string_hsave(str.c_str()); + } + name_defined = true; + break; + + case 1: // specific_area + if (!(parser.get_iss() >> this->specific_area)) + { + this->specific_area = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for specific_area.", CParser::OT_CONTINUE); + } + specific_area_defined = true; + break; + + case 2: // grams + if (!(parser.get_iss() >> this->grams)) + { + this->grams = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for grams.", CParser::OT_CONTINUE); + } + grams_defined = true; + break; + + + case 3: // charge_balance + if (!(parser.get_iss() >> this->charge_balance)) + { + this->charge_balance = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for charge_balance.", CParser::OT_CONTINUE); + } + charge_balance_defined = true; + break; + + case 4: // mass_water + if (!(parser.get_iss() >> this->mass_water)) + { + this->mass_water = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass_water.", CParser::OT_CONTINUE); + } + mass_water_defined = true; + break; + + + case 5: // la_psi + if (!(parser.get_iss() >> this->la_psi)) + { + this->la_psi = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for la_psi.", CParser::OT_CONTINUE); + } + la_psi_defined = true; + break; + + + case 6: // diffuse_layer_totals + if ( this->diffuse_layer_totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for SurfCharge diffuse_layer_totals.", CParser::OT_CONTINUE); + } + opt_save = 6; + break; + + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (name_defined == false) { + parser.incr_input_error(); + parser.error_msg("Name not defined for SurfCharge input.", CParser::OT_CONTINUE); + } + if (specific_area_defined == false) { + parser.incr_input_error(); + parser.error_msg("Specific_area not defined for SurfCharge input.", CParser::OT_CONTINUE); + } + if (grams_defined == false) { + parser.incr_input_error(); + parser.error_msg("Grams not defined for SurfCharge input.", CParser::OT_CONTINUE); + } + if (charge_balance_defined == false) { + parser.incr_input_error(); + parser.error_msg("Charge_balance not defined for SurfCharge input.", CParser::OT_CONTINUE); + } + if (mass_water_defined == false) { + parser.incr_input_error(); + parser.error_msg("Mass_water not defined for SurfCharge input.", CParser::OT_CONTINUE); + } + if (la_psi_defined == false) { + parser.incr_input_error(); + parser.error_msg("La_psi not defined for SurfCharge input.", CParser::OT_CONTINUE); + } +} + +#ifdef SKIP +cxxSurfCharge& cxxSurfCharge::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxSurfCharge numkey; + + // Read surf_charge number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxSurfCharge& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SURF_CHARGE keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.surf_charge_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in surf_charge.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif + diff --git a/SurfCharge.h b/SurfCharge.h new file mode 100644 index 00000000..63022761 --- /dev/null +++ b/SurfCharge.h @@ -0,0 +1,50 @@ +#if !defined(SURFCHARGE_H_INCLUDED) +#define SURFCHARGE_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxSurfCharge +{ + +public: + + cxxSurfCharge(); + cxxSurfCharge(struct surface_charge *); + ~cxxSurfCharge(); + + + struct master *get_psi_master(); + + static struct surface_charge *cxxSurfCharge2surface_charge(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + char * name; + double specific_area; + double grams; + double charge_balance; + double mass_water; + double la_psi; + //std::map g; + //char * psi_master_name; + cxxNameDouble diffuse_layer_totals; + +public: + +}; + +#endif // !defined(SURFCHARGE_H_INCLUDED) diff --git a/SurfComp.cxx b/SurfComp.cxx new file mode 100644 index 00000000..e7cb0c55 --- /dev/null +++ b/SurfComp.cxx @@ -0,0 +1,537 @@ +// SurfComp.cxx: implementation of the cxxSurfComp class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "SurfComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include "output.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSurfComp::cxxSurfComp() + // + // default constructor for cxxSurfComp + // +{ + formula = NULL; + moles = 0.0; + totals.type = cxxNameDouble::ND_ELT_MOLES; + la = 0.0; + charge_number = -99; + charge_balance = 0; + phase_name = NULL; + phase_proportion = 0.0; + rate_name = NULL; +} + +cxxSurfComp::cxxSurfComp(struct surface_comp *surf_comp_ptr) + // + // constructor for cxxSurfComp from struct surface_comp + // +: +totals(surf_comp_ptr->totals) +{ + formula = surf_comp_ptr->formula; + moles = surf_comp_ptr->moles; + la = surf_comp_ptr->la; + charge_number = surf_comp_ptr->charge; + charge_balance = surf_comp_ptr->cb; + phase_name = surf_comp_ptr->phase_name; + phase_proportion = surf_comp_ptr->phase_proportion; + rate_name = surf_comp_ptr->rate_name; +} + +cxxSurfComp::~cxxSurfComp() +{ +} + +struct master *cxxSurfComp::get_master() +{ + struct master *master_ptr = NULL; + //for (std::map ::iterator it = totals.begin(); it != totals.end(); it++) { + for (cxxNameDouble::iterator it = this->totals.begin(); it != this->totals.end(); it++) { + /* Find master species */ + char *eltName = it->first; + struct element *elt_ptr = element_store(eltName); + if (elt_ptr->master == NULL) { + std::ostringstream error_oss; + error_oss << "Master species not in data base for " << elt_ptr->name << std::endl; + //Utilities::error_msg(error_oss.str(), CONTINUE); + error_msg(error_oss.str().c_str(), CONTINUE); + return(NULL); + } + if (elt_ptr->master->type != SURF) continue; + master_ptr = elt_ptr->master; + break; + } + if (master_ptr == NULL) { + std::ostringstream error_oss; + error_oss << "Surface formula does not contain an surface master species, " << this->formula << std::endl; + //Utilities::error_msg(error_oss.str(), CONTINUE); + error_msg(error_oss.str().c_str(), CONTINUE); + } + return(master_ptr); +} + +struct surface_comp *cxxSurfComp::cxxSurfComp2surface_comp(std::list& el) + // + // Builds surface_comp structure from of cxxSurfComp + // +{ + struct surface_comp *surf_comp_ptr = (struct surface_comp *) PHRQ_malloc((size_t) (el.size() * sizeof(struct surface_comp))); + if (surf_comp_ptr == NULL) malloc_error(); + + int i = 0; + for (std::list::iterator it = el.begin(); it != el.end(); ++it) { + surf_comp_ptr[i].formula = it->formula; + surf_comp_ptr[i].moles = it->moles; + surf_comp_ptr[i].master = it->get_master(); + surf_comp_ptr[i].totals = it->totals.elt_list(); + surf_comp_ptr[i].la = it->la; + surf_comp_ptr[i].charge = it->charge_number; + surf_comp_ptr[i].cb = it->charge_balance; + surf_comp_ptr[i].phase_name = it->phase_name; + surf_comp_ptr[i].phase_proportion = it->phase_proportion; + surf_comp_ptr[i].rate_name = it->rate_name; + surf_comp_ptr[i].master = it->get_master(); + i++; + } + return(surf_comp_ptr); +} + +void cxxSurfComp::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surf_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surf_Comp element and attributes + + s_oss << indent0 << "formula=\"" << this->formula << "\"" << std::endl; + s_oss << indent0 << "moles=\"" << this->moles << "\"" << std::endl; + s_oss << indent0 << "la=\"" << this->la << "\"" << std::endl; + s_oss << indent0 << "charge_number=\"" << this->charge_number << "\"" << std::endl; + s_oss << indent0 << "charge_balance=\"" << this->charge_balance << "\"" << std::endl; + if (this->phase_name != NULL) { + s_oss << indent0 << "phase_name=\"" << this->phase_name << "\"" << std::endl; + } + if (this->rate_name != NULL) { + s_oss << indent0 << "rate_name=\"" << this->rate_name << "\"" << std::endl; + } + s_oss << indent0 << "phase_proportion=\"" << this->phase_proportion << "\"" << std::endl; + + // totals + s_oss << indent0; + s_oss << "totals.dump_xml(s_oss, indent + 1); + +} + +void cxxSurfComp::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surf_comp message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surf_Comp element and attributes + + s_oss << indent0 << "-formula " << this->formula << std::endl; + s_oss << indent0 << "-moles " << this->moles << std::endl; + s_oss << indent0 << "-la " << this->la << std::endl; + s_oss << indent0 << "-charge_number " << this->charge_number << std::endl; + s_oss << indent0 << "-charge_balance " << this->charge_balance << std::endl; + if (this->phase_name != NULL) { + s_oss << indent0 << "-phase_name " << this->phase_name << std::endl; + } + if (this->rate_name != NULL) { + s_oss << indent0 << "-rate_name " << this->rate_name << std::endl; + } + s_oss << indent0 << "-phase_proportion " << this->phase_proportion << std::endl; + + // totals + s_oss << indent0; + s_oss << "-totals" << std::endl; + this->totals.dump_raw(s_oss, indent + 1); + +} + +void cxxSurfComp::read_raw(CParser& parser) +{ + std::string str; + + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(10); + vopts.push_back("formula"); // 0 + vopts.push_back("moles"); // 1 + vopts.push_back("la"); // 2 + vopts.push_back("charge_number"); // 3 + vopts.push_back("charge_balance"); // 4 + vopts.push_back("phase_name"); // 5 + vopts.push_back("rate_name"); // 6 + vopts.push_back("phase_proportion"); // 7 + vopts.push_back("totals"); // 8 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + + opt_save = CParser::OPT_ERROR; + bool formula_defined(false); + bool moles_defined(false); + bool la_defined(false); + bool charge_number_defined(false); + bool charge_balance_defined(false); + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPT_DEFAULT) + { + opt = opt_save; + } + + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_KEYWORD; + // Allow return to Surface for more processing + //parser.error_msg("Unknown input in SURF_COMP read.", CParser::OT_CONTINUE); + //parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // formula + if (!(parser.get_iss() >> str)) + { + this->formula = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for formula.", CParser::OT_CONTINUE); + } else { + this->formula = string_hsave(str.c_str()); + } + formula_defined = true; + break; + + case 1: // moles + if (!(parser.get_iss() >> this->moles)) + { + this->moles = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for moles.", CParser::OT_CONTINUE); + } + moles_defined = true; + break; + + case 2: // la + if (!(parser.get_iss() >> this->la)) + { + this->la = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for la.", CParser::OT_CONTINUE); + } + la_defined = true; + break; + + case 3: // charge_number + if (!(parser.get_iss() >> this->charge_number)) + { + this->charge_number = 0; + parser.incr_input_error(); + parser.error_msg("Expected integer value for charge_number.", CParser::OT_CONTINUE); + } + charge_number_defined = true; + break; + + case 4: // charge_balance + if (!(parser.get_iss() >> this->charge_balance)) + { + this->charge_balance = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for charge_balance.", CParser::OT_CONTINUE); + } + charge_balance_defined = true; + break; + + case 5: // phase_name + if (!(parser.get_iss() >> str)) + { + this->phase_name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for phase_name.", CParser::OT_CONTINUE); + } else { + this->phase_name = string_hsave(str.c_str()); + } + break; + + case 6: // rate_name + if (!(parser.get_iss() >> str)) + { + this->rate_name = NULL; + parser.incr_input_error(); + parser.error_msg("Expected string value for rate_name.", CParser::OT_CONTINUE); + } else { + this->rate_name = string_hsave(str.c_str()); + } + break; + + case 7: // phase_proportion + if (!(parser.get_iss() >> this->phase_proportion)) + { + this->phase_proportion = 0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for phase_proportion.", CParser::OT_CONTINUE); + } + break; + + case 8: // totals + if ( this->totals.read_raw(parser, next_char) != CParser::PARSER_OK) { + parser.incr_input_error(); + parser.error_msg("Expected element name and molality for SurfComp totals.", CParser::OT_CONTINUE); + } + opt_save = 8; + break; + + } + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (formula_defined == false) { + parser.incr_input_error(); + parser.error_msg("Formula not defined for SurfComp input.", CParser::OT_CONTINUE); + } + if (moles_defined == false) { + parser.incr_input_error(); + parser.error_msg("Moles not defined for SurfComp input.", CParser::OT_CONTINUE); + } + if (la_defined == false) { + parser.incr_input_error(); + parser.error_msg("La not defined for SurfComp input.", CParser::OT_CONTINUE); + } + if (charge_number_defined == false) { + parser.incr_input_error(); + parser.error_msg("Charge_number not defined for SurfComp input.", CParser::OT_CONTINUE); + } + if (charge_balance_defined == false) { + parser.incr_input_error(); + parser.error_msg("Charge_balance not defined for SurfComp input.", CParser::OT_CONTINUE); + } +} + +#ifdef SKIP +cxxSurfComp& cxxSurfComp::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxSurfComp numkey; + + // Read surf_comp number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxSurfComp& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SURF_COMP keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.surf_comp_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in surf_comp.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif + diff --git a/SurfComp.h b/SurfComp.h new file mode 100644 index 00000000..c025dc95 --- /dev/null +++ b/SurfComp.h @@ -0,0 +1,52 @@ +#if !defined(SURFCOMP_H_INCLUDED) +#define SURFCOMP_H_INCLUDED + +#include "NameDouble.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" + +class cxxSurfComp +{ + +public: + + cxxSurfComp(); + cxxSurfComp(struct surface_comp *); + ~cxxSurfComp(); + + + struct master *get_master(); + char *get_phase_name()const {return this->phase_name;} + char *get_rate_name()const {return this->rate_name;} + + static struct surface_comp *cxxSurfComp2surface_comp(std::list& el); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + +protected: + char * formula; + double moles; + cxxNameDouble totals; + double la; + int charge_number; + double charge_balance; + char *phase_name; + double phase_proportion; + char *rate_name; + +public: + +}; + +#endif // !defined(SURFCOMP_H_INCLUDED) diff --git a/Surface.cxx b/Surface.cxx new file mode 100644 index 00000000..f4e1a971 --- /dev/null +++ b/Surface.cxx @@ -0,0 +1,557 @@ +// Surface.cxx: implementation of the cxxSurface class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif + +#include "Utils.h" // define first +#include "Surface.h" +#include "SurfComp.h" +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "phrqproto.h" +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +cxxSurface::cxxSurface() + // + // default constructor for cxxSurface + // +: cxxNumKeyword() +{ + diffuse_layer = false; + edl = false; + only_counter_ions = false; + donnan = false; + thickness = 0.0; +} + +cxxSurface::cxxSurface(struct surface *surface_ptr) + // + // constructor for cxxSurface from struct surface + // +: +cxxNumKeyword() + +{ + int i; + + this->set_description(surface_ptr->description); + n_user = surface_ptr->n_user; + n_user_end = surface_ptr->n_user_end; + diffuse_layer = (surface_ptr->diffuse_layer == TRUE); + edl = (surface_ptr->edl == TRUE); + only_counter_ions = (surface_ptr->only_counter_ions == TRUE); + donnan = (surface_ptr->donnan == TRUE); + thickness = surface_ptr->thickness; + // Surface components + for (i = 0; i < surface_ptr->count_comps; i++) { + cxxSurfComp ec(&(surface_ptr->comps[i])); + surfComps.push_back(ec); + } + // Surface charge + for (i = 0; i < surface_ptr->count_charge; i++) { + cxxSurfCharge ec(&(surface_ptr->charge[i])); + surfCharges.push_back(ec); + } +} + +cxxSurface::~cxxSurface() +{ +} + +bool cxxSurface::get_related_phases() +{ + for (std::list::const_iterator it = this->surfComps.begin(); it != this->surfComps.end(); ++it) { + if (it->get_phase_name() == NULL) continue; + return(true); + } + return(false); +} + +bool cxxSurface::get_related_rate() +{ + for (std::list::const_iterator it = this->surfComps.begin(); it != this->surfComps.end(); ++it) { + if (it->get_rate_name() == NULL) continue; + return(true); + } + return(false); +} + +struct surface *cxxSurface::cxxSurface2surface() + // + // Builds a surface structure from instance of cxxSurface + // +{ + struct surface *surface_ptr = surface_alloc(); + + surface_ptr->description = this->get_description(); + surface_ptr->n_user = this->n_user; + surface_ptr->n_user_end = this->n_user_end; + surface_ptr->new_def = FALSE; + surface_ptr->diffuse_layer = this->diffuse_layer; + surface_ptr->edl = this->edl; + surface_ptr->only_counter_ions = this->only_counter_ions; + surface_ptr->donnan = this->donnan; + surface_ptr->thickness = this->thickness; + surface_ptr->debye_units = 1.0; + surface_ptr->solution_equilibria = FALSE; + surface_ptr->n_solution = -2; + surface_ptr->related_phases = (int) this->get_related_phases(); + surface_ptr->related_rate = (int) this->get_related_rate(); + surface_ptr->transport = FALSE; + + // Surface comps + surface_ptr->count_comps = this->surfComps.size(); + surface_ptr->comps = (struct surface_comp *) free_check_null(surface_ptr->comps); + surface_ptr->comps = cxxSurfComp::cxxSurfComp2surface_comp(this->surfComps); + + // Surface charge + surface_ptr->count_charge = this->surfCharges.size(); + surface_ptr->charge = (struct surface_charge *) free_check_null(surface_ptr->charge); + surface_ptr->charge = cxxSurfCharge::cxxSurfCharge2surface_charge(this->surfCharges); + + return(surface_ptr); +} + +void cxxSurface::dump_xml(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surface message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surface element and attributes + s_oss << indent0; + s_oss << "diffuse_layer << "\"" << std::endl; + + s_oss << indent1; + s_oss << "edl=\"" << this->edl << "\"" << std::endl; + + s_oss << indent1; + s_oss << "only_counter_ions=\"" << this->only_counter_ions << "\"" << std::endl; + + s_oss << indent1; + s_oss << "donnan=\"" << this->donnan << "\"" << std::endl; + + s_oss << indent1; + s_oss << "thickness=\"" << this->thickness << "\"" << std::endl; + + // surface component structures + s_oss << indent1; + s_oss << "::const_iterator it = this->surfComps.begin(); it != this->surfComps.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + } + // surface charge structures + s_oss << indent1; + s_oss << "::const_iterator it = surfCharges.begin(); it != surfCharges.end(); ++it) { + it->dump_xml(s_oss, indent + 2); + } + + return; +} + +void cxxSurface::dump_raw(std::ostream& s_oss, unsigned int indent)const +{ + //const char ERR_MESSAGE[] = "Packing surface message: %s, element not found\n"; + unsigned int i; + s_oss.precision(DBL_DIG - 1); + std::string indent0(""), indent1(""), indent2(""); + for(i = 0; i < indent; ++i) indent0.append(Utilities::INDENT); + for(i = 0; i < indent + 1; ++i) indent1.append(Utilities::INDENT); + for(i = 0; i < indent + 2; ++i) indent2.append(Utilities::INDENT); + + // Surface element and attributes + s_oss << indent0; + s_oss << "SURFACE_RAW " << this->n_user << " " << this->description << std::endl; + + s_oss << indent1; + s_oss << "-diffuse_layer " << this->diffuse_layer << std::endl; + + s_oss << indent1; + s_oss << "-edl " << this->edl << std::endl; + + s_oss << indent1; + s_oss << "-only_counter_ions " << this->only_counter_ions << std::endl; + + s_oss << indent1; + s_oss << "-donnan " << this->donnan << std::endl; + + s_oss << indent1; + s_oss << "-thickness " << this->thickness << std::endl; + + // surfComps structures + for (std::list::const_iterator it = surfComps.begin(); it != surfComps.end(); ++it) { + s_oss << indent1; + s_oss << "-component" << std::endl; + it->dump_raw(s_oss, indent + 2); + } + // surface charge structures + { + for (std::list::const_iterator it = surfCharges.begin(); it != surfCharges.end(); ++it) { + s_oss << indent1; + s_oss << "-charge_component " << std::endl; + it->dump_raw(s_oss, indent + 2); + } + } + + return; +} + +void cxxSurface::read_raw(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(15); + vopts.push_back("diffuse_layer"); // 0 + vopts.push_back("edl"); // 1 + vopts.push_back("only_counter_ions"); // 2 + vopts.push_back("donnan"); // 3 + vopts.push_back("thickness"); // 4 + vopts.push_back("component"); // 5 + vopts.push_back("charge_component"); // 6 + } + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + int opt_save; + bool useLastLine(false); + + // Read surface number and description + this->read_number_description(parser); + + opt_save = CParser::OPT_ERROR; + bool diffuse_layer_defined(false); + bool edl_defined(false); + bool only_counter_ions_defined(false); + bool donnan_defined(false); + bool thickness_defined(false); + + for (;;) + { + int opt; + if (useLastLine == false) { + opt = parser.get_option(vopts, next_char); + } else { + opt = parser.getOptionFromLastLine(vopts, next_char); + } + switch (opt) + { + case CParser::OPT_EOF: + break; + case CParser::OPT_KEYWORD: + break; + case CParser::OPT_DEFAULT: + case CParser::OPT_ERROR: + opt = CParser::OPT_EOF; + parser.error_msg("Unknown input in SURF_COMP_RAW keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + useLastLine = false; + break; + + case 0: // diffuse_layer + if (!(parser.get_iss() >> this->diffuse_layer)) + { + this->diffuse_layer = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for diffuse_layer.", CParser::OT_CONTINUE); + } + diffuse_layer_defined = true; + useLastLine = false; + break; + + case 1: // edl + if (!(parser.get_iss() >> this->edl)) + { + this->edl = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for edl.", CParser::OT_CONTINUE); + } + edl_defined = true; + useLastLine = false; + break; + + case 2: // only_counter_ions + if (!(parser.get_iss() >> this->only_counter_ions)) + { + this->only_counter_ions = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for only_counter_ions.", CParser::OT_CONTINUE); + } + only_counter_ions_defined = true; + useLastLine = false; + break; + + case 3: // donnan + if (!(parser.get_iss() >> this->donnan)) + { + this->donnan = false; + parser.incr_input_error(); + parser.error_msg("Expected boolean value for donnan.", CParser::OT_CONTINUE); + } + donnan_defined = true; + useLastLine = false; + break; + + case 4: // thickness + if (!(parser.get_iss() >> this->thickness)) + { + this->thickness = 0.0; + parser.incr_input_error(); + parser.error_msg("Expected numeric value for thickness.", CParser::OT_CONTINUE); + } + thickness_defined = true; + useLastLine = false; + break; + + case 5: // component + { + cxxSurfComp ec; + ec.read_raw(parser); + this->surfComps.push_back(ec); + } + useLastLine = true; + break; + + case 6: // charge_component + { + cxxSurfCharge ec; + ec.read_raw(parser); + this->surfCharges.push_back(ec); + } + useLastLine = true; + break; + } + + if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD) break; + } + // members that must be defined + if (diffuse_layer_defined == false) { + parser.incr_input_error(); + parser.error_msg("Diffuse_layer not defined for SURFACE_RAW input.", CParser::OT_CONTINUE); + } + if (edl_defined == false) { + parser.incr_input_error(); + parser.error_msg("Edl not defined for SURFACE_RAW input.", CParser::OT_CONTINUE); + } + if (only_counter_ions_defined == false) { + parser.incr_input_error(); + parser.error_msg("Only_counter_ions not defined for SURFACE_RAW input.", CParser::OT_CONTINUE); + } + if (donnan_defined == false) { + parser.incr_input_error(); + parser.error_msg("Donnan not defined for SURFACE_RAW input.", CParser::OT_CONTINUE); + } + if (thickness_defined == false) { + parser.incr_input_error(); + parser.error_msg("Thickness not defined for SURFACE_RAW input.", CParser::OT_CONTINUE); + } +} +#ifdef SKIP +cxxSurface& cxxSurface::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + cxxSurface numkey; + + // Read surface number and description + numkey.read_number_description(parser); + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + //cxxSurface& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SURFACE keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = cxxPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.surface_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + cxxIsotope isotope; + if (isotope.read(parser) == cxxIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in surface.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + cxxConc conc; + if (conc.read(parser, sol) == cxxConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif diff --git a/Surface.h b/Surface.h new file mode 100644 index 00000000..03652f56 --- /dev/null +++ b/Surface.h @@ -0,0 +1,56 @@ +#if !defined(SURFACE_H_INCLUDED) +#define SURFACE_H_INCLUDED + +#include "NumKeyword.h" +#define EXTERNAL extern +#include "global.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + +#include "char_star.h" +#include "SurfComp.h" +#include "SurfCharge.h" + +class cxxSurface : public cxxNumKeyword +{ + +public: + cxxSurface(); + cxxSurface(struct surface *); + ~cxxSurface(); + + struct surface *cxxSurface2surface(); + + struct surf_comp *cxxSurfComp2surf_comp(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void dump_raw(std::ostream& s_oss, unsigned int indent)const; + + void read_raw(CParser& parser); + + bool get_related_phases(void); + + bool get_related_rate(void); + + +protected: + std::list surfComps; + std::list surfCharges; + bool diffuse_layer; + bool edl; + bool only_counter_ions; + bool donnan; + double thickness; + //double debye_units; + //int transport; + +public: + //static std::map& map; + +}; + +#endif // !defined(SURFACE_H_INCLUDED) diff --git a/Utils.cxx b/Utils.cxx new file mode 100644 index 00000000..81efd109 --- /dev/null +++ b/Utils.cxx @@ -0,0 +1,79 @@ +#ifdef _DEBUG +#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger) +#endif +#include // ::tolower +#include // ::tolower +#include //std::transform +#include // std::cout std::cerr + +#include "Utils.h" +#include "Parser.h" +#include "output.h" +//////////////////////////////////////////////////////////////////////////// +int Utilities::strcmp_nocase_arg1(const char *str1, const char *str2) +//////////////////////////////////////////////////////////////////////////// +{ + // + // Compare two strings disregarding case + // + int c1, c2; + while ((c1 = ::tolower(*str1++)) == (c2 = *str2++)) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} + +//////////////////////////////////////////////////////////////////////////// +int Utilities::strcmp_nocase(const char *str1, const char *str2) +//////////////////////////////////////////////////////////////////////////// +{ + // + // Compare two strings disregarding case + // + int c1, c2; + while ((c1 = ::tolower(*str1++)) == (c2 = ::tolower(*str2++))) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} + +//////////////////////////////////////////////////////////////////////////// +void Utilities::str_tolower(std::string& str) +//////////////////////////////////////////////////////////////////////////// +{ + std::transform(str.begin(), str.end(), str.begin(), tolower); +} + + + +//////////////////////////////////////////////////////////////////////////// +bool Utilities::replace(const char* str1, const char* str2, std::string& str) +//////////////////////////////////////////////////////////////////////////// +{ + std::string::size_type n = str.find(str1, 0); + if (n == std::string::npos) return false; + + str.replace(n, ::strlen(str1), str2); + return true; +} +//////////////////////////////////////////////////////////////////////////// +void Utilities::squeeze_white(std::string& s_l) +//////////////////////////////////////////////////////////////////////////// +{ + std::string str; + std::string::iterator beg = s_l.begin(); + std::string::iterator end = s_l.end(); + CParser::copy_token(str, beg, end); + s_l = str; +} +#ifdef SKIP +//////////////////////////////////////////////////////////////////////////// +void Utilities::error_msg (const std::string& err_str, const int stop) +//////////////////////////////////////////////////////////////////////////// +{ + //std::cerr << err_str << std::endl; + output_message(OUTPUT_ERROR, err_str, stop, "", args); +} +#endif diff --git a/Utils.h b/Utils.h new file mode 100644 index 00000000..0c1bba6c --- /dev/null +++ b/Utils.h @@ -0,0 +1,31 @@ +#if !defined(UTILITIES_H_INCLUDED) +#define UTILITIES_H_INCLUDED + +#include + +namespace Utilities { + + const char INDENT[] = " "; + + enum STATUS_TYPE { + OK = 0, + ERROR = 1 + }; + + STATUS_TYPE parse_couple(std::string& token); + + int strcmp_nocase(const char *str1, const char *str2); + + int strcmp_nocase_arg1(const char *str1, const char *str2); + + void str_tolower(std::string& str); + + bool replace(const char* str1, const char* str2, std::string& str); + + void squeeze_white(std::string& s_l); + + void error_msg(const std::string&, const int stopflag); + +} + +#endif // UTILITIES_H_INCLUDED diff --git a/advection.cpp b/advection.cpp new file mode 100644 index 00000000..9453c372 --- /dev/null +++ b/advection.cpp @@ -0,0 +1,103 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: advection.c 78 2005-02-01 22:47:12Z dlpark $"; + +/* ---------------------------------------------------------------------- */ +int advection(void) +/* ---------------------------------------------------------------------- */ +{ + int i, n; + LDBLE kin_time; + if (svnid == NULL) fprintf(stderr," "); +/* + * Calculate advection + */ + state = ADVECTION; +/* mass_water_switch = TRUE; */ +/* + * Check existence of all solutions + */ + for (i = 0; i <= count_ad_cells; i++) { + if (solution_bsearch(i, &n, TRUE) == NULL) { + input_error++; + sprintf(error_string, "Solution %d is needed for advection, but is not defined.", i); + error_msg(error_string, CONTINUE); + } + } +/* + * Check kinetics logic + */ + kin_time = advection_kin_time; + if (kin_time <= 0.0) { + for (i = 1; i <= count_ad_cells; i++) { + if (kinetics_bsearch(i, &n) != NULL) { + input_error++; + sprintf(error_string, "KINETIC reaction(s) defined, but time_step is not defined in ADVECTION keyword."); + error_msg(error_string, CONTINUE); + break; + } + } + } +/* + * Quit on error + */ + if (input_error > 0) { + error_msg("Program terminating due to input errors.", STOP); + } +/* + * Equilibrate solutions with phases, exchangers, surfaces + */ + last_model.force_prep = TRUE; + rate_sim_time_start = 0; + for (advection_step = 1; advection_step <= count_ad_shifts; advection_step++) { + output_msg(OUTPUT_LOG, "\nBeginning of advection time step %d, cumulative pore volumes %f.\n", advection_step, (double) (((LDBLE) advection_step) / ((LDBLE) count_ad_cells))); + if (pr.use == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE, "Beginning of advection time step %d, cumulative pore volumes %f.\n", + advection_step, (double) (((LDBLE) advection_step) / ((LDBLE) count_ad_cells))); + } +/* + * Advect + */ + for (i = count_ad_cells; i > 0; i--) { + solution_duplicate(i - 1, i); + } +/* + * Equilibrate and (or) mix + */ + for (i = 1; i <= count_ad_cells; i++) { + + cell_no = i; + set_advection(i, TRUE, TRUE, i); + run_reactions(i, kin_time, TRUE, 1.0); + if (advection_kin_time_defined == TRUE) { + rate_sim_time = rate_sim_time_start + kin_time; + } + output_msg(OUTPUT_LOG, "\nCell %d.\n\n", i); + if (pr.use == TRUE && pr.all == TRUE && + advection_step % print_ad_modulus == 0 && + advection_print[i-1] == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nCell %d.\n\n", i); + } + if (advection_step % punch_ad_modulus == 0 && + advection_punch[i-1] == TRUE ) { + punch_all(); + } + if (advection_step % print_ad_modulus == 0 && + advection_print[i-1] == TRUE ) { + print_all(); + } + if (i > 1) solution_duplicate(-2, i-1); + saver(); + } + solution_duplicate(-2, count_ad_cells); + rate_sim_time_start += kin_time; + } + initial_total_time += rate_sim_time_start; + /* free_model_allocs(); */ + mass_water_switch = FALSE; + return(OK); +} diff --git a/basic.cpp b/basic.cpp new file mode 100644 index 00000000..5b567552 --- /dev/null +++ b/basic.cpp @@ -0,0 +1,4400 @@ +/* Output from p2c, the Pascal-to-C translator */ +/* From input file "basic.p" */ + + +static char const svnid[] = "$Id: basic.c 247 2005-04-14 13:47:35Z dlpark $"; + +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +int n_user_punch_index; +#ifdef PHREEQ98 +void GridChar(char* s, char* a); +extern int colnr, rownr; +#endif + +#include "p2c.h" + +static int sget_logical_line(char **ptr, int *l, char *return_line); + +#define checking true +#define varnamelen 20 +#define maxdims 4 + +typedef Char varnamestring[varnamelen + 1]; +typedef Char string255[256]; + +#define tokvar 0 +#define toknum 1 +#define tokstr 2 +#define toksnerr 3 +#define tokplus 4 +#define tokminus 5 +#define toktimes 6 +#define tokdiv 7 +#define tokup 8 +#define toklp 9 +#define tokrp 10 +#define tokcomma 11 +#define toksemi 12 +#define tokcolon 13 +#define tokeq 14 +#define toklt 15 +#define tokgt 16 +#define tokle 17 +#define tokge 18 +#define tokne 19 +#define tokand 20 +#define tokor 21 +#define tokxor 22 +#define tokmod 23 +#define toknot 24 +#define toksqr 25 +#define toksqrt 26 +#define toksin 27 +#define tokcos 28 +#define toktan 29 +#define tokarctan 30 +#define toklog 31 +#define tokexp 32 +#define tokabs 33 +#define toksgn 34 +#define tokstr_ 35 +#define tokval 36 +#define tokchr_ 37 +#define tokasc 38 +#define toklen 39 +#define tokmid_ 40 +#define tokpeek 41 +#define tokrem 42 +#define toklet 43 +#define tokprint 44 +#define tokinput 45 +#define tokgoto 46 +#define tokif 47 +#define tokend 48 +#define tokstop 49 +#define tokfor 50 +#define toknext 51 +#define tokwhile 52 +#define tokwend 53 +#define tokgosub 54 +#define tokreturn 55 +#define tokread 56 +#define tokdata 57 +#define tokrestore 58 +#define tokgotoxy 59 +#define tokon 60 +#define tokdim 61 +#define tokpoke 62 +#define toklist 63 +#define tokrun 64 +#define toknew 65 +#define tokload 66 +#define tokmerge 67 +#define toksave 68 +#define tokbye 69 +#define tokdel 70 +#define tokrenum 71 +#define tokthen 72 +#define tokelse 73 +#define tokto 74 +#define tokstep 75 +#define toktc 76 +#define tokm0 77 +#define tokm 78 +#define tokparm 79 +#define tokact 80 +#define tokmol 81 +#define tokla 82 +#define toklm 83 +#define toksr 84 +#define toksi 85 +#define toktot 86 +#define toktk 87 +#define toktime 88 +#define toklog10 89 +#define toksim_time 90 +#define tokequi 91 +#define tokgas 92 +#define tokpunch 93 +#define tokkin 94 +#define toks_s 95 +#define tokmu 96 +#define tokalk 97 +#define tokrxn 98 +#define tokdist 99 +#define tokmisc1 100 +#define tokmisc2 101 +#define tokedl 102 +#define tokstep_no 103 +#define toksim_no 104 +#define toktotal_time 105 +#define tokput 106 +#define tokget 107 +#define tokcharge_balance 109 +#define tokpercent_error 110 +#ifdef PHREEQ98 +#define tokgraph_x 111 +#define tokgraph_y 112 +#define tokgraph_sy 113 +#endif +#define tokcell_no 114 +#define tokexists 115 +#define toksurf 116 +#define toklk_species 117 +#define toklk_named 118 +#define toklk_phase 119 +#define toksum_species 120 +#define toksum_gas 121 +#define toksum_s_s 122 +#define tokcalc_value 123 +#define tokdescription 124 +#define toksys 125 +#define tokinstr 126 +#define tokltrim 127 +#define tokrtrim 128 +#define toktrim 129 +#define tokpad 130 + +typedef LDBLE numarray[]; +typedef Char *strarray[]; + +#define forloop 0 +#define whileloop 1 +#define gosubloop 2 + +typedef struct tokenrec { + struct tokenrec *next; + int kind; + union { + struct varrec *vp; + LDBLE num; + Char *sp; + Char snch; + } UU; +} tokenrec; + +typedef struct linerec { + long num, num2; + tokenrec *txt; + struct linerec *next; +} linerec; + +typedef struct varrec { + varnamestring name; + struct varrec *next; + long dims[maxdims]; + char numdims; + boolean stringvar; + union { + struct { + LDBLE *arr; + LDBLE *val, rv; + } U0; + struct { + Char **sarr; + Char **sval, *sv; + } U1; + } UU; +} varrec; + +typedef struct valrec { + boolean stringval; + union { + LDBLE val; + Char *sval; + } UU; +} valrec; + +typedef struct looprec { + struct looprec *next; + linerec *homeline; + tokenrec *hometok; + int kind; + union { + struct { + varrec *vp; + LDBLE max, step; + } U0; + } UU; +} looprec; + + +Static Char *inbuf; +Static linerec *linebase; +Static varrec *varbase; +Static looprec *loopbase; +Static long curline; +Static linerec *stmtline, *dataline; +Static tokenrec *stmttok, *datatok, *buf; +Static boolean exitflag; + +Static int free_dim_stringvar(struct varrec *varbase); +extern long EXCP_LINE; +Static void parseinput(tokenrec **buf); +Static void exec(void); +Static void disposetokens(tokenrec **tok); + +/*$if not checking$ + $range off$ +$end$*/ +static HashTable *command_hash_table; +static const struct key command[] = { + {"and", tokand}, + {"or", tokor}, + {"xor", tokxor}, + {"not", toknot}, + {"mod", tokmod}, + {"sqr", toksqr}, + {"sqrt", toksqrt}, + {"sin", toksin}, + {"cos", tokcos}, + {"tan", toktan}, + {"arctan", tokarctan}, + {"log", toklog}, + {"exp", tokexp}, + {"abs", tokabs}, + {"sgn", toksgn}, + {"str$", tokstr_}, + {"val", tokval}, + {"chr$", tokchr_}, + {"asc", tokasc}, + {"len", toklen}, + {"mid$", tokmid_}, + {"peek", tokpeek}, + {"let", toklet}, + {"print", tokprint}, + {"punch", tokpunch}, +#ifdef PHREEQ98 + {"graph_x", tokgraph_x}, + {"graph_y", tokgraph_y}, + {"graph_sy", tokgraph_sy}, +#endif + {"input", tokinput}, + {"goto", tokgoto}, + {"go to", tokgoto}, + {"if", tokif}, + {"end", tokend}, + {"stop", tokstop}, + {"for", tokfor}, + {"next", toknext}, + {"while", tokwhile}, + {"wend", tokwend}, + {"gosub", tokgosub}, + {"return", tokreturn}, + {"read", tokread}, + {"data", tokdata}, + {"restore", tokrestore}, + {"gotoxy", tokgotoxy}, + {"on", tokon}, + {"dim", tokdim}, + {"poke", tokpoke}, + {"list", toklist}, + {"run", tokrun}, + {"new", toknew}, + {"load", tokload}, + {"merge", tokmerge}, + {"save", toksave}, + {"bye", tokbye}, + {"quit", tokbye}, + {"del", tokdel}, + {"renum", tokrenum}, + {"then", tokthen}, + {"else", tokelse}, + {"to", tokto}, + {"step", tokstep}, + {"tc", toktc}, + {"tk", toktk}, + {"time", toktime}, + {"sim_time", toksim_time}, + {"total_time", toktotal_time}, + {"m0", tokm0}, + {"m", tokm}, + {"parm", tokparm}, + {"act", tokact}, + {"edl", tokedl}, + {"surf", toksurf}, + {"equi", tokequi}, + {"kin", tokkin}, + {"gas", tokgas}, + {"s_s", toks_s}, + {"misc1", tokmisc1}, + {"misc2", tokmisc2}, + {"mu", tokmu}, + {"alk", tokalk}, + {"lk_species", toklk_species}, + {"lk_named", toklk_named}, + {"lk_phase", toklk_phase}, + {"sum_species", toksum_species}, + {"sum_gas", toksum_gas}, + {"sum_s_s", toksum_s_s}, + {"calc_value", tokcalc_value}, + {"description", tokdescription}, + {"sys", toksys}, + {"instr", tokinstr}, + {"ltrim", tokltrim}, + {"rtrim", tokrtrim}, + {"trim", toktrim}, + {"pad", tokpad}, + {"rxn", tokrxn}, + {"dist", tokdist}, + {"mol", tokmol}, + {"la", tokla}, + {"lm", toklm}, + {"sr", toksr}, + {"si", toksi}, + {"step_no", tokstep_no}, + {"cell_no", tokcell_no}, + {"sim_no", toksim_no}, + {"tot", toktot}, + {"log10", toklog10}, + {"charge_balance", tokcharge_balance}, + {"percent_error", tokpercent_error}, + {"put", tokput}, + {"get", tokget}, + {"exists", tokexists}, + {"rem", tokrem} +}; +static int NCMDS = (sizeof(command) / sizeof(struct key)); + +/* ---------------------------------------------------------------------- */ +void cmd_initialize(void) +/* ---------------------------------------------------------------------- */ +{ + ENTRY item, *found_item; + int i; +/* + * create hash table + */ + hcreate_multi((unsigned) 2*NCMDS, &command_hash_table); +/* + * fill with commands + */ + for (i = 0; i < NCMDS; i++) { + item.key = command[i].name; + item.data = (void *) &command[i]; + found_item = hsearch_multi(command_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in basic commands initialization."); + error_msg(error_string, STOP); + } + } + return; +} +/* ---------------------------------------------------------------------- */ +void cmd_free(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * destroy hash table + */ + hdestroy_multi(command_hash_table); + command_hash_table = NULL; + return; +} + +#ifdef SKIP +int main(int argc, Char *argv[]) +{ /*main*/ + char commands[] = "10a=1\n20a=a*2;30print a;40quit;run"; + basic_main(commands); + return 0; +} +#endif +int basic_compile(char *commands, void **lnbase, void **vbase, void **lpbase) +{ /*main*/ + int l; + char *ptr; + if (svnid == NULL) fprintf(stderr," "); + + PASCAL_MAIN(0, NULL); + inbuf = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (inbuf == NULL) malloc_error(); + linebase = NULL; + varbase = NULL; + loopbase = NULL; + exitflag = false; + ptr = commands; + do { + TRY(try2); + ptr = commands; + do { + if (sget_logical_line(&ptr, &l, inbuf) == EOF) { + strcpy(inbuf, "bye"); + } + parseinput(&buf); + if (curline == 0) { + stmtline = NULL; + stmttok = buf; + if (stmttok != NULL) + exec(); + disposetokens(&buf); + } + } while (!(exitflag || P_eof())); + RECOVER(try2); + if (P_escapecode != -20) { +#ifdef SKIP + printf("Error %d/%d!\n", (int)P_escapecode, (int)P_ioresult); +#endif + sprintf(error_string,"%d/%d",(int)P_escapecode, (int)P_ioresult); + error_msg(error_string, CONTINUE); + } else { + putchar('\n'); + } + ENDTRY(try2); + } while (!(exitflag || P_eof())); + /* exit(EXIT_SUCCESS); */ + free(inbuf); + *lnbase = (void *) linebase; + *vbase = (void *) varbase; + *lpbase = (void *) loopbase; + return(P_escapecode); +} +int basic_renumber(char *commands, void **lnbase, void **vbase, void **lpbase) +{ /*main*/ + int l, i; + char *ptr; + PASCAL_MAIN(0,NULL); + inbuf = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (inbuf == NULL) malloc_error(); + linebase = NULL; + varbase = NULL; + loopbase = NULL; + exitflag = false; + ptr = commands; + do { + TRY(try2); + i = 0; + ptr = commands; + do { + if (sget_logical_line(&ptr, &l, inbuf) == EOF) { + i++; + if (i == 1) { + strcpy(inbuf, "renum"); + } else if (i == 2) { + strcpy(inbuf, "list"); + } else if (i == 3) { + strcpy(inbuf, "new"); + } else if (i == 4) { + strcpy(inbuf, "bye"); + } + } + parseinput(&buf); + if (curline == 0) { + stmtline = NULL; + stmttok = buf; + if (stmttok != NULL) + exec(); + disposetokens(&buf); + } + } while (!(exitflag || P_eof())); + RECOVER(try2); + if (P_escapecode != -20) { +#ifdef SKIP + printf("Error %d/%d!\n", (int)P_escapecode, (int)P_ioresult); +#endif + sprintf(error_string,"%d/%d",(int)P_escapecode, (int)P_ioresult); + error_msg(error_string, CONTINUE); + } else { + putchar('\n'); + } + ENDTRY(try2); + } while (!(exitflag || P_eof())); + /* exit(EXIT_SUCCESS); */ + free(inbuf); + *lnbase = (void *) linebase; + *vbase = (void *) varbase; + *lpbase = (void *) loopbase; + + return(P_escapecode); +} +int basic_run(char *commands, void *lnbase, void *vbase, void *lpbase) +{ /*main*/ + int l; + char *ptr; + PASCAL_MAIN(0,NULL); + inbuf = (char *) PHRQ_calloc(max_line, sizeof(char)); + if ( inbuf == NULL) malloc_error(); + linebase = NULL; + varbase = NULL; + loopbase = NULL; + exitflag = false; + ptr = commands; + linebase = (linerec *) lnbase; + varbase = (varrec *) vbase; + loopbase = (looprec *) lpbase; + do { + TRY(try2); + do { + if (sget_logical_line(&ptr, &l, inbuf) == EOF) { + strcpy(inbuf, "bye"); + } + parseinput(&buf); + if (curline == 0) { + stmtline = NULL; + stmttok = buf; + if (stmttok != NULL) + exec(); + disposetokens(&buf); + } + } while (!(exitflag || P_eof())); + RECOVER(try2); + if (P_escapecode != -20) { +#ifdef SKIP + printf("Error %d/%d!\n", (int)P_escapecode, (int)P_ioresult); +#endif + sprintf(error_string,"%d/%d",(int)P_escapecode, (int)P_ioresult); + error_msg(error_string, CONTINUE); + } else { + putchar('\n'); + } + ENDTRY(try2); + } while (!(exitflag || P_eof())); + + /* exit(EXIT_SUCCESS); */ + free(inbuf); + return(P_escapecode); +} +int basic_main(char *commands) +{ /*main*/ + int l; + char *ptr; +#ifdef SKIP + PASCAL_MAIN(argc, argv); +#endif + PASCAL_MAIN(0,NULL); + inbuf = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (inbuf == NULL) malloc_error(); + linebase = NULL; + varbase = NULL; + loopbase = NULL; +#ifdef SKIP + printf("Chipmunk BASIC 1.0\n\n"); +#endif + exitflag = false; + ptr = commands; + do { + TRY(try2); + do { +#ifdef SKIP + putchar('>'); +#endif + if (sget_logical_line(&ptr, &l, inbuf) == EOF) { + strcpy(inbuf, "bye"); + } +#ifdef SKIP + gets(inbuf); +#endif + parseinput(&buf); + if (curline == 0) { + stmtline = NULL; + stmttok = buf; + if (stmttok != NULL) + exec(); + disposetokens(&buf); + } + } while (!(exitflag || P_eof())); + RECOVER(try2); + if (P_escapecode != -20) { +#ifdef SKIP + printf("Error %d/%d!\n", (int)P_escapecode, (int)P_ioresult); +#endif + sprintf(error_string,"%d/%d",(int)P_escapecode, (int)P_ioresult); + error_msg(error_string, CONTINUE); + } else { + putchar('\n'); + } + ENDTRY(try2); + } while (!(exitflag || P_eof())); + return 1; +/* exit(EXIT_SUCCESS); */ +} + + + + + + + +/* End. */ +/* ---------------------------------------------------------------------- */ +int sget_logical_line(char **ptr, int *l, char *return_line) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads file fp until end of line, ";", or eof + * stores characters in line_save + * reallocs line_save and line if more space is needed + * + * returns: + * EOF on empty line on end of file or + * OK otherwise + * *l returns length of line + */ + int i; + char c; + i = 0; + if (**ptr == '\0') return (EOF); + for (;;) { + c = **ptr; + if (c == '\0') break; + (*ptr)++; + if (c == ';' || c == '\n') break; + return_line[i++] = c; + } + return_line[i] = '\0'; + *l = i; + return(1); +} +Static void restoredata(void) +{ + dataline = NULL; + datatok = NULL; +} + + + +Static void clearloops(void) +{ + looprec *l; + + while (loopbase != NULL) { + l = loopbase->next; + free(loopbase); + loopbase = l; + } +} + + + +#ifdef SKIP +Static long arraysize(varrec *v) +{ + long i, j, FORLIM; + + if (v->stringvar) + j = 4; + else + j = 8; + FORLIM = v->numdims; + for (i = 0; i < FORLIM; i++) + j *= v->dims[i]; + return j; +} +#endif + +Static void clearvar(varrec *v) +{ + if (v->numdims != 0) { + if (v->stringvar == 0) { + free(v->UU.U0.arr); + v->UU.U0.arr = NULL; + } else { + free_dim_stringvar(v); + } + } else if (v->stringvar && v->UU.U1.sv != NULL) { + free(v->UU.U1.sv); + } + v->numdims = 0; + if (v->stringvar) { + v->UU.U1.sv = NULL; + v->UU.U1.sval = &v->UU.U1.sv; + } else { + v->UU.U0.rv = 0.0; + v->UU.U0.val = &v->UU.U0.rv; + } +} + + +Static void clearvars(void) +{ + varrec *v; + + v = varbase; + while (v != NULL) { + clearvar(v); + v = v->next; + } +} + +Static Char *numtostr(Char *Result, LDBLE n) +{ + /*string255 s;*/ + char *s; + long i; + + s = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (s == NULL) malloc_error(); + s[max_line - 1] = '\0'; +/* if ((n != 0 && fabs(n) < 1e-2) || fabs(n) >= 1e12) { */ + if (ceil(n) == floor(n)) { + if (punch.high_precision == FALSE) { + sprintf(s, "%12g", (double) n); + } else { + sprintf(s, "%19g", (double) n); + } + } else { + if (punch.high_precision == FALSE) { + sprintf(s, "%12.4e", (double) n); + } else { + sprintf(s, "%20.12e", (double) n); + } + } + i = strlen(s) + 1; + s[i - 1] = '\0'; +/* p2c: basic.p, line 237: + * Note: Modification of string length may translate incorrectly [146] */ + strcpy(Result, s); + free_check_null(s); + return (Result); +/* } else { + if (punch.high_precision == FALSE) sprintf(s, "%30.10f", n); + else sprintf(s, "%30.12f", n); + i = strlen(s) + 1; + do { + i--; + } while (s[i - 1] == '0'); + if (s[i - 1] == '.') + i--; + s[i] = '\0'; + * p2c: basic.p, line 248: + * Note: Modification of string length may translate incorrectly [146] * + return strcpy(Result, strltrim(s)); + } */ +} + +#define toklength 20 + + +typedef long chset[9]; + + + + + +Static void parse(Char *inbuf, tokenrec **buf) +{ + long i, j, begin, len, m; + Char token[toklength + 1]; + tokenrec *t, *tptr; + varrec *v; + Char ch; + ENTRY item, *found_item; + char *ptr; + + tptr = NULL; + *buf = NULL; + i = 1; + do { + ch = ' '; + while (i <= (int) strlen(inbuf) && (ch == ' ' || ch == '\t')) { + ch = inbuf[i - 1]; + i++; + } + if (ch != ' ') { + t = (tokenrec *) PHRQ_malloc(sizeof(tokenrec)); + if ( t == NULL) malloc_error(); + if (tptr == NULL) + *buf = t; + else + tptr->next = t; + tptr = t; + t->next = NULL; + switch (ch) { + + case '"': + case '\'': + t->kind = tokstr; + j = 0; + len = strlen(inbuf); + begin = i; + while (i <= len && inbuf[i - 1] != ch) { + ++j; + ++i; + } + m = 256; + if (j + 1 > m) m = j + 1; + t->UU.sp = (char *) PHRQ_malloc(m); + if (t->UU.sp == NULL) malloc_error(); + strncpy(t->UU.sp, inbuf + begin - 1, j); + t->UU.sp[j] = '\0'; +/* p2c: basic.p, line 415: + * Note: Modification of string length may translate incorrectly [146] */ + i++; + break; + + case '+': + t->kind = tokplus; + break; + + case '-': + t->kind = tokminus; + break; + + case '*': + t->kind = toktimes; + break; + + case '/': + t->kind = tokdiv; + break; + + case '^': + t->kind = tokup; + break; + + case '(': + case '[': + t->kind = toklp; + break; + + case ')': + case ']': + t->kind = tokrp; + break; + + case ',': + t->kind = tokcomma; + break; + + case ';': + t->kind = toksemi; + break; + + case ':': + t->kind = tokcolon; + break; + + case '?': + t->kind = tokprint; + break; + + case '=': + t->kind = tokeq; + break; + + case '<': + if (i <= (int) strlen(inbuf) && inbuf[i - 1] == '=') { + t->kind = tokle; + i++; + } else if (i <= (int) strlen(inbuf) && inbuf[i - 1] == '>') { + t->kind = tokne; + i++; + } else + t->kind = toklt; + break; + + case '>': + if (i <= (int) strlen(inbuf) && inbuf[i - 1] == '=') { + t->kind = tokge; + i++; + } else + t->kind = tokgt; + break; + + default: + if (isalpha((int) ch)) { + i--; + j = 0; + token[toklength] = '\0'; + while (i <= (int) strlen(inbuf) && + (inbuf[i - 1] == '$' || inbuf[i - 1] == '_' || + isalnum((int) inbuf[i - 1]))) { + if (j < toklength) { + j++; + token[j - 1] = inbuf[i - 1]; + } + i++; + } + token[j] = '\0'; +/* p2c: basic.p, line 309: + * Note: Modification of string length may translate incorrectly [146] */ +#define INT +#ifdef INT +/* + * Search hash list + */ + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(command_hash_table, item, FIND); + if (found_item != NULL) { + t->kind = ((struct key *) (found_item->data))->keycount; + if (t->kind == tokrem) { + m = strlen(inbuf) + 1; + if (m < 256) m = 256; + t->UU.sp = (char *) PHRQ_malloc(m); + if ( t->UU.sp == NULL) malloc_error(); + sprintf(t->UU.sp, "%.*s", + (int)(strlen(inbuf) - i + 1), inbuf + i - 1); + i = strlen(inbuf) + 1; + } +#endif +#ifdef LONG + if (!strcmp(token, "and")) + t->kind = tokand; + else if (!strcmp(token, "or")) + t->kind = tokor; + else if (!strcmp(token, "xor")) + t->kind = tokxor; + else if (!strcmp(token, "not")) + t->kind = toknot; + else if (!strcmp(token, "mod")) + t->kind = tokmod; + else if (!strcmp(token, "sqr")) + t->kind = toksqr; + else if (!strcmp(token, "sqrt")) + t->kind = toksqrt; + else if (!strcmp(token, "sin")) + t->kind = toksin; + else if (!strcmp(token, "cos")) + t->kind = tokcos; + else if (!strcmp(token, "tan")) + t->kind = toktan; + else if (!strcmp(token, "arctan")) + t->kind = tokarctan; + else if (!strcmp(token, "log")) + t->kind = toklog; + else if (!strcmp(token, "exp")) + t->kind = tokexp; + else if (!strcmp(token, "abs")) + t->kind = tokabs; + else if (!strcmp(token, "sgn")) + t->kind = toksgn; + else if (!strcmp(token, "str$")) + t->kind = tokstr_; + else if (!strcmp(token, "val")) + t->kind = tokval; + else if (!strcmp(token, "chr$")) + t->kind = tokchr_; + else if (!strcmp(token, "asc")) + t->kind = tokasc; + else if (!strcmp(token, "len")) + t->kind = toklen; + else if (!strcmp(token, "mid$")) + t->kind = tokmid_; + else if (!strcmp(token, "peek")) + t->kind = tokpeek; + else if (!strcmp(token, "let")) + t->kind = toklet; + else if (!strcmp(token, "print")) + t->kind = tokprint; + else if (!strcmp(token, "punch")) + t->kind = tokpunch; +#ifdef PHREEQ98 + else if (!strcmp(token, "graph_x")) + t->kind = tokgraph_x; + else if (!strcmp(token, "graph_y")) + t->kind = tokgraph_y; + else if (!strcmp(token, "graph_sy")) + t->kind = tokgraph_sy; +#endif + else if (!strcmp(token, "input")) + t->kind = tokinput; + else if (!strcmp(token, "goto")) + t->kind = tokgoto; + else if (!strcmp(token, "go to")) + t->kind = tokgoto; + else if (!strcmp(token, "if")) + t->kind = tokif; + else if (!strcmp(token, "end")) + t->kind = tokend; + else if (!strcmp(token, "stop")) + t->kind = tokstop; + else if (!strcmp(token, "for")) + t->kind = tokfor; + else if (!strcmp(token, "next")) + t->kind = toknext; + else if (!strcmp(token, "while")) + t->kind = tokwhile; + else if (!strcmp(token, "wend")) + t->kind = tokwend; + else if (!strcmp(token, "gosub")) + t->kind = tokgosub; + else if (!strcmp(token, "return")) + t->kind = tokreturn; + else if (!strcmp(token, "read")) + t->kind = tokread; + else if (!strcmp(token, "data")) + t->kind = tokdata; + else if (!strcmp(token, "restore")) + t->kind = tokrestore; + else if (!strcmp(token, "gotoxy")) + t->kind = tokgotoxy; + else if (!strcmp(token, "on")) + t->kind = tokon; + else if (!strcmp(token, "dim")) + t->kind = tokdim; + else if (!strcmp(token, "poke")) + t->kind = tokpoke; + else if (!strcmp(token, "list")) + t->kind = toklist; + else if (!strcmp(token, "run")) + t->kind = tokrun; + else if (!strcmp(token, "new")) + t->kind = toknew; + else if (!strcmp(token, "load")) + t->kind = tokload; + else if (!strcmp(token, "merge")) + t->kind = tokmerge; + else if (!strcmp(token, "save")) + t->kind = toksave; + else if (!strcmp(token, "bye")) + t->kind = tokbye; + else if (!strcmp(token, "quit")) + t->kind = tokbye; + else if (!strcmp(token, "del")) + t->kind = tokdel; + else if (!strcmp(token, "renum")) + t->kind = tokrenum; + else if (!strcmp(token, "then")) + t->kind = tokthen; + else if (!strcmp(token, "else")) + t->kind = tokelse; + else if (!strcmp(token, "to")) + t->kind = tokto; + else if (!strcmp(token, "step")) + t->kind = tokstep; +/* + * dlp: added functions + */ + else if (!strcmp(token, "tc")) + t->kind = toktc; + else if (!strcmp(token, "tk")) + t->kind = toktk; + else if (!strcmp(token, "time")) + t->kind = toktime; + else if (!strcmp(token, "sim_time")) + t->kind = toksim_time; + else if (!strcmp(token, "total_time")) + t->kind = toktotal_time; + else if (!strcmp(token, "m0")) + t->kind = tokm0; + else if (!strcmp(token, "m")) + t->kind = tokm; + else if (!strcmp(token, "parm")) + t->kind = tokparm; + else if (!strcmp(token, "act")) + t->kind = tokact; + else if (!strcmp(token, "edl")) + t->kind = tokedl; + else if (!strcmp(token, "surf")) + t->kind = toksurf; + else if (!strcmp(token, "equi")) + t->kind = tokequi; + else if (!strcmp(token, "kin")) + t->kind = tokkin; + else if (!strcmp(token, "gas")) + t->kind = tokgas; + else if (!strcmp(token, "s_s")) + t->kind = toks_s; + else if (!strcmp(token, "misc1")) + t->kind = tokmisc1; + else if (!strcmp(token, "misc2")) + t->kind = tokmisc2; + else if (!strcmp(token, "mu")) + t->kind = tokmu; + else if (!strcmp(token, "alk")) + t->kind = tokalk; + else if (!strcmp(token, "lk_species")) + t->kind = toklk_species; + else if (!strcmp(token, "lk_named")) + t->kind = toklk_named; + else if (!strcmp(token, "lk_phase")) + t->kind = toklk_phase; + else if (!strcmp(token, "sum_species")) + t->kind = toksum_species; + else if (!strcmp(token, "sum_gas")) + t->kind = toksum_gas; + else if (!strcmp(token, "sum_s_s")) + t->kind = toksum_s_s; + else if (!strcmp(token, "calc_value")) + t->kind = tokcalc_value; + else if (!strcmp(token, "description")) + t->kind = tokdescription; + else if (!strcmp(token, "sys")) + t->kind = toksys; + else if (!strcmp(token, "instr")) + t->kind = tokinstr; + else if (!strcmp(token, "ltrim")) + t->kind = tokltrim; + else if (!strcmp(token, "rtrim")) + t->kind = tokrtrim; + else if (!strcmp(token, "trim")) + t->kind = toktrim; + else if (!strcmp(token, "pad")) + t->kind = tokpad; + else if (!strcmp(token, "rxn")) + t->kind = tokrxn; + else if (!strcmp(token, "dist")) + t->kind = tokdist; + else if (!strcmp(token, "mol")) + t->kind = tokmol; + else if (!strcmp(token, "la")) + t->kind = tokla; + else if (!strcmp(token, "lm")) + t->kind = toklm; + else if (!strcmp(token, "sr")) + t->kind = toksr; + else if (!strcmp(token, "step_no")) + t->kind = tokstep_no; + else if (!strcmp(token, "cell_no")) + t->kind = tokcell_no; + else if (!strcmp(token, "sim_no")) + t->kind = toksim_no; + else if (!strcmp(token, "si")) + t->kind = toksi; + else if (!strcmp(token, "tot")) + t->kind = toktot; + else if (!strcmp(token, "log10")) + t->kind = toklog10; + else if (!strcmp(token, "put")) + t->kind = tokput; + else if (!strcmp(token, "get")) + t->kind = tokget; + else if (!strcmp(token, "exists")) + t->kind = tokexists; + else if (!strcmp(token, "charge_balance")) + t->kind = tokcharge_balance; + else if (!strcmp(token, "percent_error")) + t->kind = tokpercent_error; + else if (!strcmp(token, "rem")) { + t->kind = tokrem; + m = strlen(inbuf) + 1; + if (m < 256) m = 256; + t->UU.sp = (char *) PHRQ_malloc(m)); + if ( t->UU.sp == NULL) malloc_error(); + sprintf(t->UU.sp, "%.*s", + (int)(strlen(inbuf) - i + 1), inbuf + i - 1); + i = strlen(inbuf) + 1; +#endif + } else { + t->kind = tokvar; + v = varbase; + while (v != NULL && strcmp(v->name, token)) + v = v->next; + if (v == NULL) { + v = (varrec *) PHRQ_malloc(sizeof(varrec)); + if ( v == NULL) malloc_error(); + v->UU.U0.arr = NULL; + v->next = varbase; + varbase = v; + strcpy(v->name, token); + v->numdims = 0; + if (token[strlen(token) - 1] == '$') { + v->stringvar = true; + v->UU.U1.sv = NULL; + v->UU.U1.sval = &v->UU.U1.sv; + } else { + v->stringvar = false; + v->UU.U0.rv = 0.0; + v->UU.U0.val = &v->UU.U0.rv; + } + } + t->UU.vp = v; + } + } else if (isdigit((int) ch) || ch == '.') { + t->kind = toknum; + i--; + t->UU.num = strtod(&inbuf[i-1], &ptr); + if (&inbuf[i-1] == ptr) { + /* + Note: the following causes an infinite loop: + X = ..9 + */ + t->kind = toksnerr; + t->UU.snch = ch; + i++; + break; + } + i += (int) (ptr - &inbuf[i-1]); + } else { + t->kind = toksnerr; + t->UU.snch = ch; + } + break; + } + } + } while (i <= (int) strlen(inbuf)); +} + +#undef toklength + + + +Static void listtokens(FILE *f, tokenrec *buf) +{ + boolean ltr; + Char STR1[256]; + char *string; + ltr = false; + while (buf != NULL) { + if ((buf->kind >= (long)toknot && buf->kind <= (long)tokrenum) || + buf->kind == (long)toknum || buf->kind == (long)tokvar || + buf->kind >= (long)toktc) { + if (ltr) + /*putc(' ', f);*/ + output_msg(OUTPUT_BASIC, " "); + ltr = (boolean) (buf->kind != toknot); + } else + ltr = false; + switch (buf->kind) { + + case tokvar: + /*fputs(buf->UU.vp->name, f);*/ + output_msg(OUTPUT_BASIC, "%s", buf->UU.vp->name); + break; + + case toknum: + /*fputs(numtostr(STR1, buf->UU.num), f);*/ + string = numtostr(STR1, buf->UU.num); + string_trim(string); + output_msg(OUTPUT_BASIC, "%s", string); + break; + + case tokstr: + output_msg(OUTPUT_BASIC, "\"%s\"", buf->UU.sp); + break; + + case toksnerr: + output_msg(OUTPUT_BASIC, "{%c}", buf->UU.snch); + break; + + case tokplus: + /*putc('+', f);*/ + output_msg(OUTPUT_BASIC, "+"); + break; + + case tokminus: + /*putc('-', f);*/ + output_msg(OUTPUT_BASIC, "-"); + break; + + case toktimes: + /*putc('*', f);*/ + output_msg(OUTPUT_BASIC, "*"); + break; + + case tokdiv: + /*putc('/', f);*/ + output_msg(OUTPUT_BASIC, "/"); + break; + + case tokup: + /*putc('^', f);*/ + output_msg(OUTPUT_BASIC, "^"); + break; + + case toklp: + /*putc('(', f);*/ + output_msg(OUTPUT_BASIC, "("); + break; + + case tokrp: + /*putc(')', f);*/ + output_msg(OUTPUT_BASIC, ")"); + break; + + case tokcomma: + /*putc(',', f);*/ + output_msg(OUTPUT_BASIC, ","); + break; + + case toksemi: + /*putc(';', f);*/ + output_msg(OUTPUT_BASIC, ";"); + break; + + case tokcolon: + output_msg(OUTPUT_BASIC, " : "); + break; + + case tokeq: + output_msg(OUTPUT_BASIC, " = "); + break; + + case toklt: + output_msg(OUTPUT_BASIC, " < "); + break; + + case tokgt: + output_msg(OUTPUT_BASIC, " > "); + break; + + case tokle: + output_msg(OUTPUT_BASIC, " <= "); + break; + + case tokge: + output_msg(OUTPUT_BASIC, " >= "); + break; + + case tokne: + output_msg(OUTPUT_BASIC, " <> "); + break; + + case tokand: + output_msg(OUTPUT_BASIC, " AND "); + break; + + case tokor: + output_msg(OUTPUT_BASIC, " OR "); + break; + + case tokxor: + output_msg(OUTPUT_BASIC, " XOR "); + break; + + case tokmod: + output_msg(OUTPUT_BASIC, " MOD "); + break; + + case toknot: + output_msg(OUTPUT_BASIC, "NOT "); + break; + + case toksqr: + output_msg(OUTPUT_BASIC, "SQR"); + break; + + case toksqrt: + output_msg(OUTPUT_BASIC, "SQRT"); + break; + + case toksin: + output_msg(OUTPUT_BASIC, "SIN"); + break; + + case tokcos: + output_msg(OUTPUT_BASIC, "COS"); + break; + + case toktan: + output_msg(OUTPUT_BASIC, "TAN"); + break; + + case tokarctan: + output_msg(OUTPUT_BASIC, "ARCTAN"); + break; + + case toklog: + output_msg(OUTPUT_BASIC, "LOG"); + break; + + case tokexp: + output_msg(OUTPUT_BASIC, "EXP"); + break; + + case tokabs: + output_msg(OUTPUT_BASIC, "ABS"); + break; + + case toksgn: + output_msg(OUTPUT_BASIC, "SGN"); + break; + + case tokstr_: + output_msg(OUTPUT_BASIC, "STR$"); + break; + + case tokval: + output_msg(OUTPUT_BASIC, "VAL"); + break; + + case tokchr_: + output_msg(OUTPUT_BASIC, "CHR$"); + break; + + case tokasc: + output_msg(OUTPUT_BASIC, "ASC"); + break; + + case toklen: + output_msg(OUTPUT_BASIC, "LEN"); + break; + + case tokmid_: + output_msg(OUTPUT_BASIC, "MID$"); + break; + + case tokpeek: + output_msg(OUTPUT_BASIC, "PEEK"); + break; + + case tokrem: + output_msg(OUTPUT_BASIC, "REM%s", buf->UU.sp); + break; + + case toklet: + output_msg(OUTPUT_BASIC, "LET"); + break; + + case tokprint: + output_msg(OUTPUT_BASIC, "PRINT"); + break; + + case tokinput: + output_msg(OUTPUT_BASIC, "INPUT"); + break; + + case tokgoto: + output_msg(OUTPUT_BASIC, "GOTO"); + break; + + case tokif: + output_msg(OUTPUT_BASIC, "IF"); + break; + + case tokend: + output_msg(OUTPUT_BASIC, "END"); + break; + + case tokstop: + output_msg(OUTPUT_BASIC, "STOP"); + break; + + case tokfor: + output_msg(OUTPUT_BASIC, "FOR"); + break; + + case toknext: + output_msg(OUTPUT_BASIC, "NEXT"); + break; + + case tokwhile: + output_msg(OUTPUT_BASIC, "WHILE"); + break; + + case tokwend: + output_msg(OUTPUT_BASIC, "WEND"); + break; + + case tokgosub: + output_msg(OUTPUT_BASIC, "GOSUB"); + break; + + case tokreturn: + output_msg(OUTPUT_BASIC, "RETURN"); + break; + + case tokread: + output_msg(OUTPUT_BASIC, "READ"); + break; + + case tokdata: + output_msg(OUTPUT_BASIC, "DATA"); + break; + + case tokrestore: + output_msg(OUTPUT_BASIC, "RESTORE"); + break; + + case tokgotoxy: + output_msg(OUTPUT_BASIC, "GOTOXY"); + break; + + case tokon: + output_msg(OUTPUT_BASIC, "ON"); + break; + + case tokdim: + output_msg(OUTPUT_BASIC, "DIM"); + break; + + case tokpoke: + output_msg(OUTPUT_BASIC, "POKE"); + break; + + case toklist: + output_msg(OUTPUT_BASIC, "LIST"); + break; + + case tokrun: + output_msg(OUTPUT_BASIC, "RUN"); + break; + + case toknew: + output_msg(OUTPUT_BASIC, "NEW"); + break; + + case tokload: + output_msg(OUTPUT_BASIC, "LOAD"); + break; + + case tokmerge: + output_msg(OUTPUT_BASIC, "MERGE"); + break; + + case toksave: + output_msg(OUTPUT_BASIC, "SAVE"); + break; + + case tokbye: + output_msg(OUTPUT_BASIC, "BYE"); + break; + + case tokdel: + output_msg(OUTPUT_BASIC, "DEL"); + break; + + case tokrenum: + output_msg(OUTPUT_BASIC, "RENUM"); + break; + + case tokthen: + output_msg(OUTPUT_BASIC, " THEN "); + break; + + case tokelse: + output_msg(OUTPUT_BASIC, " ELSE "); + break; + + case tokto: + output_msg(OUTPUT_BASIC, " TO "); + break; + + case tokstep: + output_msg(OUTPUT_BASIC, " STEP "); + break; + + case toktc: + output_msg(OUTPUT_BASIC, "TC"); + break; + + case tokm0: + output_msg(OUTPUT_BASIC, "M0"); + break; + + case tokm: + output_msg(OUTPUT_BASIC, "M"); + break; + + case tokparm: + output_msg(OUTPUT_BASIC, "PARM"); + break; + + case tokact: + output_msg(OUTPUT_BASIC, "ACT"); + break; + + case tokmol: + output_msg(OUTPUT_BASIC, "MOL"); + break; + + case tokla: + output_msg(OUTPUT_BASIC, "LA"); + break; + + case toklm: + output_msg(OUTPUT_BASIC, "LM"); + break; + + case toksr: + output_msg(OUTPUT_BASIC, "SR"); + break; + + case toksi: + output_msg(OUTPUT_BASIC, "SI"); + break; + + case toktot: + output_msg(OUTPUT_BASIC, "TOT"); + break; + + case toktk: + output_msg(OUTPUT_BASIC, "TK"); + break; + + case toktime: + output_msg(OUTPUT_BASIC, "TIME"); + break; + + case toklog10: + output_msg(OUTPUT_BASIC, "LOG10"); + break; + + case toksim_time: + output_msg(OUTPUT_BASIC, "SIM_TIME"); + break; + + case tokequi: + output_msg(OUTPUT_BASIC, "EQUI"); + break; + + case tokgas: + output_msg(OUTPUT_BASIC, "GAS"); + break; + + case tokpunch: + output_msg(OUTPUT_BASIC, "PUNCH"); + break; + + case tokkin: + output_msg(OUTPUT_BASIC, "KIN"); + break; + + case toks_s: + output_msg(OUTPUT_BASIC, "S_S"); + break; + + case tokmu: + output_msg(OUTPUT_BASIC, "MU"); + break; + + case tokalk: + output_msg(OUTPUT_BASIC, "ALK"); + break; + + case toklk_species: + output_msg(OUTPUT_BASIC, "LK_SPECIES"); + break; + + case toklk_named: + output_msg(OUTPUT_BASIC, "LK_NAMED"); + break; + + case toklk_phase: + output_msg(OUTPUT_BASIC, "LK_PHASE"); + break; + + case toksum_species: + output_msg(OUTPUT_BASIC, "SUM_SPECIES"); + break; + + case toksum_gas: + output_msg(OUTPUT_BASIC, "SUM_GAS"); + break; + + case toksum_s_s: + output_msg(OUTPUT_BASIC, "SUM_s_s"); + break; + + case tokcalc_value: + output_msg(OUTPUT_BASIC, "CALC_VALUE"); + break; + + case tokdescription: + output_msg(OUTPUT_BASIC, "DESCRIPTION"); + break; + + case toksys: + output_msg(OUTPUT_BASIC, "SYS"); + break; + + case tokinstr: + output_msg(OUTPUT_BASIC, "INSTR"); + break; + + case tokltrim: + output_msg(OUTPUT_BASIC, "LTRIM"); + break; + + case tokrtrim: + output_msg(OUTPUT_BASIC, "RTRIM"); + break; + + case toktrim: + output_msg(OUTPUT_BASIC, "TRIM"); + break; + + case tokpad: + output_msg(OUTPUT_BASIC, "PAD"); + break; + + case tokrxn: + output_msg(OUTPUT_BASIC, "RXN"); + break; + + case tokdist: + output_msg(OUTPUT_BASIC, "DIST"); + break; + + case tokmisc1: + output_msg(OUTPUT_BASIC, "MISC1"); + break; + + case tokmisc2: + output_msg(OUTPUT_BASIC, "MISC2"); + break; + + case tokedl: + output_msg(OUTPUT_BASIC, "EDL"); + break; + + case toksurf: + output_msg(OUTPUT_BASIC, "SURF"); + break; + + case tokstep_no: + output_msg(OUTPUT_BASIC, "STEP_NO"); + break; + + case toksim_no: + output_msg(OUTPUT_BASIC, "SIM_NO"); + break; + + case toktotal_time: + output_msg(OUTPUT_BASIC, "TOTAL_TIME"); + break; + + case tokput: + output_msg(OUTPUT_BASIC, "PUT"); + break; + + case tokget: + output_msg(OUTPUT_BASIC, "GET"); + break; + + case tokcharge_balance: + output_msg(OUTPUT_BASIC, "CHARGE_BALANCE"); + break; + + case tokpercent_error: + output_msg(OUTPUT_BASIC, "PERCENT_ERROR"); + break; + +#ifdef PHREEQ98 + case tokgraph_x: + output_msg(OUTPUT_BASIC, "GRAPH_X"); + break; + + case tokgraph_y: + output_msg(OUTPUT_BASIC, "GRAPH_Y"); + break; + + case tokgraph_sy: + output_msg(OUTPUT_BASIC, "GRAPH_SY"); + break; +#endif + + case tokcell_no: + output_msg(OUTPUT_BASIC, "CELL_NO"); + break; + + case tokexists: + output_msg(OUTPUT_BASIC, "EXISTS"); + break; + + } + buf = buf->next; + } +} + + + +Static void disposetokens(tokenrec **tok) +{ + tokenrec *tok1; + + while (*tok != NULL) { + tok1 = (*tok)->next; + if ((*tok)->kind == (long)tokrem || (*tok)->kind == (long)tokstr) { + (*tok)->UU.sp = (char*) free_check_null((*tok)->UU.sp); + } + *tok = (struct tokenrec *)free_check_null(*tok); + *tok = tok1; + } +} + + + +Static void parseinput(tokenrec **buf) +{ + linerec *l, *l0, *l1; + + while (replace("\t"," ",inbuf)); + while (replace("\r"," ",inbuf)); + string_trim(inbuf); + curline = 0; + while (*inbuf != '\0' && isdigit((int) inbuf[0])) { + curline = curline * 10 + inbuf[0] - 48; +#ifdef SKIP + strcpy(inbuf, inbuf + 1); +#endif + memmove(inbuf, inbuf + 1, strlen(inbuf)); + } + parse(inbuf, buf); + if (curline == 0) + return; + l = linebase; + l0 = NULL; + while (l != NULL && l->num < curline) { + l0 = l; + l = l->next; + } + if (l != NULL && l->num == curline) { + l1 = l; + l = l->next; + if (l0 == NULL) + linebase = l; + else + l0->next = l; + disposetokens(&l1->txt); + free(l1); + } + if (*buf != NULL) { + l1 = (linerec *) PHRQ_malloc(sizeof(linerec)); + if ( l1 == NULL) malloc_error(); + l1->next = l; + if (l0 == NULL) + linebase = l1; + else + l0->next = l1; + l1->num = curline; + l1->txt = *buf; + } + clearloops(); + restoredata(); +} + +Static void errormsg(Char *s) +{ +#ifdef SKIP + printf("\007%s", s); +#endif + error_msg(s, CONTINUE); + _Escape(42); +} + + +Static void snerr(void) +{ + errormsg("Syntax error"); +} + + +Static void tmerr(void) +{ + errormsg("Type mismatch error"); +} + + +Static void badsubscr(void) +{ + errormsg("Bad subscript"); +} + + +/* Local variables for exec: */ +struct LOC_exec { + boolean gotoflag, elseflag; + tokenrec *t; +} ; + +Local valrec factor(struct LOC_exec *LINK); +Local valrec expr(struct LOC_exec *LINK); +Local Char *stringfactor(Char *Result, struct LOC_exec *LINK); + +Local LDBLE realfactor(struct LOC_exec *LINK) +{ + valrec n; + + n = factor(LINK); + if (n.stringval) + tmerr(); + return (n.UU.val); +} + +Local Char *strfactor(struct LOC_exec *LINK) +{ + valrec n; + + n = factor(LINK); + if (!n.stringval) + tmerr(); + return (n.UU.sval); +} + +Local Char *stringfactor(Char *Result, struct LOC_exec *LINK) +{ + valrec n; + + n = factor(LINK); + if (!n.stringval) + tmerr(); + strcpy(Result, n.UU.sval); + free(n.UU.sval); + return Result; +} + +Local long intfactor(struct LOC_exec *LINK) +{ + return ((long)floor(realfactor(LINK) + 0.5)); +} + +Local LDBLE realexpr(struct LOC_exec *LINK) +{ + valrec n; + + n = expr(LINK); + if (n.stringval) + tmerr(); + return (n.UU.val); +} + +Local Char *strexpr(struct LOC_exec *LINK) +{ + valrec n; + + n = expr(LINK); + if (!n.stringval) + tmerr(); + return (n.UU.sval); +} + +Local Char *stringexpr(Char *Result, struct LOC_exec *LINK) +{ + valrec n; + + n = expr(LINK); + if (!n.stringval) + tmerr(); + strcpy(Result, n.UU.sval); + free(n.UU.sval); + return Result; +} + +Local long intexpr(struct LOC_exec *LINK) +{ + return ((long)floor(realexpr(LINK) + 0.5)); +} + + +Local void require(int k, struct LOC_exec *LINK) +{ + if (LINK->t == NULL || LINK->t->kind != k) + snerr(); + LINK->t = LINK->t->next; +} + + +Local void skipparen(struct LOC_exec *LINK) +{ + do { + if (LINK->t == NULL) + snerr(); + if (LINK->t->kind == tokrp || LINK->t->kind == tokcomma) + goto _L1; + if (LINK->t->kind == toklp) { + LINK->t = LINK->t->next; + skipparen(LINK); + } + LINK->t = LINK->t->next; + } while (true); +_L1: ; +} + + +Local varrec *findvar(struct LOC_exec *LINK) +{ + varrec *v; + long i, j, k; + tokenrec *tok; + long FORLIM; + + if (LINK->t == NULL || LINK->t->kind != tokvar) + snerr(); + v = LINK->t->UU.vp; + LINK->t = LINK->t->next; + if (LINK->t == NULL || LINK->t->kind != toklp) { + if (v->numdims != 0) + badsubscr(); + return v; + } + if (v->numdims == 0) { + tok = LINK->t; + i = 0; + j = 1; + do { + if (i >= maxdims) + badsubscr(); + LINK->t = LINK->t->next; + skipparen(LINK); + j *= 11; + i++; + v->dims[i - 1] = 11; + } while (LINK->t->kind != tokrp); + v->numdims = (char) i; + if (v->stringvar) { + v->UU.U1.sarr = (Char **) PHRQ_malloc(j * sizeof(char *)); + if (v->UU.U1.sarr == NULL) malloc_error(); + for (k = 0; k < j; k++) + v->UU.U1.sarr[k] = NULL; + } else { + v->UU.U0.arr = (LDBLE *) PHRQ_malloc(j * sizeof(LDBLE)); + if ( v->UU.U0.arr == NULL) malloc_error(); + for (k = 0; k < j; k++) + v->UU.U0.arr[k] = 0.0; + } + LINK->t = tok; + } + k = 0; + LINK->t = LINK->t->next; + FORLIM = v->numdims; + for (i = 1; i <= FORLIM; i++) { + j = intexpr(LINK); + if ((unsigned long)j >= (unsigned long) v->dims[i - 1]) + badsubscr(); + k = k * v->dims[i - 1] + j; + if (i < v->numdims) + require(tokcomma, LINK); + } + require(tokrp, LINK); + if (v->stringvar) + v->UU.U1.sval = &v->UU.U1.sarr[k]; + else + v->UU.U0.val = &v->UU.U0.arr[k]; + return v; +} + + +#ifdef SKIP +Local long inot(long i, struct LOC_exec *LINK) +{ + return (-i - 1); +} + +Local long ixor(long a, long b, struct LOC_exec *LINK) +{ + return ((a & (~b)) | ((~a) & b)); +} +#endif + +Local valrec factor(struct LOC_exec *LINK) +{ + varrec *v; + tokenrec *facttok; + valrec n; + long i, j, m; + tokenrec *tok, *tok1; + Char *s; + LDBLE dummy; + int i_rate; + union { + long i; + Char *c; + } trick; + struct save_values s_v, *s_v_ptr; + int k; + LDBLE TEMP; + Char *STR1, *STR2; + char *elt_name, *surface_name, *mytemplate, *name; + struct varrec *count_varrec=NULL, *names_varrec=NULL, *types_varrec=NULL, *moles_varrec=NULL; + char **names_arg, **types_arg; + LDBLE *moles_arg; + int arg_num; + LDBLE count_species; + char *ptr, *string1, *string2; + + STR1 = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (STR1 == NULL) malloc_error(); + STR2 = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (STR2 == NULL) malloc_error(); + + if (LINK->t == NULL) + snerr(); + facttok = LINK->t; + LINK->t = LINK->t->next; + n.stringval = false; + s_v.count_subscripts = 0; + s_v.subscripts = (int*) PHRQ_malloc(sizeof(int)); + switch (facttok->kind) { + + case toknum: + n.UU.val = facttok->UU.num; + break; + + case tokstr: + n.stringval = true; + m = strlen(facttok->UU.sp) + 1; + if (m < 256) m = 256; + n.UU.sval = (char *) PHRQ_malloc(m); + if (n.UU.sval == NULL) malloc_error(); + strcpy(n.UU.sval, facttok->UU.sp); + break; + + case tokvar: + LINK->t = facttok; + v = findvar(LINK); + n.stringval = v->stringvar; + if (n.stringval) { + if (*v->UU.U1.sval != NULL) { + m = strlen(*v->UU.U1.sval) + 1; + if (m < 256) m = 256; + } else { + m = 256; + } + n.UU.sval = (char *) PHRQ_malloc(m); + if (n.UU.sval == NULL) malloc_error(); + if (*v->UU.U1.sval != NULL) { + strcpy(n.UU.sval, *v->UU.U1.sval); + } + + } else + n.UU.val = *v->UU.U0.val; + break; + + case toklp: + n = expr(LINK); + require(tokrp, LINK); + break; + + case tokminus: + n.UU.val = -realfactor(LINK); + break; + + case tokplus: + n.UU.val = realfactor(LINK); + break; + + case toknot: + n.UU.val = ~intfactor(LINK); + break; + + case toksqr: + TEMP = realfactor(LINK); + n.UU.val = TEMP * TEMP; + break; + + case toksqrt: + n.UU.val = sqrt(realfactor(LINK)); + break; + + case toktc: + n.UU.val = tc_x; + break; + + case toktk: + n.UU.val = tc_x+273.16; + break; + + case toktime: + n.UU.val = rate_time; + break; + + case toksim_time: + if (use.kinetics_in == FALSE) { + if (state == PHAST) { + n.UU.val = rate_sim_time; + } else if (state == TRANSPORT) { + n.UU.val = transport_step * timest; + } else if (state == ADVECTION) { + if (advection_kin_time_defined == TRUE) { + n.UU.val = advection_step * advection_kin_time; + } else { + n.UU.val = advection_step; + } + } else { + n.UU.val = 0; + } + } else { + n.UU.val = rate_sim_time; + } + break; + + case toktotal_time: + if (use.kinetics_in == FALSE) { + if (state == PHAST) { + n.UU.val = rate_sim_time_end; + } else if (state == TRANSPORT) { + n.UU.val = initial_total_time + transport_step * timest; + } else if (state == ADVECTION) { + n.UU.val = initial_total_time + advection_step * advection_kin_time; + } else { + n.UU.val = 0; + } + } else { + n.UU.val = initial_total_time + rate_sim_time; + } + break; + + case tokm0: + n.UU.val = rate_m0; + break; + + case tokm: + n.UU.val = rate_m; + break; + + case tokparm: + i_rate = intfactor(LINK); + if ( i_rate > count_rate_p) { + errormsg("Parameter subscript out of range."); + } + n.UU.val = rate_p[i_rate - 1]; + break; + + case tokact: + n.UU.val = activity(stringfactor(STR1, LINK)); + break; + + case tokedl: + require(toklp, LINK); + elt_name = stringfactor(STR1, LINK); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + surface_name = stringfactor(STR2, LINK); + } else { + surface_name = NULL; + } + require(tokrp, LINK); + n.UU.val = diff_layer_total(elt_name, surface_name); + break; + + case toksurf: + require(toklp, LINK); + elt_name = stringfactor(STR1, LINK); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + surface_name = stringfactor(STR2, LINK); + } else { + surface_name = NULL; + } + require(tokrp, LINK); + n.UU.val = surf_total(elt_name, surface_name); + break; + + case tokequi: + n.UU.val = equi_phase(stringfactor(STR1, LINK)); + break; + + case tokkin: + n.UU.val = kinetics_moles(stringfactor(STR1, LINK)); + break; + + case tokgas: + n.UU.val = find_gas_comp(stringfactor(STR1, LINK)); + break; + + case toks_s: + n.UU.val = find_s_s_comp(stringfactor(STR1, LINK)); + break; + + case tokmisc1: + n.UU.val = find_misc1(stringfactor(STR1, LINK)); + break; + + case tokmisc2: + n.UU.val = find_misc2(stringfactor(STR1, LINK)); + break; + + case tokmu: + n.UU.val = mu_x; + break; + + case tokalk: + n.UU.val = total_alkalinity/mass_water_aq_x; + break; + + case toklk_species: + n.UU.val = calc_logk_s(stringfactor(STR1, LINK)); + break; + + case toklk_named: + n.UU.val = calc_logk_n(stringfactor(STR1, LINK)); + break; + + case toklk_phase: + n.UU.val = calc_logk_p(stringfactor(STR1, LINK)); + break; + + case toksum_species: + require(toklp, LINK); + mytemplate = stringfactor(STR1, LINK); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + elt_name = stringfactor(STR2, LINK); + } else { + elt_name = NULL; + } + require(tokrp, LINK); + n.UU.val = sum_match_species(mytemplate, elt_name); + break; + + case toksum_gas: + require(toklp, LINK); + mytemplate = stringfactor(STR1, LINK); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + elt_name = stringfactor(STR2, LINK); + } else { + elt_name = NULL; + } + require(tokrp, LINK); + n.UU.val = sum_match_gases(mytemplate, elt_name); + break; + + case toksum_s_s: + require(toklp, LINK); + mytemplate = stringfactor(STR1, LINK); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + elt_name = stringfactor(STR2, LINK); + } else { + elt_name = NULL; + } + require(tokrp, LINK); + n.UU.val = sum_match_s_s(mytemplate, elt_name); + break; + + case tokcalc_value: + require(toklp, LINK); + name = stringfactor(STR1, LINK); + require(tokrp, LINK); + n.UU.val = get_calculate_value(name); + break; + + case tokdescription: + n.stringval = true; + n.UU.sval = string_duplicate(use.solution_ptr->description); + while (replace("\t"," ",n.UU.sval)); + break; + + case tokinstr: + require(toklp, LINK); + string1 = stringfactor(STR1, LINK); + require(tokcomma, LINK); + string2 = stringfactor(STR2, LINK); + require(tokrp, LINK); + ptr = strstr(string1, string2); + if (ptr == NULL) { + n.UU.val = 0; + } else { + n.UU.val = ((LDBLE) (ptr - string1)) + 1; + } + break; + + case tokltrim: + n.stringval = true; + require(toklp, LINK); + string1 = stringfactor(STR1, LINK); + require(tokrp, LINK); + string_trim_left(string1); + n.UU.sval = string_duplicate(string1); + break; + + case tokrtrim: + n.stringval = true; + require(toklp, LINK); + string1 = stringfactor(STR1, LINK); + require(tokrp, LINK); + string_trim_right(string1); + n.UU.sval = string_duplicate(string1); + break; + + case toktrim: + n.stringval = true; + require(toklp, LINK); + string1 = stringfactor(STR1, LINK); + require(tokrp, LINK); + string_trim(string1); + n.UU.sval = string_duplicate(string1); + break; + + case tokpad: + n.stringval = true; + require(toklp, LINK); + string1 = stringfactor(STR1, LINK); + require(tokcomma, LINK); + i = intexpr(LINK); + require(tokrp, LINK); + n.UU.sval = string_pad(string1, i); + break; + + case toksys: + require(toklp, LINK); + elt_name = stringfactor(STR1, LINK); + /* + * Parse arguments + */ + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + /* struct varrec *count_varrec, *names_varrec, *types_varrec, *moles_varrec; */ + /* return number of species */ + LINK->t = LINK->t->next; + count_varrec = LINK->t->UU.vp; + if (count_varrec->stringvar != 0) snerr(); + + /* return number of names of species */ + LINK->t = LINK->t->next; + require(tokcomma, LINK); + names_varrec = LINK->t->UU.vp; + if (names_varrec->stringvar != 1) snerr(); + + /* return number of types of species */ + LINK->t = LINK->t->next; + require(tokcomma, LINK); + types_varrec = LINK->t->UU.vp; + if (types_varrec->stringvar != 1) snerr(); + + /* return number of moles of species */ + LINK->t = LINK->t->next; + require(tokcomma, LINK); + moles_varrec = LINK->t->UU.vp; + if (moles_varrec->stringvar != 0) snerr(); + LINK->t = LINK->t->next; + arg_num = 4; + } else { + arg_num = 1; + } + require(tokrp, LINK); + + if (arg_num > 1) { + free_dim_stringvar(names_varrec); + free_dim_stringvar(types_varrec); + free_check_null(moles_varrec->UU.U0.arr); + moles_varrec->UU.U0.arr = NULL; + } + /* + * Call subroutine + */ + /* + n.UU.val = system_total(elt_name, count_varrec->UU.U0.val, &(names_varrec->UU.U1.sarr), &(types_varrec->UU.U1.sarr), &(moles_varrec->UU.U0.arr)); + */ + n.UU.val = system_total(elt_name, &count_species, &(names_arg), &(types_arg), &(moles_arg)); + + /* + * fill in varrec structure + */ + if (arg_num > 1) { + *count_varrec->UU.U0.val = count_species; + names_varrec->UU.U1.sarr = names_arg; + types_varrec->UU.U1.sarr = types_arg; + moles_varrec->UU.U0.arr = moles_arg; + + for (i = 0; i < maxdims; i++) { + names_varrec->dims[i] = 0; + types_varrec->dims[i] = 0; + moles_varrec->dims[i] = 0; + } + names_varrec->dims[0] = (long) (*count_varrec->UU.U0.val) + 1; + types_varrec->dims[0] = (long) (*count_varrec->UU.U0.val) + 1; + moles_varrec->dims[0] = (long) (*count_varrec->UU.U0.val) + 1; + names_varrec->numdims = 1; + types_varrec->numdims = 1; + moles_varrec->numdims = 1; + } else { + for (i = 0; i < count_species + 1; i++) { + free_check_null(names_arg[i]); + free_check_null(types_arg[i]); + } + free_check_null(names_arg); + free_check_null(types_arg); + free_check_null(moles_arg); + } + break; + case tokrxn: + if (state == REACTION) { + n.UU.val = step_x; + } else { + n.UU.val = 0.0; + } + break; + + case tokdist: + if (state == PHAST) { + n.UU.val = 0; + } else if (state == TRANSPORT) { + n.UU.val = cell_data[cell-1].mid_cell_x; + } else if (state == ADVECTION) { + n.UU.val = (LDBLE) use.n_solution_user; + } else { + n.UU.val = 0; + } + break; + + case tokmol: + n.UU.val = molality(stringfactor(STR1, LINK)); + break; + + case tokla: + n.UU.val = log_activity(stringfactor(STR1, LINK)); + break; + + case toklm: + n.UU.val = log_molality(stringfactor(STR1, LINK)); + break; + + case toksr: + n.UU.val = saturation_ratio(stringfactor(STR1, LINK)); + break; + + case tokstep_no: + if (state == PHAST) { + n.UU.val = 0; + } else if (state == TRANSPORT) { + n.UU.val = transport_step; + } else if (state == ADVECTION) { + n.UU.val = advection_step; + } else if (state == REACTION) { + n.UU.val = reaction_step; + } else { + n.UU.val = 0; + } + break; + + case tokcell_no: + if (state == TRANSPORT) { + n.UU.val = cell_no; + } else if (state == PHAST) { + n.UU.val = cell_no; + } else if (state == ADVECTION) { + n.UU.val = cell_no; + } else if (state < REACTION) { + n.UU.val = use.solution_ptr->n_user; + } else { + if (use.mix_in == TRUE) { + n.UU.val = use.n_mix_user; + } else { + n.UU.val = use.n_solution_user; + } + } + break; + + case toksim_no: + n.UU.val = simulation; + break; + + case tokget: + require(toklp, LINK); + + s_v.count_subscripts = 0; + /* get first subscript */ + if (LINK->t != NULL && LINK->t->kind != tokrp) { + i = intexpr(LINK); + s_v.subscripts = (int*) PHRQ_realloc(s_v.subscripts, (size_t) (s_v.count_subscripts + 1) * sizeof(int)); + if (s_v.subscripts == NULL) malloc_error(); + s_v.subscripts[s_v.count_subscripts] = i; + s_v.count_subscripts++; + } + + /* get other subscripts */ + for (;;) { + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + j = intexpr(LINK); + s_v.subscripts = (int*) PHRQ_realloc(s_v.subscripts, (size_t) (s_v.count_subscripts + 1) * sizeof(int)); + if (s_v.subscripts == NULL) malloc_error(); + s_v.subscripts[s_v.count_subscripts] = j; + s_v.count_subscripts++; + } else { + /* get right parentheses */ + require(tokrp, LINK); + break; + } + } + s_v_ptr = save_values_bsearch(&s_v, &k); + if (s_v_ptr == NULL) { + n.UU.val = 0; + } else { + n.UU.val = s_v_ptr->value; + } + break; + + case tokexists: + require(toklp, LINK); + + s_v.count_subscripts = 0; + /* get first subscript */ + if (LINK->t != NULL && LINK->t->kind != tokrp) { + i = intexpr(LINK); + s_v.subscripts = (int*) PHRQ_realloc(s_v.subscripts, (size_t) (s_v.count_subscripts + 1) * sizeof(int)); + if (s_v.subscripts == NULL) malloc_error(); + s_v.subscripts[s_v.count_subscripts] = i; + s_v.count_subscripts++; + } + + /* get other subscripts */ + for (;;) { + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + j = intexpr(LINK); + s_v.subscripts = (int*) PHRQ_realloc(s_v.subscripts, (size_t) (s_v.count_subscripts + 1) * sizeof(int)); + if (s_v.subscripts == NULL) malloc_error(); + s_v.subscripts[s_v.count_subscripts] = j; + s_v.count_subscripts++; + } else { + /* get right parentheses */ + require(tokrp, LINK); + break; + } + } + s_v_ptr = save_values_bsearch(&s_v, &k); + if (s_v_ptr == NULL) { + n.UU.val = 0; + } else { + n.UU.val = 1; + } + break; + + case tokcharge_balance: + n.UU.val = cb_x; + break; + + case tokpercent_error: + n.UU.val = 100*cb_x/total_ions_x; + break; + + case toksi: + saturation_index(stringfactor(STR1, LINK), &dummy, &n.UU.val); + break; + + case toktot: + n.UU.val = total(stringfactor(STR1, LINK)); + break; + + case toklog10: + n.UU.val = log10(realfactor(LINK)); + break; + + case toksin: + n.UU.val = sin(realfactor(LINK)); + break; + + case tokcos: + n.UU.val = cos(realfactor(LINK)); + break; + + case toktan: + n.UU.val = realfactor(LINK); + n.UU.val = sin(n.UU.val) / cos(n.UU.val); + break; + + case tokarctan: + n.UU.val = atan(realfactor(LINK)); + break; + + case toklog: + n.UU.val = log(realfactor(LINK)); + break; + + case tokexp: + n.UU.val = exp(realfactor(LINK)); + break; + + case tokabs: + n.UU.val = fabs(realfactor(LINK)); + break; + + case toksgn: + n.UU.val = realfactor(LINK); + n.UU.val = (n.UU.val > 0) - (n.UU.val < 0); + break; + + case tokstr_: + n.stringval = true; + n.UU.sval = (char *) PHRQ_malloc(256); + if (n.UU.sval == NULL) malloc_error(); + numtostr(n.UU.sval, realfactor(LINK)); + break; + + case tokval: + s = strfactor(LINK); + tok1 = LINK->t; + parse(s, &LINK->t); + tok = LINK->t; + if (tok == NULL) + n.UU.val = 0.0; + else + n = expr(LINK); + disposetokens(&tok); + LINK->t = tok1; + free(s); + break; + + case tokchr_: + n.stringval = true; + n.UU.sval = (char *) PHRQ_malloc(256); + if (n.UU.sval == NULL) malloc_error(); + strcpy(n.UU.sval, " "); + n.UU.sval[0] = (Char)intfactor(LINK); + break; + + case tokasc: + s = strfactor(LINK); + if (*s == '\0') + n.UU.val = 0.0; + else + n.UU.val = s[0]; + free(s); + break; + + case tokmid_: + n.stringval = true; + require(toklp, LINK); + n.UU.sval = strexpr(LINK); + require(tokcomma, LINK); + i = intexpr(LINK); + if (i < 1) + i = 1; + /*j = 255;*/ + j = strlen(n.UU.sval); + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + j = intexpr(LINK); + } + if (j > (int) strlen(n.UU.sval) - i + 1) + j = strlen(n.UU.sval) - i + 1; + if (i > (int) strlen(n.UU.sval)) + *n.UU.sval = '\0'; + else { + STR1 = (char *) PHRQ_realloc(STR1, j + 1); + if (STR1 == NULL) malloc_error(); + sprintf(STR1, "%.*s", (int)j, n.UU.sval + i - 1); + strcpy(n.UU.sval, STR1); + } + require(tokrp, LINK); + break; + + case toklen: + s = strfactor(LINK); + n.UU.val = strlen(s); + free(s); + break; + + case tokpeek: +/* p2c: basic.p, line 1029: Note: Range checking is OFF [216] */ + trick.i = intfactor(LINK); + n.UU.val = *trick.c; +/* p2c: basic.p, line 1032: Note: Range checking is ON [216] */ + break; + + default: + snerr(); + break; + } + s_v.subscripts = (int*) free_check_null(s_v.subscripts); + free_check_null(STR1); + free_check_null(STR2); + return n; +} + +Local valrec upexpr(struct LOC_exec *LINK) +{ + valrec n, n2; + + n = factor(LINK); + while (LINK->t != NULL && LINK->t->kind == tokup) { + if (n.stringval) + tmerr(); + LINK->t = LINK->t->next; + n2 = upexpr(LINK); + if (n2.stringval) + tmerr(); + if (n.UU.val >= 0) { + if (n.UU.val >0) { + n.UU.val = exp(n2.UU.val * log(n.UU.val)); + } + continue; + } + if (n2.UU.val != (long)n2.UU.val) + n.UU.val = log(n.UU.val); + n.UU.val = exp(n2.UU.val * log(-n.UU.val)); + if (((long)n2.UU.val) & 1) + n.UU.val = -n.UU.val; + } + return n; +} + +Local valrec term(struct LOC_exec *LINK) +{ + valrec n, n2; + int k; + + n = upexpr(LINK); + while (LINK->t != NULL && (unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & ((1L << ((long)toktimes)) | + (1L << ((long)tokdiv)) | (1L << ((long)tokmod)))) != 0) { + k = LINK->t->kind; + LINK->t = LINK->t->next; + n2 = upexpr(LINK); + if (n.stringval || n2.stringval) + tmerr(); + if (k == tokmod) { + /* n.UU.val = (long)floor(n.UU.val + 0.5) % (long)floor(n2.UU.val + 0.5); */ + if (n.UU.val != 0) { + n.UU.val = fabs(n.UU.val)/n.UU.val * fmod(fabs(n.UU.val) + 1e-14, n2.UU.val); + } else { + n.UU.val = 0; + } +/* p2c: basic.p, line 1078: + * Note: Using % for possibly-negative arguments [317] */ + } else if (k == toktimes) + n.UU.val *= n2.UU.val; + else + if (n2.UU.val != 0) { + n.UU.val /= n2.UU.val; + } else { + error_msg("Zero divide in Basic. Value set to zero.", CONTINUE); + n.UU.val = 0; + } + } + return n; +} + +Local valrec sexpr(struct LOC_exec *LINK) +{ + valrec n, n2; + int k, m; + + n = term(LINK); + while (LINK->t != NULL && (unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)tokplus)) | (1L << ((long)tokminus)))) != 0) { + k = LINK->t->kind; + LINK->t = LINK->t->next; + n2 = term(LINK); + if (n.stringval != n2.stringval) + tmerr(); + if (k == tokplus) { + if (n.stringval) { + m = strlen(n.UU.sval) + strlen(n2.UU.sval) + 1; + if (m < 256) m = 256; + + n.UU.sval = (char *) PHRQ_realloc(n.UU.sval, m); + if (n.UU.sval == NULL) malloc_error(); + strcat(n.UU.sval, n2.UU.sval); + free(n2.UU.sval); + } else + n.UU.val += n2.UU.val; + } else { + if (n.stringval) + tmerr(); + else + n.UU.val -= n2.UU.val; + } + } + return n; +} + +Local valrec relexpr(struct LOC_exec *LINK) +{ + valrec n, n2; + boolean f; + int k; + + n = sexpr(LINK); + while (LINK->t != NULL && (unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)tokne + 1)) - (1L << ((long)tokeq)))) != 0) { + k = LINK->t->kind; + LINK->t = LINK->t->next; + n2 = sexpr(LINK); + if (n.stringval != n2.stringval) + tmerr(); + if (n.stringval) { + f = (boolean) ((!strcmp(n.UU.sval, n2.UU.sval) && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)tokeq)) | + (1L << ((long)tokge)) | (1L << ((long)tokle)))) != 0) || + (strcmp(n.UU.sval, n2.UU.sval) < 0 && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)toklt)) | + (1L << ((long)tokle)) | (1L << ((long)tokne)))) != 0) || + (strcmp(n.UU.sval, n2.UU.sval) > 0 && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)tokgt)) | + (1L << ((long)tokge)) | (1L << ((long)tokne)))) != 0)); + /* p2c: basic.p, line 2175: Note: + * Line breaker spent 0.0+1.00 seconds, 5000 tries on line 1518 [251] */ + free(n.UU.sval); + free(n2.UU.sval); + } else + f = (boolean) ((n.UU.val == n2.UU.val && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)tokeq)) | + (1L << ((long)tokge)) | (1L << ((long)tokle)))) != 0) || + (n.UU.val < n2.UU.val && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)toklt)) | + (1L << ((long)tokle)) | (1L << ((long)tokne)))) != 0) || + (n.UU.val > n2.UU.val && (unsigned long)k < 32 && + ((1L << ((long)k)) & ((1L << ((long)tokgt)) | + (1L << ((long)tokge)) | (1L << ((long)tokne)))) != 0)); + /* p2c: basic.p, line 2175: Note: + * Line breaker spent 0.0+2.00 seconds, 5000 tries on line 1532 [251] */ + n.stringval = false; + n.UU.val = f; + } + return n; +} + +Local valrec andexpr(struct LOC_exec *LINK) +{ + valrec n, n2; + + n = relexpr(LINK); + while (LINK->t != NULL && LINK->t->kind == tokand) { + LINK->t = LINK->t->next; + n2 = relexpr(LINK); + if (n.stringval || n2.stringval) + tmerr(); + n.UU.val = ((long)n.UU.val) & ((long)n2.UU.val); + } + return n; +} + +Local valrec expr(struct LOC_exec *LINK) +{ + valrec n, n2; + int k; + + n = andexpr(LINK); + while (LINK->t != NULL && (unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)tokor)) | (1L << ((long)tokxor)))) != 0) { + k = LINK->t->kind; + LINK->t = LINK->t->next; + n2 = andexpr(LINK); + if (n.stringval || n2.stringval) + tmerr(); + if (k == tokor) + n.UU.val = ((long)n.UU.val) | ((long)n2.UU.val); + else + n.UU.val = ((long)n.UU.val) ^ ((long)n2.UU.val); + } + return n; +} + + +Local void checkextra(struct LOC_exec *LINK) +{ + if (LINK->t != NULL) + errormsg("Extra information on line"); +} + + +Local boolean iseos(struct LOC_exec *LINK) +{ + return ( (boolean) (LINK->t == NULL || LINK->t->kind == (long)tokelse || + LINK->t->kind == (long)tokcolon) ); +} + + +Local void skiptoeos(struct LOC_exec *LINK) +{ + while (!iseos(LINK)) + LINK->t = LINK->t->next; +} + + +#ifdef SKIP +/* LINK not used */ +Local linerec *findline(long n, struct LOC_exec *LINK) +#endif +Local linerec *findline(long n) +{ + linerec *l; + + l = linebase; + while (l != NULL && l->num != n) + l = l->next; + return l; +} + + +#ifdef SKIP +Local linerec *mustfindline(long n, struct LOC_exec *LINK) +#endif +Local linerec *mustfindline(long n) +{ + linerec *l; + +#ifdef SKIP + l = findline(n, LINK); +#endif + l = findline(n); + if (l == NULL) + errormsg("Undefined line"); + return l; +} + + +Local void cmdend(struct LOC_exec *LINK) +{ + stmtline = NULL; + LINK->t = NULL; +} + + +Local void cmdnew(struct LOC_exec *LINK) +{ + void *p; + int i, k; + + cmdend(LINK); + clearloops(); + restoredata(); + while (linebase != NULL) { + p = linebase->next; + disposetokens(&linebase->txt); + free(linebase); + linebase = (struct linerec *) p; + } + while (varbase != NULL) { + p = varbase->next; + if (varbase->stringvar) { + if (varbase->numdims > 0) { + k = 1; + for (i = 0; i < varbase->numdims; i++) { + k = k*(varbase->dims[i]); + } + for (i = 0; i < k; i++) { + free_check_null(varbase->UU.U1.sarr[i]); + } + free_check_null(varbase->UU.U1.sarr); + } else if (*varbase->UU.U1.sval != NULL) { + *varbase->UU.U1.sval = (char*) free_check_null(*varbase->UU.U1.sval); + } + + } else { + free_check_null(varbase->UU.U0.arr); + varbase->UU.U0.arr = NULL; + } + free(varbase); + varbase = (struct varrec *) p; + } +} + + +Local void cmdlist(struct LOC_exec *LINK) +{ + linerec *l; + long n1, n2; + + do { + n1 = 0; + n2 = LONG_MAX; + if (LINK->t != NULL && LINK->t->kind == toknum) { + n1 = (long)LINK->t->UU.num; + LINK->t = LINK->t->next; + if (LINK->t == NULL || LINK->t->kind != tokminus) + n2 = n1; + } + if (LINK->t != NULL && LINK->t->kind == tokminus) { + LINK->t = LINK->t->next; + if (LINK->t != NULL && LINK->t->kind == toknum) { + n2 = (long)LINK->t->UU.num; + LINK->t = LINK->t->next; + } else + n2 = LONG_MAX; + } + l = linebase; + while (l != NULL && l->num <= n2) { + if (l->num >= n1) { + /* printf("%ld ", l->num); */ + /* listtokens(stdout, l->txt); */ + /* putchar('\n'); */ + output_msg(OUTPUT_MESSAGE, "%ld ", l->num); + listtokens(NULL, l->txt); + output_msg(OUTPUT_MESSAGE, "\n"); + } + l = l->next; + } + if (!iseos(LINK)) + require(tokcomma, LINK); + } while (!iseos(LINK)); +} + + +Local void cmdload(boolean merging, Char *name, struct LOC_exec *LINK) +{ + FILE *f; + tokenrec *buf; + Char STR1[256]; + Char *TEMP; + + f = NULL; + if (!merging) + cmdnew(LINK); + if (f != NULL) { + sprintf(STR1, "%s.TEXT", name); + f = freopen(STR1, "r", f); + } else { + sprintf(STR1, "%s.TEXT", name); + f = fopen(STR1, "r"); + } + if (f == NULL) + _EscIO(FileNotFound); + while (fgets(inbuf, 256, f) != NULL) { + TEMP = strchr(inbuf, '\n'); + if (TEMP != NULL) + *TEMP = 0; + parseinput(&buf); + if (curline == 0) { + printf("Bad line in file\n"); + disposetokens(&buf); + } + } + if (f != NULL) + fclose(f); + f = NULL; + if (f != NULL) + fclose(f); +} + + +Local void cmdrun(struct LOC_exec *LINK) +{ + linerec *l; + long i; + /*string255 s;*/ + char *s; + + s = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (s == NULL) malloc_error(); + + l = linebase; + if (!iseos(LINK)) { + if (LINK->t->kind == toknum) +#ifdef SKIP + l = mustfindline(intexpr(LINK), LINK); +#endif + l = mustfindline(intexpr(LINK)); + else { + stringexpr(s, LINK); + i = 0; + if (!iseos(LINK)) { + require(tokcomma, LINK); + i = intexpr(LINK); + } + checkextra(LINK); + cmdload(false, s, LINK); + if (i == 0) + l = linebase; + else +#ifdef SKIP + l = mustfindline(i, LINK); +#endif + l = mustfindline(i); + } + } + stmtline = l; + LINK->gotoflag = true; + clearvars(); + clearloops(); + restoredata(); + free_check_null(s); + return; +} + +#ifdef SKIP +Local void cmdsave(struct LOC_exec *LINK) +{ + FILE *f; + linerec *l; + Char STR1[256], STR2[256]; + + f = NULL; + if (f != NULL) { + sprintf(STR2, "%s.TEXT", stringexpr(STR1, LINK)); + f = freopen(STR2, "w", f); + } else { + sprintf(STR2, "%s.TEXT", stringexpr(STR1, LINK)); + f = fopen(STR2, "w"); + } + if (f == NULL) + _EscIO(FileNotFound); + l = linebase; + while (l != NULL) { + /* fprintf(f, "%ld ", l->num);*/ + listtokens(f, l->txt); + putc('\n', f); + l = l->next; + } + if (f != NULL) + fclose(f); + f = NULL; + if (f != NULL) + fclose(f); +} +#endif + +/* replace basic save command with transport of rate back to calc_kinetic_rate */ +Local void cmdsave(struct LOC_exec *LINK) +{ +#ifdef SKIP + boolean semiflag; +#endif + valrec n; + while (!iseos(LINK)) { +#ifdef SKIP + semiflag = false; +#endif + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { +#ifdef SKIP + semiflag = true; +#endif + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (n.stringval) { + snerr(); + } else { + rate_moles = n.UU.val; + } + } +} +Local void cmdput(struct LOC_exec *LINK) +{ + int j; + struct save_values s_v; + + s_v.count_subscripts = 0; + s_v.subscripts = (int*) PHRQ_malloc(sizeof(int)); + + /* get parentheses */ + require(toklp, LINK); + + /* get first argumen */ + s_v.value = realexpr(LINK); + + for (;;) { + if (LINK->t != NULL && LINK->t->kind == tokcomma) { + LINK->t = LINK->t->next; + j = intexpr(LINK); + s_v.count_subscripts++; + s_v.subscripts = (int*) PHRQ_realloc(s_v.subscripts, (size_t) s_v.count_subscripts * sizeof(int)); + if (s_v.subscripts == NULL) malloc_error(); + s_v.subscripts[s_v.count_subscripts - 1] = j; + } else { + /* get right parentheses */ + require(tokrp, LINK); + break; + } + } + + save_values_store(&s_v); + s_v.subscripts = (int*) free_check_null(s_v.subscripts); +} +#ifdef SKIP +/* LINK not used */ +Local void cmdbye(struct LOC_exec *LINK) +#endif +Local void cmdbye(void) +{ + exitflag = true; +} + +Local void cmddel(struct LOC_exec *LINK) +{ + linerec *l, *l0, *l1; + long n1, n2; + + do { + if (iseos(LINK)) + snerr(); + n1 = 0; + n2 = LONG_MAX; + if (LINK->t != NULL && LINK->t->kind == toknum) { + n1 = (long)LINK->t->UU.num; + LINK->t = LINK->t->next; + if (LINK->t == NULL || LINK->t->kind != tokminus) + n2 = n1; + } + if (LINK->t != NULL && LINK->t->kind == tokminus) { + LINK->t = LINK->t->next; + if (LINK->t != NULL && LINK->t->kind == toknum) { + n2 = (long)LINK->t->UU.num; + LINK->t = LINK->t->next; + } else + n2 = LONG_MAX; + } + l = linebase; + l0 = NULL; + while (l != NULL && l->num <= n2) { + l1 = l->next; + if (l->num >= n1) { + if (l == stmtline) { + cmdend(LINK); + clearloops(); + restoredata(); + } + if (l0 == NULL) + linebase = l->next; + else + l0->next = l->next; + disposetokens(&l->txt); + free(l); + } else + l0 = l; + l = l1; + } + if (!iseos(LINK)) + require(tokcomma, LINK); + } while (!iseos(LINK)); +} + + +Local void cmdrenum(struct LOC_exec *LINK) +{ + linerec *l, *l1; + tokenrec *tok; + long lnum, step; + + lnum = 10; + step = 10; + if (!iseos(LINK)) { + lnum = intexpr(LINK); + if (!iseos(LINK)) { + require(tokcomma, LINK); + step = intexpr(LINK); + } + } + l = linebase; + if (l == NULL) + return; + while (l != NULL) { + l->num2 = lnum; + lnum += step; + l = l->next; + } + l = linebase; + do { + tok = l->txt; + do { + if (tok->kind == (long)tokdel || tok->kind == (long)tokrestore || + tok->kind == (long)toklist || tok->kind == (long)tokrun || + tok->kind == (long)tokelse || tok->kind == (long)tokthen || + tok->kind == (long)tokgosub || tok->kind == (long)tokgoto) { + while (tok->next != NULL && tok->next->kind == toknum) { + tok = tok->next; + lnum = (long)floor(tok->UU.num + 0.5); + l1 = linebase; + while (l1 != NULL && l1->num != lnum) + l1 = l1->next; + if (l1 == NULL) + printf("Undefined line %ld in line %ld\n", lnum, l->num2); + else + tok->UU.num = l1->num2; + if (tok->next != NULL && tok->next->kind == tokcomma) + tok = tok->next; + } + } + tok = tok->next; + } while (tok != NULL); + l = l->next; + } while (l != NULL); + l = linebase; + while (l != NULL) { + l->num = l->num2; + l = l->next; + } +} + + +Local void cmdprint(struct LOC_exec *LINK) +{ + boolean semiflag; + valrec n; + Char STR1[256]; + + semiflag = false; + while (!iseos(LINK)) { + semiflag = false; + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { + semiflag = true; + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (n.stringval) { +/* fputs(n.UU.sval, stdout); */ + output_msg(OUTPUT_MESSAGE, "%s ", n.UU.sval); + free(n.UU.sval); + } else +/* printf("%s ", numtostr(STR1, n.UU.val)); */ + output_msg(OUTPUT_MESSAGE, "%s ", numtostr(STR1, n.UU.val)); + } + if (!semiflag) +/* putchar('\n');*/ + output_msg(OUTPUT_MESSAGE, "\n"); +} + +Local void cmdpunch(struct LOC_exec *LINK) +{ +#ifdef SKIP + boolean semiflag; +#endif + valrec n; + /* Char STR1[256]; */ + +#ifdef SKIP + semiflag = false; +#endif + while (!iseos(LINK)) { +#ifdef SKIP + semiflag = false; +#endif + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { +#ifdef SKIP + semiflag = true; +#endif + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (n.stringval) { +/* fputs(n.UU.sval, stdout); */ + if (punch.high_precision == FALSE) { + if (strlen(n.UU.sval) <= 12) { + fpunchf_user(n_user_punch_index, "%12.12s\t", n.UU.sval); + } else { + fpunchf_user(n_user_punch_index, "%s\t", n.UU.sval); + } + } else { + if (strlen(n.UU.sval) <= 20) { + fpunchf_user(n_user_punch_index, "%20.20s\t", n.UU.sval); + } else { + fpunchf_user(n_user_punch_index, "%s\t", n.UU.sval); + } + } + free(n.UU.sval); + } else + if (punch.high_precision == FALSE) { + fpunchf_user(n_user_punch_index, "%12.4e\t", n.UU.val); + } else { + fpunchf_user(n_user_punch_index, "%20.12e\t", n.UU.val); + } + ++n_user_punch_index; + } +} + +#ifdef PHREEQ98 +Local void cmdgraph_x(struct LOC_exec *LINK) +{ + boolean semiflag; + valrec n; + Char STR1[256]; + semiflag = false; + while (!iseos(LINK)) { + semiflag = false; + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { + semiflag = true; + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (colnr == 0) rownr++; + if (n.stringval) { +/* fputs(n.UU.sval, stdout); */ + GridChar(n.UU.sval, "x"); + Free(n.UU.sval); + } else + GridChar(numtostr(STR1, n.UU.val), "x"); + colnr++; + } +} + +Local void cmdgraph_y(struct LOC_exec *LINK) +{ + boolean semiflag; + valrec n; + Char STR1[256]; + semiflag = false; + while (!iseos(LINK)) { + semiflag = false; + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { + semiflag = true; + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (n.stringval) { +/* fputs(n.UU.sval, stdout); */ + GridChar(n.UU.sval, "y"); + Free(n.UU.sval); + } else + GridChar(numtostr(STR1, n.UU.val), "y"); + colnr++; + } +} + +Local void cmdgraph_sy(struct LOC_exec *LINK) +{ + boolean semiflag; + valrec n; + Char STR1[256]; + semiflag = false; + while (!iseos(LINK)) { + semiflag = false; + if ((unsigned long)LINK->t->kind < 32 && + ((1L << ((long)LINK->t->kind)) & + ((1L << ((long)toksemi)) | (1L << ((long)tokcomma)))) != 0) { + semiflag = true; + LINK->t = LINK->t->next; + continue; + } + n = expr(LINK); + if (n.stringval) { +/* fputs(n.UU.sval, stdout); */ + GridChar(n.UU.sval, "s"); + Free(n.UU.sval); + } else + GridChar(numtostr(STR1, n.UU.val), "s"); + colnr++; + } +} +#endif + +#ifdef SKIP +Local void cmdinput(struct LOC_exec *LINK) +{ + varrec *v; + /* string255 s; */ + char *s; + tokenrec *tok, *tok0, *tok1; + boolean strflag; + + /* + s = (char *) PHRQ_calloc(max_line, sizeof(char)); + if (s == NULL) malloc_error(); + */ + /* need to free s if this subroutine is used */ + + if (LINK->t != NULL && LINK->t->kind == tokstr) { + fputs(LINK->t->UU.sp, stdout); + LINK->t = LINK->t->next; + require(toksemi, LINK); + } else + printf("? "); + tok = LINK->t; + if (LINK->t == NULL || LINK->t->kind != tokvar) + snerr(); + strflag = LINK->t->UU.vp->stringvar; + do { + if (LINK->t != NULL && LINK->t->kind == tokvar) { + if (LINK->t->UU.vp->stringvar != strflag) + snerr(); + } + LINK->t = LINK->t->next; + } while (!iseos(LINK)); + LINK->t = tok; + if (strflag) { + do { + gets(s); + v = findvar(LINK); + if (*v->UU.U1.sval != NULL) + *v->UU.U1.sval = free_check_null(*v->UU.U1.sval); + *v->UU.U1.sval = (char *) PHRQ_malloc(256); + if (*v->UU.U1.sval == NULL) malloc_error(); + strcpy(*v->UU.U1.sval, s); + if (!iseos(LINK)) { + require(tokcomma, LINK); + printf("?? "); + } + } while (!iseos(LINK)); + return; + } + gets(s); + parse(s, &tok); + tok0 = tok; + do { + v = findvar(LINK); + while (tok == NULL) { + printf("?? "); + gets(s); + disposetokens(&tok0); + parse(s, &tok); + tok0 = tok; + } + tok1 = LINK->t; + LINK->t = tok; + *v->UU.U0.val = realexpr(LINK); + if (LINK->t != NULL) { + if (LINK->t->kind == tokcomma) + LINK->t = LINK->t->next; + else + snerr(); + } + tok = LINK->t; + LINK->t = tok1; + if (!iseos(LINK)) + require(tokcomma, LINK); + } while (!iseos(LINK)); + disposetokens(&tok0); +} +#endif + +Local void cmdlet(boolean implied, struct LOC_exec *LINK) +{ + varrec *v; + Char *old, *mynew; + LDBLE d_value; + LDBLE *target; + char **starget; + target = NULL; + starget = NULL; + if (implied) + LINK->t = stmttok; + v = findvar(LINK); + if (v->stringvar) { + starget = v->UU.U1.sval; + } else { + target = v->UU.U0.val; + } + require(tokeq, LINK); + if (!v->stringvar) { + /* in case array is used on right hand side */ + d_value = realexpr(LINK); + v->UU.U0.val = target; + *v->UU.U0.val = d_value; + /* *v->UU.U0.val = realexpr(LINK); */ + return; + } + mynew = strexpr(LINK); + v->UU.U1.sval = starget; + old = *v->UU.U1.sval; + *v->UU.U1.sval = mynew; + if (old != NULL) + free(old); +} + + +Local void cmdgoto(struct LOC_exec *LINK) +{ +#ifdef SKIP + stmtline = mustfindline(intexpr(LINK), LINK); +#endif + stmtline = mustfindline(intexpr(LINK)); + LINK->t = NULL; + LINK->gotoflag = true; +} + + +Local void cmdif(struct LOC_exec *LINK) +{ + LDBLE n; + long i; + + n = realexpr(LINK); + require(tokthen, LINK); + if (n == 0) { + i = 0; + do { + if (LINK->t != NULL) { + if (LINK->t->kind == tokif) + i++; + if (LINK->t->kind == tokelse) + i--; + LINK->t = LINK->t->next; + } + } while (LINK->t != NULL && i >= 0); + } + if (LINK->t != NULL && LINK->t->kind == toknum) + cmdgoto(LINK); + else + LINK->elseflag = true; +} + + +Local void cmdelse(struct LOC_exec *LINK) +{ + LINK->t = NULL; +} + + +Local boolean skiploop(int up, int dn, struct LOC_exec *LINK) +{ + boolean Result; + long i; + linerec *saveline; + + saveline = stmtline; + i = 0; + do { + while (LINK->t == NULL) { + if (stmtline == NULL || stmtline->next == NULL) { + Result = false; + stmtline = saveline; + goto _L1; + } + stmtline = stmtline->next; + LINK->t = stmtline->txt; + } + if (LINK->t->kind == up) + i++; + if (LINK->t->kind == dn) + i--; + LINK->t = LINK->t->next; + } while (i >= 0); + Result = true; +_L1: + return Result; +} + + +Local void cmdfor(struct LOC_exec *LINK) +{ + looprec *l, lr; + linerec *saveline; + long i, j; + + lr.UU.U0.vp = findvar(LINK); + if (lr.UU.U0.vp->stringvar) + snerr(); + require(tokeq, LINK); + *lr.UU.U0.vp->UU.U0.val = realexpr(LINK); + require(tokto, LINK); + lr.UU.U0.max = realexpr(LINK); + if (LINK->t != NULL && LINK->t->kind == tokstep) { + LINK->t = LINK->t->next; + lr.UU.U0.step = realexpr(LINK); + } else + lr.UU.U0.step = 1.0; + lr.homeline = stmtline; + lr.hometok = LINK->t; + lr.kind = forloop; + lr.next = loopbase; + if ((lr.UU.U0.step >= 0 && *lr.UU.U0.vp->UU.U0.val > lr.UU.U0.max) || + (lr.UU.U0.step <= 0 && *lr.UU.U0.vp->UU.U0.val < lr.UU.U0.max)) { + saveline = stmtline; + i = 0; + j = 0; + do { + while (LINK->t == NULL) { + if (stmtline == NULL || stmtline->next == NULL) { + stmtline = saveline; + errormsg("FOR without NEXT"); + } + stmtline = stmtline->next; + LINK->t = stmtline->txt; + } + if (LINK->t->kind == tokfor) { + if (LINK->t->next != NULL && LINK->t->next->kind == tokvar && + LINK->t->next->UU.vp == lr.UU.U0.vp) + j++; + else + i++; + } + if (LINK->t->kind == toknext) { + if (LINK->t->next != NULL && LINK->t->next->kind == tokvar && + LINK->t->next->UU.vp == lr.UU.U0.vp) + j--; + else + i--; + } + LINK->t = LINK->t->next; + } while (i >= 0 && j >= 0); + skiptoeos(LINK); + return; + } + l = (looprec *) PHRQ_malloc(sizeof(looprec)); + if (l == NULL) malloc_error(); + *l = lr; + loopbase = l; +} + + +Local void cmdnext(struct LOC_exec *LINK) +{ + varrec *v; + boolean found; + looprec *l, *WITH; + + if (!iseos(LINK)) + v = findvar(LINK); + else + v = NULL; + do { + if (loopbase == NULL || loopbase->kind == gosubloop) + errormsg("NEXT without FOR"); + found = (boolean) (loopbase->kind == forloop && + (v == NULL || loopbase->UU.U0.vp == v)); + if (!found) { + l = loopbase->next; + free(loopbase); + loopbase = l; + } + } while (!found); + WITH = loopbase; + *WITH->UU.U0.vp->UU.U0.val += WITH->UU.U0.step; + if ((WITH->UU.U0.step < 0 || *WITH->UU.U0.vp->UU.U0.val <= WITH->UU.U0.max) && + (WITH->UU.U0.step > 0 || *WITH->UU.U0.vp->UU.U0.val >= WITH->UU.U0.max)) { + stmtline = WITH->homeline; + LINK->t = WITH->hometok; + return; + } + l = loopbase->next; + free(loopbase); + loopbase = l; +} + + +Local void cmdwhile(struct LOC_exec *LINK) +{ + looprec *l; + + l = (looprec *) PHRQ_malloc(sizeof(looprec)); + if (l == NULL) malloc_error(); + l->next = loopbase; + loopbase = l; + l->kind = whileloop; + l->homeline = stmtline; + l->hometok = LINK->t; + if (iseos(LINK)) + return; + if (realexpr(LINK) != 0) + return; + if (!skiploop(tokwhile, tokwend, LINK)) + errormsg("WHILE without WEND"); + l = loopbase->next; + free(loopbase); + loopbase = l; + skiptoeos(LINK); +} + + +Local void cmdwend(struct LOC_exec *LINK) +{ + tokenrec *tok; + linerec *tokline; + looprec *l; + boolean found; + + do { + if (loopbase == NULL || loopbase->kind == gosubloop) + errormsg("WEND without WHILE"); + found = (boolean) (loopbase->kind == whileloop); + if (!found) { + l = loopbase->next; + free(loopbase); + loopbase = l; + } + } while (!found); + if (!iseos(LINK)) { + if (realexpr(LINK) != 0) + found = false; + } + tok = LINK->t; + tokline = stmtline; + if (found) { + stmtline = loopbase->homeline; + LINK->t = loopbase->hometok; + if (!iseos(LINK)) { + if (realexpr(LINK) == 0) + found = false; + } + } + if (found) + return; + LINK->t = tok; + stmtline = tokline; + l = loopbase->next; + free(loopbase); + loopbase = l; +} + + +Local void cmdgosub(struct LOC_exec *LINK) +{ + looprec *l; + + l = (looprec *) PHRQ_malloc(sizeof(looprec)); + if (l == NULL) malloc_error(); + l->next = loopbase; + loopbase = l; + l->kind = gosubloop; + l->homeline = stmtline; + l->hometok = LINK->t; + cmdgoto(LINK); +} + + +Local void cmdreturn(struct LOC_exec *LINK) +{ + looprec *l; + boolean found; + + do { + if (loopbase == NULL) + errormsg("RETURN without GOSUB"); + found = (boolean) (loopbase->kind == gosubloop); + if (!found) { + l = loopbase->next; + free(loopbase); + loopbase = l; + } + } while (!found); + stmtline = loopbase->homeline; + LINK->t = loopbase->hometok; + l = loopbase->next; + free(loopbase); + loopbase = l; + skiptoeos(LINK); +} + + +Local void cmdread(struct LOC_exec *LINK) +{ + varrec *v; + tokenrec *tok; + boolean found; + + do { + v = findvar(LINK); + tok = LINK->t; + LINK->t = datatok; + if (dataline == NULL) { + dataline = linebase; + LINK->t = dataline->txt; + } + if (LINK->t == NULL || LINK->t->kind != tokcomma) { + do { + while (LINK->t == NULL) { + if (dataline == NULL || dataline->next == NULL) + errormsg("Out of Data"); + dataline = dataline->next; + LINK->t = dataline->txt; + } + found = (boolean) (LINK->t->kind == tokdata); + LINK->t = LINK->t->next; + } while (!found || iseos(LINK)); + } else + LINK->t = LINK->t->next; + if (v->stringvar) { + if (*v->UU.U1.sval != NULL) + *v->UU.U1.sval = (char *) free_check_null(*v->UU.U1.sval); + *v->UU.U1.sval = strexpr(LINK); + } else + *v->UU.U0.val = realexpr(LINK); + datatok = LINK->t; + LINK->t = tok; + if (!iseos(LINK)) + require(tokcomma, LINK); + } while (!iseos(LINK)); +} + + +Local void cmddata(struct LOC_exec *LINK) +{ + skiptoeos(LINK); +} + + +Local void cmdrestore(struct LOC_exec *LINK) +{ + if (iseos(LINK)) + restoredata(); + else { +#ifdef SKIP + dataline = mustfindline(intexpr(LINK), LINK); +#endif + dataline = mustfindline(intexpr(LINK)); + datatok = dataline->txt; + } +} + + +Local void cmdgotoxy(struct LOC_exec *LINK) +{ +#ifdef SKIP + long i; + + i = intexpr(LINK); +#endif + intexpr(LINK); + require(tokcomma, LINK); +} + + +Local void cmdon(struct LOC_exec *LINK) +{ + long i; + looprec *l; + + i = intexpr(LINK); + if (LINK->t != NULL && LINK->t->kind == tokgosub) { + l = (looprec *) PHRQ_malloc(sizeof(looprec)); + if (l == NULL) malloc_error(); + l->next = loopbase; + loopbase = l; + l->kind = gosubloop; + l->homeline = stmtline; + l->hometok = LINK->t; + LINK->t = LINK->t->next; + } else + require(tokgoto, LINK); + if (i < 1) { + skiptoeos(LINK); + return; + } + while (i > 1 && !iseos(LINK)) { + require(toknum, LINK); + if (!iseos(LINK)) + require(tokcomma, LINK); + i--; + } + if (!iseos(LINK)) + cmdgoto(LINK); +} + + +Local void cmddim(struct LOC_exec *LINK) +{ + long i, j, k; + varrec *v; + boolean done; + + do { + if (LINK->t == NULL || LINK->t->kind != tokvar) + snerr(); + v = LINK->t->UU.vp; + LINK->t = LINK->t->next; + if (v->numdims != 0) + errormsg("Array already dimensioned"); + j = 1; + i = 0; + require(toklp, LINK); + do { + k = intexpr(LINK) + 1; + if (k < 1) + badsubscr(); + if (i >= maxdims) + badsubscr(); + i++; + v->dims[i - 1] = k; + j *= k; + done = (boolean) (LINK->t != NULL && LINK->t->kind == tokrp); + if (!done) + require(tokcomma, LINK); + } while (!done); + LINK->t = LINK->t->next; + v->numdims = (char) i; + if (v->stringvar) { + v->UU.U1.sarr = (Char **) PHRQ_malloc(j * sizeof(char *)); + if (v->UU.U1.sarr == NULL) malloc_error(); + for (i = 0; i < j; i++) + v->UU.U1.sarr[i] = NULL; + } else { + v->UU.U0.arr = (LDBLE *) PHRQ_malloc(j * sizeof(LDBLE)); + if (v->UU.U0.arr == NULL) malloc_error(); + for (i = 0; i < j; i++) + v->UU.U0.arr[i] = 0.0; + } + if (!iseos(LINK)) + require(tokcomma, LINK); + } while (!iseos(LINK)); +} + + +Local void cmdpoke(struct LOC_exec *LINK) +{ + union { + long i; + Char *c; + } trick; + +/* p2c: basic.p, line 2073: Note: Range checking is OFF [216] */ + trick.i = intexpr(LINK); + require(tokcomma, LINK); + *trick.c = (Char)intexpr(LINK); +/* p2c: basic.p, line 2077: Note: Range checking is ON [216] */ +} + + + + + + + + + +Static void exec(void) +{ + struct LOC_exec V; + Char *ioerrmsg; + Char STR1[256]; + + + TRY(try1); + do { + do { + V.gotoflag = false; + V.elseflag = false; + while (stmttok != NULL && stmttok->kind == tokcolon) + stmttok = stmttok->next; + V.t = stmttok; + if (V.t != NULL) { + V.t = V.t->next; + switch (stmttok->kind) { + + case tokrem: + /* blank case */ + break; + + case toklist: + cmdlist(&V); + break; + + case tokrun: + cmdrun(&V); + break; + + case toknew: + cmdnew(&V); + break; + + case tokload: + cmdload(false, stringexpr(STR1, &V), &V); + break; + + case tokmerge: + cmdload(true, stringexpr(STR1, &V), &V); + break; + + case toksave: + cmdsave(&V); + break; + + case tokbye: +#ifdef SKIP + cmdbye(&V); +#endif + cmdbye(); + break; + + case tokdel: + cmddel(&V); + break; + + case tokrenum: + cmdrenum(&V); + break; + + case toklet: + cmdlet(false, &V); + break; + + case tokvar: + cmdlet(true, &V); + break; + + case tokprint: + cmdprint(&V); + break; + + case tokpunch: + cmdpunch(&V); + break; + + case tokput: + cmdput(&V); + break; + +#ifdef PHREEQ98 + case tokgraph_x: + cmdgraph_x(&V); + break; + + case tokgraph_y: + cmdgraph_y(&V); + break; + + case tokgraph_sy: + cmdgraph_sy(&V); + break; +#endif + + case tokinput: + error_msg("Basic command INPUT is not a legal command in PHREEQC.", STOP); +#ifdef SKIP + cmdinput(&V); +#endif + break; + + case tokgoto: + cmdgoto(&V); + break; + + case tokif: + cmdif(&V); + break; + + case tokelse: + cmdelse(&V); + break; + + case tokend: + cmdend(&V); + break; + + case tokstop: + P_escapecode = -20; + goto _Ltry1; + + case tokfor: + cmdfor(&V); + break; + + case toknext: + cmdnext(&V); + break; + + case tokwhile: + cmdwhile(&V); + break; + + case tokwend: + cmdwend(&V); + break; + + case tokgosub: + cmdgosub(&V); + break; + + case tokreturn: + cmdreturn(&V); + break; + + case tokread: + cmdread(&V); + break; + + case tokdata: + cmddata(&V); + break; + + case tokrestore: + cmdrestore(&V); + break; + + case tokgotoxy: + cmdgotoxy(&V); + break; + + case tokon: + cmdon(&V); + break; + + case tokdim: + cmddim(&V); + break; + + case tokpoke: + cmdpoke(&V); + break; + + default: + errormsg("Illegal command"); + break; + } + } + if (!V.elseflag && !iseos(&V)) + checkextra(&V); + stmttok = V.t; + } while (V.t != NULL); + if (stmtline != NULL) { + if (!V.gotoflag) + stmtline = stmtline->next; + if (stmtline != NULL) + stmttok = stmtline->txt; + } + } while (stmtline != NULL); + RECOVER2(try1,_Ltry1); + if (P_escapecode == -20) + error_msg("Break", CONTINUE); +#ifdef SKIP + printf("Break"); +#endif + else if (P_escapecode != 42) { + switch (P_escapecode) { + + case -4: +#ifdef SKIP + printf("\007Integer overflow"); +#endif + error_msg("Integer overflow", CONTINUE); + break; + + case -5: +#ifdef SKIP + printf("\007Divide by zero"); +#endif + error_msg("Divide by zero", CONTINUE); + break; + + case -6: +#ifdef SKIP + printf("\007Real math overflow"); +#endif + error_msg("Real math overflow", CONTINUE); + break; + + case -7: +#ifdef SKIP + printf("\007Real math underflow"); +#endif + error_msg("Real math underflow", CONTINUE); + break; + + case -8: + case -19: + case -18: + case -17: + case -16: + case -15: +#ifdef SKIP + printf("\007Value range error"); +#endif + error_msg("Value range error", CONTINUE); + break; + + case -10: + ioerrmsg = (char *) PHRQ_malloc(256); + if (ioerrmsg == NULL) malloc_error(); + sprintf(ioerrmsg, "I/O Error %d", (int)P_ioresult); +#ifdef SKIP + printf("\007%s", ioerrmsg); +#endif + error_msg(ioerrmsg, CONTINUE); + free(ioerrmsg); + break; + + default: + if (EXCP_LINE != -1) { + sprintf(error_string, "%12ld\n", EXCP_LINE); + error_msg(error_string, CONTINUE); + } +#ifdef SKIP + printf("%12ld\n", EXCP_LINE); +#endif + _Escape(P_escapecode); + break; + } + } + if (stmtline != NULL) { + sprintf(error_string, " in line %ld", stmtline->num); + error_msg(error_string, CONTINUE); + } +#ifdef SKIP + printf(" in %ld", stmtline->num); + putchar('\n'); +#endif + ENDTRY(try1); +} /*exec*/ + +int free_dim_stringvar(struct varrec *varbase) +{ + int i, k; + if (varbase->numdims > 0) { + k = 1; + for (i = 0; i < varbase->numdims; i++) { + k = k*(varbase->dims[i]); + } + for (i = 0; i < k; i++) { + free_check_null(varbase->UU.U1.sarr[i]); + } + varbase->UU.U1.sarr = (char **) free_check_null(varbase->UU.U1.sarr); + } + return(OK); +} diff --git a/basicsubs.cpp b/basicsubs.cpp new file mode 100644 index 00000000..cf129578 --- /dev/null +++ b/basicsubs.cpp @@ -0,0 +1,1774 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: basicsubs.c 338 2005-06-15 14:10:45Z dlpark $"; + +struct system_species { + char * name; + char *type; + LDBLE moles; +}; +struct system_species *sys; +int count_sys, max_sys; +LDBLE sys_tot; + +/* ---------------------------------------------------------------------- */ +LDBLE activity (char *species_name) +/* ---------------------------------------------------------------------- */ +{ + struct species *s_ptr; + LDBLE a; + if (svnid == NULL) fprintf(stderr," "); + + s_ptr = s_search(species_name); + if (s_ptr == s_h2o) { + a = pow(10., s_h2o->la); + } else if (s_ptr == s_eminus) { + a = pow(10.,s_eminus->la); + } else if (s_ptr == NULL || s_ptr->in == FALSE) { + a = 1e-99; + } else { + a = pow(10., s_ptr->lm + s_ptr->lg); + } + return(a); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_logk_n(char *name) +/* ---------------------------------------------------------------------- */ +{ + char token[MAX_LENGTH]; + int i; + LDBLE lk; + struct logk *logk_ptr; + LDBLE logk[8]; + struct name_coef add_logk; + + for (i = 0; i < 8; i++) { + logk[i] = 0.0; + } + strcpy(token, name); + logk_ptr = logk_search(token); + if (logk_ptr != NULL) { + add_logk.name = token; + add_logk.coef = 1.0; + add_other_logk(logk, 1, &add_logk); + lk = k_calc(logk, tk_x); + return(lk); + } + return(-999.99); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_logk_p(char *name) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + char token[MAX_LENGTH]; + struct phase *phase_ptr; + LDBLE lk; + LDBLE logk[8]; + + strcpy(token, name); + phase_ptr = phase_bsearch(token, &j, FALSE); + if (phase_ptr != NULL) { + for (i = 0; i < 8; i++) { + logk[i] = 0.0; + } + select_log_k_expression(phase_ptr->logk, logk); + add_other_logk(logk, phase_ptr->count_add_logk, phase_ptr->add_logk); + lk = k_calc(logk, tk_x); + return(lk); + } + return(-999.99); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_logk_s(char *name) +/* ---------------------------------------------------------------------- */ +{ + int i; + char token[MAX_LENGTH]; + struct species *s_ptr; + LDBLE lk, logk[8]; + + strcpy(token, name); + s_ptr = s_search(token); + if (s_ptr != NULL) { + for (i = 0; i < 8; i++) { + logk[i] = 0.0; + } + select_log_k_expression(s_ptr->logk, logk); + add_other_logk(logk, s_ptr->count_add_logk, s_ptr->add_logk); + lk = k_calc(logk, tk_x); + return(lk); + } + return(-999.99); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_surface_charge(char *surface_name) +/* ---------------------------------------------------------------------- */ +{ + char token[MAX_LENGTH], token1[MAX_LENGTH]; + char *ptr; + int i, j, k; + LDBLE charge; + struct rxn_token_temp *token_ptr; + struct master *master_ptr; + + /* + * Go through species, sum charge + */ + charge = 0; + for (k = 0; k < count_s_x; k++) { + if (s_x[k]->type != SURF) continue; + /* + * Match surface_name + */ + count_trxn=0; + trxn_add (s_x[k]->rxn_s, 1.0, FALSE); /* rxn_s is set in tidy_model */ + for (i=1; i < count_trxn; i++) { + token_ptr = &(trxn.token[i]); + if (token_ptr->s->type != SURF) continue; + master_ptr = trxn.token[i].s->primary; + strcpy(token, master_ptr->elt->name); + replace ("_", " ", token); + ptr = token; + copy_token(token1, &ptr, &j); + if (strcmp(surface_name, token1) == 0) { + charge += s_x[k]->moles *s_x[k]->z; + } + } + } + return(charge); +} +/* ---------------------------------------------------------------------- */ +LDBLE diff_layer_total(char *total_name, char *surface_name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in LDBLE layer + */ + int i, j, k, count_g; + struct surface_charge *surface_charge_ptr1; + char name[MAX_LENGTH], token[MAX_LENGTH]; + char surface_name_local[MAX_LENGTH]; + char *ptr; + + LDBLE mass_water_surface; + LDBLE molality, moles_excess, moles_surface, charge; + + if (use.surface_ptr == NULL || (diffuse_layer_x == FALSE && + strcmp_nocase("psi", total_name) != 0 && + strcmp_nocase("charge", total_name) != 0 && + strcmp_nocase("sigma", total_name) != 0 ) + ) return(0); + +/* + * Find surface... + */ + i = 0; + for (j =0; j < count_unknowns; j++) { + if (use.surface_ptr->edl == TRUE) { + if (x[j]->type != SURFACE_CB) continue; + strcpy(name, x[j]->master[0]->elt->name); + replace ("_psi", "", name); + } else { + if (x[j]->type != SURFACE) continue; + strcpy(token, x[j]->master[0]->elt->name); + replace ("_", " ", token); + ptr = token; + copy_token(name, &ptr, &k); + } + if (surface_name != NULL) { + if (strcmp(name, surface_name) == 0) break; + } else { + break; + } + } + if (j >= count_unknowns) return(0); + strcpy(surface_name_local, name); + /* + * Psi, charge, sigma + */ + if (strcmp_nocase("psi", total_name) == 0) { + if (use.surface_ptr->edl == TRUE) { + return((LDBLE) (x[j]->master[0]->s->la * 2 * R_KJ_DEG_MOL * + tk_x * LOG_10 / F_KJ_V_EQ)); + } else { + return(0); + } + } else if (strcmp_nocase("charge", total_name) == 0) { + if (use.surface_ptr->edl == TRUE && diffuse_layer_x == FALSE) { + return((LDBLE) (x[j]->f)); + } else { + return(calc_surface_charge(surface_name_local)); + } + } else if (strcmp_nocase("sigma", total_name) == 0) { + if (use.surface_ptr->edl == TRUE) { + if (diffuse_layer_x == TRUE) { + charge = calc_surface_charge(surface_name_local); + } else { + charge = x[j]->f; + } + if ((x[j]->surface_charge->specific_area * x[j]->surface_charge->grams) > 0) { + return((LDBLE) (charge * F_C_MOL / (x[j]->surface_charge->specific_area * x[j]->surface_charge->grams))); + } else { + return(0); + } + } else { + return(0); + } + } else if (strcmp_nocase("water", total_name) == 0) { + if (diffuse_layer_x == TRUE) { + return(x[j]->surface_charge->mass_water); + } else { + return(0); + } + } +/* + * find total moles of each element in diffuse layer... + */ + surface_charge_ptr1 = x[j]->surface_charge; + mass_water_surface = surface_charge_ptr1->mass_water; + count_elts = 0; + paren_count = 0; + for (j = 0; j < count_s_x; j++) { + if (s_x[j]->type > HPLUS) continue; + molality = under(s_x[j]->lm); + count_g = s_x[j]->diff_layer[i].count_g; + + moles_excess = mass_water_aq_x * molality * surface_charge_ptr1->g[count_g].g; + moles_surface = mass_water_surface * molality + moles_excess; +/* + * Accumulate elements in diffuse layer + */ + add_elt_list(s_x[j]->next_elt, moles_surface); + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } +/* + * Return totals + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + return((LDBLE) elt_list[j].coef); + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE equi_phase (char *phase_name) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + + if (use.pp_assemblage_in == FALSE || use.pp_assemblage_ptr == NULL) return(0); + for( j = 0; j < count_unknowns; j++) { + if (x[j]->type != PP) continue; + if (strcmp_nocase(x[j]->pure_phase->name, phase_name) == 0) { + break; + } + } +/* + * Print pure phase assemblage data + */ + if (j == count_unknowns) { + /* if not an unknown */ + for (i=0; i < use.pp_assemblage_ptr->count_comps; i++) { + if (strcmp_nocase(use.pp_assemblage_ptr->pure_phases[i].name,phase_name) == 0) { + return(use.pp_assemblage_ptr->pure_phases[i].moles); + } + } + } else { + /* if an unknown */ + if (x[j]->moles < 0.0) x[j]->moles = 0.0; + return(x[j]->moles); + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE find_gas_comp (char *gas_comp_name) +/* ---------------------------------------------------------------------- */ +{ + int i; + + if (use.gas_phase_in == FALSE || use.gas_phase_ptr == NULL) return(0); + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + if (strcmp_nocase(use.gas_phase_ptr->comps[i].name, gas_comp_name) == 0) { + return(use.gas_phase_ptr->comps[i].phase->moles_x); + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE find_misc1 (char *s_s_name) +/* ---------------------------------------------------------------------- */ +{ + int j; + + if (use.s_s_assemblage_in == FALSE || use.s_s_assemblage_ptr == NULL) return(0.0); + for (j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + if (strcmp_nocase(use.s_s_assemblage_ptr->s_s[j].name, s_s_name) == 0) { + if (use.s_s_assemblage_ptr->s_s[j].miscibility == TRUE) { + return(use.s_s_assemblage_ptr->s_s[j].xb1); + } else { + return(1.0); + } + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE find_misc2 (char *s_s_name) +/* ---------------------------------------------------------------------- */ +{ + int j; + + if (use.s_s_assemblage_in == FALSE || use.s_s_assemblage_ptr == NULL) return(0.0); + for (j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + if (strcmp_nocase(use.s_s_assemblage_ptr->s_s[j].name, s_s_name) == 0) { + if (use.s_s_assemblage_ptr->s_s[j].miscibility == TRUE) { + return(use.s_s_assemblage_ptr->s_s[j].xb2); + } else { + return(1.0); + } + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE find_s_s_comp (char *s_s_comp_name) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + + if (use.s_s_assemblage_in == FALSE || use.s_s_assemblage_ptr == NULL) return(0); + for (j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i=0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (strcmp_nocase(use.s_s_assemblage_ptr->s_s[j].comps[i].name, s_s_comp_name) == 0) { + if (use.s_s_assemblage_ptr->s_s[j].s_s_in == TRUE) { + return(use.s_s_assemblage_ptr->s_s[j].comps[i].moles); + } else { + return(0.0); + } + } + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE get_calculate_value(char *name) +/* ---------------------------------------------------------------------- */ +/* + * Gets value from a calclate_value structure + * arguments: name + * return: LDBLE of value + */ +{ + struct calculate_value *calculate_value_ptr; + calculate_value_ptr = calculate_value_search(name); + if (calculate_value_ptr == NULL) { + sprintf(error_string, "CALC_VALUE Basic function, %s not found.", name); + error_msg(error_string, CONTINUE); + input_error++; + return(MISSING); + } + if (name == NULL) { + sprintf(error_string, "Definition for calculated value not found, %s", name); + input_error++; + error_msg(error_string, CONTINUE); + return (MISSING); + } + if (calculate_value_ptr->calculated == FALSE) { + sprintf(error_string, "Calculated value used before it has been calculated, %s.\nCalculated values are evalutated in the order in which they were defined.", name); + input_error++; + error_msg(error_string, CONTINUE); + return (MISSING); + } + return(calculate_value_ptr->value); +} +/* ---------------------------------------------------------------------- */ +LDBLE kinetics_moles (char *kinetics_name) +/* ---------------------------------------------------------------------- */ +{ + int i; + + if (use.kinetics_in == FALSE || use.kinetics_ptr == NULL) return(0); + for (i = 0; i < use.kinetics_ptr->count_comps; i++) { + if (strcmp_nocase(use.kinetics_ptr->comps[i].rate_name, kinetics_name) == 0) { + return (use.kinetics_ptr->comps[i].m); + } + } + + sprintf(error_string, "No data for rate %s in KINETICS keyword.", kinetics_name); + warning_msg(error_string); + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE log_activity (char *species_name) +/* ---------------------------------------------------------------------- */ +{ + struct species *s_ptr; + LDBLE la; + + s_ptr = s_search(species_name); + + if (s_ptr == s_eminus) { + la = s_eminus->la; + } else if (s_ptr == NULL || s_ptr->in == FALSE) { + la = -99.99; + } else if (s_ptr == s_h2o) { + la = s_h2o->la; + } else { + la = s_ptr->lm + s_ptr->lg; + } + return(la); +} +/* ---------------------------------------------------------------------- */ +LDBLE log_molality (char *species_name) +/* ---------------------------------------------------------------------- */ +{ + struct species *s_ptr; + LDBLE lm; + + s_ptr = s_search(species_name); + + if (s_ptr == s_eminus) { + lm = -99.99; + } else if (s_ptr == NULL || s_ptr->in == FALSE) { + lm = -99.99; + } else if (s_ptr == s_h2o) { + lm = log10(s_ptr->moles / mass_water_aq_x); + } else { + lm = s_ptr->lm; + } + return(lm); +} +/* ---------------------------------------------------------------------- */ +LDBLE molality (char *species_name) +/* ---------------------------------------------------------------------- */ +{ + struct species *s_ptr; + LDBLE m; + + s_ptr = s_search(species_name); + if (s_ptr == NULL || s_ptr == s_eminus || s_ptr->in == FALSE) { + m = 1e-99; + } else { + /* m = pow(10., s_ptr->lm); */ + m = s_ptr->moles/mass_water_aq_x; + } + return(m); +} +/* ---------------------------------------------------------------------- */ +LDBLE saturation_ratio (char *phase_name) +/* ---------------------------------------------------------------------- */ +{ + struct rxn_token *rxn_ptr; + struct phase *phase_ptr; + int l; + LDBLE si, iap; + + iap = 0.0; + phase_ptr = phase_bsearch(phase_name, &l, FALSE); + if (phase_ptr == NULL) { + sprintf(error_string, "Mineral %s, not found.", phase_name); + warning_msg(error_string); + return(1e-99); + } else if (phase_ptr->in != FALSE) { + for (rxn_ptr = phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->s->la * rxn_ptr->coef; + } + si = iap - phase_ptr->lk; + return(pow(10.0, si)); + } + return(0.0); + +} +/* ---------------------------------------------------------------------- */ +int saturation_index (char *phase_name, LDBLE *iap, LDBLE *si) +/* ---------------------------------------------------------------------- */ +{ + struct rxn_token *rxn_ptr; + struct phase *phase_ptr; + int l; + + *si = -99.99; + *iap = 0.0; + phase_ptr = phase_bsearch(phase_name, &l, FALSE); + if (phase_ptr == NULL) { + sprintf(error_string, "Mineral %s, not found.", phase_name); + warning_msg(error_string); + *si = -99; + } else if (phase_ptr->in != FALSE) { + for (rxn_ptr = phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + *iap += rxn_ptr->s->la * rxn_ptr->coef; + } + *si = *iap - phase_ptr->lk; + } else { + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE sum_match_gases (char *mytemplate, char *name) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE tot; + struct elt_list *next_elt; + + if (use.gas_phase_in == FALSE || use.gas_phase_ptr == NULL) return(0); + tot = 0; + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + if (match_elts_in_species(use.gas_phase_ptr->comps[i].phase->formula,mytemplate) == TRUE) { + if (name == NULL) { + tot += use.gas_phase_ptr->comps[i].phase->moles_x; + } else { + for (next_elt = use.gas_phase_ptr->comps[i].phase->next_elt; next_elt->elt != NULL; next_elt++) { + if (strcmp(next_elt->elt->name, name) == 0) { + tot += next_elt->coef * use.gas_phase_ptr->comps[i].phase->moles_x; + break; + } + } + } + } + } + return(tot); +} +/* ---------------------------------------------------------------------- */ +LDBLE sum_match_species (char *mytemplate, char *name) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE tot; + struct elt_list *next_elt; + + count_elts = 0; + paren_count = 0; + tot = 0; + for (i = 0; i < count_s_x; i++) { + if (match_elts_in_species(s_x[i]->name, mytemplate) == TRUE) { + if (name == NULL) { + tot += s_x[i]->moles; + } else { + for (next_elt = s_x[i]->next_elt; next_elt->elt != NULL; next_elt++) { + if (strcmp(next_elt->elt->name, name) == 0) { + tot += next_elt->coef * s_x[i]->moles; + break; + } + } + } + } + } + return(tot); +} +/* ---------------------------------------------------------------------- */ +LDBLE sum_match_s_s (char *mytemplate, char *name) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + LDBLE tot; + struct elt_list *next_elt; + + if (use.s_s_assemblage_in == FALSE || use.s_s_assemblage_ptr == NULL) return(0); + tot = 0; + for (j=0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + if (strcmp_nocase(use.s_s_assemblage_ptr->s_s[j].name, mytemplate) == 0) { + if (use.s_s_assemblage_ptr->s_s[j].s_s_in == FALSE) { + tot = 0; + break; + } + for (i=0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (name == NULL) { + tot += use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + } else { + for (next_elt = use.s_s_assemblage_ptr->s_s[j].comps[i].phase->next_elt; next_elt->elt != NULL; next_elt++) { + if (strcmp(next_elt->elt->name, name) == 0) { + tot += next_elt->coef * use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + break; + } + } + } + } + break; + } + } + return(tot); +} +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +LDBLE sum_match_s_s (char *template, char *name) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + LDBLE tot; + struct elt_list *next_elt; + + if (use.s_s_assemblage_in == FALSE || use.s_s_assemblage_ptr == NULL) return(0); + tot = 0; + for (j=0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i=0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (match_elts_in_species(use.s_s_assemblage_ptr->s_s[j].comps[i].phase->formula,template) == TRUE) { + if (name == NULL) { + tot += use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + } else { + for (next_elt = use.s_s_assemblage_ptr->s_s[j].comps[i].phase->next_elt; next_elt->elt != NULL; next_elt++) { + if (strcmp(next_elt->elt->name, name) == 0) { + tot += next_elt->coef * use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + break; + } + } + } + } + } + } + return(tot); +} +#endif +/* ---------------------------------------------------------------------- */ +int match_elts_in_species (char *name, char *mytemplate) +/* ---------------------------------------------------------------------- */ +{ +/* + * Makes a list of elements with their coefficients, stores elements + * in elt_list at position count_elts. Global variable count_elts is + * updated with each stored element. Also uses static global variable + * paren_count. + * + * Arguments: + * **t_ptr input, point in token string to start looking + * output, is next position to start looking + * coef input, coefficient to multiply subscripts by + */ + int i, i1, l, case_no, match; + char c, c1; + char *ptr, *ptr1, *replace_name, *name_ptr; + LDBLE d; + char element[MAX_LENGTH]; + char token[MAX_LENGTH], equal_list[MAX_LENGTH], elt_name[MAX_LENGTH]; + char token1[MAX_LENGTH], template1[MAX_LENGTH], equal_list1[MAX_LENGTH]; + char str[2]; + + strcpy(token, name); + squeeze_white(token); + while (replace("(+","(",token)); + while (replace("++++++","+6",token)); + while (replace("+++++","+5",token)); + while (replace("++++","+4",token)); + while (replace("+++","+3",token)); + while (replace("++","+2",token)); + while (replace("------","-6",token)); + while (replace("-----","-5",token)); + while (replace("----","-4",token)); + while (replace("---","-3",token)); + while (replace("--","-2",token)); + + ptr = token; + count_match_tokens = 0; + while ( (c=*ptr) != '\0') { + c1=*(ptr+1); + str[0] = c; + str[1] = '\0'; +/* + * New element + */ + if (isupper((int) c) || (c == 'e' && c1 == '-') || (c == '[')) { + /* + * Get new element and subscript + */ + if ( get_elt( &ptr, element, &l) == ERROR) { + return(ERROR); + } + match_tokens[count_match_tokens].name = string_hsave(element); + if ( get_num( &ptr , &d ) == ERROR) { + return(ERROR); + } + match_tokens[count_match_tokens++].coef = d; + } else { + match_tokens[count_match_tokens].name = string_hsave(str); + match_tokens[count_match_tokens++].coef = 1.0; + ptr += 1; + } + } + /* + * Replace elements with first of equivalent elements + */ + strcpy(template1, mytemplate); + squeeze_white(template1); + ptr = template1; + while (extract_bracket(&ptr, equal_list) == TRUE) { + replace("{","",equal_list); + replace("}","",equal_list); + while (replace(","," ",equal_list) == TRUE); + ptr1 = equal_list; + /* + * Get first name in a list from template + */ + if (copy_token(elt_name, &ptr1, &l) == EMPTY) { + sprintf(error_string, "Expecting a nonempty list of element names in isotope sum. %s", mytemplate); + error_msg(error_string, CONTINUE); + return(ERROR); + } + replace_name = string_hsave(elt_name); + /* + * Replace in species all equivalent names from template + */ + while (copy_token(elt_name, &ptr1, &l) != EMPTY) { + name_ptr = string_hsave (elt_name); + for (i = 0; i < count_match_tokens; i++) { + if (name_ptr == match_tokens[i].name) { + match_tokens[i].name = replace_name; + } + } + } + } + /* + * Combine contiguous elements + */ + i1 = 0; + for ( i = 1; i < count_match_tokens; i++) { + if ((isupper((int) (match_tokens[i].name[0])) != FALSE) && (match_tokens[i].name == match_tokens[i1].name)) { + match_tokens[i1].coef += match_tokens[i].coef; + } else { + i1++; + match_tokens[i1].name = match_tokens[i].name; + match_tokens[i1].coef = match_tokens[i].coef; + } + } + count_match_tokens = i1 + 1; + /* + * write out string + */ + token[0] = '\0'; + for (i = 0; i < count_match_tokens; i++) { + strcat(token, match_tokens[i].name); + if (match_tokens[i].coef != 1.0) { + sprintf(token1, "%g", (double) match_tokens[i].coef); + strcat(token, token1); + } + } + /* + * Write a template name using first of equivalent elements + */ + strcpy(template1, mytemplate); + squeeze_white(template1); + ptr = template1; + while (extract_bracket(&ptr, equal_list) == TRUE) { + strcpy(equal_list1, equal_list); + replace("{","",equal_list); + replace("}","",equal_list); + while (replace(","," ",equal_list) == TRUE); + ptr1 = equal_list; + /* + * Get first name in a list + */ + if (copy_token(elt_name, &ptr1, &l) == EMPTY) { + sprintf(error_string, "Expecting a nonempty list of element names in isotope sum. %s", mytemplate); + error_msg(error_string, CONTINUE); + return(ERROR); + } + replace_name = string_hsave(elt_name); + replace(equal_list1, replace_name, template1); + squeeze_white(template1); + ptr = template1; + } + /* + * Compare string + */ + /* Cases: 0 exact match + * 1 leading wild card + * 2 trailing wild card + * 3 leading and trailing wild card + */ + case_no = 0; + if (template1[0] == '*') case_no = 1; + l = strlen(template1); + if (template1[l - 1] == '*') { + if (case_no != 1) { + case_no = 2; + } else { + case_no = 3; + } + } + while (replace("*","",template1)); + match = FALSE; + switch (case_no) { + case 0: + /* exact match */ + if (strcmp(token, template1) == 0) match = TRUE; + break; + case 1: + /* leading wild card */ + if ((ptr = strstr(token, template1)) == NULL) { + match = FALSE; + } else { + if (strcmp(ptr, template1) == 0) match = TRUE; + } + break; + case 2: + /* trailing wild card */ + if (strstr(token, template1) == token) match = TRUE; + break; + case 3: + /* trailing wild card */ + if (strstr(token, template1) != NULL) match = TRUE; + break; + } + return (match); +} +/* ---------------------------------------------------------------------- */ +int extract_bracket(char **string, char *bracket_string) +/* ---------------------------------------------------------------------- */ +{ + char *ptr, *ptr1; + + if ((ptr = strstr(*string, "{")) == NULL) return(FALSE); + strcpy(bracket_string, ptr); + if ((ptr1 = strstr(bracket_string, "}")) == NULL) { + sprintf(error_string, "No matching bracket (}) in isotope template string %s", *string); + error_msg(error_string, CONTINUE); + input_error++; + return(FALSE); + } + ptr1[1] = '\0'; + *string = strstr(*string, "}"); + *string += 1; + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +LDBLE surf_total(char *total_name, char *surface_name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in LDBLE layer + */ + int i, j, k; + char name[MAX_LENGTH], token[MAX_LENGTH]; + char surface_name_local[MAX_LENGTH]; + char *ptr; + + if (use.surface_ptr == NULL) return(0); + +/* + * Find surface... + */ + for (j =0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE) continue; + strcpy(token, x[j]->master[0]->elt->name); + replace ("_", " ", token); + ptr = token; + copy_token(name, &ptr, &k); + if (surface_name != NULL) { + if (strcmp(name, surface_name) == 0) break; + } else { + break; + } + } + if (j >= count_unknowns) return(0); + strcpy(surface_name_local, name); +/* + * find total moles of each element in diffuse layer... + */ + count_elts = 0; + paren_count = 0; + for (j = 0; j < count_s_x; j++) { + if (s_x[j]->type != SURF) continue; + for (i=0; s_x[j]->next_elt[i].elt != NULL; i++) { + strcpy(token, s_x[j]->next_elt[i].elt->name); + replace ("_", " ", token); + ptr = token; + copy_token(name, &ptr, &k); + if (strcmp(name, surface_name_local) == 0) { +/* + * Accumulate elements in diffuse layer + */ + add_elt_list(s_x[j]->next_elt, s_x[j]->moles); + break; + } + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } +/* + * Return totals + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + return((LDBLE) elt_list[j].coef); + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +LDBLE total (char *total_name) +/* ---------------------------------------------------------------------- */ +{ + struct master *master_ptr; + LDBLE t; + int i; + + if (strcmp_nocase(total_name,"water") == 0) { + return(mass_water_aq_x); + } + if (strcmp(total_name,"H") == 0) { + return(total_h_x/mass_water_aq_x); + } + if (strcmp(total_name,"O") == 0) { + return(total_o_x/mass_water_aq_x); + } + master_ptr = master_bsearch(total_name); + t = 0.0; + if (master_ptr == NULL) { + sprintf(error_string,"Can not find definition for master species, %s.", total_name); + warning_msg(error_string); +/* + * Primary master species + */ + } else if (master_ptr->primary == TRUE) { + /* + * Not a redox element + */ + if (master_ptr->s->secondary == NULL) { + t = master_ptr->total/mass_water_aq_x; + /* + * Redox element, need to sum totals of all redox states + */ + } else { + t = 0; + for (i = master_ptr->number + 1; master[i]->elt->primary == master_ptr; i++) { + t += master[i]->total/mass_water_aq_x; + } + } +/* + * Secondary master species + */ + } else { + t = master_ptr->total/mass_water_aq_x; + } + return(t); +} +/* ---------------------------------------------------------------------- */ +LDBLE system_total(char *total_name, LDBLE *count, char ***names, char ***types, LDBLE **moles) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i; + + sys_tot = 0; + count_sys = 0; + max_sys = 100; + space ((void **) ((void *) &sys), INIT, &max_sys, sizeof (struct system_species)); + if (strcmp_nocase(total_name,"elements") == 0) { + system_total_elements(); + } else if (strcmp_nocase(total_name,"phases") == 0) { + system_total_si(); + } else if (strcmp_nocase(total_name,"aq") == 0) { + system_total_aq(); + } else if (strcmp_nocase(total_name,"ex") == 0) { + system_total_ex(); + } else if (strcmp_nocase(total_name,"surf") == 0) { + system_total_surf(); + } else if (strcmp_nocase(total_name,"s_s") == 0) { + system_total_s_s(); + } else if (strcmp_nocase(total_name,"gas") == 0) { + system_total_gas(); + } else { + if (strstr(total_name,"(") == NULL) { + system_total_elt(total_name); + } else { + system_total_elt_secondary(total_name); + } + } + /* + * Sort system species + */ + if (count_sys > 1 ) { + qsort (sys, (size_t) count_sys, + (size_t) sizeof(struct system_species), system_species_compare); + } + /* + * malloc space + */ + *names = (char **) PHRQ_malloc((size_t) (count_sys+1) * sizeof (char *)); + if (names == NULL) malloc_error(); + *types = (char **) PHRQ_malloc((size_t) (count_sys+1) * sizeof (char *)); + if (types == NULL) malloc_error(); + *moles = (LDBLE *) PHRQ_malloc((size_t) (count_sys+1) * sizeof (LDBLE)); + if (moles == NULL) malloc_error(); + + (*names)[0] = NULL; + (*types)[0] = NULL; + (*moles)[0] = 0; + for(i = 0; i < count_sys; i++) { + /* output_msg(OUTPUT_MESSAGE, "%20s\t%10s\t%e\n", sys[i].name, sys[i].type, sys[i].moles); */ + (*names)[i + 1] = sys[i].name; + (*types)[i + 1] = sys[i].type; + (*moles)[i + 1] = sys[i].moles; + } + *count = (LDBLE) count_sys; + PHRQ_free(sys); + if (strcmp_nocase(total_name,"elements") == 0) { + sys_tot = 0;; + for (i = 0; i < count_sys; i++) { + if (strcmp(sys[i].type,"dis") == 0 && + strstr(sys[i].name,"(") == NULL && + strcmp(sys[i].name,"H") != 0 && + strcmp(sys[i].name,"O") != 0) { + sys_tot += sys[i].moles; + } + } + } + return(sys_tot); +} +/* ---------------------------------------------------------------------- */ +int system_total_elements(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + LDBLE t; + char name[MAX_LENGTH]; + struct master *master_ptr; + + /* + * Include H and O + */ + sys[count_sys].name = string_duplicate("H"); + sys[count_sys].moles = total_h_x; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("dis"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + sys[count_sys].name = string_duplicate("O"); + sys[count_sys].moles = total_o_x; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("dis"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + /* + * Include H(1) and O(-2) + */ + sys[count_sys].name = string_duplicate("H(1)"); + sys[count_sys].moles = solution_sum_secondary("H(1)"); + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("dis"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + sys[count_sys].name = string_duplicate("O(-2)"); + sys[count_sys].moles = solution_sum_secondary("O(-2)"); + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("dis"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + + for (i = 0; i < count_master; i++) { + master_ptr=master[i]; + if (master_ptr->primary == TRUE && master_ptr->total_primary <= 0) continue; + if (master_ptr->in == FALSE && (master_ptr->primary == FALSE || master_ptr->total_primary == 0)) continue; + /* + * H and O + */ + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } + if (master_ptr->primary == TRUE) { + if (master_ptr->total_primary > 0) { + t = master_ptr->total_primary; + /* + * Not a redox element + */ + } else if (master_ptr->s->secondary == NULL) { + t = master_ptr->total; + /* + * Redox element, need to sum totals of all redox states + */ + } else { + t = 0; + for (j = master_ptr->number + 1; master[j]->elt->primary == master_ptr; j++) { + t += master[j]->total; + } + } + /* + * Secondary master species + */ + } else { + t = master_ptr->total; + } + strcpy(name, master[i]->elt->name); + sys[count_sys].name = string_duplicate(name); + sys[count_sys].moles = t; + sys_tot += sys[count_sys].moles; + if (master[i]->s->type <= SOLID) { + sys[count_sys].type = string_duplicate("dis"); + } else if (master[i]->s->type == EX) { + sys[count_sys].type = string_duplicate("ex"); + } else if (master[i]->s->type == SURF || master[i]->s->type == SURF_PSI) { + sys[count_sys].type = string_duplicate("surf"); + } + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_si(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE si, iap; + struct rxn_token *rxn_ptr; + char name[MAX_LENGTH]; + + for (i=0; i < count_phases; i++) { + if (phases[i]->in == FALSE || phases[i]->type != SOLID) continue; +/* + * Print saturation index + */ + iap = 0.0; + for (rxn_ptr = phases[i]->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->s->la * rxn_ptr->coef; + } + si=-phases[i]->lk + iap; + /* output_msg(OUTPUT_MESSAGE,"\t%-15s%7.2f%8.2f%8.2f %s\n",phases[i]->name, si, iap, (LDBLE) phases[i]->lk, phases[i]->formula); */ + strcpy(name, phases[i]->name); + sys[count_sys].name = string_duplicate(name); + sys[count_sys].moles = si; + if (si > sys_tot) sys_tot = si; + sys[count_sys].type = string_duplicate("phase"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_aq(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i; +/* + * find total moles in aq, surface, and exchange + */ + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type != AQ) continue; + sys[count_sys].name = string_duplicate(s_x[i]->name); + sys[count_sys].moles = s_x[i]->moles; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("aq"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_ex(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i; +/* + * find total moles in aq, surface, and exchange + */ + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type != EX) continue; + if (s_x[i]->primary != NULL) continue; + sys[count_sys].name = string_duplicate(s_x[i]->name); + sys[count_sys].moles = s_x[i]->moles; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("ex"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_surf(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i; +/* + * find total moles in aq, surface, and exchange + */ + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type != SURF) continue; + sys[count_sys].name = string_duplicate(s_x[i]->name); + sys[count_sys].moles = s_x[i]->moles; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("surf"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_gas(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i; + +/* + * find total in gas phase + */ + if (use.gas_phase_ptr == NULL) return(OK); + for( i = 0; i < use.gas_phase_ptr->count_comps; i++) { + sys[count_sys].name = string_duplicate(use.gas_phase_ptr->comps[i].phase->name); + sys[count_sys].moles = use.gas_phase_ptr->comps[i].phase->moles_x; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("gas"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_s_s(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i, k; + +/* + * Solid solutions + */ + if (use.s_s_assemblage_ptr == NULL) return(OK); + for( k = 0; k < use.s_s_assemblage_ptr->count_s_s; k++) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[k].count_comps; i++) { + sys[count_sys].name = string_duplicate(use.s_s_assemblage_ptr->s_s[k].comps[i].phase->name); + sys[count_sys].moles = use.s_s_assemblage_ptr->s_s[k].comps[i].moles; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("s_s"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_elt(char *total_name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i, j, k, count_g; + LDBLE molality, moles_excess, moles_surface, mass_water_surface; + char name[MAX_LENGTH]; + +/* + * find total moles in aq, surface, and exchange + */ + for (i = 0; i < count_s_x; i++) { + count_elts = 0; + paren_count = 0; + add_elt_list(s_x[i]->next_elt, s_x[i]->moles); + + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* + * Look for element + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(s_x[i]->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + if (s_x[i]->type == AQ) { + sys[count_sys].type = string_duplicate("aq"); + } else if (s_x[i]->type == EX) { + sys[count_sys].type = string_duplicate("ex"); + } else if (s_x[i]->type == SURF) { + sys[count_sys].type = string_duplicate("surf"); + } else if (s_x[i]->type == HPLUS) { + sys[count_sys].type = string_duplicate("aq"); + /* sys[count_sys].moles = total_h_x; */ + } else if (s_x[i]->type == H2O) { + sys[count_sys].type = string_duplicate("aq"); + /* sys[count_sys].moles = total_o_x; */ + } else { + error_msg("System_total", STOP); + } + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + if (use.surface_ptr != NULL && diffuse_layer_x == TRUE) { + /* + * Find position of component in surface charge data + */ + i = -1; + for (k = 0; k < count_unknowns; k++) { + if (x[k]->type != SURFACE_CB) continue; + i++; + /* + * Loop through all surface components, calculate each H2O surface (diffuse layer), + * H2O aq, and H2O bulk (diffuse layers plus aqueous). + */ + mass_water_surface = x[k]->surface_charge->mass_water; + count_elts = 0; + paren_count = 0; + for (j = 0; j < count_s_x; j++) { + if (s_x[j]->type > HPLUS) continue; + molality = under(s_x[j]->lm); + count_g = s_x[j]->diff_layer[i].count_g; + moles_excess = mass_water_aq_x * molality * x[k]->surface_charge->g[count_g].g; + moles_surface = mass_water_surface * molality + moles_excess; + /* + * Accumulate elements in diffuse layer + */ + add_elt_list(s_x[j]->next_elt, moles_surface); + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* + * Print totals + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + strcpy(name, x[k]->master[0]->elt->name); + replace ("_psi", "", name); + sys[count_sys].name = string_duplicate(name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("diff"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } +/* + * find total moles in mineral phases + */ + if (use.pp_assemblage_in == TRUE && use.pp_assemblage_ptr != NULL) { + for( i = 0; i < count_unknowns; i++) { + if (x[i]->type != PP) continue; + if (x[i]->pure_phase->add_formula != NULL) continue; + count_elts = 0; + paren_count = 0; + add_elt_list(x[i]->pure_phase->phase->next_elt, x[i]->moles); + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(x[i]->pure_phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("equi"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } +/* + * Solid solutions + */ + if (use.s_s_assemblage_ptr != NULL) { + for( k = 0; k < use.s_s_assemblage_ptr->count_s_s; k++) { + if (use.s_s_assemblage_ptr->s_s[k].s_s_in == TRUE) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[k].count_comps; i++) { + count_elts = 0; + paren_count = 0; + add_elt_list(use.s_s_assemblage_ptr->s_s[k].comps[i].phase->next_elt, use.s_s_assemblage_ptr->s_s[k].comps[i].moles); + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(use.s_s_assemblage_ptr->s_s[k].comps[i].phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("s_s"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } + } + } +/* + * find total in gas phase + */ + if (use.gas_phase_ptr != NULL) { + for( i = 0; i < use.gas_phase_ptr->count_comps; i++) { + if (use.gas_phase_ptr->comps[i].phase->in == TRUE) { + count_elts = 0; + paren_count = 0; + add_elt_list(use.gas_phase_ptr->comps[i].phase->next_elt, use.gas_phase_ptr->comps[i].phase->moles_x); + + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* + * Look for element + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(use.gas_phase_ptr->comps[i].phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("gas"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_total_elt_secondary(char *total_name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i, j, k, l, count_g; + LDBLE molality, moles_excess, moles_surface, mass_water_surface, sum, coef; + char name[MAX_LENGTH]; +/* + * find total moles in aq, surface, and exchange + */ + for (i = 0; i < count_s_x; i++) { + count_elts = 0; + paren_count = 0; + if (s_x[i]->next_secondary != NULL) { + add_elt_list(s_x[i]->next_secondary, s_x[i]->moles); + } else { + add_elt_list(s_x[i]->next_sys_total, s_x[i]->moles); + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* debug + output_msg(OUTPUT_MESSAGE, "%s\n", s_x[i]->name); + for ( j=0; j < count_elts; j++ ) { + output_msg(OUTPUT_MESSAGE, "\t%10s\t%g\n", elt_list[j].elt->name, elt_list[j].coef); + } + */ + /* + * Look for element + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(s_x[i]->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + if (s_x[i]->type == AQ) { + sys[count_sys].type = string_duplicate("aq"); + } else if (s_x[i]->type == EX) { + sys[count_sys].type = string_duplicate("ex"); + } else if (s_x[i]->type == SURF) { + sys[count_sys].type = string_duplicate("surf"); + } else if (s_x[i]->type == HPLUS) { + sys[count_sys].type = string_duplicate("aq"); + /* sys[count_sys].moles = total_h_x; */ + } else if (s_x[i]->type == H2O) { + sys[count_sys].type = string_duplicate("aq"); + /* sys[count_sys].moles = total_o_x; */ + } else { + error_msg("System_total", STOP); + } + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + if (use.surface_ptr != NULL && diffuse_layer_x == TRUE) { + /* + * Find position of component in surface charge data + */ + i = -1; + for (k = 0; k < count_unknowns; k++) { + if (x[k]->type != SURFACE_CB) continue; + i++; + /* + * Loop through all surface components, calculate each H2O surface (diffuse layer), + * H2O aq, and H2O bulk (diffuse layers plus aqueous). + */ + mass_water_surface = x[k]->surface_charge->mass_water; + sum = 0; + for (j = 0; j < count_s_x; j++) { + count_elts = 0; + paren_count = 0; + if (s_x[i]->next_secondary != NULL) { + add_elt_list(s_x[i]->next_secondary, 1); + } else { + add_elt_list(s_x[i]->next_sys_total, 1); + } + for ( l=0; l < count_elts; l++ ) { + if (strcmp(elt_list[l].elt->name, total_name) == 0) { + coef = elt_list[l].coef; + if (s_x[j]->type > H2O) continue; + molality = under(s_x[j]->lm); + count_g = s_x[j]->diff_layer[i].count_g; + moles_excess = mass_water_aq_x * molality * x[k]->surface_charge->g[count_g].g; + moles_surface = mass_water_surface * molality + moles_excess; + sum += moles_surface * coef; + break; + } + } + if (l >= count_elts) continue; + strcpy(name, x[k]->master[0]->elt->name); + replace ("_psi", "", name); + sys[count_sys].name = string_duplicate(name); + sys[count_sys].moles = sum; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("diff"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } +/* + * find total moles in mineral phases + */ + if (use.pp_assemblage_in == TRUE && use.pp_assemblage_ptr != NULL) { + for( i = 0; i < count_unknowns; i++) { + if (x[i]->type != PP) continue; + if (x[i]->pure_phase->add_formula != NULL) continue; + count_elts = 0; + paren_count = 0; + add_elt_list(x[i]->pure_phase->phase->next_sys_total, x[i]->moles); + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* debug + output_msg(OUTPUT_MESSAGE, "%s\n", x[i]->pure_phase->phase->name); + for ( j=0; j < count_elts; j++ ) { + output_msg(OUTPUT_MESSAGE, "\t%10s\t%g\n", elt_list[j].elt->name, elt_list[j].coef); + } + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(x[i]->pure_phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("equi"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } +/* + * Solid solutions + */ + if (use.s_s_assemblage_ptr != NULL) { + for( k = 0; k < use.s_s_assemblage_ptr->count_s_s; k++) { + if (use.s_s_assemblage_ptr->s_s[k].s_s_in == TRUE) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[k].count_comps; i++) { + count_elts = 0; + paren_count = 0; + add_elt_list(use.s_s_assemblage_ptr->s_s[k].comps[i].phase->next_sys_total, use.s_s_assemblage_ptr->s_s[k].comps[i].moles); + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(use.s_s_assemblage_ptr->s_s[k].comps[i].phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("s_s"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } + } + } +/* + * find total in gas phase + */ + if (use.gas_phase_ptr != NULL) { + for( i = 0; i < use.gas_phase_ptr->count_comps; i++) { + if (use.gas_phase_ptr->comps[i].phase->in == TRUE) { + count_elts = 0; + paren_count = 0; + add_elt_list(use.gas_phase_ptr->comps[i].phase->next_sys_total, use.gas_phase_ptr->comps[i].phase->moles_x); + + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* + * Look for element + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sys[count_sys].name = string_duplicate(use.gas_phase_ptr->comps[i].phase->name); + sys[count_sys].moles = elt_list[j].coef; + sys_tot += sys[count_sys].moles; + sys[count_sys].type = string_duplicate("gas"); + count_sys++; + space ((void **) ((void *) &sys), count_sys, &max_sys, sizeof(struct system_species)); + break; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE solution_sum_secondary(char *total_name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in system and lists of species/phases in sort order + */ + int i, j; + LDBLE sum; +/* + * find total moles in aq, surface, and exchange + */ + sum = 0; + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type > H2O) continue; + count_elts = 0; + paren_count = 0; + if (s_x[i]->next_secondary != NULL) { + add_elt_list(s_x[i]->next_secondary, s_x[i]->moles); + } else { + add_elt_list(s_x[i]->next_sys_total, s_x[i]->moles); + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + /* + * Look for element + */ + for ( j=0; j < count_elts; j++ ) { + if (strcmp(elt_list[j].elt->name, total_name) == 0) { + sum += elt_list[j].coef; + break; + } + } + } + return(sum); +} +/* ---------------------------------------------------------------------- */ +int system_species_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct system_species *a, *b; + + a=(const struct system_species *) ptr1; + b=(const struct system_species *) ptr2; + if (a->moles < b->moles) return(1); + if (a->moles > b->moles) return(-1); + return(0); +} + +/* ---------------------------------------------------------------------- */ +int system_total_solids(struct exchange *exchange_ptr, + struct pp_assemblage *pp_assemblage_ptr, + struct gas_phase *gas_phase_ptr, + struct s_s_assemblage *s_s_assemblage_ptr, + struct surface *surface_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides total moles in solid phases + */ + int i, j; + + count_elts = 0; + paren_count = 0; +/* + * find total moles in exchanger + */ + if (exchange_ptr != NULL) { + for( i = 0; i < exchange_ptr->count_comps; i++) { + add_elt_list(exchange_ptr->comps[i].totals, 1.0); + } + } + if (surface_ptr != NULL) { + for( i = 0; i < surface_ptr->count_comps; i++) { + add_elt_list(surface_ptr->comps[i].totals, 1.0); + } + } + if (s_s_assemblage_ptr != NULL) { + for( i = 0; i < s_s_assemblage_ptr->count_s_s; i++) { + for (j = 0; j < s_s_assemblage_ptr->s_s[i].count_comps; j++) { + add_elt_list(s_s_assemblage_ptr->s_s[i].comps[j].phase->next_elt, s_s_assemblage_ptr->s_s[i].comps[j].moles); + } + } + } + if (gas_phase_ptr != NULL) { + for( i = 0; i < gas_phase_ptr->count_comps; i++) { + add_elt_list(gas_phase_ptr->comps[i].phase->next_elt, gas_phase_ptr->comps[i].moles); + } + } + if (pp_assemblage_ptr != NULL) { + for( i = 0; i < pp_assemblage_ptr->count_comps; i++) { + add_elt_list(pp_assemblage_ptr->pure_phases[i].phase->next_elt, pp_assemblage_ptr->pure_phases[i].moles); + } + } + + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + return(OK); +} diff --git a/char_star.h b/char_star.h new file mode 100644 index 00000000..9d5b65f5 --- /dev/null +++ b/char_star.h @@ -0,0 +1,11 @@ +#if !defined(CHARSTAR_H_INCLUDED) +#define CHARSTAR_H_INCLUDED + +struct CHARSTAR_LESS : std::binary_function { +bool operator()(const char* _X, const char* _Y) const +{ + return ::strcmp( _X, _Y) < 0;} +}; + +#endif + diff --git a/cl1.cpp b/cl1.cpp new file mode 100644 index 00000000..93fc89e7 --- /dev/null +++ b/cl1.cpp @@ -0,0 +1,753 @@ +#include +#include +#include +#include + +/* must be defined here and in global.h */ +#if !defined(WIN32_MEMORY_DEBUG) +#define USE_PHRQ_ALLOC +#endif +#include "phqalloc.h" +#include "output.h" +#include "phrqtype.h" + +int cl1(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q, + int *kode, LDBLE toler, + int *iter, LDBLE *x, LDBLE *res, LDBLE *error, + LDBLE *cu, int *iu, int *s, + int check); +static char const svnid[] = "$Id: cl1.c 248 2005-04-14 17:10:53Z dlpark $"; + +extern void *free_check_null(void *ptr); +extern void malloc_error(void); + +/* debug +#define DEBUG_CL1 +#define CHECK_ERRORS + */ + +int cl1(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q, + int *kode, LDBLE toler, + int *iter, LDBLE *x, LDBLE *res, LDBLE *error, + LDBLE *cu, int *iu, int *s, int check) +{ + /* System generated locals */ + LDBLE *scratch; + union double_or_int {int ival; LDBLE dval;} *q2; + + /* Local variables */ + static int nklm; + static LDBLE xmin, xmax; + static int iout, i, j; + static LDBLE z; + static int maxit, n1, n2; + static LDBLE pivot; + static int ia, ii, kk, in, nk, js; + static LDBLE sn; + static int iphase, kforce; + static LDBLE zu, zv; + static LDBLE tpivot; + static int klm, jmn, nkl, jpn; + static LDBLE cuv, sum; + static int klm1; + int q_dim, cu_dim; + int kode_arg; + LDBLE *x_arg, *res_arg, check_toler; +#ifdef CHECK_ERRORS + extern char **col_name, **row_name; + extern int *row_back, *col_back; +#endif +/* THIS SUBROUTINE USES A MODIFICATION OF THE SIMPLEX */ +/* METHOD OF LINEAR PROGRAMMING TO CALCULATE AN L1 SOLUTION */ +/* TO A K BY N SYSTEM OF LINEAR EQUATIONS */ +/* AX=B */ +/* SUBJECT TO L LINEAR EQUALITY CONSTRAINTS */ +/* CX=D */ +/* AND M LINEAR INEQUALITY CONSTRAINTS */ +/* EX.LE.F. */ +/* DESCRIPTION OF PARAMETERS */ +/* K NUMBER OF ROWS OF THE MATRIX A (K.GE.1). */ +/* L NUMBER OF ROWS OF THE MATRIX C (L.GE.0). */ +/* M NUMBER OF ROWS OF THE MATRIX E (M.GE.0). */ +/* N NUMBER OF COLUMNS OF THE MATRICES A,C,E (N.GE.1). */ +/* KLMD SET TO AT LEAST K+L+M FOR ADJUSTABLE DIMENSIONS. */ +/* KLM2D SET TO AT LEAST K+L+M+2 FOR ADJUSTABLE DIMENSIONS. */ +/* NKLMD SET TO AT LEAST N+K+L+M FOR ADJUSTABLE DIMENSIONS. */ +/* N2D SET TO AT LEAST N+2 FOR ADJUSTABLE DIMENSIONS */ +/* Q TWO DIMENSIONAL REAL ARRAY WITH KLM2D ROWS AND */ +/* AT LEAST N2D COLUMNS. */ +/* ON ENTRY THE MATRICES A,C AND E, AND THE VECTORS */ +/* B,D AND F MUST BE STORED IN THE FIRST K+L+M ROWS */ +/* AND N+1 COLUMNS OF Q AS FOLLOWS */ +/* A B */ +/* Q = C D */ +/* E F */ +/* THESE VALUES ARE DESTROYED BY THE SUBROUTINE. */ +/* KODE A CODE USED ON ENTRY TO, AND EXIT */ +/* FROM, THE SUBROUTINE. */ +/* ON ENTRY, THIS SHOULD NORMALLY BE SET TO 0. */ +/* HOWEVER, IF CERTAIN NONNEGATIVITY CONSTRAINTS */ +/* ARE TO BE INCLUDED IMPLICITLY, RATHER THAN */ +/* EXPLICITLY IN THE CONSTRAINTS EX.LE.F, THEN KODE */ +/* SHOULD BE SET TO 1, AND THE NONNEGATIVITY */ +/* CONSTRAINTS INCLUDED IN THE ARRAYS X AND */ +/* RES (SEE BELOW). */ +/* ON EXIT, KODE HAS ONE OF THE */ +/* FOLLOWING VALUES */ +/* 0- OPTIMAL SOLUTION FOUND, */ +/* 1- NO FEASIBLE SOLUTION TO THE */ +/* CONSTRAINTS, */ +/* 2- CALCULATIONS TERMINATED */ +/* PREMATURELY DUE TO ROUNDING ERRORS, */ +/* 3- MAXIMUM NUMBER OF ITERATIONS REACHED. */ +/* TOLER A SMALL POSITIVE TOLERANCE. EMPIRICAL */ +/* EVIDENCE SUGGESTS TOLER = 10**(-D*2/3), */ +/* WHERE D REPRESENTS THE NUMBER OF DECIMAL */ +/* DIGITS OF ACCURACY AVAILABLE. ESSENTIALLY, */ +/* THE SUBROUTINE CANNOT DISTINGUISH BETWEEN ZERO */ +/* AND ANY QUANTITY WHOSE MAGNITUDE DOES NOT EXCEED */ +/* TOLER. IN PARTICULAR, IT WILL NOT PIVOT ON ANY */ +/* NUMBER WHOSE MAGNITUDE DOES NOT EXCEED TOLER. */ +/* ITER ON ENTRY ITER MUST CONTAIN AN UPPER BOUND ON */ +/* THE MAXIMUM NUMBER OF ITERATIONS ALLOWED. */ +/* A SUGGESTED VALUE IS 10*(K+L+M). ON EXIT ITER */ +/* GIVES THE NUMBER OF SIMPLEX ITERATIONS. */ +/* X ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST N2D. */ +/* ON EXIT THIS ARRAY CONTAINS A */ +/* SOLUTION TO THE L1 PROBLEM. IF KODE=1 */ +/* ON ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE */ +/* SIMPLE NONNEGATIVITY CONSTRAINTS ON THE */ +/* VARIABLES. THE VALUES -1, 0, OR 1 */ +/* FOR X(J) INDICATE THAT THE J-TH VARIABLE */ +/* IS RESTRICTED TO BE .LE.0, UNRESTRICTED, */ +/* OR .GE.0 RESPECTIVELY. */ +/* RES ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST KLMD. */ +/* ON EXIT THIS CONTAINS THE RESIDUALS B-AX */ +/* IN THE FIRST K COMPONENTS, D-CX IN THE */ +/* NEXT L COMPONENTS (THESE WILL BE =0),AND */ +/* F-EX IN THE NEXT M COMPONENTS. IF KODE=1 ON */ +/* ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE SIMPLE */ +/* NONNEGATIVITY CONSTRAINTS ON THE RESIDUALS */ +/* B-AX. THE VALUES -1, 0, OR 1 FOR RES(I) */ +/* INDICATE THAT THE I-TH RESIDUAL (1.LE.I.LE.K) IS */ +/* RESTRICTED TO BE .LE.0, UNRESTRICTED, OR .GE.0 */ +/* RESPECTIVELY. */ +/* ERROR ON EXIT, THIS GIVES THE MINIMUM SUM OF */ +/* ABSOLUTE VALUES OF THE RESIDUALS. */ +/* CU A TWO DIMENSIONAL REAL ARRAY WITH TWO ROWS AND */ +/* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ +/* IU A TWO DIMENSIONAL INTEGER ARRAY WITH TWO ROWS AND */ +/* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ +/* S INTEGER ARRAY OF SIZE AT LEAST KLMD, USED FOR */ +/* WORKSPACE. */ +/* DOUBLE PRECISION DBLE */ +/* REAL */ + +/* INITIALIZATION. */ + if (svnid == NULL) fprintf(stderr," "); + + + zv = 0; + kode_arg = *kode; + x_arg = NULL; + res_arg = NULL; + if (check == 1) { + /* + q_arg = PHRQ_malloc((size_t) (max_row_count * max_column_count * sizeof(LDBLE))); + if (q_arg == NULL) malloc_error(); + for (i = 0; i < max_row_count*max_column_count; i++) { + q_arg[i] = q[i]; + } + */ + x_arg = (double *) PHRQ_malloc((size_t) (n2d * sizeof(LDBLE))); + if (x_arg == NULL) malloc_error(); + for (i = 0; i < n2d; i++) { + x_arg[i] = x[i]; + } + res_arg = (double *) PHRQ_malloc((size_t) ((k + l + m) * sizeof(LDBLE))); + if (res_arg == NULL) malloc_error(); + for (i = 0; i < k + l + m; i++) { + res_arg[i] = res[i]; + } + } +/* Parameter adjustments */ + q_dim = n2d; + q2 = (union double_or_int *) q; + cu_dim = nklmd; + +/* Function Body */ + maxit = *iter; + n1 = n + 1; + n2 = n + 2; + nk = n + k; + nkl = nk + l; + klm = k + l + m; + klm1 = klm + 1; + nklm = n + klm; + kforce = 1; + *iter = 0; + js = 0; + ia = -1; +/* Make scratch space */ + scratch = (LDBLE *) PHRQ_malloc( (size_t) nklmd * sizeof(LDBLE)); + if (scratch == NULL) malloc_error(); + for (i=0; i < nklmd; i++) { + scratch[i] = 0.0; + } +/* SET UP LABELS IN Q. */ + for (j = 0; j < n; ++j) { + q2[ klm1 * q_dim + j ].ival = j + 1; + } +/* L10: */ + for (i = 0; i < klm; ++i) { + q2[ i * q_dim + n1 ].ival = n + i + 1; + if (q2[ i * q_dim + n ].dval < 0.) { + for (j = 0; j < n1; ++j) { + q2[ i * q_dim + j ].dval = -q2[ i * q_dim + j ].dval; + } + q2[ i * q_dim + n1 ].ival = -q2[ i * q_dim + n1 ].ival; +/* L20: */ + } + } +/* L30: */ +/* SET UP PHASE 1 COSTS. */ + iphase = 2; +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Set up phase 1 costs\n"); +#endif +/* Zero first row of cu and iu */ + memcpy( (void *) &(cu[0]), (void *) &(scratch[0]), + (size_t) nklm * sizeof(LDBLE) ); + for (j = 0; j < nklm; ++j) { + iu[ j ] = 0; + } +/* L40: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L40\n"); +#endif + if (l != 0) { + for (j = nk; j < nkl; ++j) { + cu[ j ] = 1.; + iu[ j ] = 1; + } +/* L50: */ + iphase = 1; + } + +/* Copy first row of cu and iu to second row */ + memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), + (size_t) nklm * sizeof(LDBLE) ); + memcpy( (void *) &(iu[cu_dim]), (void *) &(iu[0]), + (size_t) nklm * sizeof(int) ); + +/* L60: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L60\n"); +#endif + if (m != 0) { + for (j = nkl; j < nklm; ++j) { + cu[ cu_dim + j ] = 1.; + iu[ cu_dim + j ] = 1; + jmn = j - n; + if (q2[ jmn * q_dim + n1 ].ival < 0) { + iphase = 1; + } + } +/* L70: */ + } +/* L80: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L80\n"); +#endif + if (*kode != 0) { + for (j = 0; j < n; ++j) { + if ( x[j] < 0.) { +/* L90: */ + cu[ j ] = 1.; + iu[ j ] = 1; + } else if (x[j] > 0.) { + cu[ cu_dim + j ] = 1.; + iu[ cu_dim + j ] = 1; + } + } +/* L110: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L110\n"); +#endif + for (j = 0; j < k; ++j) { + jpn = j + n; + if ( res[j] < 0.) { +/* L120: */ + cu[ jpn ] = 1.; + iu[ jpn ] = 1; + if (q2[ j * q_dim + n1 ].ival > 0) { + iphase = 1; + } + } else if (res[j] > 0.) { +/* L130: */ + cu[ cu_dim + jpn ] = 1.; + iu[ cu_dim + jpn ] = 1; + if (q2[ j * q_dim + n1 ].ival < 0) { + iphase = 1; + } + } + } +/* L140: */ + } +/* L150: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L150\n"); +#endif + if (iphase == 2) { + goto L500; + } +/* COMPUTE THE MARGINAL COSTS. */ +L160: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L160\n"); +#endif + for (j = js; j < n1; ++j) { + sum = 0.; + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + if (ii < 0) { + z = cu[ cu_dim - ii - 1 ]; + } else { + z = cu[ ii - 1 ]; + } + sum += q2[ i * q_dim + j ].dval * z; + } + q2[ klm * q_dim + j ].dval = sum; + } + for (j = js; j < n; ++j) { + ii = q2[ klm1 * q_dim + j].ival; + if (ii < 0) { + z = cu[ cu_dim - ii - 1 ]; + } else { + z = cu[ ii - 1 ]; + } + q2[ klm * q_dim + j ].dval -= z; + } +/* DETERMINE THE VECTOR TO ENTER THE BASIS. */ +L240: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L240, xmax %e\n", xmax); +#endif + xmax = 0.; + if (js >= n) { + goto L490; /* test for optimality */ + } + for (j = js; j < n; ++j) { + zu = q2[ klm * q_dim + j ].dval; + ii = q2[ klm1 * q_dim + j ].ival; + if (ii > 0) { + zv = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ]; + } else { + ii = -ii; + zv = zu; + zu = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ]; + } +/* L260 */ + if (kforce == 1 && ii > n) { + continue; + } + if (iu[ ii - 1 ] != 1 && zu > xmax){ + xmax = zu; + in = j; + } +/* L270 */ + if (iu[ cu_dim + ii - 1 ] != 1 && zv > xmax ) { + xmax = zv; + in = j; + } + } +/* L280 */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L280 xmax %e, toler %e\n", xmax, toler); +#endif + if (xmax <= toler) { +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "xmax before optimality test %e\n",xmax); +#endif + goto L490; /* test for optimality */ + } + if (q2[ klm * q_dim + in ].dval != xmax) { + for (i = 0; i < klm1; ++i) { + q2[ i * q_dim + in ].dval = -q2[ i * q_dim + in ].dval; + } + q2[ klm1 * q_dim + in ].ival = -q2[ klm1 * q_dim + in ].ival; +/* L290: */ + q2[ klm * q_dim + in ].dval = xmax; + } +/* DETERMINE THE VECTOR TO LEAVE THE BASIS. */ + if (iphase != 1 && ia != -1) { + xmax = 0.; +/* find maximum absolute value in column "in" */ + for (i = 0; i <= ia; ++i) { + z = fabs(q2[ i * q_dim + in ].dval); + if (z > xmax) { + xmax = z; + iout = i; + } + } +/* L310: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L310, xmax %e\n", xmax); +#endif +/* switch row ia with row iout, use memcpy */ + if (xmax > toler) { + memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ iout * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ iout * q_dim ]), (void *) &(scratch[ 0 ]), + (size_t) n2 * sizeof(LDBLE) ); +/* L320: */ +/* set pivot to row ia, column in */ + iout = ia; + --ia; + pivot = q2[ iout * q_dim + in ].dval; + goto L420; /* Gauss Jordan */ + } + } +/* L330: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L330, xmax %e\n", xmax); +#endif + kk = -1; +/* divide column n1 by positive value in column "in" greater than toler */ + for (i = 0; i < klm; ++i) { + z = q2[ i * q_dim + in ].dval; + if (z > toler) { + ++kk; + res[kk] = q2[ i * q_dim + n ].dval / z; + s[kk] = i; + } + } +/* L340: */ +#ifdef DEBUG_CL1 + if (kk < 0) { + output_msg(OUTPUT_MESSAGE, "kode = 2 in loop 340.\n"); + } +#endif +L350: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L350, xmax %e\n", xmax); +#endif + if (kk < 0) { +/* no positive value found in L340 or bypass intermediate verticies */ + *kode = 2; + goto L590; + } +/* L360: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L360, xmax %e\n", xmax); +#endif +/* find minimum residual */ + xmin = res[ 0 ]; + iout = s[ 0 ]; + j = 0; + if (kk != 0) { + for (i = 1; i <= kk; ++i) { + if (res[i] < xmin) { + j = i; + xmin = res[i]; + iout = s[i]; + } + } +/* L370: */ +/* put kk in position j */ + res[j] = res[kk]; + s[j] = s[kk]; + } +/* L380: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L380 iout %d, xmin %e, xmax %e\n", iout, xmin, xmax); +#endif + --kk; + pivot = q2[ iout * q_dim + in ].dval; + ii = q2[ iout * q_dim + n1 ].ival; + if (iphase != 1) { + if (ii < 0) { +/* L390: */ + if (iu[ - ii - 1 ] == 1) { + goto L420; + } + } else { + if (iu[ cu_dim + ii - 1 ] == 1) { + goto L420; + } + } + } +/* L400: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L400\n"); +#endif + ii = abs(ii); + cuv = cu[ ii - 1 ] + cu[ cu_dim + ii - 1]; + if (q2[ klm * q_dim + in ].dval - pivot * cuv > toler) { + +/* BYPASS INTERMEDIATE VERTICES. */ + for (j = js; j < n1; ++j) { + z = q2[ iout * q_dim + j ].dval; + q2[ klm * q_dim + j ].dval -= z * cuv; + q2[ iout * q_dim + j ].dval = -z; + } +/* L410: */ + q2[ iout * q_dim + n1 ].ival = -q2[ iout * q_dim + n1 ].ival; + goto L350; + } +/* GAUSS-JORDAN ELIMINATION. */ +L420: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Gauss Jordon %d\n", *iter); +#endif + if (*iter >= maxit) { + *kode = 3; + goto L590; + } +/* L430: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L430\n"); +#endif + ++(*iter); + for (j = js; j < n1; ++j) { + if (j != in) { + q2[ iout * q_dim + j ].dval /= pivot; + } + } +/* L440: */ + for (j = js; j < n1; ++j) { + if (j != in) { + z = -q2[ iout * q_dim + j ].dval; + for (i = 0; i < klm1; ++i) { + if (i != iout) { + q2[ i * q_dim + j ].dval += z * q2[ i * q_dim + in ].dval; + } + } +/* L450: */ + } + } +/* L460: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L460\n"); +#endif + tpivot = -pivot; + for (i = 0; i < klm1; ++i) { + if (i != iout) { + q2[ i * q_dim + in ].dval /= tpivot; + } + } +/* L470: */ + q2[ iout * q_dim + in ].dval = 1. / pivot; + ii = q2[ iout * q_dim + n1 ].ival; + q2[ iout * q_dim + n1 ].ival = q2[ klm1 * q_dim + in ].ival; + q2[ klm1 * q_dim + in ].ival = ii; + ii = abs(ii); + if (iu[ ii - 1 ] == 0 || iu[ cu_dim + ii - 1 ] == 0) { + goto L240; + } +/* switch column */ + for (i = 0; i < klm1; ++i) { + z = q2[ i * q_dim + in ].dval; + q2[ i * q_dim + in ].dval = q2[ i * q_dim + js ].dval; + q2[ i * q_dim + js ].dval = z; + } + i = q2[ klm1 * q_dim + in ].ival; + q2[ klm1 * q_dim + in ].ival = q2[ klm1 * q_dim + js ].ival; + q2[ klm1 * q_dim + js ].ival = i; +/* L480: */ + ++js; + goto L240; +/* TEST FOR OPTIMALITY. */ +L490: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L490\n"); +#endif + if (kforce == 0) { + if (iphase == 1) { + if (q2[ klm * q_dim + n ].dval <= toler) { + goto L500; + } +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE,"q2[klm1-1, n1-1] > *toler. %e\n",q2[ ( klm1 - 1 ) * q_dim + n1 - 1 ].dval); +#endif + *kode = 1; + goto L590; + } + *kode = 0; + goto L590; + } + if (iphase != 1 || q2[ klm * q_dim + n ].dval > toler) { + kforce = 0; + goto L240; + } +/* SET UP PHASE 2 COSTS. */ +L500: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Set up phase 2 costs %d\n", *iter); +#endif + iphase = 2; + for (j = 0; j < nklm; ++j) { + cu[ j ] = 0.; + } +/* L510: */ + for (j = n; j < nk; ++j) { + cu[ j ] = 1.; + } + memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), + (size_t) nklm * sizeof(LDBLE) ); +/* L520: */ + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + if (ii <= 0) { + if (iu[ cu_dim - ii - 1 ] == 0) { + continue; + } + cu[ cu_dim - ii - 1 ] = 0.; + } else { +/* L530: */ + if (iu[ ii - 1 ] == 0) { + continue; + } + cu[ ii - 1 ] = 0.; + } +/* L540: */ + ++ia; +/* switch row */ + memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ i * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ i * q_dim ]), (void *) &(scratch[ 0 ]), + (size_t) n2 * sizeof(LDBLE) ); +/* L550: */ + } +/* L560: */ + goto L160; + + +/* PREPARE OUTPUT. */ +L590: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L590\n"); +#endif + sum = 0.; + for (j = 0; j < n; ++j) { + x[j] = 0.; + } +/* L600: */ + for (i = 0; i < klm; ++i) { + res[i] = 0.; + } +/* L610: */ + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + sn = 1.; + if (ii < 0) { + ii = -ii; + sn = -1.; + } + if (ii <= n) { +/* L620: */ + x[ii - 1] = sn * q2[ i * q_dim + n ].dval; + } else { +/* L630: */ + res[ii - n - 1] = sn * q2[ i * q_dim + n ].dval; + if (ii >= n1 && ii <= nk ) { +/* * DBLE(Q(I,N1)) */ + sum += q2[ i * q_dim + n ].dval; + } + } + } +/* L640: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L640\n"); +#endif + *error = sum; + scratch = (double *) free_check_null (scratch); + /* + * Check calculation + */ + if ((check == 1) && (*kode == 0)) { + check_toler = 10.*toler; + /* + * Check optimization constraints + */ + if (kode_arg == 1) { + for (i = 0; i < k; i++) { + if (res_arg[i] < 0.0) { + if (res[i] > check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: optimization constraint not satisfied row %d, res %s, constraint %f.\n", row_name[row_back[i]], res[i], res_arg[i]); +#endif + *kode = 1; + } + } else if (res_arg[i] > 0.0) { + if (res[i] < -check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: optimization constraint not satisfied row %s, res %e, constraint %f.\n", row_name[row_back[i]], res[i], res_arg[i]); +#endif + *kode = 1; + } + } + } + } + /* + * Check equalities + */ + for (i = k; i < k + l; i++) { + if (fabs(res[i]) > check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: equality constraint not satisfied row %s, res %e, tolerance %e.\n", row_name[row_back[i]], res[i], check_toler); +#endif + *kode = 1; + } + } + /* + * Check inequalities + */ + for (i = k + l; i < k + l + m; i++) { + if (res[i] < -check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: inequality constraint not satisfied row %s, res %e, tolerance %e.\n", row_name[row_back[i]], res[i], check_toler); +#endif + *kode = 1; + } + } + /* + * Check dissolution/precipitation constraints + */ + if (kode_arg == 1) { + for (i = 0; i < n; i++) { + if (x_arg[i] < 0.0) { + if (x[i] > check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: dis/pre constraint not satisfied column %s, x %e, constraint %f.\n", col_name[col_back[i]], x[i], x_arg[i]); +#endif + *kode = 1; + } + } else if (x_arg[i] > 0.0) { + if (x[i] < -check_toler) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1: dis/pre constraint not satisfied column %s, x %e, constraint %f.\n", col_name[col_back[i]], x[i], x_arg[i]); +#endif + *kode = 1; + } + } + } + } + if (*kode == 1) { + output_msg(OUTPUT_MESSAGE, "\n\tCL1: Roundoff errors in optimization.\n\t Try using -multiple_precision in INVERSE_MODELING\n"); + } + } + if (check == 1) { + x_arg = (double *) free_check_null(x_arg); + res_arg = (double *) free_check_null(res_arg); + } + return 0; +} diff --git a/cl1mp.cpp b/cl1mp.cpp new file mode 100644 index 00000000..ca15c0bb --- /dev/null +++ b/cl1mp.cpp @@ -0,0 +1,974 @@ +#include +#include +#include +#include +#include + +/* must be defined here and in global.h */ +#if !defined(WIN32_MEMORY_DEBUG) +#define USE_PHRQ_ALLOC +#endif +#include "phqalloc.h" +#include "output.h" +#include "phrqtype.h" + +extern int max_row_count, max_column_count; +static char const svnid[] = "$Id: cl1mp.c 78 2005-02-01 22:47:12Z dlpark $"; + +int cl1mp(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q_arg, + int *kode, LDBLE toler, + int *iter, LDBLE *x_arg, LDBLE *res_arg, LDBLE *error, + LDBLE *cu_arg, int *iu, int *s, int check, LDBLE censor_arg); +extern void *free_check_null(void *ptr); +extern void malloc_error(void); + +/* debug +#define DEBUG_CL1 +#define CHECK_ERRORS + */ + + +int cl1mp(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q_arg, + int *kode_arg, LDBLE toler_arg, + int *iter, LDBLE *x_arg, LDBLE *res_arg, LDBLE *error_arg, + LDBLE *cu_arg, int *iu, int *s, int check, LDBLE censor_arg) +{ + /* System generated locals */ + union double_or_int {int ival; mpf_t dval;} *q2; + + /* Local variables */ + static int nklm; + static int iout, i, j; + static int maxit, n1, n2; + static int ia, ii, kk, in, nk, js; + static int iphase, kforce; + static int klm, jmn, nkl, jpn; + static int klm1; + static int *kode; + int q_dim, cu_dim; + int iswitch; + mpf_t *q; + mpf_t *x; + mpf_t *res; + mpf_t error; + mpf_t *cu; + mpf_t dummy, dummy1, sum, z, zu, zv, xmax, minus_one, toler, check_toler; + /*mpf_t *scratch;*/ + mpf_t pivot, xmin, cuv, tpivot, sn; + mpf_t zero; + int censor; + mpf_t censor_tol; +/* THIS SUBROUTINE USES A MODIFICATION OF THE SIMPLEX */ +/* METHOD OF LINEAR PROGRAMMING TO CALCULATE AN L1 SOLUTION */ +/* TO A K BY N SYSTEM OF LINEAR EQUATIONS */ +/* AX=B */ +/* SUBJECT TO L LINEAR EQUALITY CONSTRAINTS */ +/* CX=D */ +/* AND M LINEAR INEQUALITY CONSTRAINTS */ +/* EX.LE.F. */ +/* DESCRIPTION OF PARAMETERS */ +/* K NUMBER OF ROWS OF THE MATRIX A (K.GE.1). */ +/* L NUMBER OF ROWS OF THE MATRIX C (L.GE.0). */ +/* M NUMBER OF ROWS OF THE MATRIX E (M.GE.0). */ +/* N NUMBER OF COLUMNS OF THE MATRICES A,C,E (N.GE.1). */ +/* KLMD SET TO AT LEAST K+L+M FOR ADJUSTABLE DIMENSIONS. */ +/* KLM2D SET TO AT LEAST K+L+M+2 FOR ADJUSTABLE DIMENSIONS. */ +/* NKLMD SET TO AT LEAST N+K+L+M FOR ADJUSTABLE DIMENSIONS. */ +/* N2D SET TO AT LEAST N+2 FOR ADJUSTABLE DIMENSIONS */ +/* Q TWO DIMENSIONAL REAL ARRAY WITH KLM2D ROWS AND */ +/* AT LEAST N2D COLUMNS. */ +/* ON ENTRY THE MATRICES A,C AND E, AND THE VECTORS */ +/* B,D AND F MUST BE STORED IN THE FIRST K+L+M ROWS */ +/* AND N+1 COLUMNS OF Q AS FOLLOWS */ +/* A B */ +/* Q = C D */ +/* E F */ +/* THESE VALUES ARE DESTROYED BY THE SUBROUTINE. */ +/* KODE A CODE USED ON ENTRY TO, AND EXIT */ +/* FROM, THE SUBROUTINE. */ +/* ON ENTRY, THIS SHOULD NORMALLY BE SET TO 0. */ +/* HOWEVER, IF CERTAIN NONNEGATIVITY CONSTRAINTS */ +/* ARE TO BE INCLUDED IMPLICITLY, RATHER THAN */ +/* EXPLICITLY IN THE CONSTRAINTS EX.LE.F, THEN KODE */ +/* SHOULD BE SET TO 1, AND THE NONNEGATIVITY */ +/* CONSTRAINTS INCLUDED IN THE ARRAYS X AND */ +/* RES (SEE BELOW). */ +/* ON EXIT, KODE HAS ONE OF THE */ +/* FOLLOWING VALUES */ +/* 0- OPTIMAL SOLUTION FOUND, */ +/* 1- NO FEASIBLE SOLUTION TO THE */ +/* CONSTRAINTS, */ +/* 2- CALCULATIONS TERMINATED */ +/* PREMATURELY DUE TO ROUNDING ERRORS, */ +/* 3- MAXIMUM NUMBER OF ITERATIONS REACHED. */ +/* TOLER A SMALL POSITIVE TOLERANCE. EMPIRICAL */ +/* EVIDENCE SUGGESTS TOLER = 10**(-D*2/3), */ +/* WHERE D REPRESENTS THE NUMBER OF DECIMAL */ +/* DIGITS OF ACCURACY AVAILABLE. ESSENTIALLY, */ +/* THE SUBROUTINE CANNOT DISTINGUISH BETWEEN ZERO */ +/* AND ANY QUANTITY WHOSE MAGNITUDE DOES NOT EXCEED */ +/* TOLER. IN PARTICULAR, IT WILL NOT PIVOT ON ANY */ +/* NUMBER WHOSE MAGNITUDE DOES NOT EXCEED TOLER. */ +/* ITER ON ENTRY ITER MUST CONTAIN AN UPPER BOUND ON */ +/* THE MAXIMUM NUMBER OF ITERATIONS ALLOWED. */ +/* A SUGGESTED VALUE IS 10*(K+L+M). ON EXIT ITER */ +/* GIVES THE NUMBER OF SIMPLEX ITERATIONS. */ +/* X ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST N2D. */ +/* ON EXIT THIS ARRAY CONTAINS A */ +/* SOLUTION TO THE L1 PROBLEM. IF KODE=1 */ +/* ON ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE */ +/* SIMPLE NONNEGATIVITY CONSTRAINTS ON THE */ +/* VARIABLES. THE VALUES -1, 0, OR 1 */ +/* FOR X(J) INDICATE THAT THE J-TH VARIABLE */ +/* IS RESTRICTED TO BE .LE.0, UNRESTRICTED, */ +/* OR .GE.0 RESPECTIVELY. */ +/* RES ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST KLMD. */ +/* ON EXIT THIS CONTAINS THE RESIDUALS B-AX */ +/* IN THE FIRST K COMPONENTS, D-CX IN THE */ +/* NEXT L COMPONENTS (THESE WILL BE =0),AND */ +/* F-EX IN THE NEXT M COMPONENTS. IF KODE=1 ON */ +/* ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE SIMPLE */ +/* NONNEGATIVITY CONSTRAINTS ON THE RESIDUALS */ +/* B-AX. THE VALUES -1, 0, OR 1 FOR RES(I) */ +/* INDICATE THAT THE I-TH RESIDUAL (1.LE.I.LE.K) IS */ +/* RESTRICTED TO BE .LE.0, UNRESTRICTED, OR .GE.0 */ +/* RESPECTIVELY. */ +/* ERROR ON EXIT, THIS GIVES THE MINIMUM SUM OF */ +/* ABSOLUTE VALUES OF THE RESIDUALS. */ +/* CU A TWO DIMENSIONAL REAL ARRAY WITH TWO ROWS AND */ +/* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ +/* IU A TWO DIMENSIONAL INTEGER ARRAY WITH TWO ROWS AND */ +/* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ +/* S INTEGER ARRAY OF SIZE AT LEAST KLMD, USED FOR */ +/* WORKSPACE. */ +/* DOUBLE PRECISION DBLE */ +/* REAL */ + +/* INITIALIZATION. */ + if (svnid == NULL) fprintf(stderr," "); + /* + * mp variables + */ + censor = 1; + if (censor_arg == 0.0) censor = 0; + mpf_set_default_prec(96); + mpf_init(zero); + mpf_init(dummy); + mpf_init(dummy1); + mpf_init_set_d(censor_tol, censor_arg); + q = (mpf_t *) PHRQ_malloc((size_t) (max_row_count * max_column_count * sizeof(mpf_t))); + if (q == NULL) malloc_error(); + for (i = 0; i < max_row_count*max_column_count; i++) { + mpf_init_set_d(q[i], q_arg[i]); + if (censor == 1) { + if (mpf_cmp(q[ i ], zero) != 0) { + mpf_abs(dummy1, q[ i ]); + if (mpf_cmp(dummy1, censor_tol) <= 0) { + mpf_set_si(q[ i ], 0); + } + } + } + } + x = (mpf_t *) PHRQ_malloc((size_t) (n2d * sizeof(mpf_t))); + if (x == NULL) malloc_error(); + for (i = 0; i < n2d; i++) { + mpf_init_set_d (x[i], x_arg[i]); + } + res = (mpf_t *) PHRQ_malloc((size_t) ((k + l + m) * sizeof(mpf_t))); + if (res == NULL) malloc_error(); + for (i = 0; i < k + l + m; i++) { + mpf_init_set_d (res[i], res_arg[i]); + } + cu = (mpf_t *) PHRQ_malloc((size_t) (2*nklmd * sizeof(mpf_t))); + if (cu == NULL) malloc_error(); + for (i = 0; i < 2*nklmd; i++) { + mpf_init_set_d (cu[i], cu_arg[i]); + } + kode = (int *) PHRQ_malloc(sizeof(int)); + if (kode == NULL) malloc_error(); + *kode = *kode_arg; + mpf_init(sum); + mpf_init(error); + mpf_init(z); + mpf_init(zu); + mpf_init(zv); + mpf_init(xmax); + mpf_init_set_si(minus_one, -1); + mpf_init_set_d(toler, toler_arg); + mpf_init_set_d(check_toler, toler_arg); + mpf_init(pivot); + mpf_init(xmin); + mpf_init(cuv); + mpf_init(tpivot); + mpf_init(sn); +/* Parameter adjustments */ + q_dim = n2d; + q2 = (union double_or_int *) q; + cu_dim = nklmd; + +/* Function Body */ + maxit = *iter; + n1 = n + 1; + n2 = n + 2; + nk = n + k; + nkl = nk + l; + klm = k + l + m; + klm1 = klm + 1; + nklm = n + klm; + kforce = 1; + *iter = 0; + js = 0; + ia = -1; +/* Make scratch space */ +/* + scratch = (LDBLE *) PHRQ_malloc( (size_t) nklmd * sizeof(LDBLE)); + if (scratch == NULL) malloc_error(); + for (i=0; i < nklmd; i++) { + scratch[i] = 0.0; + } +*/ +/* + scratch = (mpf_t *) PHRQ_malloc( (size_t) nklmd * sizeof(mpf_t)); + if (scratch == NULL) malloc_error(); + for (i=0; i < nklmd; i++) { + mpf_init(scratch[i]); + } +*/ +/* SET UP LABELS IN Q. */ + for (j = 0; j < n; ++j) { + q2[ klm1 * q_dim + j ].ival = j + 1; + } +/* L10: */ + for (i = 0; i < klm; ++i) { + q2[ i * q_dim + n1 ].ival = n + i + 1; + if (mpf_cmp_d(q2[ i * q_dim + n ].dval, 0.0) < 0) { + for (j = 0; j < n1; ++j) { + /* q2[ i * q_dim + j ].dval = -q2[ i * q_dim + j ].dval; */ + mpf_neg(q2[ i * q_dim + j ].dval, q2[ i * q_dim + j ].dval); + } + q2[ i * q_dim + n1 ].ival = -q2[ i * q_dim + n1 ].ival; +/* L20: */ + } + } +/* L30: */ +/* SET UP PHASE 1 COSTS. */ + iphase = 2; +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Set up phase 1 costs\n"); +#endif +/* Zero first row of cu and iu */ + /*memcpy( (void *) &(cu[0]), (void *) &(scratch[0]), (size_t) nklm * sizeof(mpf_t) );*/ + for (j = 0; j < nklm; ++j) { + mpf_set_si(cu[j], 0); + iu[ j ] = 0; + } +/* L40: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L40\n"); +#endif + if (l != 0) { + for (j = nk; j < nkl; ++j) { + mpf_set_si(cu[j], 1); + /*cu[ j ] = 1.;*/ + iu[ j ] = 1; + } +/* L50: */ + iphase = 1; + } + +/* Copy first row of cu and iu to second row */ + /*memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), (size_t) nklm * sizeof(mpf_t) );*/ + for (i = 0; i < nklm; i++) { + mpf_set(cu[cu_dim + i], cu[i]); + } + memcpy( (void *) &(iu[cu_dim]), (void *) &(iu[0]), (size_t) nklm * sizeof(int) ); +/* L60: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L60\n"); +#endif + if (m != 0) { + for (j = nkl; j < nklm; ++j) { + /* cu[ cu_dim + j ] = 1.;*/ + mpf_set_si(cu[cu_dim + j], 1); + iu[ cu_dim + j ] = 1; + jmn = j - n; + if (q2[ jmn * q_dim + n1 ].ival < 0) { + iphase = 1; + } + } +/* L70: */ + } +/* L80: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L80\n"); +#endif + if (*kode != 0) { + for (j = 0; j < n; ++j) { + /* if ( x[j] < 0.) { */ + if (mpf_cmp_si(x[j], 0) < 0) { +/* L90: */ + /* cu[ j ] = 1.;*/ + mpf_set_si(cu[j], 1); + iu[ j ] = 1; + /* } else if (x[j] > 0.) {*/ + } else if (mpf_cmp_si(x[j], 0) > 0) { + /* cu[ cu_dim + j ] = 1.; */ + mpf_set_si(cu[cu_dim + j], 1); + iu[ cu_dim + j ] = 1; + } + } +/* L110: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L110\n"); +#endif + for (j = 0; j < k; ++j) { + jpn = j + n; + /* if (res[j] < 0.) { */ + if (mpf_cmp_si(res[j], 0) < 0) { +/* L120: */ + /* cu[ jpn ] = 1.;*/ + mpf_set_si(cu[jpn], 1); + iu[ jpn ] = 1; + if (q2[ j * q_dim + n1 ].ival > 0) { + iphase = 1; + } + /* } else if (res[j] > 0.) { */ + } else if (mpf_cmp_si(res[j], 0) > 0) { +/* L130: */ + /* cu[ cu_dim + jpn ] = 1.;*/ + mpf_set_si(cu[cu_dim + jpn], 1); + iu[ cu_dim + jpn ] = 1; + if (q2[ j * q_dim + n1 ].ival < 0) { + iphase = 1; + } + } + } +/* L140: */ + } +/* L150: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L150\n"); +#endif + if (iphase == 2) { + goto L500; + } +/* COMPUTE THE MARGINAL COSTS. */ +L160: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L160\n"); +#endif + for (j = js; j < n1; ++j) { + mpf_set_si(sum, 0); + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + if (ii < 0) { + /* z = cu[ cu_dim - ii - 1 ];*/ + mpf_set(z, cu[ cu_dim - ii - 1 ]); + } else { + /*z = cu[ ii - 1 ];*/ + mpf_set(z, cu[ ii - 1 ]); + } + /*sum += q2[ i * q_dim + j ].dval * z;*/ + mpf_mul(dummy, q2[ i * q_dim + j ].dval, z); + mpf_add(sum, sum, dummy); + } + /*q2[ klm * q_dim + j ].dval = sum;*/ + mpf_set(q2[ klm * q_dim + j ].dval, sum); + } + for (j = js; j < n; ++j) { + ii = q2[ klm1 * q_dim + j].ival; + if (ii < 0) { + /*z = cu[ cu_dim - ii - 1 ];*/ + mpf_set(z, cu[ cu_dim - ii - 1 ]); + } else { + /*z = cu[ ii - 1 ];*/ + mpf_set(z, cu[ ii - 1 ]); + } + /*q2[ klm * q_dim + j ].dval -= z;*/ + mpf_sub(q2[ klm * q_dim + j ].dval, q2[ klm * q_dim + j ].dval, z); + } +/* DETERMINE THE VECTOR TO ENTER THE BASIS. */ +L240: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L240, xmax %e\n", mpf_get_d(xmax)); +#endif + /*xmax = 0.;*/ + mpf_set_si(xmax, 0); + if (js >= n) { + goto L490; /* test for optimality */ + } + for (j = js; j < n; ++j) { + /*zu = q2[ klm * q_dim + j ].dval;*/ + mpf_set(zu, q2[ klm * q_dim + j ].dval); + ii = q2[ klm1 * q_dim + j ].ival; + if (ii > 0) { + /*zv = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ];*/ + mpf_mul(dummy, cu[ cu_dim + ii - 1 ], minus_one); + mpf_sub(dummy, dummy, cu[ ii - 1 ]); + mpf_sub(zv, dummy, zu); + } else { + ii = -ii; + /* zv = zu; */ + mpf_set(zv, zu); + /* zu = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ]; */ + mpf_mul(dummy, cu[ cu_dim + ii - 1 ], minus_one); + mpf_sub(dummy, dummy, cu[ ii - 1 ]); + mpf_sub(zu, dummy, zu); + } +/* L260 */ + if (kforce == 1 && ii > n) { + continue; + } + /*if (iu[ ii - 1 ] != 1 && zu > xmax){*/ + if ((iu[ ii - 1 ] != 1) && (mpf_cmp(zu, xmax) > 0)) { + /*xmax = zu;*/ + mpf_set(xmax, zu); + in = j; + } +/* L270 */ + /*if (iu[ cu_dim + ii - 1 ] != 1 && zv > xmax ) {*/ + if ((iu[ cu_dim + ii - 1 ] != 1) && (mpf_cmp(zv, xmax) > 0)) { + /*xmax = zv;*/ + mpf_set(xmax, zv); + in = j; + } + } +/* L280 */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L280 xmax %e, toler %e\n", mpf_get_d(xmax), mpf_get_d(toler)); +#endif + /*if (xmax <= toler) {*/ + if (mpf_cmp(xmax, toler) <= 0) { +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "xmax before optimality test %e\n", mpf_get_d(xmax)); +#endif + goto L490; /* test for optimality */ + } + /*if (q2[ klm * q_dim + in ].dval != xmax) {*/ + if (mpf_cmp(q2[ klm * q_dim + in ].dval,xmax) != 0) { + for (i = 0; i < klm1; ++i) { + /*q2[ i * q_dim + in ].dval = -q2[ i * q_dim + in ].dval;*/ + mpf_neg(q2[ i * q_dim + in ].dval, q2[ i * q_dim + in ].dval); + } + q2[ klm1 * q_dim + in ].ival = -q2[ klm1 * q_dim + in ].ival; +/* L290: */ + /*q2[ klm * q_dim + in ].dval = xmax;*/ + mpf_set(q2[ klm * q_dim + in ].dval, xmax); + } +/* DETERMINE THE VECTOR TO LEAVE THE BASIS. */ + if (iphase != 1 && ia != -1) { + /*xmax = 0.;*/ + mpf_set_si(xmax, 0); +/* find maximum absolute value in column "in" */ + for (i = 0; i <= ia; ++i) { + /*z = fabs(q2[ i * q_dim + in ].dval);*/ + mpf_abs(z, q2[ i * q_dim + in ].dval); + /*if (z > xmax) {*/ + if (mpf_cmp(z, xmax) > 0) { + /*xmax = z;*/ + mpf_set(xmax, z); + iout = i; + } + } +/* L310: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L310, xmax %e\n", mpf_get_d(xmax)); +#endif +/* switch row ia with row iout, use memcpy */ + /*if (xmax > toler) {*/ + if (mpf_cmp(xmax, toler) > 0) { + /* + memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), + (size_t) n2 * sizeof(mpf_t) ); + memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ iout * q_dim]), + (size_t) n2 * sizeof(mpf_t) ); + memcpy( (void *) &(q2[ iout * q_dim ]), (void *) &(scratch[ 0 ]), + (size_t) n2 * sizeof(mpf_t) ); + */ + for (i = 0; i < n1; i++) { + mpf_set(dummy, q2[ ia * q_dim + i].dval); + mpf_set(q2[ ia * q_dim + i].dval, q2[ iout * q_dim + i].dval); + mpf_set(q2[ iout * q_dim + i].dval, dummy); + } + j = q2[ ia * q_dim + n1].ival; + q2[ ia * q_dim + n1].ival = q2[ iout * q_dim + n1].ival; + q2[ iout * q_dim + n1].ival = j; + +/* L320: */ +/* set pivot to row ia, column in */ + iout = ia; + --ia; + /*pivot = q2[ iout * q_dim + in ].dval;*/ + mpf_set(pivot, q2[ iout * q_dim + in ].dval); + goto L420; /* Gauss Jordan */ + } + } +/* L330: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L330, xmax %e\n", mpf_get_d(xmax)); +#endif + kk = -1; +/* divide column n1 by positive value in column "in" greater than toler */ + for (i = 0; i < klm; ++i) { + /*z = q2[ i * q_dim + in ].dval;*/ + mpf_set(z, q2[ i * q_dim + in ].dval); + /*if (z > toler) {*/ + if (mpf_cmp(z, toler) > 0) { + ++kk; + /*res[kk] = q2[ i * q_dim + n ].dval / z;*/ + mpf_div(res[kk], q2[ i * q_dim + n ].dval, z); + s[kk] = i; + } + } +/* L340: */ + if (kk < 0) { + output_msg(OUTPUT_MESSAGE, "kode = 2 in loop 340.\n"); + } +L350: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L350, xmax %e\n", mpf_get_d(xmax)); +#endif + if (kk < 0) { +/* no positive value found in L340 or bypass intermediate verticies */ + *kode = 2; + goto L590; + } +/* L360: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L360, xmax %e\n", mpf_get_d(xmax)); +#endif +/* find minimum residual */ + /*xmin = res[ 0 ];*/ + mpf_set(xmin, res[0]); + iout = s[ 0 ]; + j = 0; + if (kk != 0) { + for (i = 1; i <= kk; ++i) { + /*if (res[i] < xmin) {*/ + if (mpf_cmp(res[i], xmin) < 0) { + j = i; + /*xmin = res[i];*/ + mpf_set(xmin, res[i]); + iout = s[i]; + } + } +/* L370: */ +/* put kk in position j */ + /*res[j] = res[kk];*/ + mpf_set(res[j], res[kk]); + s[j] = s[kk]; + } +/* L380: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L380 iout %d, xmin %e, xmax %e\n", iout, mpf_get_d(xmin), mpf_get_d(xmax)); +#endif + --kk; + /*pivot = q2[ iout * q_dim + in ].dval;*/ + mpf_set(pivot, q2[ iout * q_dim + in ].dval); + ii = q2[ iout * q_dim + n1 ].ival; + if (iphase != 1) { + if (ii < 0) { +/* L390: */ + if (iu[ - ii - 1 ] == 1) { + goto L420; + } + } else { + if (iu[ cu_dim + ii - 1 ] == 1) { + goto L420; + } + } + } +/* L400: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L400\n"); +#endif + ii = abs(ii); + /*cuv = cu[ ii - 1 ] + cu[ cu_dim + ii - 1];*/ + mpf_add(cuv, cu[ ii - 1 ], cu[ cu_dim + ii - 1]); + /*if (q2[ klm * q_dim + in ].dval - pivot * cuv > toler) {*/ + mpf_mul(dummy, pivot, cuv); + mpf_sub(dummy, q2[ klm * q_dim + in ].dval, dummy); + if (mpf_cmp(dummy, toler) > 0) { +/* BYPASS INTERMEDIATE VERTICES. */ + for (j = js; j < n1; ++j) { + /*z = q2[ iout * q_dim + j ].dval;*/ + mpf_set(z, q2[ iout * q_dim + j ].dval); + /*q2[ klm * q_dim + j ].dval -= z * cuv;*/ + mpf_mul(dummy1, z, cuv); + mpf_sub(q2[ klm * q_dim + j ].dval, q2[ klm * q_dim + j ].dval, dummy1); + + if (censor == 1) { + if (mpf_cmp(q2[ klm * q_dim + j ].dval, zero) != 0) { + mpf_abs(dummy1, q2[ klm * q_dim + j ].dval); + if (mpf_cmp(dummy1, censor_tol) <= 0) { + mpf_set_si(q2[ klm * q_dim + j ].dval, 0); + } + } + } + + /*q2[ iout * q_dim + j ].dval = -z;*/ + mpf_neg(q2[ iout * q_dim + j ].dval, z); + } +/* L410: */ + q2[ iout * q_dim + n1 ].ival = -q2[ iout * q_dim + n1 ].ival; + goto L350; + } +/* GAUSS-JORDAN ELIMINATION. */ +L420: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Gauss Jordon %d\n", *iter); +#endif + if (*iter >= maxit) { + *kode = 3; + goto L590; + } +/* L430: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L430\n"); +#endif + ++(*iter); + for (j = js; j < n1; ++j) { + if (j != in) { + /*q2[ iout * q_dim + j ].dval /= pivot;*/ + mpf_div(q2[ iout * q_dim + j ].dval, q2[ iout * q_dim + j ].dval, pivot); + } + } +/* L440: */ + for (j = js; j < n1; ++j) { + if (j != in) { + /*z = -q2[ iout * q_dim + j ].dval;*/ + mpf_neg(z, q2[ iout * q_dim + j ].dval); + for (i = 0; i < klm1; ++i) { + if (i != iout) { + /*q2[ i * q_dim + j ].dval += z * q2[ i * q_dim + in ].dval;*/ + mpf_mul(dummy, z, q2[ i * q_dim + in ].dval); + mpf_add(q2[ i * q_dim + j ].dval, q2[ i * q_dim + j ].dval, dummy); + + if (censor == 1) { + if (mpf_cmp(q2[ i * q_dim + j ].dval, zero) != 0) { + mpf_abs(dummy1, q2[ i * q_dim + j ].dval); + if (mpf_cmp(dummy1, censor_tol) <= 0) { + mpf_set_si(q2[ i * q_dim + j ].dval, 0); + } + } + } + } + } +/* L450: */ + } + } +/* L460: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L460\n"); +#endif + /*tpivot = -pivot;*/ + mpf_neg(tpivot, pivot); + for (i = 0; i < klm1; ++i) { + if (i != iout) { + /*q2[ i * q_dim + in ].dval /= tpivot;*/ + mpf_div(q2[ i * q_dim + in ].dval, q2[ i * q_dim + in ].dval, tpivot); + } + } +/* L470: */ + /*q2[ iout * q_dim + in ].dval = 1. / pivot;*/ + mpf_set_si(dummy, 1); + mpf_div(q2[ iout * q_dim + in ].dval, dummy, pivot); + ii = q2[ iout * q_dim + n1 ].ival; + q2[ iout * q_dim + n1 ].ival = q2[ klm1 * q_dim + in ].ival; + q2[ klm1 * q_dim + in ].ival = ii; + ii = abs(ii); + if (iu[ ii - 1 ] == 0 || iu[ cu_dim + ii - 1 ] == 0) { + goto L240; + } +/* switch column */ + for (i = 0; i < klm1; ++i) { + /*z = q2[ i * q_dim + in ].dval;*/ + mpf_set(z, q2[ i * q_dim + in ].dval); + /*q2[ i * q_dim + in ].dval = q2[ i * q_dim + js ].dval;*/ + mpf_set(q2[ i * q_dim + in ].dval, q2[ i * q_dim + js ].dval); + /*q2[ i * q_dim + js ].dval = z;*/ + mpf_set(q2[ i * q_dim + js ].dval, z); + } + i = q2[ klm1 * q_dim + in ].ival; + q2[ klm1 * q_dim + in ].ival = q2[ klm1 * q_dim + js ].ival; + q2[ klm1 * q_dim + js ].ival = i; +/* L480: */ + ++js; + goto L240; +/* TEST FOR OPTIMALITY. */ +L490: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L490\n"); +#endif + if (kforce == 0) { + if (iphase == 1) { + /*if (q2[ klm * q_dim + n ].dval <= toler) {*/ + if (mpf_cmp(q2[ klm * q_dim + n ].dval, toler) <= 0) { + goto L500; + } +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE,"q2[klm1-1, n1-1] > *toler. %e\n", mpf_get_d(q2[ ( klm1 - 1 ) * q_dim + n1 - 1 ].dval)); +#endif + *kode = 1; + goto L590; + } + *kode = 0; + goto L590; + } + /*if (iphase != 1 || q2[ klm * q_dim + n ].dval > toler) {*/ + if ((iphase != 1) || (mpf_cmp(q2[ klm * q_dim + n ].dval, toler) > 0)) { + kforce = 0; + goto L240; + } +/* SET UP PHASE 2 COSTS. */ +L500: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "Set up phase 2 costs %d\n", *iter); +#endif + iphase = 2; + for (j = 0; j < nklm; ++j) { + /*cu[ j ] = 0.;*/ + mpf_set_si(cu[j], 0); + } +/* L510: */ + for (j = n; j < nk; ++j) { + /*cu[ j ] = 1.;*/ + mpf_set_si(cu[j], 1); + } + /* + memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), (size_t) nklm * sizeof(LDBLE) ); + */ + for (i = 0; i < nklm; i++) { + mpf_set(cu[cu_dim + i], cu[i]); + } + +/* L520: */ + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + if (ii <= 0) { + if (iu[ cu_dim - ii - 1 ] == 0) { + continue; + } + /*cu[ cu_dim - ii - 1 ] = 0.;*/ + mpf_set_si(cu[ cu_dim - ii - 1 ], 0); + } else { +/* L530: */ + if (iu[ ii - 1 ] == 0) { + continue; + } + /*cu[ ii - 1 ] = 0.;*/ + mpf_set_si(cu[ ii - 1 ], 0); + } +/* L540: */ + ++ia; +/* switch row */ + /* + memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ i * q_dim]), + (size_t) n2 * sizeof(LDBLE) ); + memcpy( (void *) &(q2[ i * q_dim ]), (void *) &(scratch[ 0 ]), + (size_t) n2 * sizeof(LDBLE) ); + */ + for (iswitch = 0; iswitch < n1; iswitch++) { + mpf_set(dummy, q2[ ia * q_dim + iswitch].dval); + mpf_set(q2[ ia * q_dim + iswitch].dval, q2[ i * q_dim + iswitch].dval); + mpf_set(q2[ i * q_dim + iswitch].dval, dummy); + } + iswitch = q2[ ia * q_dim + n1].ival; + q2[ ia * q_dim + n1].ival = q2[ i * q_dim + n1].ival; + q2[ i * q_dim + n1].ival = iswitch; +/* L550: */ + } +/* L560: */ + goto L160; + + +/* PREPARE OUTPUT. */ +L590: +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L590\n"); +#endif + /*sum = 0.;*/ + mpf_set_si(sum, 0); + for (j = 0; j < n; ++j) { + /*x[j] = 0.;*/ + mpf_set_si(x[j], 0); + } +/* L600: */ + for (i = 0; i < klm; ++i) { + /*res[i] = 0.;*/ + mpf_set_si(res[i], 0); + } +/* L610: */ + for (i = 0; i < klm; ++i) { + ii = q2[ i * q_dim + n1 ].ival; + /*sn = 1.;*/ + mpf_set_si(sn, 1); + if (ii < 0) { + ii = -ii; + /*sn = -1.;*/ + mpf_set_si(sn, -1); + } + if (ii <= n) { +/* L620: */ + /*x[ii - 1] = sn * q2[ i * q_dim + n ].dval;*/ + mpf_mul(x[ii - 1], sn, q2[ i * q_dim + n ].dval); + } else { +/* L630: */ + /*res[ii - n - 1] = sn * q2[ i * q_dim + n ].dval;*/ + mpf_mul(res[ii - n - 1], sn, q2[ i * q_dim + n ].dval); + if (ii >= n1 && ii <= nk ) { +/* * DBLE(Q(I,N1)) */ + /*sum += q2[ i * q_dim + n ].dval;*/ + mpf_add(sum, sum, q2[ i * q_dim + n ].dval); + } + } + } +/* L640: */ +#ifdef DEBUG_CL1 + output_msg(OUTPUT_MESSAGE, "L640\n"); +#endif + /* + * Check calculation + */ + mpf_set_si(dummy, 100); + mpf_mul(check_toler, toler, dummy); + if (check && *kode == 0) { + /* + * Check optimization constraints + */ + if (*kode_arg == 1) { + for (i = 0; i < k; i++) { + if (res_arg[i] < 0.0) { + mpf_sub(dummy, res[i], check_toler); + mpf_set_si(dummy1, 0); + if (mpf_cmp(dummy,dummy1) > 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: optimization constraint not satisfied row %d, res %e, constraint %f.\n", i, mpf_get_d(res[i]), res_arg[i]); +#endif + *kode = 1; + } + } else if (res_arg[i] > 0.0) { + mpf_add(dummy, res[i], check_toler); + mpf_set_si(dummy1, 0); + if (mpf_cmp(dummy,dummy1) < 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: optimization constraint not satisfied row %d, res %e, constraint %f.\n", i, mpf_get_d(res[i]), res_arg[i]); +#endif + *kode = 1; + } + } + } + } + /* + * Check equalities + */ + for (i = k; i < k + l; i++) { + mpf_abs(dummy, res[i]); + if (mpf_cmp(dummy, check_toler) > 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: equality constraint not satisfied row %d, res %e, tolerance %e.\n", i, mpf_get_d(res[i]), mpf_get_d(check_toler)); +#endif + + *kode = 1; + } + } + /* + * Check inequalities + */ + for (i = k + l; i < k + l + m; i++) { + mpf_neg(dummy, check_toler); + if (mpf_cmp(res[i], dummy) < 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: inequality constraint not satisfied row %d, res %e, tolerance %e.\n", i, mpf_get_d(res[i]), mpf_get_d(check_toler)); +#endif + *kode = 1; + } + } + /* + * Check dissolution/precipitation constraints + */ + if (*kode_arg == 1) { + for (i = 0; i < n; i++) { + if (x_arg[i] < 0.0) { + mpf_sub(dummy, x[i], check_toler); + mpf_set_si(dummy1, 0); + if (mpf_cmp(dummy,dummy1) > 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: dis/pre constraint not satisfied column %d, x %e, constraint %f.\n", i, mpf_get_d(x[i]), x_arg[i]); +#endif + *kode = 1; + } + } else if (x_arg[i] > 0.0) { + mpf_add(dummy, x[i], check_toler); + mpf_set_si(dummy1, 0); + if (mpf_cmp(dummy,dummy1) < 0) { +#ifdef CHECK_ERRORS + output_msg(OUTPUT_MESSAGE, "\tCL1MP: dis/pre constraint not satisfied column %d, x %e, constraint %f.\n", i, mpf_get_d(x[i]), x_arg[i]); +#endif + *kode = 1; + } + } + } + } + if (*kode == 1) { + output_msg(OUTPUT_MESSAGE, "\n\tCL1MP: Roundoff errors in optimization.\n\t Deleting model.\n"); + } + } + /* + * set return variables + */ + /**error = sum;*/ + mpf_set(error, sum); + *error_arg = mpf_get_d(error); + *kode_arg = *kode; + for (i = 0; i < n2d; i++) { + x_arg[i] = mpf_get_d (x[i]); + } + for (i = 0; i < k + l + m; i++) { + res_arg[i] = mpf_get_d (res[i]); + } + + /*scratch = free_check_null (scratch);*/ + + for (i = 0; i < max_row_count*max_column_count; i++) { + mpf_clear(q[i]); + } + q = (mpf_t *) free_check_null(q); + for (i = 0; i < n2d; i++) { + mpf_clear (x[i]); + } + x = (mpf_t *) free_check_null(x); + for (i = 0; i < k + l + m; i++) { + mpf_clear (res[i]); + } + res = (mpf_t *) free_check_null(res); + for (i = 0; i < 2*nklmd; i++) { + mpf_clear (cu[i]); + } + cu = (mpf_t *) free_check_null(cu); + mpf_clear(dummy); + mpf_clear(dummy1); + mpf_clear(sum); + mpf_clear(error); + mpf_clear(z); + mpf_clear(zu); + mpf_clear(zv); + mpf_clear(xmax); + mpf_clear(minus_one); + mpf_clear(toler); + mpf_clear(check_toler); + mpf_clear(pivot); + mpf_clear(xmin); + mpf_clear(cuv); + mpf_clear(tpivot); + mpf_clear(sn); + mpf_clear(censor_tol); + kode = (int *) free_check_null(kode); + return 0; +} diff --git a/classes/Conc.cxx b/classes/Conc.cxx new file mode 100644 index 00000000..fae825a6 --- /dev/null +++ b/classes/Conc.cxx @@ -0,0 +1,188 @@ +#include "Conc.h" +#include "Solution.h" +#include "Utilities.h" +#include + +CConc::CConc(void) +: description("") +, moles(0.0) +, input_conc(0.0) +, units("") +, equation_name("") +, phase_si(0.0) +, n_pe(-1) +, as("") +, gfw(0.0) + //, skip(0); + //, phase(NULL) +{ +} + +CConc::~CConc(void) +{ +} + +#ifdef SKIP +CConc::STATUS_TYPE CConc::read(CParser& parser, CSolution& solution) +{ + // std::string& str = parser.line(); + std::string str = parser.line(); + + // defaults set in ctor + + // Remove space between "kg" and "solution" or "water" in units + Utilities::replace("Kg", "kg", str); + Utilities::replace("KG", "kg", str); + while (Utilities::replace("kg ", "kg", str)); + + std::istream::pos_type ptr = 0; + + // + // Read master species list for mass balance equation + // + std::string token; + std::string token1; + int count_redox_states = 0; + CParser::TOKEN_TYPE j; + while ( ((j = parser.copy_token(token, ptr)) == CParser::TT_UPPER ) || + ( token[0] == '[' ) || + ( Utilities::strcmp_nocase_arg1(token.c_str(), "ph") == 0 ) || + ( Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0 ) ) + { + ++count_redox_states; + Utilities::replace("(+", "(", token); + if (count_redox_states > 1) token1 += " "; + token1 += token; + } + if (count_redox_states == 0) { + parser.incr_input_error(); + parser.error_msg("No element or master species given for concentration input.", CParser::OT_CONTINUE); + return CConc::ERROR; + } + description = token1; + + // Determine if reading alkalinity, allow equivalents for units + Utilities::str_tolower(token1); + bool alk = false; + if (token1.find("alk") == 0) { + alk = true; + } + + // Read concentration + if (!(std::istringstream(token) >> this->input_conc)) { + std::ostringstream err; + err << "Concentration data error for " << token1 << " in solution input."; + parser.error_msg(err, CParser::OT_CONTINUE); + return CConc::ERROR; + } + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + + // Read optional data + token1 = token; + + // Check for units info + if (parser.check_units(token1, alk, false, solution.get_units(), false) == CParser::OK) { + if (parser.check_units(token1, alk, false, solution.get_units(), true) == CParser::OK) { + this->units = token1; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + } else { + return CConc::ERROR; + } + } + + // Check for "as" followed by formula to be used for gfw + token1 = token; + Utilities::str_tolower(token1); + if (token1.compare("as") == 0) + { + parser.copy_token(token, ptr); + this->as = token; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + } + // Check for "gfw" followed by gram formula weight + else if (token1.compare("gfw") == 0) + { + if (parser.copy_token(token, ptr) != CParser::TT_DIGIT) { + parser.error_msg("Expecting gram formula weight.", CParser::OT_CONTINUE); + return CConc::ERROR; + } else { + parser.get_iss() >> this->gfw; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + } + } + + // Check for redox couple for pe + if ( Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0 ) { + this->n_pe = CPe_Data::store(solution.pe, token); + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + } else if (token.find("/") != std::string::npos) { + if (parser.parse_couple(token) == CParser::OK) { + this->n_pe = CPe_Data::store(solution.pe, token); + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + } else { + return CConc::ERROR; + } + } + + // Must have phase + this->equation_name = token; + if ( (j = parser.copy_token(token, ptr)) == CParser::TT_EMPTY) return CConc::OK; + + // Check for saturation index + if (!(std::istringstream(token) >> this->phase_si)) + { + parser.error_msg("Expected saturation index.", CParser::OT_CONTINUE); + return CConc::ERROR; + } + return CConc::OK; +} +#endif + +void CConc::dump_xml(const CSolution& solution, std::ostream& os, unsigned int indent)const +{ + unsigned int i; + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->description << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->input_conc << "\n"; + + if (!this->units.empty()) { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->units << "\n"; + } + + if ( !this->as.empty() ) { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->as << "\n"; + } + else if (this->gfw > 0.0) { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->gfw << "\n"; + } + ////if (this->n_pe > 0) { + solution.pe[this->n_pe].dump_xml(os, indent + 1); + ////} + + if (!this->equation_name.empty()) { + if (Utilities::strcmp_nocase_arg1(this->equation_name.c_str(), "charge") == 0) + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + } + else + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->equation_name << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->phase_si << "\n"; + } + } + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "\n"; +} diff --git a/classes/Conc.h b/classes/Conc.h new file mode 100644 index 00000000..4b867d2f --- /dev/null +++ b/classes/Conc.h @@ -0,0 +1,60 @@ +#if !defined(CONC_H_INCLUDED) +#define CONC_H_INCLUDED + +#include "Parser.h" +#include "Utilities.h" + +#include + +// forward declarations +class CSolution; // reqd for read and dump_xml + +class CConc +{ +public: + CConc(void); + ~CConc(void); + + enum STATUS_TYPE { + ERROR = 0, + OK = 1 + }; + +public: + + STATUS_TYPE read(CParser& parser, CSolution& sol); + + void dump_xml(const CSolution& solution, std::ostream& os, unsigned int indent = 0)const; + + double get_input_conc()const {return this->input_conc;} + void set_input_conc(double input_conc) {this->input_conc = input_conc;} + + std::string get_equation_name()const {return this->equation_name;} + void set_equation_name(std::string equation_name) {this->equation_name = equation_name;} + + std::string get_description()const {return this->description;} + void set_description(std::string description) {this->description = description;} + + std::string get_units()const {return this->units;} + void set_units(std::string units) {this->units = units;} + + int get_n_pe()const {return this->n_pe;} + void set_n_pe(int n_pe) {this->n_pe = n_pe;} + + bool operator<(const CConc& conc)const { return (this->description < conc.description); } + +private: + std::string description; + // int m_skip; + double moles; + double input_conc; + std::string units; + std::string equation_name; + // struct phase *m_phase; + double phase_si; + int n_pe; + std::string as; + double gfw; +}; + +#endif // CONC_H_INCLUDED diff --git a/classes/Isotope.cxx b/classes/Isotope.cxx new file mode 100644 index 00000000..5654e1df --- /dev/null +++ b/classes/Isotope.cxx @@ -0,0 +1,100 @@ +#include "Isotope.h" +#include "Utilities.h" +#include + +CIsotope::CIsotope(void) +: isotope_number(0.0) +, ratio_uncertainty_defined(false) +{ +} + +CIsotope::~CIsotope(void) +{ +} + +std::string CIsotope::get_name()const +{ + std::ostringstream oss; + oss << this->isotope_number << this->elt_name; + return oss.str(); +} +#ifdef SKIP +CIsotope::STATUS CIsotope::read(CParser& parser) +{ + if ( !(parser.get_iss() >> this->isotope_number) ) { + assert(parser.get_iss().fail()); + parser.incr_input_error(); + parser.error_msg("Expected isotope name to" + " begin with an isotopic number.", CParser::OT_CONTINUE); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + + // read and save element name + std::istringstream::int_type c = parser.get_iss().peek(); + if ( c == std::char_traits::eof() || !(::isupper(c)) ) { + parser.error_msg("Expecting element name.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + parser.incr_input_error(); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + if ( !(parser.get_iss() >> this->elt_name) ) { + // should never get here + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + assert(!this->elt_name.empty() && ::isupper(this->elt_name[0])); + + // read and store isotope ratio + if ( !(parser.get_iss() >> this->ratio) ) { + assert(parser.get_iss().fail()); + parser.incr_input_error(); + parser.error_msg("Expected numeric value for isotope ratio.", CParser::OT_CONTINUE); + return ERROR; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + + // read and store isotope ratio + this->ratio_uncertainty_defined = false; + if ( !(parser.get_iss() >> this->ratio_uncertainty)) { + if ( !parser.get_iss().eof() ) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for uncertainty in isotope ratio.", CParser::OT_CONTINUE); + return ERROR; + } + } else { + this->ratio_uncertainty_defined = true; + } + assert(parser.get_iss().good() || parser.get_iss().eof()); + return OK; +} +#endif +#ifdef SKIP +void CIsotope::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "ratio << "\""; + if ( this->ratio_uncertainty_defined /* Utilities::isnan(this->ratio_uncertainty) */ ) { + os << "/>\n"; + } + else { + os << ">\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->ratio_uncertainty << "\n"; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "\n"; + } +} +#endif +bool CIsotope::operator<(const CIsotope& isotope)const +{ + int i = Utilities::strcmp_nocase(this->elt_name.c_str(), isotope.elt_name.c_str()); + if (i != 0) return (i < 0); + return ( this->isotope_number < isotope.isotope_number ); +} + diff --git a/classes/Isotope.h b/classes/Isotope.h new file mode 100644 index 00000000..9ded5525 --- /dev/null +++ b/classes/Isotope.h @@ -0,0 +1,40 @@ +#if !defined(ISOTOPE_H_INCLUDED) +#define ISOTOPE_H_INCLUDED + +#include "Parser.h" +#include // std::ostream +#include // std::string + +class CIsotope +{ +public: + CIsotope(void); + ~CIsotope(void); + + enum STATUS { + ERROR = 0, + OK = 1 + }; + + CIsotope::STATUS read(CParser& parser); + + void dump_xml(std::ostream& os, unsigned int indent)const; + + std::string get_name()const ; + + double get_ratio()const { return this->ratio; } + + double get_ratio_uncertainty()const { return this->ratio_uncertainty; } + + bool get_ratio_uncertainty_defined()const { return this->ratio_uncertainty_defined; } + + bool operator<(const CIsotope& conc)const; + +private: + double isotope_number; + std::string elt_name; + double ratio; + double ratio_uncertainty; + bool ratio_uncertainty_defined; +}; +#endif // ISOTOPE_H_INCLUDED diff --git a/classes/Makefile b/classes/Makefile new file mode 100644 index 00000000..04119bc6 --- /dev/null +++ b/classes/Makefile @@ -0,0 +1,35 @@ +.SUFFIXES : .o .cxx + +.cxx.o : + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + +CXX = g++ +CPPFLAGS = -I/z/srv2rcolkr/home/charlton/cppunit-robocomp/include +CXXFLAGS = -Wall +LDFLAGS = -lcppunit -L/z/srv2rcolkr/home/charlton/cppunit-robocomp/lib -static + + +COMMON_OBJS = Conc.o\ + Isotope.o\ + NumKeyword.o\ + Parser.o\ + Pe_Data.o\ + Solution.o\ + Utilities.o + +TEST_OBJS = TestCIsotope.o\ + TestCSolution.o\ + TestCParser.o\ + test.o + +all: phreeqcxx test + + +phreeqcxx : ${COMMON_OBJS} main.o + ${CXX} -o $@ ${COMMON_OBJS} main.o + +test : ${COMMON_OBJS} ${TEST_OBJS} + ${CXX} -o $@ ${COMMON_OBJS} ${TEST_OBJS} ${LDFLAGS} + +clean : + rm -f ${COMMON_OBJS} main.o ${TEST_OBJS} diff --git a/classes/NumKeyword.cxx b/classes/NumKeyword.cxx new file mode 100644 index 00000000..8590b95f --- /dev/null +++ b/classes/NumKeyword.cxx @@ -0,0 +1,119 @@ +// NumKeyword.cxx: implementation of the CNumKeyword class. +// +////////////////////////////////////////////////////////////////////// + +#include "NumKeyword.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CNumKeyword::CNumKeyword() +{ +} + +CNumKeyword::~CNumKeyword() +{ +} + +void CNumKeyword::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->n_user << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->n_user_end << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << " "; + os << "" << this->description << "" << "\n"; +} + +void CNumKeyword::read_number_description(CParser& parser) +{ + // skip keyword + std::string keyword; + std::istream::pos_type ptr; + parser.copy_token(keyword, ptr); + + std::istream::pos_type ptr1 = ptr; + std::string::size_type pos; + std::string token; + if (parser.copy_token(token, ptr) != CParser::TT_DIGIT) + { + this->n_user = 1; + this->n_user_end = 1; + } + else if ( (pos = token.find_first_of("-")) != std::string::npos ) + { + token.replace(pos, 1, " "); + std::istringstream iss(token); + if (!(iss >> this->n_user >> this->n_user_end)) + { + std::ostringstream err_oss; + if (parser.next_keyword() >= 0) + { + err_oss << "Reading number range for " << keyword << "."; + } + else + { + err_oss << "Reading number range for keyword."; + } + parser.error_msg(err_oss, CParser::OT_CONTINUE); + parser.incr_input_error(); + } + ptr1 = ptr; + } + else + { + std::istringstream iss(token); + iss >> this->n_user; + this->n_user_end = this->n_user; + ptr1 = ptr; + } + + // reset get position + parser.get_iss().seekg(ptr1); + + // skip whitespace + while (::isspace(parser.get_iss().peek())) parser.get_iss().ignore(); + + // copy description + std::getline(parser.get_iss(), this->description); +} + +void CNumKeyword::read_number_description(std::istream& is) +{ + // KEYWORD [[1[-20]] [This is the description]] + + // eat keyword + std::string token; + is >> token; + + // skip whitespace + while (::isspace(is.peek())) is.ignore(); + + if (::isdigit(is.peek())) + { + is >> this->n_user; + char ch = is.peek(); + if (ch == '-') + { + is >> ch; // eat '-' + is >> this->n_user_end; + } + else + { + this->n_user_end = this->n_user; + } + } + else + { + this->n_user = this->n_user_end = 1; + } + + while (::isspace(is.peek())) is.ignore(); + + std::getline(is, this->description); +} diff --git a/classes/NumKeyword.h b/classes/NumKeyword.h new file mode 100644 index 00000000..0b885426 --- /dev/null +++ b/classes/NumKeyword.h @@ -0,0 +1,34 @@ +#if !defined(NUMKEYWORD_H_INCLUDED) +#define NUMKEYWORD_H_INCLUDED + +#include "Parser.h" +#include // std::ostream +#include // std::string + +class CNumKeyword +{ +public: + CNumKeyword(); + virtual ~CNumKeyword(); + + int get_n_user()const { return this->n_user; } + void set_n_user(int user) { this->n_user = user; } + + int get_n_user_end()const { return this->n_user_end; } + void set_n_user_end(int user_end) { this->n_user_end = user_end; } + + bool operator<(const CNumKeyword& key)const { return (this->n_user < key.n_user); } + + virtual void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + void read_number_description(CParser& parser); + +protected: + int n_user; + int n_user_end; + std::string description; + +private: + void read_number_description(std::istream& is); +}; +#endif // !defined(NUMKEYWORD_H_INCLUDED) diff --git a/classes/Parser.cxx b/classes/Parser.cxx new file mode 100644 index 00000000..3316162d --- /dev/null +++ b/classes/Parser.cxx @@ -0,0 +1,836 @@ +// Parser.cpp: implementation of the CParser class. +// +////////////////////////////////////////////////////////////////////// + +#include "Parser.h" +#include "utilities.h" +#include // std::transform +#include // std::map +#include // assert +#include // std::cout std::cerr + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CParser::CParser(std::istream& input) +: m_input_stream(input), m_output_stream(std::cout), m_error_stream(std::cerr) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::CParser(std::istream& input, std::ostream& output) +: m_input_stream(input), m_output_stream(output), m_error_stream(std::cerr) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::CParser(std::istream& input, std::ostream& output, std::ostream& error) +: m_input_stream(input), m_output_stream(output), m_error_stream(error) +, m_input_error(0), m_next_keyword(KT_NONE) +{ + m_line_save.reserve(80); + m_line.reserve(80); +} + +CParser::~CParser() +{ +} + +CParser::LINE_TYPE CParser::check_line(const std::string& str, bool allow_empty, bool allow_eof, bool allow_keyword, bool print) +{ + LINE_TYPE i; + + // Get line + do { + i = get_line(); + // reset iss + m_line_iss.str(m_line); + m_line_iss.seekg(0, std::ios_base::beg); + m_line_iss.clear(); + + + if (true) // pr.echo_input == TRUE + { + if ((print && i != LT_EOF) || i == LT_KEYWORD) + { + get_output() << "\t" << m_line_save << "\n"; + } + } + + } while (i == LT_EMPTY && allow_empty == false); + + // Check eof + if (i == LT_EOF && allow_eof == false) + { + std::ostringstream msg; + msg << "Unexpected eof while reading " << str << "\nExecution terminated.\n"; + error_msg(msg, OT_STOP); + } + + // Check keyword + if (i == LT_KEYWORD && allow_keyword == false) + { + std::ostringstream msg; + msg << "Expected data for " << str << ", but got a keyword ending data block."; + error_msg(msg, OT_CONTINUE); + incr_input_error(); + } + return i; +} + +CParser::LINE_TYPE CParser::get_line() +{ + CParser::LINE_TYPE return_value = LT_EMPTY; + while (return_value == LT_EMPTY) + { + // + // Eliminate all characters after # sign as a comment + // + + // + // Get line, check for eof + // + if (get_logical_line() == LT_EOF) + { + if (!m_input_stream.eof()) + { + error_msg("Reading input file.", OT_CONTINUE); + error_msg("istream::get() returned an error.", OT_STOP); + } + else + { + //{{MOD + m_line.erase(m_line.begin(), m_line.end()); // m_line.clear(); + //}}MOD + m_next_keyword = KT_EOF; + return LT_EOF; + } + } + + // + // Get long lines + // + bool empty = true; + m_line = m_line_save.substr(0, m_line_save.find_first_of('#')); + for (unsigned int i = 0; i < m_line.size(); ++i) + { + if (!::isspace(m_line[i])) + { + empty = false; + break; + } + } + + // + // New line character encountered + // + return_value = (empty ? LT_EMPTY : LT_OK); + } + + // + // Determine return_value + // + if (return_value == LT_OK) + { + if (check_key(m_line.begin(), m_line.end())) + { + return_value = LT_KEYWORD; + } + else + { + std::string::iterator beg = m_line.begin(); + std::string::iterator end = m_line.end(); + std::string token; + copy_token(token, beg, end); + + if (token.size() > 1 && token[0] == '-' && ::isalpha(token[1])) + { + return_value = LT_OPTION; + } + } + } + return return_value; +} + +/** + Reads input stream until end of line, ";", or eof + stores characters in line_save + + returns: + EOF on empty line on end of file or + OK otherwise +*/ +CParser::LINE_TYPE CParser::get_logical_line() +{ + int j; + unsigned int pos; + char c; + + m_line_save.erase(m_line_save.begin(), m_line_save.end()); // m_line_save.clear(); + + while ((j = m_input_stream.get()) != std::char_traits::eof()) { + c = (char) j; + if (c == '#') { + // ignore all chars after # until newline + do { + c = (char) j; + if (c == '\n') { + break; + } + m_line_save += c; + } while ((j = m_input_stream.get()) != std::char_traits::eof()); + } + if (c == ';') break; + if (c == '\n') { + break; + } + if (c == '\\') { + pos = m_line_save.size(); + m_line_save += c; + while ((j = m_input_stream.get()) != std::char_traits::eof()) { + c = (char) j; + if (c == '\\') { + pos = m_line_save.size(); + m_line_save += c; + continue; + } + if (c == '\n') { + // remove '\\' + for (; pos < m_line_save.size(); pos++) { + m_line_save[pos] = m_line_save[pos+1]; + } + m_line_save.erase(m_line_save.size() - 1, 1); + break; + } + m_line_save += c; + if (!::isspace(j)) break; + } + } else { + m_line_save += c; + } + } + if (j == std::char_traits::eof() && m_line_save.size() == 0) { + return(LT_EOF); + } + return(LT_OK); +} + + +//bool CParser::check_key(const std::string::iterator ptr) +bool CParser::check_key(std::string::iterator begin, std::string::iterator end) +{ + static std::map s_keyword_map; + if (s_keyword_map.size() == 0) + { + s_keyword_map.insert(std::map::value_type("solution", KT_SOLUTION)); + s_keyword_map.insert(std::map::value_type("end", KT_END)); + } + + std::string lowercase; + copy_token(lowercase, begin, end); + std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(), tolower); + + m_next_keyword = KT_NONE; + std::map::iterator map_iter = s_keyword_map.find(lowercase); + if (map_iter == s_keyword_map.end()) + return false; + m_next_keyword = (*map_iter).second; + return true; +} + +CParser::STATUS_TYPE CParser::check_units(std::string& tot_units, bool alkalinity, bool check_compatibility, + const std::string& default_units, bool print) +{ +/* + * Check if legitimate units + * Input: + * tot_units character string to check, + * alkalinity true if alkalinity, false if any other total, + * check_compatibility true check alk and default units, false otherwise + * default_units character string of default units (check /L, /kg, etc) + * print true print warning messages + * Output: + * tot_units standard form for unit + */ + using utilities::str_tolower; + using utilities::replace; + using utilities::squeeze_white; + + static const char *units[] = { + "Mol/l", /* 0 */ + "mMol/l", /* 1 */ + "uMol/l", /* 2 */ + "g/l", /* 3 */ + "mg/l", /* 4 */ + "ug/l", /* 5 */ + "Mol/kgs", /* 6 */ + "mMol/kgs", /* 7 */ + "uMol/kgs", /* 8 */ + "g/kgs", /* 9 = ppt */ + "mg/kgs", /* 10 = ppm */ + "ug/kgs", /* 11 = ppb */ + "Mol/kgw", /* 12 = mol/kg H2O */ + "mMol/kgw", /* 13 = mmol/kg H2O */ + "uMol/kgw", /* 14 = umol/kg H2O */ + "g/kgw", /* 15 = mol/kg H2O */ + "mg/kgw", /* 16 = mmol/kg H2O */ + "ug/kgw", /* 17 = umol/kg H2O */ + "eq/l", /* 18 */ + "meq/l", /* 19 */ + "ueq/l", /* 20 */ + "eq/kgs", /* 21 */ + "meq/kgs", /* 22 */ + "ueq/kgs", /* 23 */ + "eq/kgw", /* 24 */ + "meq/kgw", /* 25 */ + "ueq/kgw", /* 26 */ + }; + + squeeze_white(tot_units); + str_tolower(tot_units); + replace("milli", "m", tot_units); + replace("micro", "u", tot_units); + replace("grams", "g", tot_units); + replace("gram", "g", tot_units); + replace("moles", "Mol", tot_units); + replace("mole", "Mol", tot_units); + replace("mol", "Mol", tot_units); + replace("liter", "l", tot_units); + replace("kgh", "kgw", tot_units); + replace("ppt", "g/kgs", tot_units); + replace("ppm", "mg/kgs", tot_units); + replace("ppb", "ug/kgs", tot_units); + replace("equivalents", "eq", tot_units); + replace("equivalent", "eq", tot_units); + replace("equiv", "eq", tot_units); + + std::string::size_type end; + if ((end = tot_units.find("/l")) != std::string::npos) { + tot_units.resize(end + 2); + } + if ((end = tot_units.find("/kgs")) != std::string::npos) { + tot_units.resize(end + 4); + } + if ((end = tot_units.find("/kgw")) != std::string::npos) { + tot_units.resize(end + 4); + } + + // + // Check if unit in list + // + bool found = false; + for (unsigned int i = 0; i < sizeof(units) / sizeof(char *); ++i) { + if (tot_units.compare(units[i]) == 0) { + found = true; + break; + } + } + if (!found) { + if (print) { + std::ostringstream err; + err << "Unknown unit, " << tot_units; + error_msg(err, OT_CONTINUE); + } + return ERROR; + } + + // + // Check if units are compatible with default_units + // + if (check_compatibility == false) return OK; + + // + // Special cases for alkalinity + // + if (alkalinity == true && tot_units.find("Mol") != std::string::npos) { + if (print) { + warning_msg("Alkalinity given in moles, assumed to be equivalents."); + } + replace("Mol", "eq", tot_units); + } + if (alkalinity == false && tot_units.find("eq") != std::string::npos) { + if (print) { + error_msg("Only alkalinity can be entered in equivalents.", OT_CONTINUE); + } + return ERROR; + } + + // + // See if default_units are compatible with tot_units + // + if (default_units.find("/l") != std::string::npos && tot_units.find("/l") != std::string::npos) return OK; + if (default_units.find("/kgs") != std::string::npos && tot_units.find("/kgs") != std::string::npos) return OK; + if (default_units.find("/kgw") != std::string::npos && tot_units.find("/kgw") != std::string::npos) return OK; + + std::string str = default_units; + replace("kgs", "kg solution", str); + replace("kgs", "kg solution", tot_units); + replace("kgw", "kg water", str); + replace("kgw", "kg water", tot_units); + replace("/l", "/L", str); + replace("Mol", "mol", str); + replace("/l", "/L", tot_units); + replace("Mol", "mol", tot_units); + + if (print) { + std::ostringstream err; + err << "Units for master species, " << tot_units << ", are not compatible with default units, " << str << "."; + error_msg(err, OT_CONTINUE); + } + return ERROR; +} + +CParser::TOKEN_TYPE CParser::token_type(const std::string& token) +{ + if (!token.empty()) { + if (::isupper(token[0])) { + return CParser::TT_UPPER; + } else if (::islower(token[0])) { + return CParser::TT_LOWER; + } else if (::isdigit(token[0]) || token[0] == '.' || token[0] == '-') { + return CParser::TT_DIGIT; + } else { + assert(!::isspace(token[0])); + return CParser::TT_UNKNOWN; + } + } + else { + return CParser::TT_EMPTY; + } +} + +CParser::TOKEN_TYPE CParser::peek_token() +{ + std::istringstream::pos_type pos = m_line_iss.tellg(); + std::string token; + m_line_iss >> token; + m_line_iss.seekg(pos); + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::string::iterator& begin, std::string::iterator& end) +{ + if (begin != end) + { + std::string::iterator b = begin; + for (; b < end && ::isspace(*b); ++b); + + begin = b; + for (; begin < end && !::isspace(*begin); ++begin); + + token.assign(b, begin); + } + else + { + token.resize(0); + } + + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::istream& is) +{ + is >> token; + return token_type(token); +} + +CParser::TOKEN_TYPE CParser::copy_token(std::string& token, std::istream::pos_type& pos) +{ + m_line_iss.seekg(pos); + // m_line_iss >> token; + if( !(m_line_iss >> token)) { + token.erase(token.begin(), token.end()); // token.clear(); + } + pos = m_line_iss.tellg(); + return token_type(token); +} + +CParser::FIND_TYPE CParser::find_option(const std::string& item, int *n, const std::vector& list, bool exact) +{ + std::string token(item); + std::transform(token.begin(), token.end(), token.begin(), tolower); + for (unsigned int i = 0; i < list.size(); i++) + { + if (exact == true) + { + if (list[i].compare(token) == 0) + { + *n = i; + return FT_OK; + } + } + else + { + if(list[i].find(token) == 0) + { + *n = i; + return FT_OK; + } + } + } + + *n = -1; + return FT_ERROR; +} + +// OPTION_TYPE get_option(const char **opt_list, int count_opt_list, char **next_char) +// OPTION_TYPE CParser::get_option(const std::vector& opt_list, std::string::iterator& next_char) +int CParser::get_option(const std::vector& opt_list, std::string::iterator& next_char) +{ + // + // Read a line and check for options + // + int j; + int /* opt_l, */ opt; + //char *opt_ptr; + std::string::iterator opt_ptr; + + // char option[MAX_LENGTH]; + std::string option; + + // + // Read line + // + LINE_TYPE lt = check_line("get_option", false, true, true, false); + if (lt == LT_EOF) + { + j = OPTION_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPTION_KEYWORD; + } + else if (lt == LT_OPTION) + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, false) == CParser::FT_OK) + { + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + next_char = opt_ptr; + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + //////std::istringstream err_msg; + //////err_msg << "Unknown option."; + //////err_msg << line_save; + //////error_msg(const std::string& msg, ONERROR_TYPE); + + // error_msg("Unknown option.", CONTINUE); + // error_msg(line_save, CONTINUE); + // input_error++; + std::cerr << "Unknown option." << "\n"; + std::cerr << m_line_save << "\n"; + + j = OPTION_ERROR; + next_char = m_line.begin(); + } + } + else + { + opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_char = opt_ptr; + } + else + { + j = OPTION_DEFAULT; + next_char = m_line.begin(); + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + std::cout << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} + +int CParser::get_option(const std::vector& opt_list, std::istream::pos_type& next_pos) +{ + // + // Read a line and check for options + // + int j; + int opt; + std::istream::pos_type pos_ptr; + std::string option; + + // + // Read line + // + LINE_TYPE lt = check_line("get_option", false, true, true, false); + if (lt == LT_EOF) + { + j = OPTION_EOF; + } + else if (lt == LT_KEYWORD) + { + j = OPTION_KEYWORD; + } + else if (lt == LT_OPTION) + { + std::string::iterator opt_ptr = m_line.begin(); + std::string::iterator end = m_line.end(); + copy_token(option, opt_ptr, end); + if (find_option(option.substr(1), &opt, opt_list, false) == FT_OK) + { + // replace -option with option + j = opt; + m_line_save.replace(m_line_save.find(option), option.size(), opt_list[opt]); + m_line.replace(m_line.find(option), option.size(), opt_list[opt]); + + // reset iss + m_line_iss.str(m_line); + m_line_iss.seekg(0, std::ios_base::beg); + m_line_iss.clear(); + + pos_ptr = 0; + copy_token(option, pos_ptr); + next_pos = pos_ptr; + //{{ + //// m_line_iss.clear(); + //}} + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + else + { + if (true) // (database_file == NULL) + { + get_output() << "\t" << m_line_save << "\n"; + } + error_msg("Unknown option.", OT_CONTINUE); + error_msg(m_line_save.c_str(), OT_CONTINUE); + incr_input_error(); + j = OPTION_ERROR; + next_pos = pos_ptr; + } + } + else + { + pos_ptr = 0; + copy_token(option, pos_ptr); + if (find_option(option, &opt, opt_list, true) == FT_OK) + { + j = opt; + next_pos = pos_ptr; + } + else + { + j = OPTION_DEFAULT; + next_pos = 0; + } + if (true) // pr.echo_input == TRUE + { + if (true) // database_file == NULL + { + get_output() << "\t" << m_line_save << "\n"; + } + } + } + return (j); +} + +int CParser::error_msg(const char *err_str, ONERROR_TYPE ot) +{ + m_error_stream << "ERROR: " << err_str << "\n"; + m_error_stream.flush(); + + m_output_stream << "ERROR: " << err_str << "\n"; + m_output_stream.flush(); + + if (ot == OT_STOP) + { + exit(1); + } + return 0; +} + +int CParser::warning_msg(const char *err_str) +{ + m_error_stream << "WARNING: " << err_str << "\n"; + m_error_stream.flush(); + + m_output_stream << "WARNING: " << err_str << "\n"; + m_output_stream.flush(); + + return 0; +} + +CParser::STATUS_TYPE CParser::get_elt(std::string::iterator& begin, const std::string::iterator end, std::string& element) +{ + element.erase(element.begin(), element.end()); // element.clear(); + + if (begin == end) { + error_msg("Empty string in get_elt. Expected an element name.", OT_CONTINUE); + return ERROR; + } + + // + // Load name into char array element + // + char c = *begin; + ++begin; + element.insert(element.end(), c); // element.push_back(c); + if (c == '[') { + while ( (c = *begin) != ']' ) { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if ( (c = *begin) == ']' ) { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + break; + } else if (begin == end) { + error_msg("No ending bracket (]) for element name", OT_CONTINUE); + incr_input_error(); + return ERROR; + } + } + while (::islower(c = *begin) || c == '_') { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if (begin == end) break; + } + } else { + while (::islower(c = *begin) || c == '_') { + element.insert(element.end(), c); // element.push_back(c); + ++begin; + if (begin == end) break; + } + } + return OK; +} + +CParser::STATUS_TYPE CParser::parse_couple(std::string& token) +{ + // Parse couple puts redox couples in standard form + // "+" is removed and couples are rewritten in sort + // order. + + if (utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0) { + utilities::str_tolower(token); + return OK; + } + + while ( utilities::replace("+", "", token) ); + + std::string::iterator ptr = token.begin(); + std::string elt1; + get_elt(ptr, token.end(), elt1); + + if (*ptr != '(') { + std::ostringstream err_msg; + err_msg << "Element name must be followed by " << + "parentheses in redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + incr_input_error(); + return ERROR; + } + + int paren_count = 1; + std::string paren1 = "("; + while ( ptr != token.end() ) { + ++ptr; + if (*ptr == '/' || ptr == token.end()) { + std::ostringstream err_msg; + err_msg << "End of line or ""/"" encountered before end of parentheses, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return ERROR; + } + paren1.insert(paren1.end(), *ptr); // element.push_back(c); + if (*ptr == '(') ++paren_count; + if (*ptr == ')') --paren_count; + if (paren_count == 0) break; + } + + ++ptr; + if (ptr == token.end() || *ptr != '/') { + std::ostringstream err_msg; + err_msg << " ""/"" must follow parentheses " << + "ending first half of redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + return ERROR; + } + ++ptr; + std::string elt2; + get_elt(ptr, token.end(), elt2); + if (elt1.compare(elt2) != 0) { + std::ostringstream err_msg; + err_msg << "Redox couple must be two redox states " << + "of the same element, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + return ERROR; + } + if (*ptr != '(') { + std::ostringstream err_msg; + err_msg << "Element name must be followed by " + "parentheses in redox couple, " << token << "."; + error_msg(err_msg, OT_CONTINUE); + incr_input_error(); + return ERROR; + } + std::string paren2 = "("; + paren_count = 1; + + while ( ptr != token.end() ) { + ++ptr; + if (*ptr == '/' || ptr == token.end()) { + std::ostringstream err_msg; + err_msg << "End of line or ""/"" encountered before end of parentheses, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return ERROR; + } + paren2.insert(paren2.end(), *ptr); // element.push_back(c); + if (*ptr == '(') ++paren_count; + if (*ptr == ')') --paren_count; + if (paren_count == 0) break; + } + if (paren1.compare(paren2) < 0) { + token = elt1 + paren1 + std::string("/") + elt2 + paren2; + } else if (paren1.compare(paren2) > 0) { + token = elt2 + paren2 + std::string("/") + elt1 + paren1; + } else { + std::ostringstream err_msg; + err_msg << "Both parts of redox couple are the same, " << + token << "."; + error_msg(err_msg, OT_CONTINUE); + return ERROR; + } + return OK; +} diff --git a/classes/Parser.h b/classes/Parser.h new file mode 100644 index 00000000..71281780 --- /dev/null +++ b/classes/Parser.h @@ -0,0 +1,196 @@ +#if !defined(PARSER_H_INCLUDED) +#define PARSER_H_INCLUDED + +#include // std::string +#include // std::vector +#include // std::istringstream std::ostringstream +#include // std::ostream +#include // std::istream + +class CParser +{ +public: + CParser(std::istream& input); + CParser(std::istream& input, std::ostream& output); + CParser(std::istream& input, std::ostream& output, std::ostream& error); + + virtual ~CParser(); + + enum LINE_TYPE { + LT_EOF = -1, + LT_OK = 1, + LT_EMPTY = 2, + LT_KEYWORD = 3, + LT_OPTION = 8 + }; + + enum TOKEN_TYPE { + TT_EMPTY = 2, + TT_UPPER = 4, + TT_LOWER = 5, + TT_DIGIT = 6, + TT_UNKNOWN = 7 + }; + + enum FIND_TYPE { + FT_OK = 0, + FT_ERROR = 1 + }; + + enum KEY_TYPE { + KT_NONE = -1, + KT_END = 0, + KT_EOF = 1, + KT_SOLUTION = 4 + }; + + enum OPTION_TYPE { + OPTION_DEFAULT = -4, + OPTION_ERROR = -3, + OPTION_KEYWORD = -2, + OPTION_EOF = -1 + }; + + enum ONERROR_TYPE { + OT_CONTINUE = 0, + OT_STOP = 1, + }; + + enum STATUS_TYPE { + ERROR = 0, + OK = 1 + }; + + /** + Function gets a new line and checks for empty, eof, and keywords. + + Arguments: + string Input, character string used in printing error message + allow_empty Input, True or false, if a blank line is accepable + if false, another line is read + allow_eof Input, True or false, if EOF is acceptable + allow_keyword Input, True or false, if a keyword is acceptable + + Returns: + LT_EMPTY if empty line read and allow_empty == true + LT_KEYWORD if line begins with keyword + LT_EOF if eof and allow_eof == true + LT_OK otherwise + LT_OPTION if line begins with -[alpha] + + Terminates if EOF and allow_eof == false. + */ + LINE_TYPE check_line(const std::string& str, bool allow_empty, bool allow_eof, bool allow_keyword, bool print); + + /** + Read a line from input file put in "line". + Copy of input line is stored in "line_save". + Characters after # are discarded in line but retained in "line_save" + + Arguments: + None + Returns: + LT_EMPTY, + LT_EOF, + LT_KEYWORD, + LT_OK, + LT_OPTION + */ + LINE_TYPE get_line(); + + // bool check_key(const std::string::iterator ptr); + bool check_key(std::string::iterator begin, std::string::iterator end); + + STATUS_TYPE check_units(std::string& tot_units, bool alkalinity, bool check_compatibility, + const std::string& default_units, bool print); + + + KEY_TYPE next_keyword()const { return m_next_keyword; } + int get_option(const std::vector& opt_list, std::string::iterator& next_char); + int get_option(const std::vector& opt_list, std::istream::pos_type& next_pos); + + + std::string& line() {return m_line;} + std::istringstream& get_iss() {return m_line_iss;} + int incr_input_error() {return ++m_input_error;} + std::ostream& get_output() {return m_output_stream;} + int get_input_error() {return m_input_error;} + + + /** + Copies from begin to token until first space is encountered. + + Arguments: + token output, the token + begin input, begin iterator + end input, end iterator + + Returns: + TT_EMPTY + TT_UPPER + TT_LOWER + TT_DIGIT + TT_UNKNOWN + */ + static TOKEN_TYPE copy_token(std::string& token, std::string::iterator& begin, std::string::iterator& end); + static TOKEN_TYPE token_type(const std::string& token); + static TOKEN_TYPE copy_token(std::string& token, std::istream& is); + TOKEN_TYPE copy_token(std::string& token, std::istream::pos_type& pos); + CParser::TOKEN_TYPE peek_token(); + + /** + Function reads an element name out of the equation string. + An element name is composed of a capital letter followed by any number + of lower case characters. + + Arguments: + begin input, points to position in the equation to begin + output, points to next character of equation after + element name. + end input, points to last position in the equation + element input pointer to place to return element character string + */ + STATUS_TYPE get_elt(std::string::iterator& begin, const std::string::iterator end, std::string& element); + + + /** + Compares a string value to match beginning letters of a list of options + + Arguments: + item entry: pointer to string to compare + n exit: item in list that was matched + list entry: pointer to list of character values, assumed to + be lower case + count_list entry: number of character values in list + + Returns: + OK item matched + ERROR item not matched + n -1 item not matched + i position of match in list + */ + static FIND_TYPE find_option(const std::string& item, int *n, const std::vector& list, bool exact); + + + int error_msg(const std::ostringstream& err_str, ONERROR_TYPE stop) {return error_msg(err_str.str().c_str(), stop);} + int error_msg(const char *err_str, ONERROR_TYPE stop); + int warning_msg(const char *err_str); + + + STATUS_TYPE parse_couple(std::string& token); + +protected: + LINE_TYPE get_logical_line(); + +private: + std::istream& m_input_stream; + std::ostream& m_output_stream; + std::ostream& m_error_stream; + int m_input_error; + KEY_TYPE m_next_keyword; + std::string m_line; + std::string m_line_save; + std::istringstream m_line_iss; +}; + +#endif // PARSER_H_INCLUDED diff --git a/classes/Pe_Data.cxx b/classes/Pe_Data.cxx new file mode 100644 index 00000000..1109971d --- /dev/null +++ b/classes/Pe_Data.cxx @@ -0,0 +1,45 @@ +#include "Pe_Data.h" +#include "Utilities.h" +#include // std::ostream + +CPe_Data::CPe_Data() +: name("") +{ +} + +CPe_Data::CPe_Data(const std::string& name) +: name(name) +{ +} + +CPe_Data::~CPe_Data() +{ +} + +int CPe_Data::store(std::vector& vec_pe_data, const std::string& token) +{ + unsigned int i = 0; + unsigned int size = vec_pe_data.size(); + for (; i < size; ++i) { + if (vec_pe_data[i].name.compare(token) == 0) + return i; + } + vec_pe_data.push_back(token); + return i; +} + +std::vector CPe_Data::alloc() +{ + std::vector vec; + vec.push_back(CPe_Data("pe")); + // TODO: see pe_data_alloc + return vec; +} + +void CPe_Data::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "" << this->name << "\n"; +} + diff --git a/classes/Pe_Data.h b/classes/Pe_Data.h new file mode 100644 index 00000000..263709ea --- /dev/null +++ b/classes/Pe_Data.h @@ -0,0 +1,27 @@ +#if !defined(PE_DATA_H_INCLUDED) +#define PE_DATA_H_INCLUDED + +#include +#include + +class CPe_Data +{ +public: + CPe_Data(); + CPe_Data(const std::string& name); + + ~CPe_Data(); + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + + std::string get_name()const {return this->name;}; + void set_name(std::string name) {this->name = name;}; + + static int store(std::vector& vec, const std::string& token); + static std::vector CPe_Data::alloc(); + +private: + std::string name; +}; + +#endif // PE_DATA_H_INCLUDED diff --git a/classes/Solution.cxx b/classes/Solution.cxx new file mode 100644 index 00000000..429168d6 --- /dev/null +++ b/classes/Solution.cxx @@ -0,0 +1,312 @@ +// Solution.cxx: implementation of the CSolutionxx class. +// +////////////////////////////////////////////////////////////////////// + +#include "Solution.h" + +#include // assert +#include // std::sort + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +//static std::map ss_map; +//std::map& CSolution::s_map = ss_map; + +CSolution::CSolution() +: CNumKeyword() +, units("mMol/kgw") +, pe(CPe_Data::alloc()) +{ + ph = 7.0; + tc = 25.0; + density = 1.0; + + solution_pe = 4.0; + mu = 1e-7; + ah2o = 1.0; + mass_water = 1.0; + default_pe = -1; +} + +CSolution::~CSolution() +{ +} +#ifdef SKIP +CSolution& CSolution::read(CParser& parser) +{ + static std::vector vopts; + if (vopts.empty()) { + vopts.reserve(11); + vopts.push_back("temp"); // 0 + vopts.push_back("temperature"); // 1 + vopts.push_back("dens"); // 2 + vopts.push_back("density"); // 3 + vopts.push_back("units"); // 4 + vopts.push_back("redox"); // 5 + vopts.push_back("ph"); // 6 + vopts.push_back("pe"); // 7 + vopts.push_back("unit"); // 8 + vopts.push_back("isotope"); // 9 + vopts.push_back("water"); // 10 + } + // const int count_opt_list = vopts.size(); + + CSolution numkey; + + // Read solution number and description + numkey.read_number_description(parser); + + // Malloc space for solution data + //// g_solution_map[numkey.n_user()] = numkey; + s_map[numkey.n_user()] = numkey; + + std::istream::pos_type ptr; + std::istream::pos_type next_char; + std::string token; + CParser::TOKEN_TYPE j; + + CSolution& sol = s_map[numkey.n_user()]; + int default_pe = 0; + + for (;;) + { + int opt = parser.get_option(vopts, next_char); + if (opt == CParser::OPTION_DEFAULT) + { + ptr = next_char; + if (parser.copy_token(token, ptr) == CParser::TT_DIGIT) { + opt = 9; + } + } + + switch (opt) + { + case CParser::OPTION_EOF: + break; + case CParser::OPTION_KEYWORD: + break; + case CParser::OPTION_ERROR: + opt = CParser::OPTION_EOF; + parser.error_msg("Unknown input in SOLUTION keyword.", CParser::OT_CONTINUE); + parser.error_msg(parser.line().c_str(), CParser::OT_CONTINUE); + break; + + case 0: // temp + case 1: // temperature + if (!(parser.get_iss() >> sol.tc)) + { + sol.tc = 25; + } + break; + + case 2: // dens + case 3: // density + parser.get_iss() >> sol.density; + break; + + case 4: // units + case 8: // unit + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.check_units(token, false, false, sol.units, true) == CParser::OK) { + sol.units = token; + } else { + parser.incr_input_error(); + } + break; + + case 5: // redox + if (parser.copy_token(token, next_char) == CParser::TT_EMPTY) break; + if (parser.parse_couple(token) == CParser::OK) { + default_pe = CPe_Data::store(sol.pe, token); + } else { + parser.incr_input_error(); + } + break; + + case 6: // ph + { + CConc conc; + if (conc.read(parser, sol) == CConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.ph = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("H(1)"); + sol.add(conc); + } + break; + + case 7: // pe + { + CConc conc; + if (conc.read(parser, sol) == CConc::ERROR) { + parser.incr_input_error(); + break; + } + sol.solution_pe = conc.get_input_conc(); + if (conc.get_equation_name().empty()) { + break; + } + conc.set_description("E"); + sol.add(conc); + } + break; + + case 9: // isotope + { + CIsotope isotope; + if (isotope.read(parser) == CIsotope::OK) { + sol.add(isotope); + } + } + break; + + case 10: // water + j = parser.copy_token(token, next_char); + if (j == CParser::TT_EMPTY) { + sol.mass_water = 1.0; + } else if (j != CParser::TT_DIGIT) { + parser.incr_input_error(); + parser.error_msg("Expected numeric value for mass of water in solution.", CParser::OT_CONTINUE); + } else { + std::istringstream(token) >> sol.mass_water; + } + break; + + case CParser::OPTION_DEFAULT: + { + // Read concentration + CConc conc; + if (conc.read(parser, sol) == CConc::ERROR) { + parser.incr_input_error(); + } else { + sol.add(conc); + } + } + break; + } + if (opt == CParser::OPTION_EOF || opt == CParser::OPTION_KEYWORD) break; + } +#ifdef SKIP + // + // Sort totals by description + // + std::sort(sol.totals.begin(), sol.totals.end()); +#endif + + // + // fix up default units and default pe + // + std::string token1; + std::vector::iterator iter = sol.totals.begin(); + for (; iter != sol.totals.end(); ++iter) + { + token = (*iter).get_description(); + Utilities::str_tolower(token); + if ((*iter).get_units().empty()) { + (*iter).set_units(sol.units); + } else { + bool alk = false; + if (token.find("alk") == 0) alk = true; + token1 = (*iter).get_units(); + if (parser.check_units(token1, alk, true, sol.get_units(), true) == CParser::ERROR) { + parser.incr_input_error(); + } else { + (*iter).set_units(token1); + } + } + if ((*iter).get_n_pe() < 0) { + (*iter).set_n_pe(default_pe); + } + } + sol.default_pe = default_pe; + return sol; +} +#endif +void CSolution::dump_xml(std::ostream& os, unsigned int indent)const +{ + unsigned int i; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "\n"; + + CNumKeyword::dump_xml(os, indent); + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_tc() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_ph() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_solution_pe() << "" << "\n"; + + assert(this->pe.size() > 0); + assert(this->default_pe >= 0); + assert(this->pe.size() > (unsigned int) this->default_pe); + this->pe[this->default_pe].dump_xml(os, indent + 1); + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_units() << "" << "\n"; + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_density() << "" << "\n"; + + // foreach conc + if (!this->totals.empty()) + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + + std::vector::const_iterator iter = this->totals.begin(); + for(; iter != this->totals.end(); ++iter) + { + (*iter).dump_xml(*this, os, indent + 2); + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + } + + // foreach isotope + if (!this->isotopes.empty()) + { + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + + std::list::const_iterator iter = this->isotopes.begin(); + for(; iter != this->isotopes.end(); ++iter) + { + (*iter).dump_xml(os, indent + 2); + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "\n"; + } + + for(i = 0; i < indent + 1; ++i) os << Utilities::INDENT; + os << "" << this->get_mass_water() << "" << "\n"; + + for(i = 0; i < indent; ++i) os << Utilities::INDENT; + os << "" << "\n"; +} + + + + + + + + + + + + + + + diff --git a/classes/Solution.h b/classes/Solution.h new file mode 100644 index 00000000..012977b9 --- /dev/null +++ b/classes/Solution.h @@ -0,0 +1,72 @@ +#if !defined(SOLUTION_H_INCLUDED) +#define SOLUTION_H_INCLUDED + +#include "NumKeyword.h" +#include "Parser.h" +#include "Conc.h" +#include "Isotope.h" +#include "Pe_Data.h" +#include // assert +#include // std::map +#include // std::string +#include // std::list +#include // std::vector + + +class CSolution : public CNumKeyword +{ +public: + CSolution(); + ~CSolution(); + + static CSolution& read(CParser& parser); + + void add(CConc conc) { this->totals.push_back(conc); } + void add(CIsotope isotope) { this->isotopes.push_back(isotope); } + + double get_ph()const {return this->ph;} + void set_ph(double pH) {this->ph = pH;} + + double get_solution_pe()const {return this->solution_pe;} + void set_solution_pe(double solution_pe) {this->solution_pe = solution_pe;} + + double get_tc()const {return this->tc;} + void set_tc(double tc) {this->tc = tc;} + + double get_density()const {return this->density;} + void set_density(double density) {this->density = density;} + + std::string get_units()const {return this->units;} + void set_units(std::string units) {this->units = units;} + + std::string get_redox()const {return this->pe[this->default_pe].get_name();} + + long double get_mass_water()const {return this->mass_water;}; + void set_mass_water(long double mass_water) {this->mass_water = mass_water;}; + + void dump_xml(std::ostream& os, unsigned int indent = 0)const; + +protected: + friend class CConc; // for this->pe access + double ph; + double tc; + double solution_pe; + double mu; + double ah2o; + double density; + long double mass_water; + std::string units; + + + std::vector totals; /// std::set m_totals; ////std::list m_totals; + std::vector pe; + int default_pe; + + std::list isotopes; + +public: + static std::map& map; + +}; + +#endif // !defined(SOLUTION_H_INCLUDED) diff --git a/classes/TestCIsotope.cxx b/classes/TestCIsotope.cxx new file mode 100644 index 00000000..27f0828e --- /dev/null +++ b/classes/TestCIsotope.cxx @@ -0,0 +1,164 @@ +#include "TestCIsotope.h" +#include "Parser.h" +#include "utilities.h" + +TestCIsotope::TestCIsotope() +{ +} + +TestCIsotope::~TestCIsotope() +{ +} + +void TestCIsotope::test_read_1() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("-isotope"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expected isotope name to begin with an isotopic number.\n") == 0); +} + +void TestCIsotope::test_read_2() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("-isotope C"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expected isotope name to begin with an isotopic number.\n") == 0); +} + +void TestCIsotope::test_read_3() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expecting element name.\nERROR: isotope 13\n") == 0); +} + +void TestCIsotope::test_read_4() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13C"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expected numeric value for isotope ratio.\n") == 0); +} + +void TestCIsotope::test_read_5() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13C -"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expected numeric value for isotope ratio.\n") == 0); +} + +void TestCIsotope::test_read_6() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13C -12."); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::OK); + CPPUNIT_ASSERT(oss_err.str().empty()); + + CPPUNIT_ASSERT(iso.get_name().compare("13C") == 0); + CPPUNIT_ASSERT(iso.get_ratio() == -12.0); + CPPUNIT_ASSERT(!iso.get_ratio_uncertainty_defined()); +} + +void TestCIsotope::test_read_7() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13C -12. a"); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: Expected numeric value for uncertainty in isotope ratio.\n") == 0); +} + +void TestCIsotope::test_read_8() +{ + CIsotope iso; + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream::pos_type next_pos; + std::vector opt_list; + + std::istringstream iss_in("isotope 13C -12. 1."); + + CParser parser(iss_in, oss_out, oss_err); + opt_list.push_back("isotope"); + + CPPUNIT_ASSERT(parser.get_option(opt_list, next_pos) == 0); + CPPUNIT_ASSERT(iso.read(parser) == CIsotope::OK); + CPPUNIT_ASSERT(oss_err.str().empty()); + + CPPUNIT_ASSERT(iso.get_name().compare("13C") == 0); + CPPUNIT_ASSERT(iso.get_ratio() == -12.0); + CPPUNIT_ASSERT(iso.get_ratio_uncertainty() == 1.0); + CPPUNIT_ASSERT(iso.get_ratio_uncertainty_defined()); +} diff --git a/classes/TestCIsotope.h b/classes/TestCIsotope.h new file mode 100644 index 00000000..97cdaebc --- /dev/null +++ b/classes/TestCIsotope.h @@ -0,0 +1,39 @@ +#if !defined(TESTCISOTOPE_H_INCLUDED) +#define TESTCISOTOPE_H_INCLUDED + +#include "Isotope.h" +#include +#include + + +class TestCIsotope : + public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( TestCIsotope ); + CPPUNIT_TEST( test_read_1 ); + CPPUNIT_TEST( test_read_2 ); + CPPUNIT_TEST( test_read_3 ); + CPPUNIT_TEST( test_read_4 ); + CPPUNIT_TEST( test_read_5 ); + CPPUNIT_TEST( test_read_6 ); + CPPUNIT_TEST( test_read_7 ); + CPPUNIT_TEST( test_read_8 ); + CPPUNIT_TEST_SUITE_END(); + +public: + TestCIsotope(void); + ~TestCIsotope(void); + +public: + // read + void test_read_1(); + void test_read_2(); + void test_read_3(); + void test_read_4(); + void test_read_5(); + void test_read_6(); + void test_read_7(); + void test_read_8(); +}; + +#endif // TESTCISOTOPE_H_INCLUDED diff --git a/classes/TestCParser.cxx b/classes/TestCParser.cxx new file mode 100644 index 00000000..4c3de473 --- /dev/null +++ b/classes/TestCParser.cxx @@ -0,0 +1,192 @@ +#include "TestCParser.h" +#include "Parser.h" + +TestCParser::TestCParser(void) +{ +} + +TestCParser::~TestCParser(void) +{ +} + +void TestCParser::testEmptyInput() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in(""); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); +} + +void TestCParser::testCommentOnlyInput() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("#this is a comment"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); +} + +void TestCParser::testLineContinuation() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("Line \\\n1"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_OK); + CPPUNIT_ASSERT(parser.line().compare("Line 1") == 0); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_EOF); + CPPUNIT_ASSERT(parser.line().compare("") == 0); +} + +void TestCParser::testMultipleLineContinuation() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("Line \\\n\\\n\\\n\\\n1"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_OK); + CPPUNIT_ASSERT(parser.line().compare("Line 1") == 0); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_EOF); + CPPUNIT_ASSERT(parser.line().compare("") == 0); +} + +void TestCParser::testLogicalLineSeparator() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("Line 1;Line 2"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_OK); + CPPUNIT_ASSERT(parser.line().compare("Line 1") == 0); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_OK); + CPPUNIT_ASSERT(parser.line().compare("Line 2") == 0); + + CPPUNIT_ASSERT(parser.get_line() == CParser::LT_EOF); + CPPUNIT_ASSERT(parser.line().compare("") == 0); +} + +void TestCParser::test_check_line_1() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("SOLUTION"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_KEYWORD); + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); + CPPUNIT_ASSERT(oss_out.str().compare("\tSOLUTION\n") == 0); +} + +void TestCParser::test_check_line_2() +{ + std::ostringstream oss_out; + std::ostringstream oss_err; + std::istringstream iss_in("NOT_A_KEYWORD"); + + CParser parser(iss_in, oss_out, oss_err); + + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_OK); + CPPUNIT_ASSERT(parser.check_line("", false, true, true, true) == CParser::LT_EOF); +} + +void TestCParser::test_get_elt_1() +{ + std::istringstream iss_in; + std::ostringstream oss_out; + std::ostringstream oss_err; + + std::string token(""); + CParser parser(iss_in, oss_out, oss_err); + std::string::iterator begin = token.begin(); + std::string element; + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::ERROR); + CPPUNIT_ASSERT(element.empty()); +} + +void TestCParser::test_get_elt_2() +{ + std::istringstream iss_in; + std::ostringstream oss_out; + std::ostringstream oss_err; + + std::string token("Ca"); + CParser parser(iss_in, oss_out, oss_err); + std::string::iterator begin = token.begin(); + std::string element; + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::OK); + CPPUNIT_ASSERT(element.compare("Ca") == 0); + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::ERROR); +} + +void TestCParser::test_get_elt_3() +{ + std::istringstream iss_in; + std::ostringstream oss_out; + std::ostringstream oss_err; + + std::string token("CaCO3"); + CParser parser(iss_in, oss_out, oss_err); + std::string::iterator begin = token.begin(); + std::string element; + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::OK); + CPPUNIT_ASSERT(element.compare("Ca") == 0); + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::OK); + CPPUNIT_ASSERT(element.compare("C") == 0); + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::OK); + CPPUNIT_ASSERT(element.compare("O") == 0); +} + +void TestCParser::test_get_elt_4() +{ + std::istringstream iss_in; + std::ostringstream oss_out; + std::ostringstream oss_err; + + std::string token("[18O]"); + CParser parser(iss_in, oss_out, oss_err); + std::string::iterator begin = token.begin(); + std::string element; + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::OK); + CPPUNIT_ASSERT(element.compare("[18O]") == 0); + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::ERROR); +} + +void TestCParser::test_get_elt_5() +{ + std::istringstream iss_in; + std::ostringstream oss_out; + std::ostringstream oss_err; + + std::string token("[18O"); + CParser parser(iss_in, oss_out, oss_err); + std::string::iterator begin = token.begin(); + std::string element; + + CPPUNIT_ASSERT(parser.get_elt(begin, token.end(), element) == CParser::ERROR); + CPPUNIT_ASSERT(oss_err.str().compare("ERROR: No ending bracket (]) for element name\n") == 0); +} diff --git a/classes/TestCParser.h b/classes/TestCParser.h new file mode 100644 index 00000000..315f0428 --- /dev/null +++ b/classes/TestCParser.h @@ -0,0 +1,48 @@ +#if !defined(TESTCPARSER_H_INCLUDED) +#define TESTCPARSER_H_INCLUDED + +#include +#include + +class TestCParser : + public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( TestCParser ); + CPPUNIT_TEST( testEmptyInput ); + CPPUNIT_TEST( testCommentOnlyInput ); + CPPUNIT_TEST( testLineContinuation ); + CPPUNIT_TEST( testMultipleLineContinuation ); + CPPUNIT_TEST( testLogicalLineSeparator ); + CPPUNIT_TEST( test_check_line_1 ); + CPPUNIT_TEST( test_check_line_2 ); + CPPUNIT_TEST( test_get_elt_1 ); + CPPUNIT_TEST( test_get_elt_2 ); + CPPUNIT_TEST( test_get_elt_3 ); + CPPUNIT_TEST( test_get_elt_4 ); + CPPUNIT_TEST( test_get_elt_5 ); + CPPUNIT_TEST_SUITE_END(); + +public: + TestCParser(void); + ~TestCParser(void); + +public: + void testEmptyInput(); + void testCommentOnlyInput(); + void testLineContinuation(); + void testMultipleLineContinuation(); + void testLogicalLineSeparator(); + + // check_line + void test_check_line_1(); + void test_check_line_2(); + + // get_elt + void test_get_elt_1(); + void test_get_elt_2(); + void test_get_elt_3(); + void test_get_elt_4(); + void test_get_elt_5(); + +}; +#endif // TESTCPARSER_H_INCLUDED diff --git a/classes/TestCSolution.cxx b/classes/TestCSolution.cxx new file mode 100644 index 00000000..cd30e0a8 --- /dev/null +++ b/classes/TestCSolution.cxx @@ -0,0 +1,124 @@ +#include "TestCSolution.h" +#include "Solution.h" +#include "Parser.h" +#include "utilities.h" +#include // std::cout std::cerr + +TestCSolution::TestCSolution() +{ +} + +TestCSolution::~TestCSolution() +{ +} + +CParser::LINE_TYPE read_input(CParser& parser) +{ + CParser::LINE_TYPE i; + while ((i = parser.check_line("Subroutine Read", false, true, true, true)) != CParser::LT_KEYWORD) + { + if (i == CParser::LT_EOF) return CParser::LT_EOF; + } + + for (;;) { + switch(parser.next_keyword()) + { + case CParser::KT_END: + case CParser::KT_EOF: + case CParser::KT_NONE: + goto END_OF_SIMULATION_INPUT; + break; + + case CParser::KT_SOLUTION: + CSolution::read(parser); + break; + + default: + break; + } + } + +END_OF_SIMULATION_INPUT: + return CParser::LT_OK; +} + +void TestCSolution::test_read_ex1() +{ + CPPUNIT_ASSERT(CSolution::s_map.find(1) == CSolution::s_map.end()); + std::string input = + "SOLUTION 1 SEAWATER FROM NORDSTROM ET AL. (1979)\n" + " units ppm\n" + " pH 8.22\n" + " pe 8.451\n" + " density 1.023\n" + " temp 25.0\n" + " redox O(0)/O(-2)\n" + " Ca 412.3\n" + " Mg 1291.8\n" + " Na 10768.0\n" + " K 399.1\n" + " Fe 0.002\n" + " Mn 0.0002 pe\n" + " Si 4.28\n" + " Cl 19353.0\n" + " Alkalinity 141.682 as HCO3\n" + " S(6) 2712.0\n" + " N(5) 0.29 gfw 62.0\n" + " N(-3) 0.03 as NH4\n" + " U 3.3 ppb N(5)/N(-3)\n" + " O(0) 1.0 O2(g) -0.7\n" + ; + + // setup parser + std::istringstream iss_in(input); + std::ostringstream oss_out; + std::ostringstream oss_err; + CParser parser(iss_in, oss_out, oss_err); + for (int simulation = 1; ; ++simulation) { + if (read_input(parser) == CParser::LT_EOF) break; + } + CPPUNIT_ASSERT(parser.get_input_error() == 0); + CPPUNIT_ASSERT(CSolution::s_map.size() == 1); + CPPUNIT_ASSERT(CSolution::s_map.find(1) != CSolution::s_map.end()); + + CPPUNIT_ASSERT(CSolution::s_map[1].get_units().compare("mg/kgs") == 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.22, CSolution::s_map[1].get_ph(), 0.005); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.451, CSolution::s_map[1].get_solution_pe(), 0.0005); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.023, CSolution::s_map[1].get_density(), 0.0005); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.0, CSolution::s_map[1].get_tc(), 0.5); + CPPUNIT_ASSERT(CSolution::s_map[1].get_redox().compare("O(-2)/O(0)") == 0); + + // empty map for subsequent tests + CSolution::s_map.erase(CSolution::s_map.begin(), CSolution::s_map.end()); +} + +void TestCSolution::test_read_ex7() +{ + CPPUNIT_ASSERT(CSolution::s_map.find(1) == CSolution::s_map.end()); + std::string input = + "SOLUTION 1\n" + ; + + // setup parser + std::istringstream iss_in(input); + std::ostringstream oss_out; + std::ostringstream oss_err; + CParser parser(iss_in, oss_out, oss_err); + for (int simulation = 1; ; ++simulation) { + if (read_input(parser) == CParser::LT_EOF) break; + } + CPPUNIT_ASSERT(parser.get_input_error() == 0); + CPPUNIT_ASSERT(CSolution::s_map.size() == 1); + CPPUNIT_ASSERT(CSolution::s_map.find(1) != CSolution::s_map.end()); + + CPPUNIT_ASSERT(CSolution::s_map[1].get_units().compare("mMol/kgw") == 0); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.0, CSolution::s_map[1].get_ph(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, CSolution::s_map[1].get_solution_pe(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, CSolution::s_map[1].get_density(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.0, CSolution::s_map[1].get_tc(), 0.5); + CPPUNIT_ASSERT(CSolution::s_map[1].get_redox().compare("pe") == 0); + + // empty map for subsequent tests + CSolution::s_map.erase(CSolution::s_map.begin(), CSolution::s_map.end()); +} diff --git a/classes/TestCSolution.h b/classes/TestCSolution.h new file mode 100644 index 00000000..8bb8f3cb --- /dev/null +++ b/classes/TestCSolution.h @@ -0,0 +1,24 @@ +#if !defined(TESTCSOLUTION_H_INCLUDED) +#define TESTCSOLUTION_H_INCLUDED + +#include +#include + +class TestCSolution : + public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( TestCSolution ); + CPPUNIT_TEST( test_read_ex1 ); + CPPUNIT_TEST( test_read_ex7 ); + CPPUNIT_TEST_SUITE_END(); + +public: + TestCSolution(void); + ~TestCSolution(void); + +public: + void test_read_ex1(); + void test_read_ex7(); + +}; +#endif // TESTCSOLUTION_H_INCLUDED diff --git a/classes/main.cxx b/classes/main.cxx new file mode 100644 index 00000000..81acf510 --- /dev/null +++ b/classes/main.cxx @@ -0,0 +1,83 @@ +#include // std::cout std::cerr +#include // std::string +#include // std::vector +#include // std::map + +#include "Parser.h" +#include "Solution.h" + +CParser::LINE_TYPE read_input(CParser& parser) +{ + CParser::LINE_TYPE i; + while ((i = parser.check_line("Subroutine Read", false, true, true, true)) != CParser::LT_KEYWORD) + { + if (i == CParser::LT_EOF) return CParser::LT_EOF; + } + + for (;;) { + switch(parser.next_keyword()) + { + case CParser::KT_END: + case CParser::KT_EOF: + case CParser::KT_NONE: + goto END_OF_SIMULATION_INPUT; + break; + + case CParser::KT_SOLUTION: + CSolution::read(parser); + break; + + default: + break; + } + } + +END_OF_SIMULATION_INPUT: + return CParser::LT_OK; +} + +int main(void) +{ + std::string input = + "SOLUTION 25 Test solution number 25\n" + " temp 25.0 \n" + " pH 7.0 charge \n" + " pe 4.5 \n" + " redox O(-2)/O(0) \n" + " units ppm \n" + " density 1.02 \n" + " Ca 80. \n" + " S(6) 96. as SO4 \n" + " S(-2) 1. as S \n" + " N(5) N(3) 14. as N \n" + " O(0) 8.0 \n" + " C 61.0 as HCO3 CO2(g) -3.5 \n" + " Fe 55. ug/kgs as Fe S(6)/S(-2) Pyrite \n" + " -isotope 13C -12. 1. # permil PDB \n" + " -isotope 34S 15. 1.5 # permil CDT \n" + " -water 0.5 # kg \n" + ; + + // setup parser + std::istringstream iss_in(input); + std::ostringstream oss_out; + std::ostringstream oss_err; + CParser parser(iss_in, oss_out, oss_err); + for (int simulation = 1; ; ++simulation) { + if (read_input(parser) == CParser::LT_EOF) break; + } + + // dump solutions as xml string + std::ostringstream oss_tmp; + std::map::const_iterator it = CSolution::s_map.begin(); + for (; it != CSolution::s_map.end(); ++it) + { + (*it).second.dump_xml(oss_tmp); + } + oss_tmp << "\n"; + + // output xml string + std::cout << oss_tmp.str(); + + return 0; +} diff --git a/classes/test.cxx b/classes/test.cxx new file mode 100644 index 00000000..9046a76f --- /dev/null +++ b/classes/test.cxx @@ -0,0 +1,23 @@ +#include +#include + +#include "TestCParser.h" +#include "TestCIsotope.h" +#include "TestCSolution.h" + +int main(int argc, char **argv) +{ + CppUnit::TextUi::TestRunner runner; + + runner.addTest(TestCParser::suite()); + runner.addTest(TestCIsotope::suite()); + runner.addTest(TestCSolution::suite()); + + runner.setOutputter( + CppUnit::CompilerOutputter::defaultOutputter(&runner.result(), std::cout) + ); + + bool wasSucessful = runner.run("", false); + return wasSucessful; +} + diff --git a/classes/utilities.cxx b/classes/utilities.cxx new file mode 100644 index 00000000..0a13b46d --- /dev/null +++ b/classes/utilities.cxx @@ -0,0 +1,68 @@ +#include // ::tolower +#include // ::tolower +#include //std::transform + +#include "utilities.h" +#include "Parser.h" + +//////////////////////////////////////////////////////////////////////////// +int utilities::strcmp_nocase_arg1(const char *str1, const char *str2) +//////////////////////////////////////////////////////////////////////////// +{ + // + // Compare two strings disregarding case + // + int c1, c2; + while ((c1 = ::tolower(*str1++)) == (c2 = *str2++)) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} + +//////////////////////////////////////////////////////////////////////////// +int utilities::strcmp_nocase(const char *str1, const char *str2) +//////////////////////////////////////////////////////////////////////////// +{ + // + // Compare two strings disregarding case + // + int c1, c2; + while ((c1 = ::tolower(*str1++)) == (c2 = ::tolower(*str2++))) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} + +//////////////////////////////////////////////////////////////////////////// +void utilities::str_tolower(std::string& str) +//////////////////////////////////////////////////////////////////////////// +{ + std::transform(str.begin(), str.end(), str.begin(), tolower); +} + + + +//////////////////////////////////////////////////////////////////////////// +bool utilities::replace(const char* str1, const char* str2, std::string& str) +//////////////////////////////////////////////////////////////////////////// +{ + std::string::size_type n = str.find(str1, 0); + if (n == std::string::npos) return false; + + str.replace(n, ::strlen(str1), str2); + return true; +} + +//////////////////////////////////////////////////////////////////////////// +void utilities::squeeze_white(std::string& s_l) +//////////////////////////////////////////////////////////////////////////// +{ + std::string str; + std::string::iterator beg = s_l.begin(); + std::string::iterator end = s_l.end(); + CParser::copy_token(str, beg, end); + s_l = str; +} + diff --git a/classes/utilities.h b/classes/utilities.h new file mode 100644 index 00000000..f4580d9d --- /dev/null +++ b/classes/utilities.h @@ -0,0 +1,28 @@ +#if !defined(UTILITIES_H_INCLUDED) +#define UTILITIES_H_INCLUDED + +#include + +namespace utilities { + + const char INDENT[] = " "; + + enum STATUS_TYPE { + OK = 0, + ERROR = 1 + }; + + STATUS_TYPE parse_couple(std::string& token); + + int strcmp_nocase(const char *str1, const char *str2); + + int strcmp_nocase_arg1(const char *str1, const char *str2); + + void str_tolower(std::string& str); + + bool replace(const char* str1, const char* str2, std::string& str); + + void squeeze_white(std::string& s_l); +} + +#endif // UTILITIES_H_INCLUDED diff --git a/cpp.dsw b/cpp.dsw new file mode 100644 index 00000000..fd89dcc2 --- /dev/null +++ b/cpp.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cpp"=.\cpp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/cvdense.cpp b/cvdense.cpp new file mode 100644 index 00000000..62538545 --- /dev/null +++ b/cvdense.cpp @@ -0,0 +1,473 @@ +/******************************************************************* + * * + * File : cvdense.c * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * Radu Serban @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/cvode/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for the CVODE dense linear * + * solver, CVDENSE. * + * * + *******************************************************************/ + + +#include +#include +#include +#include "cvdense.h" +#include "cvode.h" +#include "dense.h" +#include "sundialstypes.h" +#include "nvector.h" +#include "sundialsmath.h" +#include "output.h" +#include "phqalloc.h" +/* WARNING don't include any headers below here */ +#define malloc PHRQ_malloc + +static char const svnid[] = "$Id: cvdense.c 78 2005-02-01 22:47:12Z dlpark $"; + +/* Error Messages */ + +#define CVDENSE "CVDense/CVReInitDense-- " + +#define MSG_CVMEM_NULL CVDENSE "CVode Memory is NULL.\n\n" + +#define MSG_MEM_FAIL CVDENSE "A memory request failed.\n\n" + +#define MSG_WRONG_NVEC CVDENSE "Incompatible NVECTOR implementation.\n\n" + +/* Other Constants */ + +#define MIN_INC_MULT RCONST(1000.0) +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) +#define TWO RCONST(2.0) + + +/****************************************************************** + * * + * Types : CVDenseMemRec, CVDenseMem * + *----------------------------------------------------------------* + * The type CVDenseMem is pointer to a CVDenseMemRec. This * + * structure contains CVDense solver-specific data. * + * * + ******************************************************************/ + +typedef struct { + + CVDenseJacFn d_jac; /* jac = Jacobian routine to be called */ + + DenseMat d_M; /* M = I - gamma J, gamma = h / l1 */ + + integertype *d_pivots; /* pivots = pivot array for PM = LU */ + + DenseMat d_savedJ; /* savedJ = old Jacobian */ + + long int d_nstlj; /* nstlj = nst at last Jacobian eval. */ + + long int d_nje; /* nje = no. of calls to jac */ + + void *d_J_data; /* J_data is passed to jac */ + +} CVDenseMemRec, *CVDenseMem; + + +/* CVDENSE linit, lsetup, lsolve, lfree, and DQJac routines */ + +static int CVDenseInit(CVodeMem cv_mem); + +static int CVDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + +static int CVDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + +static void CVDenseFree(CVodeMem cv_mem); + +static void CVDenseDQJac(integertype N, DenseMat J, RhsFn f, void *f_data, + realtype t, N_Vector y, N_Vector fy, N_Vector ewt, + realtype h, realtype uround, void *jac_data, + long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + +/*************** CVDenseDQJac **************************************** + + This routine generates a dense difference quotient approximation to + the Jacobian of f(t,y). It assumes that a dense matrix of type + DenseMat is stored column-wise, and that elements within each column + are contiguous. The address of the jth column of J is obtained via + the macro DENSE_COL and an N_Vector with the jth column as the + component array is created using N_VMake and N_VSetData. Finally, the + actual computation of the jth column of the Jacobian is done with a + call to N_VLinearSum. + +**********************************************************************/ + +static void CVDenseDQJac(integertype N, DenseMat J, RhsFn f, void *f_data, + realtype tn, N_Vector y, N_Vector fy, N_Vector ewt, + realtype h, realtype uround, void *jac_data, + long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + realtype fnorm, minInc, inc, inc_inv, yjsaved, srur; + realtype *y_data, *ewt_data; + N_Vector ftemp, jthCol; + M_Env machEnv; + integertype j; + + if (svnid == NULL) fprintf(stderr," "); + machEnv = y->menv; /* Get machine environment */ + + ftemp = vtemp1; /* Rename work vector for use as f vector value */ + + /* Obtain pointers to the data for ewt, y */ + ewt_data = N_VGetData(ewt); + y_data = N_VGetData(y); + + /* Set minimum increment based on uround and norm of f */ + srur = RSqrt(uround); + fnorm = N_VWrmsNorm(fy, ewt); + minInc = (fnorm != ZERO) ? + (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; + + jthCol = N_VMake(N, y_data, machEnv); /* j loop overwrites this data address */ + + /* This is the only for loop for 0..N-1 in CVODE */ + for (j = 0; j < N; j++) { + + /* Generate the jth col of J(tn,y) */ + + N_VSetData(DENSE_COL(J,j), jthCol); + yjsaved = y_data[j]; + inc = MAX(srur*ABS(yjsaved), minInc/ewt_data[j]); + y_data[j] += inc; + f(N, tn, y, ftemp, f_data); + inc_inv = ONE/inc; + N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol); + y_data[j] = yjsaved; + } + + N_VDispose(jthCol); + + /* Increment counter nfe = *nfePtr */ + *nfePtr += N; +} + + +/* Readability Replacements */ + +#define N (cv_mem->cv_N) +#define lmm (cv_mem->cv_lmm) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define uround (cv_mem->cv_uround) +#define nst (cv_mem->cv_nst) +#define tn (cv_mem->cv_tn) +#define h (cv_mem->cv_h) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define gamrat (cv_mem->cv_gamrat) +#define ewt (cv_mem->cv_ewt) +#define nfe (cv_mem->cv_nfe) +#define errfp (cv_mem->cv_errfp) +#define iopt (cv_mem->cv_iopt) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) +#define setupNonNull (cv_mem->cv_setupNonNull) +#define machenv (cv_mem->cv_machenv) + +#define jac (cvdense_mem->d_jac) +#define M (cvdense_mem->d_M) +#define pivots (cvdense_mem->d_pivots) +#define savedJ (cvdense_mem->d_savedJ) +#define nstlj (cvdense_mem->d_nstlj) +#define nje (cvdense_mem->d_nje) +#define J_data (cvdense_mem->d_J_data) + + +/*************** CVDense ********************************************* + + This routine initializes the memory record and sets various function + fields specific to the dense linear solver module. CVDense first + calls the existing lfree routine if this is not NULL. Then it sets + the cv_linit, cv_lsetup, cv_lsolve, cv_lfree fields in (*cvode_mem) + to be CVDenseInit, CVDenseSetup, CVDenseSolve, and CVDenseFree, + respectively. It allocates memory for a structure of type + CVDenseMemRec and sets the cv_lmem field in (*cvode_mem) to the + address of this structure. It sets setupNonNull in (*cvode_mem) to + TRUE, the d_J_data field in CVDenseMemRec to be the input + parameter jac_data, and the d_jac field to be: + (1) the input parameter djac if djac != NULL or + (2) CVDenseDQJac if djac == NULL. + Finally, it allocates memory for M, savedJ, and pivots. + The return value is SUCCESS = 0, or LMEM_FAIL = -1. + + NOTE: The dense linear solver assumes a serial implementation + of the NVECTOR package. Therefore, CVDense will first + test for compatible a compatible N_Vector internal + representation by checking (1) the machine environment + ID tag and (2) that the functions N_VMake, N_VDispose, + N_VGetData, and N_VSetData are implemented. + +**********************************************************************/ + +int CVDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data) +{ + CVodeMem cv_mem; + CVDenseMem cvdense_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) { /* CVode reports this error */ + output_msg(OUTPUT_CVODE, MSG_CVMEM_NULL); + return(LMEM_FAIL); + } + + /* Test if the NVECTOR package is compatible with the DENSE solver */ + if ((strcmp(machenv->tag,"serial")) || + machenv->ops->nvmake == NULL || + machenv->ops->nvdispose == NULL || + machenv->ops->nvgetdata == NULL || + machenv->ops->nvsetdata == NULL) { + output_msg(OUTPUT_CVODE, MSG_WRONG_NVEC); + return(LMEM_FAIL); + } + + if (lfree !=NULL) lfree(cv_mem); + + /* Set four main function fields in cv_mem */ + linit = CVDenseInit; + lsetup = CVDenseSetup; + lsolve = CVDenseSolve; + lfree = CVDenseFree; + + /* Get memory for CVDenseMemRec */ + lmem = cvdense_mem = (CVDenseMem) malloc(sizeof(CVDenseMemRec)); + if (cvdense_mem == NULL) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + return(LMEM_FAIL); + } + + /* Set Jacobian routine field, J_data, and setupNonNull */ + if (djac == NULL) { + jac = CVDenseDQJac; + } else { + jac = djac; + } + J_data = jac_data; + setupNonNull = TRUE; + + /* Allocate memory for M, savedJ, and pivot array */ + + M = DenseAllocMat(N); + if (M == NULL) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + return(LMEM_FAIL); + } + savedJ = DenseAllocMat(N); + if (savedJ == NULL) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + DenseFreeMat(M); + return(LMEM_FAIL); + } + pivots = DenseAllocPiv(N); + if (pivots == NULL) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + DenseFreeMat(M); + DenseFreeMat(savedJ); + return(LMEM_FAIL); + } + + return(SUCCESS); +} + +/*************** CVReInitDense**************************************** + + This routine resets the link between the main CVODE module and the + dense linear solver module CVDENSE. No memory freeing or allocation + operations are done, as the existing linear solver memory is assumed + sufficient. All other initializations are the same as in CVDense. + The return value is SUCCESS = 0, or LMEM_FAIL = -1. + +**********************************************************************/ + +int CVReInitDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data) +{ + CVodeMem cv_mem; + CVDenseMem cvdense_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) { /* CVode reports this error */ + output_msg(OUTPUT_CVODE, MSG_CVMEM_NULL); + return(LMEM_FAIL); + } + + /* Test if the NVECTOR package is compatible with the DENSE solver */ + if ((strcmp(machenv->tag,"serial")) || + machenv->ops->nvmake == NULL || + machenv->ops->nvdispose == NULL || + machenv->ops->nvgetdata == NULL || + machenv->ops->nvsetdata == NULL) { + output_msg(OUTPUT_CVODE, MSG_WRONG_NVEC); + return(LMEM_FAIL); + } + + cvdense_mem = (CVDenseMem) lmem; /* Use existing linear solver memory pointer */ + + /* Set four main function fields in cv_mem */ + linit = CVDenseInit; + lsetup = CVDenseSetup; + lsolve = CVDenseSolve; + lfree = CVDenseFree; + + /* Set Jacobian routine field, J_data, and setupNonNull */ + if (djac == NULL) { + jac = CVDenseDQJac; + } else { + jac = djac; + } + J_data = jac_data; + setupNonNull = TRUE; + + return(SUCCESS); +} + +/*************** CVDenseInit ***************************************** + + This routine does remaining initializations specific to the dense + linear solver. + +**********************************************************************/ + +static int CVDenseInit(CVodeMem cv_mem) +{ + CVDenseMem cvdense_mem; + cvdense_mem = (CVDenseMem) lmem; + + /* Initialize nje and nstlj, and set workspace lengths */ + + nje = 0; + if (iopt != NULL) { + iopt[DENSE_NJE] = nje; + iopt[DENSE_LRW] = 2*N*N; + iopt[DENSE_LIW] = N; + } + nstlj = 0; + + return(LINIT_OK); +} + +/*************** CVDenseSetup **************************************** + + This routine does the setup operations for the dense linear solver. + It makes a decision whether or not to call the Jacobian evaluation + routine based on various state variables, and if not it uses the + saved copy. In any case, it constructs the Newton matrix + M = I - gamma*J, updates counters, and calls the dense LU + factorization routine. + +**********************************************************************/ + +static int CVDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, booleantype *jcurPtr, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) +{ + booleantype jbad, jok; + realtype dgamma; + integertype ier; + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ + + dgamma = ABS((gamma/gammap) - ONE); + jbad = (nst == 0) || (nst > nstlj + CVD_MSBJ) || + ((convfail == FAIL_BAD_J) && (dgamma < CVD_DGMAX)) || + (convfail == FAIL_OTHER); + jok = !jbad; + + if (jok) { + /* If jok = TRUE, use saved copy of J */ + *jcurPtr = FALSE; + DenseCopy(savedJ, M); + } else { + /* If jok = FALSE, call jac routine for new J value */ + nje++; + if (iopt != NULL) iopt[DENSE_NJE] = nje; + nstlj = nst; + *jcurPtr = TRUE; + DenseZero(M); + jac(N, M, f, f_data, tn, ypred, fpred, ewt, h, + uround, J_data, &nfe, vtemp1, vtemp2, vtemp3); + DenseCopy(M, savedJ); + } + + /* Scale and add I to get M = I - gamma*J */ + DenseScale(-gamma, M); + DenseAddI(M); + + /* Do LU factorization of M */ + ier = DenseFactor(M, pivots); + + /* Return 0 if the LU was complete; otherwise return 1 */ + if (ier > 0) return(1); + return(0); +} + +/*************** CVDenseSolve **************************************** + + This routine handles the solve operation for the dense linear solver + by calling the dense backsolve routine. The returned value is 0. + +**********************************************************************/ + +static int CVDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur) +{ + CVDenseMem cvdense_mem; + realtype *bd; + + cvdense_mem = (CVDenseMem) lmem; + + bd = N_VGetData(b); + DenseBacksolve(M, pivots, bd); + N_VSetData(bd, b); + + /* If BDF, scale the correction to account for change in gamma */ + if ((lmm == BDF) && (gamrat != ONE)) { + N_VScale(TWO/(ONE + gamrat), b, b); + } + + return(0); +} + +/*************** CVDenseFree ***************************************** + + This routine frees memory specific to the dense linear solver. + +**********************************************************************/ + +static void CVDenseFree(CVodeMem cv_mem) +{ + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + DenseFreeMat(M); + DenseFreeMat(savedJ); + DenseFreePiv(pivots); + free(cvdense_mem); +} diff --git a/cvdense.h b/cvdense.h new file mode 100644 index 00000000..af4931c0 --- /dev/null +++ b/cvdense.h @@ -0,0 +1,224 @@ +/******************************************************************* + * * + * File : cvdense.h * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * Radu Serban @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/cvode/LICENSE * + *-----------------------------------------------------------------* + * This is the header file for the CVODE dense linear solver, * + * CVDENSE. * + * * + * Note: The type integertype must be large enough to store the * + * value of the linear system size N. * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidcvdense[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvdense_h +#define _cvdense_h + + +#include +#include "cvode.h" +#include "sundialstypes.h" +#include "dense.h" +#include "nvector.h" + + +/****************************************************************** + * * + * CVDENSE solver statistics indices * + *----------------------------------------------------------------* + * The following enumeration gives a symbolic name to each * + * CVDENSE statistic. The symbolic names are used as indices into * + * the iopt and ropt arrays passed to CVodeMalloc. * + * The CVDENSE statistics are: * + * * + * iopt[DENSE_NJE] : number of Jacobian evaluations, i.e. of * + * calls made to the dense Jacobian routine * + * (default or user-supplied). * + * * + * iopt[DENSE_LRW] : size (in realtype words) of real workspace * + * matrices and vectors used by this solver. * + * * + * iopt[DENSE_LIW] : size (in integertype words) of integer * + * workspace vectors used by this solver. * + * * + ******************************************************************/ + +enum { DENSE_NJE=CVODE_IOPT_SIZE, DENSE_LRW, DENSE_LIW }; + + +/****************************************************************** + * * + * CVDENSE solver constants * + *----------------------------------------------------------------* + * CVD_MSBJ : maximum number of steps between dense Jacobian * + * evaluations * + * * + * CVD_DGMAX : maximum change in gamma between dense Jacobian * + * evaluations * + * * + ******************************************************************/ + +#define CVD_MSBJ 50 + +#define CVD_DGMAX RCONST(0.2) + + +/****************************************************************** + * * + * Type : CVDenseJacFn * + *----------------------------------------------------------------* + * A dense Jacobian approximation function Jac must have the * + * prototype given below. Its parameters are: * + * * + * N is the length of all vector arguments. * + * * + * J is the dense matrix (of type DenseMat) that will be loaded * + * by a CVDenseJacFn with an approximation to the Jacobian matrix * + * J = (df_i/dy_j) at the point (t,y). * + * J is preset to zero, so only the nonzero elements need to be * + * loaded. Two efficient ways to load J are: * + * * + * (1) (with macros - no explicit data structure references) * + * for (j=0; j < N; j++) { * + * col_j = DENSE_COL(J,j); * + * for (i=0; i < N; i++) { * + * generate J_ij = the (i,j)th Jacobian element * + * col_j[i] = J_ij; * + * } * + * } * + * * + * (2) (without macros - explicit data structure references) * + * for (j=0; j < N; j++) { * + * col_j = (J->data)[j]; * + * for (i=0; i < N; i++) { * + * generate J_ij = the (i,j)th Jacobian element * + * col_j[i] = J_ij; * + * } * + * } * + * * + * The DENSE_ELEM(A,i,j) macro is appropriate for use in small * + * problems in which efficiency of access is NOT a major concern. * + * * + * f is the right hand side function for the ODE problem. * + * * + * f_data is a pointer to user data to be passed to f, the same * + * as the F_data parameter passed to CVodeMalloc. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector, * + * namely the predicted value of y(t). * + * * + * fy is the vector f(t,y). * + * * + * ewt is the error weight vector. * + * * + * h is a tentative step size in t. * + * * + * uround is the machine unit roundoff. * + * * + * jac_data is a pointer to user data - the same as the jac_data * + * parameter passed to CVDense. * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. The Jacobian * + * routine should update this counter by adding on the number * + * of f calls made in order to approximate the Jacobian, if any. * + * For example, if the routine calls f a total of N times, then * + * the update is *nfePtr += N. * + * * + * vtemp1, vtemp2, and vtemp3 are pointers to memory allocated * + * for vectors of length N which can be used by a CVDenseJacFn * + * as temporary storage or work space. * + * * + ******************************************************************/ + +typedef void (*CVDenseJacFn)(integertype N, DenseMat J, RhsFn f, void *f_data, + realtype t, N_Vector y, N_Vector fy, N_Vector ewt, + realtype h, realtype uround, void *jac_data, + long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + +/****************************************************************** + * * + * Function : CVDense * + *----------------------------------------------------------------* + * A call to the CVDense function links the main CVODE integrator * + * with the CVDENSE linear solver. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * djac is the dense Jacobian approximation routine to be used. * + * A user-supplied djac routine must be of type * + * CVDenseJacFn. Pass NULL for djac to use the default * + * difference quotient routine CVDenseDQJac supplied * + * with this solver. * + * * + * jac_data is a pointer to user data which is passed to the * + * djac routine every time it is called. * + * * + * The return values of CVDense are: * + * SUCCESS = 0 if successful * + * LMEM_FAIL = -1 if there was a memory allocation failure * + * * + * NOTE: The dense linear solver assumes a serial implementation * + * of the NVECTOR package. Therefore, CVDense will first * + * test for a compatible N_Vector internal representation * + * by checking (1) the machine environment ID tag and * + * (2) that the functions N_VMake, N_VDispose, N_VGetData, * + * and N_VSetData are implemented. * + * * + ******************************************************************/ + +int CVDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data); + + +/****************************************************************** + * * + * Function : CVReInitDense * + *----------------------------------------------------------------* + * A call to the CVReInitDense function resets the link between * + * the main CVODE integrator and the CVDENSE linear solver. * + * After solving one problem using CVDENSE, call CVReInit and then* + * CVReInitDense to solve another problem of the same size, if * + * there is a change in the CVDense parameters djac or jac_data. * + * If there is no change in parameters, it is not necessary to * + * call either CVReInitDense or CVDense for the new problem. * + * * + * All arguments to CVReInitDense have the same names and meanings* + * as those of CVDense. The cvode_mem argument must be identical * + * to its value in the previous CVDense call. * + * * + * The return values of CVReInitDense are: * + * SUCCESS = 0 if successful, or * + * LMEM_FAIL = -1 if the cvode_mem argument is NULL * + * * + * NOTE: CVReInitDense performs the same compatibility tests as * + * CVDense. * + * * + ******************************************************************/ + +int CVReInitDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/cvode.cpp b/cvode.cpp new file mode 100644 index 00000000..b5c07e94 --- /dev/null +++ b/cvode.cpp @@ -0,0 +1,3330 @@ +/*#define DEBUG_CVODE*/ +extern char *error_string; +/******************************************************************* + * * + * File : cvode.c * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, Radu Serban, * + * and Dan Shumaker @ LLNL * + * Version of : 24 July 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/cvode/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for the main CVODE integrator. * + * It is independent of the CVODE linear solver in use. * + * * + *******************************************************************/ + + +/************************************************************/ +/******************* BEGIN Imports **************************/ +/************************************************************/ + +#include +#include +#include "cvode.h" +#include "sundialstypes.h" +#include "nvector.h" +#include "sundialsmath.h" +#include "output.h" +#define KINETICS_EXTERNAL +#include "kinetics.h" +#include "phqalloc.h" +/* WARNING don't include any headers below here */ +#define malloc PHRQ_malloc +static char const svnid[] = "$Id: cvode.c 663 2005-11-16 00:46:04Z dlpark $"; + +/************************************************************/ +/******************** END Imports ***************************/ +/************************************************************/ + + +/***************************************************************/ +/*********************** BEGIN Macros **************************/ +/***************************************************************/ + +/* Macro: loop */ + +#define loop for(;;) + +/***************************************************************/ +/************************ END Macros ***************************/ +/***************************************************************/ + + + +/************************************************************/ +/************** BEGIN CVODE Private Constants ***************/ +/************************************************************/ + +#define FOURTH RCONST(0.25) /* real 0.25 */ +#define THREE RCONST(3.0) /* real 3.0 */ +#define FOUR RCONST(4.0) /* real 4.0 */ +#define HUN RCONST(100.0) /* real 100.0 */ +#define TINY RCONST(1.0e-10) /* small number */ +#define HALF RCONST(0.5) /* real 0.5 */ +#define ZERO RCONST(0.0) /* real 0.0 */ +#define ONE RCONST(1.0) /* real 1.0 */ +#define TWO RCONST(2.0) /* real 2.0 */ +#define TWELVE RCONST(12.0) /* real 12.0 */ + +/***************************************************************/ +/************** BEGIN Default Constants ************************/ +/***************************************************************/ + +#define HMIN_DEFAULT ZERO /* hmin default value */ +#define HMAX_INV_DEFAULT ZERO /* hmax_inv default value */ +#define MXHNIL_DEFAULT 10 /* mxhnil default value */ +#define MXSTEP_DEFAULT 50 /* mxstep default value */ + + +/***************************************************************/ +/*************** END Default Constants *************************/ +/***************************************************************/ + + +/***************************************************************/ +/************ BEGIN Routine-Specific Constants *****************/ +/***************************************************************/ + +/* CVodeDky */ + +#define FUZZ_FACTOR RCONST(100.0) + +/* CVHin */ + +#define HLB_FACTOR RCONST(100.0) +#define HUB_FACTOR RCONST(0.1) +#define H_BIAS HALF +#define MAX_ITERS 4 + +/* CVSet */ + +#define CORTES RCONST(0.1) + +/* CVStep return values */ + +#define SUCCESS_STEP 0 +#define REP_ERR_FAIL -1 +#define REP_CONV_FAIL -2 +#define SETUP_FAILED -3 +#define SOLVE_FAILED -4 + +/* CVStep control constants */ + +#define PREDICT_AGAIN -5 +#define DO_ERROR_TEST 1 + +/* CVStep */ + +#define THRESH RCONST(1.5) +#define ETAMX1 RCONST(10000.0) +#define ETAMX2 RCONST(10.0) +#define ETAMX3 RCONST(10.0) +#define ETAMXF RCONST(0.2) +#define ETAMIN RCONST(0.1) +#define ETACF RCONST(0.25) +#define ADDON RCONST(0.000001) +#define BIAS1 RCONST(6.0) +#define BIAS2 RCONST(6.0) +#define BIAS3 RCONST(10.0) +#define ONEPSM RCONST(1.000001) + +#define SMALL_NST 10 /* nst > SMALL_NST => use ETAMX3 */ +#define MXNCF 10 /* max no. of convergence failures during */ + /* one step try */ +#define MXNEF 7 /* max no. of error test failures during */ + /* one step try */ +#define MXNEF1 3 /* max no. of error test failures before */ + /* forcing a reduction of order */ +#define SMALL_NEF 2 /* if an error failure occurs and */ + /* SMALL_NEF <= nef <= MXNEF1, then */ + /* reset eta = MIN(eta, ETAMXF) */ +#define LONG_WAIT 10 /* number of steps to wait before */ + /* considering an order change when */ + /* q==1 and MXNEF1 error test failures */ + /* have occurred */ + +/* CVnls return values */ + +#define SOLVED 0 +#define CONV_FAIL -1 +#define SETUP_FAIL_UNREC -2 +#define SOLVE_FAIL_UNREC -3 + +/* CVnls input flags */ + +#define FIRST_CALL 0 +#define PREV_CONV_FAIL -1 +#define PREV_ERR_FAIL -2 + +/* CVnls other constants */ + +#define FUNC_MAXCOR 3 /* maximum no. of corrector iterations */ + /* for iter == FUNCTIONAL */ +#define NEWT_MAXCOR 3 /* maximum no. of corrector iterations */ + /* for iter == NEWTON */ + +#define CRDOWN RCONST(0.3) /* constant used in the estimation of the */ + /* convergence rate (crate) of the */ + /* iterates for the nonlinear equation */ +#define DGMAX RCONST(0.3) /* iter == NEWTON, |gamma/gammap-1| > DGMAX */ + /* => call lsetup */ + +#define RDIV TWO /* declare divergence if ratio del/delp > RDIV */ +#define MSBP 20 /* max no. of steps between lsetup calls */ + +#define TRY_AGAIN 99 /* control constant for CVnlsNewton - should be */ + /* distinct from CVnls return values */ + + +/***************************************************************/ +/*************** END Routine-Specific Constants ***************/ +/***************************************************************/ + + +/***************************************************************/ +/***************** BEGIN Error Messages ************************/ +/***************************************************************/ + +/* CVodeMalloc/CVReInit Error Messages */ + +#define CVM "CVodeMalloc/CVReInit-- " + +#define MSG_Y0_NULL CVM "y0=NULL illegal.\n\n" + +#define MSG_BAD_N CVM "N=%ld < 1 illegal.\n\n" + +#define MSG_BAD_LMM_1 CVM "lmm=%d illegal.\n" +#define MSG_BAD_LMM_2 "The legal values are ADAMS=%d and BDF=%d.\n\n" +#define MSG_BAD_LMM MSG_BAD_LMM_1 MSG_BAD_LMM_2 + +#define MSG_BAD_ITER_1 CVM "iter=%d illegal.\n" +#define MSG_BAD_ITER_2 "The legal values are FUNCTIONAL=%d " +#define MSG_BAD_ITER_3 "and NEWTON=%d.\n\n" +#define MSG_BAD_ITER MSG_BAD_ITER_1 MSG_BAD_ITER_2 MSG_BAD_ITER_3 + +#define MSG_BAD_ITOL_1 CVM "itol=%d illegal.\n" +#define MSG_BAD_ITOL_2 "The legal values are SS=%d and SV=%d.\n\n" +#define MSG_BAD_ITOL MSG_BAD_ITOL_1 MSG_BAD_ITOL_2 + +#define MSG_F_NULL CVM "f=NULL illegal.\n\n" + +#define MSG_RELTOL_NULL CVM "reltol=NULL illegal.\n\n" + +#define MSG_BAD_RELTOL CVM "*reltol=%g < 0 illegal.\n\n" + +#define MSG_ABSTOL_NULL CVM "abstol=NULL illegal.\n\n" + +#define MSG_BAD_ABSTOL CVM "Some abstol component < 0.0 illegal.\n\n" + +#define MSG_BAD_OPTIN_1 CVM "optIn=%d illegal.\n" +#define MSG_BAD_OPTIN_2 "The legal values are FALSE=%d and TRUE=%d.\n\n" +#define MSG_BAD_OPTIN MSG_BAD_OPTIN_1 MSG_BAD_OPTIN_2 + +#define MSG_BAD_OPT CVM "optIn=TRUE, but iopt=ropt=NULL.\n\n" + +#define MSG_MEM_FAIL CVM "A memory request failed.\n\n" + +#define MSG_BAD_EWT CVM "Some initial ewt component = 0.0 illegal.\n\n" + +#define MSG_REI_NO_MEM "CVReInit-- cvode_mem = NULL illegal.\n\n" + +#define MSG_REI_MAXORD1 "CVReInit-- Illegal attempt to increase " +#define MSG_REI_MAXORD2 "maximum method order from %d to %d.\n\n" +#define MSG_REI_MAXORD MSG_REI_MAXORD1 MSG_REI_MAXORD2 + + +/* CVode error messages */ + +#define CVODE "CVode-- " + +#define NO_MEM "cvode_mem=NULL illegal.\n\n" + +#define MSG_CVODE_NO_MEM CVODE NO_MEM + +#define MSG_LINIT_NULL CVODE "The linear solver's init routine is NULL.\n\n" + +#define MSG_LSETUP_NULL CVODE "The linear solver's setup routine is NULL.\n\n" + +#define MSG_LSOLVE_NULL CVODE "The linear solver's solve routine is NULL.\n\n" + +#define MSG_LFREE_NULL CVODE "The linear solver's free routine is NULL.\n\n" + +#define MSG_LINIT_FAIL CVODE "The linear solver's init routine failed.\n\n" + +#define MSG_YOUT_NULL CVODE "yout=NULL illegal.\n\n" + +#define MSG_T_NULL CVODE "t=NULL illegal.\n\n" + +#define MSG_BAD_ITASK_1 CVODE "itask=%d illegal.\nThe legal values are" +#define MSG_BAD_ITASK_2 " NORMAL=%d and ONE_STEP=%d.\n\n" +#define MSG_BAD_ITASK MSG_BAD_ITASK_1 MSG_BAD_ITASK_2 + +#define MSG_BAD_HMIN_HMAX_1 CVODE "Inconsistent step size limits:\n" +#define MSG_BAD_HMIN_HMAX_2 "ropt[HMIN]=%g > ropt[HMAX]=%g.\n\n" +#define MSG_BAD_HMIN_HMAX MSG_BAD_HMIN_HMAX_1 MSG_BAD_HMIN_HMAX_2 + +#define MSG_BAD_H0 CVODE "h0=%g and tout-t0=%g inconsistent.\n\n" + +#define MSG_BAD_TOUT_1 CVODE "Trouble interpolating at tout = %g.\n" +#define MSG_BAD_TOUT_2 "tout too far back in direction of integration.\n\n" +#define MSG_BAD_TOUT MSG_BAD_TOUT_1 MSG_BAD_TOUT_2 + +#define MSG_MAX_STEPS_1 CVODE "At t=%g, mxstep=%d steps taken on " +#define MSG_MAX_STEPS_2 "this call before\nreaching tout=%g.\n\n" +#define MSG_MAX_STEPS MSG_MAX_STEPS_1 MSG_MAX_STEPS_2 + +#define MSG_EWT_NOW_BAD_1 CVODE "At t=%g, " +#define MSG_EWT_NOW_BAD_2 "some ewt component has become <= 0.0.\n\n" +#define MSG_EWT_NOW_BAD MSG_EWT_NOW_BAD_1 MSG_EWT_NOW_BAD_2 + +#define MSG_TOO_MUCH_ACC CVODE "At t=%g, too much accuracy requested.\n\n" + +#define MSG_HNIL_1 CVODE "Warning.. internal t=%g and step size h=%g\n" +#define MSG_HNIL_2 "are such that t + h == t on the next step.\n" +#define MSG_HNIL_3 "The solver will continue anyway.\n\n" +#define MSG_HNIL MSG_HNIL_1 MSG_HNIL_2 MSG_HNIL_3 + +#define MSG_HNIL_DONE_1 CVODE "The above warning has been issued %d times " +#define MSG_HNIL_DONE_2 "and will not be\nissued again for this problem.\n\n" +#define MSG_HNIL_DONE MSG_HNIL_DONE_1 MSG_HNIL_DONE_2 + +#define MSG_ERR_FAILS_1 CVODE "At t=%g and step size h=%g, the error test\n" +#define MSG_ERR_FAILS_2 "failed repeatedly or with |h| = hmin.\n\n" +#define MSG_ERR_FAILS MSG_ERR_FAILS_1 MSG_ERR_FAILS_2 + +#define MSG_CONV_FAILS_1 CVODE "At t=%g and step size h=%g, the corrector\n" +#define MSG_CONV_FAILS_2 "convergence failed repeatedly or " +#define MSG_CONV_FAILS_3 "with |h| = hmin.\n\n" +#define MSG_CONV_FAILS MSG_CONV_FAILS_1 MSG_CONV_FAILS_2 MSG_CONV_FAILS_3 + +#define MSG_SETUP_FAILED_1 CVODE "At t=%g, the setup routine failed in an " +#define MSG_SETUP_FAILED_2 "unrecoverable manner.\n\n" +#define MSG_SETUP_FAILED MSG_SETUP_FAILED_1 MSG_SETUP_FAILED_2 + +#define MSG_SOLVE_FAILED_1 CVODE "At t=%g, the solve routine failed in an " +#define MSG_SOLVE_FAILED_2 "unrecoverable manner.\n\n" +#define MSG_SOLVE_FAILED MSG_SOLVE_FAILED_1 MSG_SOLVE_FAILED_2 + +#define MSG_TOO_CLOSE_1 CVODE "tout=%g too close to t0=%g to start" +#define MSG_TOO_CLOSE_2 " integration.\n\n" +#define MSG_TOO_CLOSE MSG_TOO_CLOSE_1 MSG_TOO_CLOSE_2 + + +/* CVodeDky Error Messages */ + +#define DKY "CVodeDky-- " + +#define MSG_DKY_NO_MEM DKY NO_MEM + +#define MSG_BAD_K DKY "k=%d illegal.\n\n" + +#define MSG_BAD_T_1 DKY "t=%g illegal.\n" +#define MSG_BAD_T_2 "t not in interval tcur-hu=%g to tcur=%g.\n\n" +#define MSG_BAD_T MSG_BAD_T_1 MSG_BAD_T_2 + +#define MSG_BAD_DKY DKY "dky=NULL illegal.\n\n" + +/***************************************************************/ +/****************** END Error Messages *************************/ +/***************************************************************/ + + +/************************************************************/ +/*************** END CVODE Private Constants ****************/ +/************************************************************/ + + +/**************************************************************/ +/********* BEGIN Private Helper Functions Prototypes **********/ +/**************************************************************/ + +static booleantype CVAllocVectors(CVodeMem cv_mem, integertype neq, int maxord, + M_Env machEnv); +static void CVFreeVectors(CVodeMem cv_mem, int maxord); + +static booleantype CVEwtSet(CVodeMem cv_mem, N_Vector ycur); +static booleantype CVEwtSetSS(CVodeMem cv_mem, N_Vector ycur); +static booleantype CVEwtSetSV(CVodeMem cv_mem, N_Vector ycur); + +static booleantype CVHin(CVodeMem cv_mem, realtype tout); +static realtype CVUpperBoundH0(CVodeMem cv_mem, realtype tdist); +static realtype CVYddNorm(CVodeMem cv_mem, realtype hg); + +static int CVStep(CVodeMem cv_mem); + +static int CVsldet(CVodeMem cv_mem); + +static void CVAdjustParams(CVodeMem cv_mem); +static void CVAdjustOrder(CVodeMem cv_mem, int deltaq); +static void CVAdjustAdams(CVodeMem cv_mem, int deltaq); +static void CVAdjustBDF(CVodeMem cv_mem, int deltaq); +static void CVIncreaseBDF(CVodeMem cv_mem); +static void CVDecreaseBDF(CVodeMem cv_mem); + +static void CVRescale(CVodeMem cv_mem); + +static void CVPredict(CVodeMem cv_mem); + +static void CVSet(CVodeMem cv_mem); +static void CVSetAdams(CVodeMem cv_mem); +static realtype CVAdamsStart(CVodeMem cv_mem, realtype m[]); +static void CVAdamsFinish(CVodeMem cv_mem, realtype m[], realtype M[], + realtype hsum); +static realtype CVAltSum(int iend, realtype a[], int k); +static void CVSetBDF(CVodeMem cv_mem); +static void CVSetTqBDF(CVodeMem cv_mem, realtype hsum, realtype alpha0, + realtype alpha0_hat, realtype xi_inv, realtype xistar_inv); + +static int CVnls(CVodeMem cv_mem, int nflag); +static int CVnlsFunctional(CVodeMem cv_mem); +static int CVnlsNewton(CVodeMem cv_mem, int nflag); +static int CVNewtonIteration(CVodeMem cv_mem); + +static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, realtype saved_t, + int *ncfPtr); + +static void CVRestore(CVodeMem cv_mem, realtype saved_t); + +static booleantype CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, int *kflagPtr, + realtype saved_t, int *nefPtr, realtype *dsmPtr); + +static void CVCompleteStep(CVodeMem cv_mem); + +static void CVPrepareNextStep(CVodeMem cv_mem, realtype dsm); +static void CVSetEta(CVodeMem cv_mem); +static realtype CVComputeEtaqm1(CVodeMem cv_mem); +static realtype CVComputeEtaqp1(CVodeMem cv_mem); +static void CVChooseEta(CVodeMem cv_mem); +static void CVBDFStab(CVodeMem cv_mem); + +static int CVHandleFailure(CVodeMem cv_mem,int kflag); + + +/**************************************************************/ +/********** END Private Helper Functions Prototypes ***********/ +/**************************************************************/ + + +/**************************************************************/ +/**************** BEGIN Readability Constants *****************/ +/**************************************************************/ + + +#define uround (cv_mem->cv_uround) +#define zn (cv_mem->cv_zn) +#define ewt (cv_mem->cv_ewt) +#define y (cv_mem->cv_y) +#define acor (cv_mem->cv_acor) +#define tempv (cv_mem->cv_tempv) +#define ftemp (cv_mem->cv_ftemp) +#define q (cv_mem->cv_q) +#define qprime (cv_mem->cv_qprime) +#define qwait (cv_mem->cv_qwait) +#define L (cv_mem->cv_L) +#define h (cv_mem->cv_h) +#define hprime (cv_mem->cv_hprime) +#define eta (cv_mem-> cv_eta) +#define etaqm1 (cv_mem-> cv_etaqm1) +#define etaq (cv_mem-> cv_etaq) +#define etaqp1 (cv_mem-> cv_etaqp1) +#define nscon (cv_mem->cv_nscon) +#define ssdat (cv_mem->cv_ssdat) +#define hscale (cv_mem->cv_hscale) +#define tn (cv_mem->cv_tn) +#define tau (cv_mem->cv_tau) +#define tq (cv_mem->cv_tq) +#define l (cv_mem->cv_l) +#define rl1 (cv_mem->cv_rl1) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define gamrat (cv_mem->cv_gamrat) +#define crate (cv_mem->cv_crate) +#define acnrm (cv_mem->cv_acnrm) +#define mnewt (cv_mem->cv_mnewt) +#define qmax (cv_mem->cv_qmax) +#define mxstep (cv_mem->cv_mxstep) +#define maxcor (cv_mem->cv_maxcor) +#define mxhnil (cv_mem->cv_mxhnil) +#define hmin (cv_mem->cv_hmin) +#define hmax_inv (cv_mem->cv_hmax_inv) +#define etamax (cv_mem->cv_etamax) +#define nst (cv_mem->cv_nst) +#define nfe (cv_mem->cv_nfe) +#define ncfn (cv_mem->cv_ncfn) +#define netf (cv_mem->cv_netf) +#define nni (cv_mem-> cv_nni) +#define nsetups (cv_mem->cv_nsetups) +#define nhnil (cv_mem->cv_nhnil) +#define lrw (cv_mem->cv_lrw) +#define liw (cv_mem->cv_liw) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) +#define qu (cv_mem->cv_qu) +#define nstlp (cv_mem->cv_nstlp) +#define hu (cv_mem->cv_hu) +#define saved_tq5 (cv_mem->cv_saved_tq5) +#define jcur (cv_mem->cv_jcur) +#define tolsf (cv_mem->cv_tolsf) +#define setupNonNull (cv_mem->cv_setupNonNull) +#define machenv (cv_mem->cv_machenv) +#define sldeton (cv_mem->cv_sldeton) + +/**************************************************************/ +/***************** END Readability Constants ******************/ +/**************************************************************/ + + +/***************************************************************/ +/************* BEGIN CVODE Implementation **********************/ +/***************************************************************/ + + +/***************************************************************/ +/********* BEGIN Exported Functions Implementation *************/ +/***************************************************************/ + + +/******************** CVodeMalloc ******************************* + + CVodeMalloc allocates and initializes memory for a problem. All + problem specification inputs are checked for errors. If any + error occurs during initialization, it is reported to the file + whose file pointer is errfp and NULL is returned. Otherwise, the + pointer to successfully initialized problem memory is returned. + +*****************************************************************/ + +void *CVodeMalloc(integertype N, RhsFn f, realtype t0, N_Vector y0, + int lmm, int iter, int itol, + realtype *reltol, void *abstol, + void *f_data, FILE *errfp, booleantype optIn, + long int iopt[], realtype ropt[], M_Env machEnv) +{ + booleantype allocOK, ioptExists, roptExists, neg_abstol, ewtsetOK; + int maxord; + CVodeMem cv_mem; + FILE *fp; + int i,k; + + if (svnid == NULL) fprintf(stderr," "); + /* Check for legal input parameters */ + + fp = (errfp == NULL) ? stdout : errfp; + + if (y0==NULL) { + output_msg(OUTPUT_CVODE, MSG_Y0_NULL); + return(NULL); + } + + if (N <= 0) { + output_msg(OUTPUT_CVODE, MSG_BAD_N, N); + return(NULL); + } + + if ((lmm != ADAMS) && (lmm != BDF)) { + output_msg(OUTPUT_CVODE, MSG_BAD_LMM, lmm, ADAMS, BDF); + return(NULL); + } + + if ((iter != FUNCTIONAL) && (iter != NEWTON)) { + output_msg(OUTPUT_CVODE, MSG_BAD_ITER, iter, FUNCTIONAL, NEWTON); + return(NULL); + } + + if ((itol != SS) && (itol != SV)) { + output_msg(OUTPUT_CVODE, MSG_BAD_ITOL, itol, SS, SV); + return(NULL); + } + + if (f == NULL) { + output_msg(OUTPUT_CVODE, MSG_F_NULL); + return(NULL); + } + + if (reltol == NULL) { + output_msg(OUTPUT_CVODE, MSG_RELTOL_NULL); + return(NULL); + } + + if (*reltol < ZERO) { + output_msg(OUTPUT_CVODE, MSG_BAD_RELTOL, (double) *reltol); + return(NULL); + } + + if (abstol == NULL) { + output_msg(OUTPUT_CVODE, MSG_ABSTOL_NULL); + return(NULL); + } + + if (itol == SS) { + neg_abstol = (*((realtype *)abstol) < ZERO); + } else { + neg_abstol = (N_VMin((N_Vector)abstol) < ZERO); + } + if (neg_abstol) { + output_msg(OUTPUT_CVODE, MSG_BAD_ABSTOL); + return(NULL); + } + + if ((optIn != FALSE) && (optIn != TRUE)) { + output_msg(OUTPUT_CVODE, MSG_BAD_OPTIN, optIn, FALSE, TRUE); + return(NULL); + } + + if ((optIn) && (iopt == NULL) && (ropt == NULL)) { + output_msg(OUTPUT_CVODE, MSG_BAD_OPT); + return(NULL); + } + + ioptExists = (iopt != NULL); + roptExists = (ropt != NULL); + + /* Compute maxord */ + + maxord = (lmm == ADAMS) ? ADAMS_Q_MAX : BDF_Q_MAX; + + if (optIn && ioptExists) { + if (iopt[MAXORD] > 0) maxord = MIN(maxord, iopt[MAXORD]); + } + + cv_mem = (CVodeMem) malloc(sizeof(struct CVodeMemRec)); + if (cv_mem == NULL) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + return(NULL); + } + + /* Allocate the vectors */ + + allocOK = CVAllocVectors(cv_mem, N, maxord, machEnv); + if (!allocOK) { + output_msg(OUTPUT_CVODE, MSG_MEM_FAIL); + free(cv_mem); + return(NULL); + } + + /* Copy tolerances into memory, and set the ewt vector */ + + cv_mem->cv_itol = itol; + cv_mem->cv_reltol = reltol; + cv_mem->cv_abstol = abstol; + ewtsetOK = CVEwtSet(cv_mem, y0); + if (!ewtsetOK) { + output_msg(OUTPUT_CVODE, MSG_BAD_EWT); + CVFreeVectors(cv_mem, maxord); + free(cv_mem); + return(NULL); + } + + /* All error checking is complete at this point */ + + /* Copy the remaining input parameters into CVODE memory */ + + cv_mem->cv_N = N; + cv_mem->cv_f = f; + cv_mem->cv_f_data = f_data; + cv_mem->cv_lmm = lmm; + cv_mem->cv_iter = iter; + cv_mem->cv_optIn = optIn; + cv_mem->cv_iopt = iopt; + cv_mem->cv_ropt = ropt; + cv_mem->cv_errfp = fp; + tn = t0; + machenv = machEnv; + + /* Set step parameters */ + + q = 1; + L = 2; + qwait = L; + qmax = maxord; + etamax = ETAMX1; + + /* Set uround */ + + uround = UnitRoundoff(); + + /* Set the linear solver addresses to NULL. + (We check != NULL later, in CVode, if using NEWTON.) */ + + linit = NULL; + lsetup = NULL; + lsolve = NULL; + lfree = NULL; + lmem = NULL; + + /* Initialize zn[0] in the history array */ + + N_VScale(ONE, y0, zn[0]); + + /* Handle the remaining optional inputs (CVode checks ropt[HMAX]) */ + + hmax_inv = HMAX_INV_DEFAULT; + hmin = HMIN_DEFAULT; + if (optIn && roptExists) { + if (ropt[HMIN] > ZERO) hmin = ropt[HMIN]; + } + + mxhnil = MXHNIL_DEFAULT; + mxstep = MXSTEP_DEFAULT; + if (optIn && ioptExists) { + if (iopt[MXHNIL] != 0) mxhnil = iopt[MXHNIL]; + if (iopt[MXSTEP] > 0) mxstep = iopt[MXSTEP]; + } + + if ((!optIn) && roptExists) ropt[H0] = ZERO; + + /* Set maxcor */ + + maxcor = (iter==NEWTON) ? NEWT_MAXCOR : FUNC_MAXCOR; + + /* Initialize all the counters */ + + nst = nfe = ncfn = netf = nni = nsetups = nhnil = nstlp = 0; + + /* Initialize all other variables corresponding to optional outputs */ + + qu = 0; + hu = ZERO; + tolsf = ONE; + + /* Initialize optional output locations in iopt, ropt */ + /* and Stablilty Limit Detection data. */ + + nscon = 0; + sldeton = FALSE; + if (ioptExists) { + iopt[NST] = iopt[NFE] = iopt[NSETUPS] = iopt[NNI] = 0; + iopt[NCFN] = iopt[NETF] = 0; + iopt[QU] = qu; + iopt[QCUR] = 0; + iopt[LENRW] = lrw; + iopt[LENIW] = liw; + if(optIn && iopt[SLDET] && (lmm == BDF)) { + sldeton = TRUE; + iopt[NOR] = 0; + for (i = 1; i <= 5; i++) { + for (k = 1; k <= 3; k++) ssdat[i-1][k-1] = ZERO;} + } + } + + if (roptExists) { + ropt[HU] = hu; + ropt[HCUR] = ZERO; + ropt[TCUR] = t0; + ropt[TOLSF] = tolsf; + } + + + /* Problem has been successfully initialized */ + + return((void *)cv_mem); +} + + +/******************** CVReInit ********************************** + + CVReInit re-initializes CVODE's memory for a problem, assuming + it has already been allocated in a prior CVodeMalloc call. + All problem specification inputs are checked for errors. + The problem size N is assumed to be unchanged since the call to + CVodeMalloc, and the maximum order maxord must not be larger. + If any error occurs during initialization, it is reported to the + file whose file pointer is errfp. + The return value is SUCCESS = 0 if no errors occurred, or + a negative value otherwise. + +*****************************************************************/ + +int CVReInit(void *cvode_mem, RhsFn f, realtype t0, N_Vector y0, + int lmm, int iter, int itol, + realtype *reltol, void *abstol, + void *f_data, FILE *errfp, booleantype optIn, + long int iopt[], realtype ropt[], M_Env machEnv) +{ + booleantype ioptExists, roptExists, neg_abstol, ewtsetOK; + int maxord, i,k; + CVodeMem cv_mem; + FILE *fp; + + /* Check for legal input parameters */ + + fp = (errfp == NULL) ? stdout : errfp; + + if (cvode_mem == NULL) { + output_msg(OUTPUT_CVODE, MSG_REI_NO_MEM); + return(CVREI_NO_MEM); + } + cv_mem = (CVodeMem) cvode_mem; + + if (y0 == NULL) { + output_msg(OUTPUT_CVODE, MSG_Y0_NULL); + return(CVREI_ILL_INPUT); + } + + if ((lmm != ADAMS) && (lmm != BDF)) { + output_msg(OUTPUT_CVODE, MSG_BAD_LMM, lmm, ADAMS, BDF); + return(CVREI_ILL_INPUT); + } + + if ((iter != FUNCTIONAL) && (iter != NEWTON)) { + output_msg(OUTPUT_CVODE, MSG_BAD_ITER, iter, FUNCTIONAL, NEWTON); + return(CVREI_ILL_INPUT); + } + + if ((itol != SS) && (itol != SV)) { + output_msg(OUTPUT_CVODE, MSG_BAD_ITOL, itol, SS, SV); + return(CVREI_ILL_INPUT); + } + + if (f == NULL) { + output_msg(OUTPUT_CVODE, MSG_F_NULL); + return(CVREI_ILL_INPUT); + } + + if (reltol == NULL) { + output_msg(OUTPUT_CVODE, MSG_RELTOL_NULL); + return(CVREI_ILL_INPUT); + } + + if (*reltol < ZERO) { + output_msg(OUTPUT_CVODE, MSG_BAD_RELTOL,(double) *reltol); + return(CVREI_ILL_INPUT); + } + + if (abstol == NULL) { + output_msg(OUTPUT_CVODE, MSG_ABSTOL_NULL); + return(CVREI_ILL_INPUT); + } + + if (itol == SS) { + neg_abstol = (*((realtype *)abstol) < ZERO); + } else { + neg_abstol = (N_VMin((N_Vector)abstol) < ZERO); + } + if (neg_abstol) { + output_msg(OUTPUT_CVODE, MSG_BAD_ABSTOL); + return(CVREI_ILL_INPUT); + } + + if ((optIn != FALSE) && (optIn != TRUE)) { + output_msg(OUTPUT_CVODE, MSG_BAD_OPTIN, optIn, FALSE, TRUE); + return(CVREI_ILL_INPUT); + } + + if ((optIn) && (iopt == NULL) && (ropt == NULL)) { + output_msg(OUTPUT_CVODE, MSG_BAD_OPT); + return(CVREI_ILL_INPUT); + } + + ioptExists = (iopt != NULL); + roptExists = (ropt != NULL); + + /* Compute new maxord and check against old value */ + + maxord = (lmm == ADAMS) ? ADAMS_Q_MAX : BDF_Q_MAX; + if (optIn && ioptExists) + { if (iopt[MAXORD] > 0) maxord = MIN(maxord, iopt[MAXORD]); } + if (maxord > qmax) { + output_msg(OUTPUT_CVODE, MSG_REI_MAXORD, qmax, maxord); + return(CVREI_ILL_INPUT); + } + + /* Copy tolerances into memory, and set the ewt vector */ + + cv_mem->cv_itol = itol; + cv_mem->cv_reltol = reltol; + cv_mem->cv_abstol = abstol; + ewtsetOK = CVEwtSet(cv_mem, y0); + if (!ewtsetOK) { + output_msg(OUTPUT_CVODE, MSG_BAD_EWT); + return(CVREI_ILL_INPUT); + } + + /* All error checking is complete at this point */ + + /* Copy the remaining input parameters into CVODE memory */ + + cv_mem->cv_f = f; + cv_mem->cv_f_data = f_data; + cv_mem->cv_lmm = lmm; + cv_mem->cv_iter = iter; + cv_mem->cv_optIn = optIn; + cv_mem->cv_iopt = iopt; + cv_mem->cv_ropt = ropt; + cv_mem->cv_errfp = fp; + tn = t0; + machenv = machEnv; + + /* Set step parameters */ + + q = 1; + L = 2; + qwait = L; + qmax = maxord; + etamax = ETAMX1; + + /* Set uround */ + + uround = UnitRoundoff(); + + /* Initialize zn[0] in the history array */ + + N_VScale(ONE, y0, zn[0]); + + /* Handle the remaining optional inputs (CVode checks ropt[HMAX]) */ + + hmax_inv = HMAX_INV_DEFAULT; + hmin = HMIN_DEFAULT; + if (optIn && roptExists) { + if (ropt[HMIN] > ZERO) hmin = ropt[HMIN]; + } + + mxhnil = MXHNIL_DEFAULT; + mxstep = MXSTEP_DEFAULT; + if (optIn && ioptExists) { + if (iopt[MXHNIL] != 0) mxhnil = iopt[MXHNIL]; + if (iopt[MXSTEP] > 0) mxstep = iopt[MXSTEP]; + } + + if ((!optIn) && roptExists) ropt[H0] = ZERO; + + /* Set maxcor */ + + maxcor = (iter==NEWTON) ? NEWT_MAXCOR : FUNC_MAXCOR; + + /* Initialize all the counters */ + + nst = nfe = ncfn = netf = nni = nsetups = nhnil = nstlp = 0; + + /* Initialize all other vars corresponding to optional outputs */ + + qu = 0; + hu = ZERO; + tolsf = ONE; + + /* Initialize optional output locations in iopt, ropt */ + /* and Stablilty Limit Detection data. */ + + nscon = 0; + sldeton = FALSE; + if (ioptExists) { + iopt[NST] = iopt[NFE] = iopt[NSETUPS] = iopt[NNI] = 0; + iopt[NCFN] = iopt[NETF] = 0; + iopt[QU] = qu; + iopt[QCUR] = 0; + iopt[LENRW] = lrw; + iopt[LENIW] = liw; + if(optIn && iopt[SLDET] && (lmm == BDF)) { + sldeton = TRUE; + iopt[NOR] = 0; + for (i = 1; i <= 5; i++) { + for (k = 1; k <= 3; k++) ssdat[i-1][k-1] = ZERO;} + } + } + + if (roptExists) { + ropt[HU] = hu; + ropt[HCUR] = ZERO; + ropt[TCUR] = t0; + ropt[TOLSF] = tolsf; + } + + /* Problem has been successfully re-initialized */ + + return(SUCCESS); +} + + +/**************************************************************/ +/************** BEGIN More Readability Constants **************/ +/**************************************************************/ + +#define N (cv_mem->cv_N) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define lmm (cv_mem->cv_lmm) +#define iter (cv_mem->cv_iter) +#define itol (cv_mem->cv_itol) +#define reltol (cv_mem->cv_reltol) +#define abstol (cv_mem->cv_abstol) +#define optIn (cv_mem->cv_optIn) +#define iopt (cv_mem->cv_iopt) +#define ropt (cv_mem->cv_ropt) +#define errfp (cv_mem->cv_errfp) + +/**************************************************************/ +/*************** END More Readability Constants ***************/ +/**************************************************************/ + + +/********************* CVode **************************************** + + This routine is the main driver of the CVODE package. + + It integrates over a time interval defined by the user, by calling + CVStep to do internal time steps. + + The first time that CVode is called for a successfully initialized + problem, it computes a tentative initial step size h. + + CVode supports two modes, specified by itask: NORMAL and ONE_STEP. + In the NORMAL mode, the solver steps until it reaches or passes tout + and then interpolates to obtain y(tout). + In the ONE_STEP mode, it takes one internal step and returns. + +********************************************************************/ + +int CVode(void *cvode_mem, realtype tout, N_Vector yout, + realtype *t, int itask) +{ + int nstloc, kflag, istate, next_q, ier; + realtype rh, next_h; + booleantype hOK, ewtsetOK; + CVodeMem cv_mem; + realtype t0; + + /* Check for legal inputs in all cases */ + + cv_mem = (CVodeMem) cvode_mem; + if (cvode_mem == NULL) { + output_msg(OUTPUT_CVODE, MSG_CVODE_NO_MEM); + return(CVODE_NO_MEM); + } + + if ((y = yout) == NULL) { + output_msg(OUTPUT_CVODE, MSG_YOUT_NULL); + return(ILL_INPUT); + } + + if (t == NULL) { + output_msg(OUTPUT_CVODE, MSG_T_NULL); + return(ILL_INPUT); + } + t0 = tn; + *t = tn; + + if ((itask != NORMAL) && (itask != ONE_STEP)) { + output_msg(OUTPUT_CVODE, MSG_BAD_ITASK, itask, NORMAL, ONE_STEP); + return(ILL_INPUT); + } + + /* Set hmax_inv from ropt[HMAX] and test for hmin > hmax */ + + if (optIn && ropt != NULL) { + if (ropt[HMAX] > ZERO) hmax_inv = ONE/ropt[HMAX]; + if (hmin*hmax_inv > ONE) { + output_msg(OUTPUT_CVODE, MSG_BAD_HMIN_HMAX, (double) hmin, (double) ropt[HMAX]); + return(ILL_INPUT); + } + } + + /* On first call, check solver functions and call linit function */ + + if (nst == 0) { + if (iter == NEWTON) { + if (linit == NULL) { + output_msg(OUTPUT_CVODE, MSG_LINIT_NULL); + return(ILL_INPUT); + } + if (lsetup == NULL) { + output_msg(OUTPUT_CVODE, MSG_LSETUP_NULL); + return(ILL_INPUT); + } + if (lsolve == NULL) { + output_msg(OUTPUT_CVODE, MSG_LSOLVE_NULL); + return(ILL_INPUT); + } + if (lfree == NULL) { + output_msg(OUTPUT_CVODE, MSG_LFREE_NULL); + return(ILL_INPUT); + } + ier = linit(cv_mem); + if (ier != LINIT_OK) { + output_msg(OUTPUT_CVODE, MSG_LINIT_FAIL); + return(ILL_INPUT); + } + } + + /* On the first call, call f at (t0,y0), set zn[1] = y'(t0), + set initial h (from H0 or CVHin), and scale zn[1] by h */ + cvode_rate_sim_time = cvode_rate_sim_time_start + tn; + cvode_step_fraction = 0; + + f(N, tn, zn[0], zn[1], f_data); + nfe = 1; + h = ZERO; + if (ropt != NULL) h = ropt[H0]; + if ( (h != ZERO) && ((tout-tn)*h < ZERO) ) { + output_msg(OUTPUT_CVODE, MSG_BAD_H0, (double) h, (double) (tout-tn)); + return(ILL_INPUT); + } + if (h == ZERO) { + hOK = CVHin(cv_mem, tout); + if (!hOK) { + output_msg(OUTPUT_CVODE, MSG_TOO_CLOSE, (double) tout, (double) tn); + return(ILL_INPUT); + } + } + rh = ABS(h)*hmax_inv; + if (rh > ONE) h /= rh; + if (ABS(h) < hmin) h *= hmin/ABS(h); + hscale = h; + N_VScale(h, zn[1], zn[1]); + + } /* end of first call block */ + + /* If not the first call, check if tout already reached */ + + if ( (itask == NORMAL) && (nst > 0) && ((tn-tout)*h >= ZERO) ) { + *t = tout; + ier = CVodeDky(cv_mem, tout, 0, yout); + if (ier != OKAY) { /* ier must be == BAD_T */ + output_msg(OUTPUT_CVODE, MSG_BAD_TOUT, (double) tout); + return(ILL_INPUT); + } + return(SUCCESS); + } + + /* Looping point for internal steps */ + + nstloc = 0; + loop { + + next_h = h; + next_q = q; + + /* Reset and check ewt */ + + if (nst > 0) { + ewtsetOK = CVEwtSet(cv_mem, zn[0]); + if (!ewtsetOK) { + output_msg(OUTPUT_CVODE, MSG_EWT_NOW_BAD, (double) tn); + istate = ILL_INPUT; + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + } + + /* Check for too many steps */ + + if (nstloc >= mxstep) { + /* output_msg(OUTPUT_CVODE, MSG_MAX_STEPS, tn, mxstep, tout); */ + istate = TOO_MUCH_WORK; + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + + /* Check for too much accuracy requested */ + + if ((tolsf = uround * N_VWrmsNorm(zn[0], ewt)) > ONE) { + output_msg(OUTPUT_CVODE, MSG_TOO_MUCH_ACC, (double) tn); + istate = TOO_MUCH_ACC; + *t = tn; + N_VScale(ONE, zn[0], yout); + tolsf *= TWO; + break; + } + + /* Check for h below roundoff level in tn */ + + if (tn + h == tn) { + nhnil++; + if (nhnil <= mxhnil) output_msg(OUTPUT_CVODE, MSG_HNIL, (double) tn, (double) h); + if (nhnil == mxhnil) output_msg(OUTPUT_CVODE, MSG_HNIL_DONE, mxhnil); + } + + /* Call CVStep to take a step */ + + kflag = CVStep(cv_mem); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After CVStep, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After CVStep, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After CVStep, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After CVStep, zn OK\n"); + } +#endif + /* Process failed step cases, and exit loop */ + + if (kflag != SUCCESS_STEP) { + istate = CVHandleFailure(cv_mem, kflag); + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + + nstloc++; + + /* Check if in one-step mode, and if so copy y and exit loop */ + + if (itask == ONE_STEP) { + istate = SUCCESS; + *t = tn; + N_VScale(ONE, zn[0], yout); + next_q = qprime; + next_h = hprime; + break; + } + cvode_rate_sim_time = cvode_rate_sim_time_start + tn; + cvode_step_fraction = (tn - t0)/(tout - t0); + /* + output_msg(OUTPUT_CVODE, "ODE: tn %e, t0 %e, tout %e, step_frac %e\n", (double) tn, (double) t0, (double) tout, (double) cvode_step_fraction); + */ + /* Check if tout reached, and if so interpolate and exit loop */ + + if ((tn-tout)*h >= ZERO) { + /* + output_msg(OUTPUT_CVODE, "*tn %e, t0 %e, tout %e, h %e\n", tn, t0, tout,h); + */ + cvode_rate_sim_time = cvode_rate_sim_time_start + tout; + cvode_step_fraction = 1.0; + istate = SUCCESS; + *t = tout; + (void) CVodeDky(cv_mem, tout, 0, yout); + next_q = qprime; + next_h = hprime; + break; + } + } + + /* End of step loop; load optional outputs and return */ + + if (iopt != NULL) { + iopt[NST] = nst; + iopt[NFE] = nfe; + iopt[NSETUPS] = nsetups; + iopt[NNI] = nni; + iopt[NCFN] = ncfn; + iopt[NETF] = netf; + iopt[QU] = q; + iopt[QCUR] = next_q; + } + + if (ropt != NULL) { + ropt[HU] = h; + ropt[HCUR] = next_h; + ropt[TCUR] = tn; + ropt[TOLSF] = tolsf; + } +#ifdef DEBUG_CVODE + /* + * check interpolation + */ + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"End of cvode, Interpolated y Fail\n"); + return(-1); + } else { + output_msg(OUTPUT_CVODE,"End of cvode, Interpolated y OK\n"); + } +#endif + return(istate); +} + +/*************** CVodeDky ******************************************** + + This routine computes the k-th derivative of the interpolating + polynomial at the time t and stores the result in the vector dky. + The formula is: + q + dky = SUM c(j,k) * (t - tn)^(j-k) * h^(-j) * zn[j] , + j=k + where c(j,k) = j*(j-1)*...*(j-k+1), q is the current order, and + zn[j] is the j-th column of the Nordsieck history array. + + This function is called by CVode with k = 0 and t = tout, but + may also be called directly by the user. + +**********************************************************************/ + +int CVodeDky(void *cvode_mem, realtype t, int k, N_Vector dky) +{ + realtype s, c, r; + realtype tfuzz, tp, tn1; + int i, j; + CVodeMem cv_mem; + + cv_mem = (CVodeMem) cvode_mem; + + /* Check all inputs for legality */ + + if (cvode_mem == NULL) { + output_msg(OUTPUT_CVODE, MSG_DKY_NO_MEM); + return(DKY_NO_MEM); + } + + if (dky == NULL) { + output_msg(OUTPUT_CVODE, MSG_BAD_DKY); + return(BAD_DKY); + } + + if ((k < 0) || (k > q)) { + output_msg(OUTPUT_CVODE, MSG_BAD_K, k); + return(BAD_K); + } + + tfuzz = FUZZ_FACTOR * uround * (ABS(tn) + ABS(hu)); + if (hu < ZERO) tfuzz = -tfuzz; + tp = tn - hu - tfuzz; + tn1 = tn + tfuzz; + if ((t-tp)*(t-tn1) > ZERO) { + output_msg(OUTPUT_CVODE, MSG_BAD_T, (double) t, (double) (tn-hu), (double) tn); + return(BAD_T); + } + + /* Sum the differentiated interpolating polynomial */ + + s = (t - tn) / h; + for (j=q; j >= k; j--) { + c = ONE; + for (i=j; i >= j-k+1; i--) c *= i; + if (j == q) { + N_VScale(c, zn[q], dky); + } else { + N_VLinearSum(c, zn[j], s, dky, dky); + } + } + if (k == 0) return(OKAY); + r = RPowerI(h,-k); + N_VScale(r, dky, dky); + return(OKAY); +} + +/********************* CVodeFree ********************************** + + This routine frees the problem memory allocated by CVodeMalloc. + Such memory includes all the vectors allocated by CVAllocVectors, + and the memory lmem for the linear solver (deallocated by a call + to lfree). + +*******************************************************************/ + +void CVodeFree(void *cvode_mem) +{ + CVodeMem cv_mem; + + cv_mem = (CVodeMem) cvode_mem; + + if (cvode_mem == NULL) return; + + CVFreeVectors(cv_mem, qmax); + if (iter == NEWTON) lfree(cv_mem); + free(cv_mem); +} + + +/***************************************************************/ +/********** END Exported Functions Implementation **************/ +/***************************************************************/ + + +/*******************************************************************/ +/******** BEGIN Private Helper Functions Implementation ************/ +/*******************************************************************/ + +/****************** CVAllocVectors *********************************** + + This routine allocates the CVODE vectors ewt, acor, tempv, ftemp, and + zn[0], ..., zn[maxord]. The length of the vectors is the input + parameter neq and the maximum order (needed to allocate zn) is the + input parameter maxord. If all memory allocations are successful, + CVAllocVectors returns TRUE. Otherwise all allocated memory is freed + and CVAllocVectors returns FALSE. + This routine also sets the optional outputs lrw and liw, which are + (respectively) the lengths of the real and integer work spaces + allocated here. + +**********************************************************************/ + +static booleantype CVAllocVectors(CVodeMem cv_mem, integertype neq, + int maxord, M_Env machEnv) +{ + int i, j; + + /* Allocate ewt, acor, tempv, ftemp */ + + ewt = N_VNew(neq, machEnv); + if (ewt == NULL) return(FALSE); + acor = N_VNew(neq, machEnv); + if (acor == NULL) { + N_VFree(ewt); + return(FALSE); + } + tempv = N_VNew(neq, machEnv); + if (tempv == NULL) { + N_VFree(ewt); + N_VFree(acor); + return(FALSE); + } + ftemp = N_VNew(neq, machEnv); + if (ftemp == NULL) { + N_VFree(tempv); + N_VFree(ewt); + N_VFree(acor); + return(FALSE); + } + + /* Allocate zn[0] ... zn[maxord] */ + + for (j=0; j <= maxord; j++) { + zn[j] = N_VNew(neq, machEnv); + if (zn[j] == NULL) { + N_VFree(ewt); + N_VFree(acor); + N_VFree(tempv); + N_VFree(ftemp); + for (i=0; i < j; i++) N_VFree(zn[i]); + return(FALSE); + } + } + + /* Set solver workspace lengths */ + + lrw = (maxord + 5)*neq; + liw = 0; + + return(TRUE); +} + +/***************** CVFreeVectors ********************************* + + This routine frees the CVODE vectors allocated in CVAllocVectors. + +******************************************************************/ + +static void CVFreeVectors(CVodeMem cv_mem, int maxord) +{ + int j; + + N_VFree(ewt); + N_VFree(acor); + N_VFree(tempv); + N_VFree(ftemp); + for(j=0; j <= maxord; j++) N_VFree(zn[j]); +} + +/*********************** CVEwtSet ************************************** + + This routine is responsible for setting the error weight vector ewt, + according to tol_type, as follows: + + (1) ewt[i] = 1 / (*reltol * ABS(ycur[i]) + *abstol), i=0,...,neq-1 + if tol_type = SS + (2) ewt[i] = 1 / (*reltol * ABS(ycur[i]) + abstol[i]), i=0,...,neq-1 + if tol_type = SV + + CVEwtSet returns TRUE if ewt is successfully set as above to a + positive vector and FALSE otherwise. In the latter case, ewt is + considered undefined after the FALSE return from CVEwtSet. + + All the real work is done in the routines CVEwtSetSS, CVEwtSetSV. + +***********************************************************************/ + +static booleantype CVEwtSet(CVodeMem cv_mem, N_Vector ycur) +{ + switch(itol) { + case SS: return(CVEwtSetSS(cv_mem, ycur)); + case SV: return(CVEwtSetSV(cv_mem, ycur)); + } + return(-99); +} + +/*********************** CVEwtSetSS ********************************* + + This routine sets ewt as decribed above in the case tol_type = SS. + It tests for non-positive components before inverting. CVEwtSetSS + returns TRUE if ewt is successfully set to a positive vector + and FALSE otherwise. In the latter case, ewt is considered + undefined after the FALSE return from CVEwtSetSS. + +********************************************************************/ + +static booleantype CVEwtSetSS(CVodeMem cv_mem, N_Vector ycur) +{ + realtype rtoli, atoli; + + rtoli = *reltol; + atoli = *((realtype *)abstol); + N_VAbs(ycur, tempv); + N_VScale(rtoli, tempv, tempv); + N_VAddConst(tempv, atoli, tempv); + if (N_VMin(tempv) <= ZERO) return(FALSE); + N_VInv(tempv, ewt); + return(TRUE); +} + +/*********************** CVEwtSetSV ********************************* + + This routine sets ewt as decribed above in the case tol_type = SV. + It tests for non-positive components before inverting. CVEwtSetSV + returns TRUE if ewt is successfully set to a positive vector + and FALSE otherwise. In the latter case, ewt is considered + undefined after the FALSE return from CVEwtSetSV. + +********************************************************************/ + +static booleantype CVEwtSetSV(CVodeMem cv_mem, N_Vector ycur) +{ + realtype rtoli; + rtoli = *reltol; + N_VAbs(ycur, tempv); + N_VLinearSum(rtoli, tempv, ONE, (N_Vector) abstol, tempv); + if (N_VMin(tempv) <= ZERO) return(FALSE); + N_VInv(tempv, ewt); + return(TRUE); +} + +/******************* CVHin *************************************** + + This routine computes a tentative initial step size h0. + If tout is too close to tn (= t0), then CVHin returns FALSE and + h remains uninitialized. Otherwise, CVHin sets h to the chosen + value h0 and returns TRUE. + + The algorithm used seeks to find h0 as a solution of + (WRMS norm of (h0^2 ydd / 2)) = 1, + where ydd = estimated second derivative of y. + +*****************************************************************/ + +static booleantype CVHin(CVodeMem cv_mem, realtype tout) +{ + int sign, count; + realtype tdiff, tdist, tround, hlb, hub; + realtype hg, hgs, hnew, hrat, h0, yddnrm; + + /* Test for tout too close to tn */ + + if ((tdiff = tout-tn) == ZERO) return(FALSE); + + sign = (tdiff > ZERO) ? 1 : -1; + tdist = ABS(tdiff); + tround = uround * MAX(ABS(tn), ABS(tout)); + if (tdist < TWO*tround) return(FALSE); + + /* Set lower and upper bounds on h0, and take geometric mean + Exit with this value if the bounds cross each other */ + + hlb = HLB_FACTOR * tround; + hub = CVUpperBoundH0(cv_mem, tdist); + hg = RSqrt(hlb*hub); + if (hub < hlb) { + if (sign == -1) hg = -hg; + h = hg; + return(TRUE); + } + + /* Loop up to MAX_ITERS times to find h0. + Stop if new and previous values differ by a factor < 2. + Stop if hnew/hg > 2 after one iteration, as this probably means + that the ydd value is bad because of cancellation error. */ + + count = 0; + loop { + hgs = hg*sign; + yddnrm = CVYddNorm(cv_mem, hgs); + if (cvode_error == TRUE) { + hg /= 2.; +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE, "halving step in CVHin\n"); +#endif + continue; + } + + hnew = (yddnrm*hub*hub > TWO) ? RSqrt(TWO/yddnrm) : RSqrt(hg*hub); + count++; + if (count >= MAX_ITERS) break; + hrat = hnew/hg; + if ((hrat > HALF) && (hrat < TWO)) break; + if ((count >= 2) && (hrat > TWO)) { + hnew = hg; + break; + } + hg = hnew; + } + + /* Apply bounds, bias factor, and attach sign */ + + h0 = H_BIAS*hnew; + if (h0 < hlb) h0 = hlb; + if (h0 > hub) h0 = hub; + if (sign == -1) h0 = -h0; + h = h0; + return(TRUE); +} + +/******************** CVUpperBoundH0 ****************************** + + This routine sets an upper bound on abs(h0) based on + tdist = abs(tout - t0) and the values of y[i]/y'[i]. + +******************************************************************/ + +static realtype CVUpperBoundH0(CVodeMem cv_mem, realtype tdist) +{ + realtype atoli, hub_inv, hub; + booleantype vectorAtol; + N_Vector temp1, temp2; + + atoli = 0; + vectorAtol = (itol == SV); + if (!vectorAtol) atoli = *((realtype *) abstol); + temp1 = tempv; + temp2 = acor; + N_VAbs(zn[0], temp1); + N_VAbs(zn[1], temp2); + if (vectorAtol) { + N_VLinearSum(HUB_FACTOR, temp1, ONE, (N_Vector)abstol, temp1); + } else { + N_VScale(HUB_FACTOR, temp1, temp1); + N_VAddConst(temp1, atoli, temp1); + } + N_VDiv(temp2, temp1, temp1); + hub_inv = N_VMaxNorm(temp1); + hub = HUB_FACTOR*tdist; + if (hub*hub_inv > ONE) hub = ONE/hub_inv; + return(hub); +} + +/****************** CVYddNorm ************************************* + + This routine computes an estimate of the second derivative of y + using a difference quotient, and returns its WRMS norm. + +******************************************************************/ + +static realtype CVYddNorm(CVodeMem cv_mem, realtype hg) +{ + realtype yddnrm; + + N_VLinearSum(hg, zn[1], ONE, zn[0], y); + f(N, tn+hg, y, tempv, f_data); +#ifdef DEBUG_CVODE + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"CVYddNorm error\n"); + } +#endif + nfe++; + N_VLinearSum(ONE, tempv, -ONE, zn[1], tempv); + N_VScale(ONE/hg, tempv, tempv); + + yddnrm = N_VWrmsNorm(tempv, ewt); + return(yddnrm); +} + +/********************* CVStep ************************************** + + This routine performs one internal cvode step, from tn to tn + h. + It calls other routines to do all the work. + + The main operations done here are as follows: + * preliminary adjustments if a new step size was chosen; + * prediction of the Nordsieck history array zn at tn + h; + * setting of multistep method coefficients and test quantities; + * solution of the nonlinear system; + * testing the local error; + * updating zn and other state data if successful; + * resetting stepsize and order for the next step. + * if SLDET is on, check for stability, reduce order if necessary. + On a failure in the nonlinear system solution or error test, the + step may be reattempted, depending on the nature of the failure. + +********************************************************************/ + +static int CVStep(CVodeMem cv_mem) +{ + realtype saved_t, dsm; + int ncf, nef, nflag; + booleantype passed; + + int kflag; + + saved_t = tn; + ncf = nef = 0; + nflag = FIRST_CALL; + + + if ((nst > 0) && (hprime != h)) CVAdjustParams(cv_mem); + + /* Looping point for attempts to take a step */ + loop { + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"Before predict, y Fail, time %e\n", tn); +#endif + } else { + cvode_prev_good_time = cvode_last_good_time; + N_VScale(1.0, cvode_last_good_y, cvode_prev_good_y); + cvode_last_good_time = tn; + N_VScale(1.0, y, cvode_last_good_y); +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"Before predict, y OK, time %e\n", tn); +#endif + } +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"Before predict, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"Before predict, zn OK\n"); + } + saved_t = tn; +#endif + CVPredict(cv_mem); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After predict, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After predict, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After predict, zn Fail\n"); + + } else { + output_msg(OUTPUT_CVODE,"After predict, zn OK\n"); + } +#endif + CVSet(cv_mem); + + nflag = CVnls(cv_mem, nflag); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After CVnls, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After CVnls, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After CVnls, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After CVnls, zn OK\n"); + } +#endif + kflag = CVHandleNFlag(cv_mem, &nflag, saved_t, &ncf); + if (kflag == PREDICT_AGAIN) continue; + if (kflag != DO_ERROR_TEST) return(kflag); + /* Return if nonlinear solve failed and recovery not possible. */ +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"Before error test, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"Before error test, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"Before error test, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"Before error test, zn OK\n"); + } +#endif + passed = CVDoErrorTest(cv_mem, &nflag, &kflag, saved_t, &nef, &dsm); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After error test, y Fail, passed %d\n", passed); + } else { + output_msg(OUTPUT_CVODE,"After error test, y OK, passed %d\n", passed); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After error test, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After error test, zn OK\n"); + } +#endif + /* Return if error test failed and recovery not possible. */ + if ((!passed) && (kflag == REP_ERR_FAIL)) return(kflag); + if (passed) break; + /* Retry step if error test failed, nflag == PREV_ERR_FAIL */ + } +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE, "Finished step in CVStep\n"); +#endif + /* Nonlinear system solve and error test were both successful. + Update data, and consider change of step and/or order. */ + + + CVCompleteStep(cv_mem); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After complete step, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After complete step, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After complete step, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After complete step, zn OK\n"); + } +#endif + CVPrepareNextStep(cv_mem, dsm); + + /* If Stablilty Limit Detection is turned on, call stability limit + detection routine for possible order reduction. */ + + if (sldeton) CVBDFStab(cv_mem); +#ifdef DEBUG_CVODE + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After cvbfdstab, y Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After cvbfdstab, y OK\n"); + } + cvode_test = TRUE; + f(N, tn, zn[0], ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"After cvbfdstab, zn Fail\n"); + } else { + output_msg(OUTPUT_CVODE,"After cvbfdstab, zn OK\n"); + } +#endif + etamax = (nst <= SMALL_NST) ? ETAMX2 : ETAMX3; + + /* Finally, we rescale the acor array to be the + estimated local error vector. */ + + N_VScale(ONE/tq[2], acor, acor); + return(SUCCESS_STEP); + +} + + +/********************* CVAdjustParams ******************************** + + This routine is called when a change in step size was decided upon, + and it handles the required adjustments to the history array zn. + If there is to be a change in order, we call CVAdjustOrder and reset + q, L = q+1, and qwait. Then in any case, we call CVRescale, which + resets h and rescales the Nordsieck array. + +**********************************************************************/ + +static void CVAdjustParams(CVodeMem cv_mem) +{ + if (qprime != q) { + CVAdjustOrder(cv_mem, qprime-q); + q = qprime; + L = q+1; + qwait = L; + } + CVRescale(cv_mem); +} + +/********************* CVAdjustOrder ***************************** + + This routine is a high level routine which handles an order + change by an amount deltaq (= +1 or -1). If a decrease in order + is requested and q==2, then the routine returns immediately. + Otherwise CVAdjustAdams or CVAdjustBDF is called to handle the + order change (depending on the value of lmm). + +******************************************************************/ + +static void CVAdjustOrder(CVodeMem cv_mem, int deltaq) +{ + if ((q==2) && (deltaq != 1)) return; + + switch(lmm){ + case ADAMS: CVAdjustAdams(cv_mem, deltaq); + break; + case BDF: CVAdjustBDF(cv_mem, deltaq); + break; + } +} + +/*************** CVAdjustAdams *********************************** + + This routine adjusts the history array on a change of order q by + deltaq, in the case that lmm == ADAMS. + +*****************************************************************/ + +static void CVAdjustAdams(CVodeMem cv_mem, int deltaq) +{ + int i, j; + realtype xi, hsum; + + /* On an order increase, set new column of zn to zero and return */ + + if (deltaq==1) { + N_VConst(ZERO, zn[L]); + return; + } + + /* On an order decrease, each zn[j] is adjusted by a multiple + of zn[q]. The coefficients in the adjustment are the + coefficients of the polynomial x*x*(x+xi_1)*...*(x+xi_j), + integrated, where xi_j = [t_n - t_(n-j)]/h. */ + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[1] = ONE; + hsum = ZERO; + for (j=1; j <= q-2; j++) { + hsum += tau[j]; + xi = hsum / hscale; + for (i=j+1; i >= 1; i--) l[i] = l[i]*xi + l[i-1]; + } + + for (j=1; j <= q-2; j++) l[j+1] = q * (l[j] / (j+1)); + + for (j=2; j < q; j++) + N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); +} + +/********************** CVAdjustBDF ******************************* + + This is a high level routine which handles adjustments to the + history array on a change of order by deltaq in the case that + lmm == BDF. CVAdjustBDF calls CVIncreaseBDF if deltaq = +1 and + CVDecreaseBDF if deltaq = -1 to do the actual work. + +******************************************************************/ + +static void CVAdjustBDF(CVodeMem cv_mem, int deltaq) +{ + switch(deltaq) { + case 1 : CVIncreaseBDF(cv_mem); + return; + case -1: CVDecreaseBDF(cv_mem); + return; + } +} + +/******************** CVIncreaseBDF ********************************** + + This routine adjusts the history array on an increase in the + order q in the case that lmm == BDF. + A new column zn[q+1] is set equal to a multiple of the saved + vector (= acor) in zn[qmax]. Then each zn[j] is adjusted by + a multiple of zn[q+1]. The coefficients in the adjustment are the + coefficients of the polynomial x*x*(x+xi_1)*...*(x+xi_(q-1)), + where xi_j = [t_n - t_(n-j)]/h. + +*********************************************************************/ + +static void CVIncreaseBDF(CVodeMem cv_mem) +{ + realtype alpha0, alpha1, prod, xi, xiold, hsum, A1; + int i, j; + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[2] = alpha1 = prod = xiold = ONE; + alpha0 = -ONE; + hsum = hscale; + if (q > 1) { + for (j=1; j < q; j++) { + hsum += tau[j+1]; + xi = hsum / hscale; + prod *= xi; + alpha0 -= ONE / (j+1); + alpha1 += ONE / xi; + for (i=j+2; i >= 2; i--) l[i] = l[i]*xiold + l[i-1]; + xiold = xi; + } + } + A1 = (-alpha0 - alpha1) / prod; + N_VScale(A1, zn[qmax], zn[L]); + for (j=2; j <= q; j++) { + N_VLinearSum(l[j], zn[L], ONE, zn[j], zn[j]); + } +} + +/********************* CVDecreaseBDF ****************************** + + This routine adjusts the history array on a decrease in the + order q in the case that lmm == BDF. + Each zn[j] is adjusted by a multiple of zn[q]. The coefficients + in the adjustment are the coefficients of the polynomial + x*x*(x+xi_1)*...*(x+xi_(q-2)), where xi_j = [t_n - t_(n-j)]/h. + +******************************************************************/ + +static void CVDecreaseBDF(CVodeMem cv_mem) +{ + realtype hsum, xi; + int i, j; + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[2] = ONE; + hsum = ZERO; + for(j=1; j <= q-2; j++) { + hsum += tau[j]; + xi = hsum /hscale; + for (i=j+2; i >= 2; i--) l[i] = l[i]*xi + l[i-1]; + } + + for(j=2; j < q; j++) + N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); +} + +/**************** CVRescale *********************************** + + This routine rescales the Nordsieck array by multiplying the + jth column zn[j] by eta^j, j = 1, ..., q. Then the value of + h is rescaled by eta, and hscale is reset to h. + +***************************************************************/ + +static void CVRescale(CVodeMem cv_mem) +{ + int j; + realtype factor; + + factor = eta; + for (j=1; j <= q; j++) { + N_VScale(factor, zn[j], zn[j]); + factor *= eta; + } + h = hscale * eta; + hscale = h; + nscon = 0; +} + +/********************* CVPredict ************************************* + + This routine advances tn by the tentative step size h, and computes + the predicted array z_n(0), which is overwritten on zn. The + prediction of zn is done by repeated additions. + +*********************************************************************/ + +static void CVPredict(CVodeMem cv_mem) +{ + int j, k; + + tn += h; + for (k = 1; k <= q; k++) + for (j = q; j >= k; j--) + N_VLinearSum(ONE, zn[j-1], ONE, zn[j], zn[j-1]); +} + +/************************** CVSet ********************************* + + This routine is a high level routine which calls CVSetAdams or + CVSetBDF to set the polynomial l, the test quantity array tq, + and the related variables rl1, gamma, and gamrat. + +******************************************************************/ + +static void CVSet(CVodeMem cv_mem) +{ + switch(lmm) { + case ADAMS: CVSetAdams(cv_mem); + break; + case BDF : CVSetBDF(cv_mem); + break; + } + rl1 = ONE / l[1]; + gamma = h * rl1; + if (nst == 0) gammap = gamma; + gamrat = (nst > 0) ? gamma / gammap : ONE; /* protect x / x != 1.0 */ +} + +/******************** CVSetAdams ********************************* + + This routine handles the computation of l and tq for the + case lmm == ADAMS. + + The components of the array l are the coefficients of a + polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by + q-1 + (d/dx) Lambda(x) = c * PRODUCT (1 + x / xi_i) , where + i=1 + Lambda(-1) = 0, Lambda(0) = 1, and c is a normalization factor. + Here xi_i = [t_n - t_(n-i)] / h. + + The array tq is set to test quantities used in the convergence + test, the error test, and the selection of h at a new order. + +*****************************************************************/ + +static void CVSetAdams(CVodeMem cv_mem) +{ + realtype m[L_MAX], M[3], hsum; + + if (q == 1) { + l[0] = l[1] = tq[1] = tq[5] = ONE; + tq[2] = TWO; + tq[3] = TWELVE; + tq[4] = CORTES * tq[2]; /* = 0.1 * tq[2] */ + return; + } + + hsum = CVAdamsStart(cv_mem, m); + + M[0] = CVAltSum(q-1, m, 1); + M[1] = CVAltSum(q-1, m, 2); + + CVAdamsFinish(cv_mem, m, M, hsum); +} + +/****************** CVAdamsStart ******************************** + + This routine generates in m[] the coefficients of the product + polynomial needed for the Adams l and tq coefficients for q > 1. + +******************************************************************/ + +static realtype CVAdamsStart(CVodeMem cv_mem, realtype m[]) +{ + realtype hsum, xi_inv, sum; + int i, j; + + hsum = h; + m[0] = ONE; + for (i=1; i <= q; i++) m[i] = ZERO; + for (j=1; j < q; j++) { + if ((j==q-1) && (qwait == 1)) { + sum = CVAltSum(q-2, m, 2); + tq[1] = m[q-2] / (q * sum); + } + xi_inv = h / hsum; + for (i=j; i >= 1; i--) m[i] += m[i-1] * xi_inv; + hsum += tau[j]; + /* The m[i] are coefficients of product(1 to j) (1 + x/xi_i) */ + } + return(hsum); +} + +/****************** CVAdamsFinish ******************************* + + This routine completes the calculation of the Adams l and tq. + +******************************************************************/ + +static void CVAdamsFinish(CVodeMem cv_mem, realtype m[], realtype M[], + realtype hsum) +{ + int i; + realtype M0_inv, xi, xi_inv; + + M0_inv = ONE / M[0]; + + l[0] = ONE; + for (i=1; i <= q; i++) l[i] = M0_inv * (m[i-1] / i); + xi = hsum / h; + xi_inv = ONE / xi; + + tq[2] = xi * M[0] / M[1]; + tq[5] = xi / l[q]; + + if (qwait == 1) { + for (i=q; i >= 1; i--) m[i] += m[i-1] * xi_inv; + M[2] = CVAltSum(q, m, 2); + tq[3] = L * M[0] / M[2]; + } + + tq[4] = CORTES * tq[2]; +} + +/****************** CVAltSum ************************************** + + CVAltSum returns the value of the alternating sum + sum (i= 0 ... iend) [ (-1)^i * (a[i] / (i + k)) ]. + If iend < 0 then CVAltSum returns 0. + This operation is needed to compute the integral, from -1 to 0, + of a polynomial x^(k-1) M(x) given the coefficients of M(x). + +******************************************************************/ + +static realtype CVAltSum(int iend, realtype a[], int k) +{ + int i, sign; + realtype sum; + + if (iend < 0) return(ZERO); + + sum = ZERO; + sign = 1; + for (i=0; i <= iend; i++) { + sum += sign * (a[i] / (i+k)); + sign = -sign; + } + return(sum); +} + +/***************** CVSetBDF ************************************** + + This routine computes the coefficients l and tq in the case + lmm == BDF. CVSetBDF calls CVSetTqBDF to set the test + quantity array tq. + + The components of the array l are the coefficients of a + polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by + q-1 + Lambda(x) = (1 + x / xi*_q) * PRODUCT (1 + x / xi_i) , where + i=1 + xi_i = [t_n - t_(n-i)] / h. + + The array tq is set to test quantities used in the convergence + test, the error test, and the selection of h at a new order. + + +*****************************************************************/ + +static void CVSetBDF(CVodeMem cv_mem) +{ + realtype alpha0, alpha0_hat, xi_inv, xistar_inv, hsum; + int i,j; + + l[0] = l[1] = xi_inv = xistar_inv = ONE; + for (i=2; i <= q; i++) l[i] = ZERO; + alpha0 = alpha0_hat = -ONE; + hsum = h; + if (q > 1) { + for (j=2; j < q; j++) { + hsum += tau[j-1]; + xi_inv = h / hsum; + alpha0 -= ONE / j; + for(i=j; i >= 1; i--) l[i] += l[i-1]*xi_inv; + /* The l[i] are coefficients of product(1 to j) (1 + x/xi_i) */ + } + + /* j = q */ + alpha0 -= ONE / q; + xistar_inv = -l[1] - alpha0; + hsum += tau[q-1]; + xi_inv = h / hsum; + alpha0_hat = -l[1] - xi_inv; + for (i=q; i >= 1; i--) l[i] += l[i-1]*xistar_inv; + } + + CVSetTqBDF(cv_mem, hsum, alpha0, alpha0_hat, xi_inv, xistar_inv); +} + +/****************** CVSetTqBDF ************************************ + + This routine sets the test quantity array tq when lmm == BDF. + +******************************************************************/ + +static void CVSetTqBDF(CVodeMem cv_mem, realtype hsum, realtype alpha0, + realtype alpha0_hat, realtype xi_inv, realtype xistar_inv) +{ + realtype A1, A2, A3, A4, A5, A6; + realtype C, CPrime, CPrimePrime; + + A1 = ONE - alpha0_hat + alpha0; + A2 = ONE + q * A1; + tq[2] = ABS(alpha0 * (A2 / A1)); + tq[5] = ABS((A2) / (l[q] * xi_inv/xistar_inv)); + if (qwait == 1) { + C = xistar_inv / l[q]; + A3 = alpha0 + ONE / q; + A4 = alpha0_hat + xi_inv; + CPrime = A3 / (ONE - A4 + A3); + tq[1] = ABS(CPrime / C); + hsum += tau[q]; + xi_inv = h / hsum; + A5 = alpha0 - (ONE / (q+1)); + A6 = alpha0_hat - xi_inv; + CPrimePrime = A2 / (ONE - A6 + A5); + tq[3] = ABS(CPrimePrime * xi_inv * (q+2) * A5); + } + tq[4] = CORTES * tq[2]; +} + +/****************** CVnls ***************************************** + + This routine attempts to solve the nonlinear system associated + with a single implicit step of the linear multistep method. + Depending on iter, it calls CVnlsFunctional or CVnlsNewton + to do the work. + +******************************************************************/ + +static int CVnls(CVodeMem cv_mem, int nflag) +{ + switch(iter) { + case FUNCTIONAL : return(CVnlsFunctional(cv_mem)); + case NEWTON : return(CVnlsNewton(cv_mem, nflag)); + } + return(-99); +} + +/***************** CVnlsFunctional ******************************** + + This routine attempts to solve the nonlinear system using + functional iteration (no matrices involved). + +******************************************************************/ + +static int CVnlsFunctional(CVodeMem cv_mem) +{ + int m; + realtype del, delp, dcon; + + /* Initialize counter and evaluate f at predicted y */ + + delp = 0; + crate = ONE; + m = 0; + f(N, tn, zn[0], tempv, f_data); + nfe++; + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsFunctional, Fail at beginning\n"); +#endif + return(CONV_FAIL); + } else { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsFunctional, OK at beginning\n"); +#endif + } + N_VConst(ZERO, acor); + + /* Loop until convergence; accumulate corrections in acor */ + + loop { + /* Correct y directly from the last f value */ + N_VLinearSum(h, tempv, -ONE, zn[1], tempv); + N_VScale(rl1, tempv, tempv); + N_VLinearSum(ONE, zn[0], ONE, tempv, y); + /* Get WRMS norm of current correction to use in convergence test */ + N_VLinearSum(ONE, tempv, -ONE, acor, acor); + del = N_VWrmsNorm(acor, ewt); + N_VScale(ONE, tempv, acor); + + /* Test for convergence. If m > 0, an estimate of the convergence + rate constant is stored in crate, and used in the test. */ + if (m > 0) crate = MAX(CRDOWN * crate, del / delp); + dcon = del * MIN(ONE, crate) / tq[4]; + if (dcon <= ONE) { + acnrm = (m == 0) ? del : N_VWrmsNorm(acor, ewt); + return(SOLVED); /* Convergence achieved */ + } + + /* Stop at maxcor iterations or if iter. seems to be diverging */ + m++; + if ((m==maxcor) || ((m >= 2) && (del > RDIV * delp))) + return(CONV_FAIL); + /* Save norm of correction, evaluate f, and loop again */ + delp = del; + f(N, tn, y, tempv, f_data); + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsFunctional, Fail at end\n"); +#endif + return(CONV_FAIL); + } else { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsFunctional, OK at end\n"); +#endif + } + nfe++; + } +} + +/*********************** CVnlsNewton ********************************** + + This routine handles the Newton iteration. It calls lsetup if + indicated, calls CVNewtonIteration to perform the iteration, and + retries a failed attempt at Newton iteration if that is indicated. + See return values at top of this file. + +**********************************************************************/ + +static int CVnlsNewton(CVodeMem cv_mem, int nflag) +{ + N_Vector vtemp1, vtemp2, vtemp3; + int convfail, ier; + booleantype callSetup; + + vtemp1 = acor; /* rename acor as vtemp1 for readability */ + vtemp2 = y; /* rename y as vtemp2 for readability */ + vtemp3 = tempv; /* rename tempv as vtemp3 for readability */ + + /* Set flag convfail, input to lsetup for its evaluation decision */ + convfail = ((nflag == FIRST_CALL) || (nflag == PREV_ERR_FAIL)) ? + NO_FAILURES : FAIL_OTHER; + + /* Decide whether or not to call setup routine (if one exists) */ + if (setupNonNull) { + callSetup = (nflag == PREV_CONV_FAIL) || (nflag == PREV_ERR_FAIL) || + (nst == 0) || (nst >= nstlp + MSBP) || (ABS(gamrat-ONE) > DGMAX); + } else { + crate = ONE; + callSetup = FALSE; + } + + /* Looping point for the solution of the nonlinear system. + Evaluate f at the predicted y, call lsetup if indicated, and + call CVNewtonIteration for the Newton iteration itself. */ + + loop { + + f(N, tn, zn[0], ftemp, f_data); + + nfe++; + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsNewton, start of loop, time %e\n", tn); +#endif + return (CONV_FAIL); + } else { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsNewton, OK, start of loop, time %e\n", tn); +#endif + } + + if (callSetup) { + ier = lsetup(cv_mem, convfail, zn[0], ftemp, &jcur, + vtemp1, vtemp2, vtemp3); + nsetups++; + callSetup = FALSE; + gamrat = crate = ONE; + gammap = gamma; + nstlp = nst; + /* Return if lsetup failed */ + if (ier < 0) return(SETUP_FAIL_UNREC); + if (ier > 0) return(CONV_FAIL); + } + + /* Set acor to zero and load prediction into y vector */ + N_VConst(ZERO, acor); + N_VScale(ONE, zn[0], y); + + /* Do the Newton iteration */ + ier = CVNewtonIteration(cv_mem); + + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"After CVNewtonIteration, Fail, ier %d\n", ier); +#endif + return(CONV_FAIL); + } else { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"After CVNewtonIteration, OK, ier %d\n", ier); +#endif + } + /* If there is a convergence failure and the Jacobian-related + data appears not to be current, loop again with a call to lsetup + in which convfail=FAIL_BAD_J. Otherwise return. */ + if (ier != TRY_AGAIN) return(ier); + callSetup = TRUE; + convfail = FAIL_BAD_J; + } +} + +/********************** CVNewtonIteration **************************** + + This routine performs the Newton iteration. If the iteration succeeds, + it returns the value SOLVED. If not, it may signal the CVnlsNewton + routine to call lsetup again and reattempt the iteration, by + returning the value TRY_AGAIN. (In this case, CVnlsNewton must set + convfail to FAIL_BAD_J before calling setup again). + Otherwise, this routine returns one of the appropriate values + SOLVE_FAIL_UNREC or CONV_FAIL back to CVnlsNewton. + +*********************************************************************/ + +static int CVNewtonIteration(CVodeMem cv_mem) +{ + int m, ret; + realtype del, delp, dcon; + N_Vector b; + + + mnewt = m = 0; + delp = 0; + + /* Looping point for Newton iteration */ + loop { + + /* Evaluate the residual of the nonlinear system*/ + N_VLinearSum(rl1, zn[1], ONE, acor, tempv); + N_VLinearSum(gamma, ftemp, -ONE, tempv, tempv); + + /* Call the lsolve function */ + b = tempv; + ret = lsolve(cv_mem, b, y, ftemp); + nni++; + + if (ret < 0) return(SOLVE_FAIL_UNREC); + + /* If lsolve had a recoverable failure and Jacobian data is + not current, signal to try the solution again */ + if (ret > 0) { + if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); + return(CONV_FAIL); + } + /* Get WRMS norm of correction; add correction to acor and y */ + del = N_VWrmsNorm(b, ewt); + N_VLinearSum(ONE, acor, ONE, b, acor); + N_VLinearSum(ONE, zn[0], ONE, acor, y); + + /* Test for convergence. If m > 0, an estimate of the convergence + rate constant is stored in crate, and used in the test. */ + if (m > 0) { + crate = MAX(CRDOWN * crate, del/delp); + } + dcon = del * MIN(ONE, crate) / tq[4]; + +#ifdef DEBUG_CVODE + /* added before SOLVED */ + cvode_test = TRUE; + f(N, tn, y, ftemp, f_data); + cvode_test = FALSE; + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE,"CVnlsNewton, Fail at SOLVED\n"); + return(CONV_FAIL); + } else { + output_msg(OUTPUT_CVODE,"CVnlsNewton, OK at SOLVED\n"); + } +#endif + if (dcon <= ONE) { + acnrm = (m==0) ? del : N_VWrmsNorm(acor, ewt); + jcur = FALSE; + return(SOLVED); /* Nonlinear system was solved successfully */ + } + + mnewt = ++m; + + /* Stop at maxcor iterations or if iter. seems to be diverging. + If still not converged and Jacobian data is not current, + signal to try the solution again */ + if ((m == maxcor) || ((m >= 2) && (del > RDIV*delp))) { + if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); + return(CONV_FAIL); + } + + /* Save norm of correction, evaluate f, and loop again */ + delp = del; + f(N, tn, y, ftemp, f_data); + + if (cvode_error == TRUE) { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsNewton, Fail at end\n"); +#endif + return(CONV_FAIL); + } else { +#ifdef DEBUG_CVODE + output_msg(OUTPUT_CVODE,"CVnlsNewton, OK at end\n"); +#endif + } + nfe++; + } +} + +/********************** CVHandleNFlag ******************************* + + This routine takes action on the return value nflag = *nflagPtr + returned by CVnls, as follows: + + If CVnls succeeded in solving the nonlinear system, then + CVHandleNFlag returns the constant DO_ERROR_TEST, which tells CVStep + to perform the error test. + + If the nonlinear system was not solved successfully, then ncfn and + ncf = *ncfPtr are incremented and Nordsieck array zn is restored. + + If the solution of the nonlinear system failed due to an + unrecoverable failure by setup, we return the value SETUP_FAILED. + + If it failed due to an unrecoverable failure in solve, then we return + the value SOLVE_FAILED. + + Otherwise, a recoverable failure occurred when solving the + nonlinear system (CVnls returned nflag == CONV_FAIL). + In this case, we return the value REP_CONV_FAIL if ncf is now + equal to MXNCF or |h| = hmin. + If not, we set *nflagPtr = PREV_CONV_FAIL and return the value + PREDICT_AGAIN, telling CVStep to reattempt the step. + +*********************************************************************/ + +static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, realtype saved_t, + int *ncfPtr) +{ + int nflag; + + nflag = *nflagPtr; + + if (nflag == SOLVED) return(DO_ERROR_TEST); + + /* The nonlinear soln. failed; increment ncfn and restore zn */ + ncfn++; + CVRestore(cv_mem, saved_t); + + /* Return if lsetup or lsolve failed unrecoverably */ + if (nflag == SETUP_FAIL_UNREC) return(SETUP_FAILED); + if (nflag == SOLVE_FAIL_UNREC) return(SOLVE_FAILED); + + /* At this point, nflag == CONV_FAIL; increment ncf */ + + (*ncfPtr)++; + etamax = ONE; + /* If we had MXNCF failures or |h| = hmin, return REP_CONV_FAIL */ + if ((ABS(h) <= hmin*ONEPSM) || (*ncfPtr == MXNCF)) + return(REP_CONV_FAIL); + + /* Reduce step size; return to reattempt the step */ + eta = MAX(ETACF, hmin / ABS(h)); + *nflagPtr = PREV_CONV_FAIL; + CVRescale(cv_mem); + return(PREDICT_AGAIN); +} + +/********************** CVRestore ************************************ + + This routine restores the value of tn to saved_t and undoes the + prediction. After execution of CVRestore, the Nordsieck array zn has + the same values as before the call to CVPredict. + +********************************************************************/ + +static void CVRestore(CVodeMem cv_mem, realtype saved_t) +{ + int j, k; + + tn = saved_t; + for (k = 1; k <= q; k++) + for (j = q; j >= k; j--) + N_VLinearSum(ONE, zn[j-1], -ONE, zn[j], zn[j-1]); +} + +/******************* CVDoErrorTest ******************************** + + This routine performs the local error test. + The weighted local error norm dsm is loaded into *dsmPtr, and + the test dsm ?<= 1 is made. + + If the test passes, CVDoErrorTest returns TRUE. + + If the test fails, we undo the step just taken (call CVRestore), + set *nflagPtr to PREV_ERR_FAIL, and return FALSE. + + If MXNEF error test failures have occurred or if ABS(h) = hmin, + we set *kflagPtr = REP_ERR_FAIL. (Otherwise *kflagPtr has the + value last returned by CVHandleNflag.) + + If more than MXNEF1 error test failures have occurred, an order + reduction is forced. + +******************************************************************/ + +static booleantype CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, int *kflagPtr, + realtype saved_t, int *nefPtr, realtype *dsmPtr) +{ + realtype dsm; + + dsm = acnrm / tq[2]; + + /* If est. local error norm dsm passes test, return TRUE */ + *dsmPtr = dsm; + if (dsm <= ONE) return(TRUE); + + /* Test failed; increment counters, set nflag, and restore zn array */ + (*nefPtr)++; + netf++; + *nflagPtr = PREV_ERR_FAIL; + CVRestore(cv_mem, saved_t); + + /* At MXNEF failures or |h| = hmin, return with kflag = REP_ERR_FAIL */ + if ((ABS(h) <= hmin*ONEPSM) || (*nefPtr == MXNEF)) { + *kflagPtr = REP_ERR_FAIL; + return(FALSE); + } + + /* Set etamax = 1 to prevent step size increase at end of this step */ + etamax = ONE; + + /* Set h ratio eta from dsm, rescale, and return for retry of step */ + if (*nefPtr <= MXNEF1) { + eta = ONE / (RPowerR(BIAS2*dsm,ONE/L) + ADDON); + eta = MAX(ETAMIN, MAX(eta, hmin / ABS(h))); + if (*nefPtr >= SMALL_NEF) eta = MIN(eta, ETAMXF); + CVRescale(cv_mem); + return(FALSE); + } + + /* After MXNEF1 failures, force an order reduction and retry step */ + if (q > 1) { + eta = MAX(ETAMIN, hmin / ABS(h)); + CVAdjustOrder(cv_mem,-1); + L = q; + q--; + qwait = L; + CVRescale(cv_mem); + return(FALSE); + } + + /* If already at order 1, restart: reload zn from scratch */ + eta = MAX(ETAMIN, hmin / ABS(h)); + h *= eta; + hscale = h; + qwait = LONG_WAIT; + nscon = 0; + f(N, tn, zn[0], tempv, f_data); + if (cvode_error == TRUE) { + output_msg(OUTPUT_CVODE, "CVDoErrorTest"); + /*exit(8);*/ + error_msg("CVDoErrorTest", 1 /* STOP */); + } + nfe++; + N_VScale(h, tempv, zn[1]); + return(FALSE); +} + +/*************** CVCompleteStep ********************************** + + This routine performs various update operations when the solution + to the nonlinear system has passed the local error test. + We increment the step counter nst, record the values hu and qu, + update the tau array, and apply the corrections to the zn array. + The tau[i] are the last q values of h, with tau[1] the most recent. + The counter qwait is decremented, and if qwait == 1 (and q < qmax) + we save acor and tq[5] for a possible order increase. + +******************************************************************/ + +static void CVCompleteStep(CVodeMem cv_mem) +{ + int i, j; + + nst++; + nscon++; + hu = h; + qu = q; + + for (i=q; i >= 2; i--) tau[i] = tau[i-1]; + if ((q==1) && (nst > 1)) tau[2] = tau[1]; + tau[1] = h; + + for (j=0; j <= q; j++) + N_VLinearSum(l[j], acor, ONE, zn[j], zn[j]); + qwait--; + if ((qwait == 1) && (q != qmax)) { + N_VScale(ONE, acor, zn[qmax]); + saved_tq5 = tq[5]; + } +} + +/************* CVPrepareNextStep ********************************** + + This routine handles the setting of stepsize and order for the + next step -- hprime and qprime. Along with hprime, it sets the + ratio eta = hprime/h. It also updates other state variables + related to a change of step size or order. + +******************************************************************/ + + static void CVPrepareNextStep(CVodeMem cv_mem, realtype dsm) +{ + /* If etamax = 1, defer step size or order changes */ + if (etamax == ONE) { + qwait = MAX(qwait, 2); + qprime = q; + hprime = h; + eta = ONE; + return; + } + + /* etaq is the ratio of new to old h at the current order */ + etaq = ONE /(RPowerR(BIAS2*dsm,ONE/L) + ADDON); + + /* If no order change, adjust eta and acor in CVSetEta and return */ + if (qwait != 0) { + eta = etaq; + qprime = q; + CVSetEta(cv_mem); + return; + } + + /* If qwait = 0, consider an order change. etaqm1 and etaqp1 are + the ratios of new to old h at orders q-1 and q+1, respectively. + CVChooseEta selects the largest; CVSetEta adjusts eta and acor */ + qwait = 2; + etaqm1 = CVComputeEtaqm1(cv_mem); + etaqp1 = CVComputeEtaqp1(cv_mem); + CVChooseEta(cv_mem); + CVSetEta(cv_mem); +} + +/***************** CVSetEta *************************************** + + This routine adjusts the value of eta according to the various + heuristic limits and the optional input hmax. It also resets + etamax to be the estimated local error vector. + +*******************************************************************/ + +static void CVSetEta(CVodeMem cv_mem) +{ + + /* If eta below the threshhold THRESH, reject a change of step size */ + if (eta < THRESH) { + eta = ONE; + hprime = h; + } else { + /* Limit eta by etamax and hmax, then set hprime */ + eta = MIN(eta, etamax); + eta /= MAX(ONE, ABS(h)*hmax_inv*eta); + hprime = h * eta; + if (qprime < q) nscon = 0; + } + + /* Reset etamax for the next step size change, and scale acor */ +} + +/*************** CVComputeEtaqm1 ********************************** + + This routine computes and returns the value of etaqm1 for a + possible decrease in order by 1. + +******************************************************************/ + +static realtype CVComputeEtaqm1(CVodeMem cv_mem) +{ + realtype ddn; + + etaqm1 = ZERO; + if (q > 1) { + ddn = N_VWrmsNorm(zn[q], ewt) / tq[1]; + etaqm1 = ONE/(RPowerR(BIAS1*ddn, ONE/q) + ADDON); + } + return(etaqm1); +} + +/*************** CVComputeEtaqp1 ********************************** + + This routine computes and returns the value of etaqp1 for a + possible increase in order by 1. + +******************************************************************/ + +static realtype CVComputeEtaqp1(CVodeMem cv_mem) +{ + realtype dup, cquot; + + etaqp1 = ZERO; + if (q != qmax) { + cquot = (tq[5] / saved_tq5) * RPowerI(h/tau[2], L); + N_VLinearSum(-cquot, zn[qmax], ONE, acor, tempv); + dup = N_VWrmsNorm(tempv, ewt) /tq[3]; + etaqp1 = ONE / (RPowerR(BIAS3*dup, ONE/(L+1)) + ADDON); + } + return(etaqp1); +} + +/******************* CVChooseEta ********************************** + + Given etaqm1, etaq, etaqp1 (the values of eta for qprime = + q - 1, q, or q + 1, respectively), this routine chooses the + maximum eta value, sets eta to that value, and sets qprime to the + corresponding value of q. If there is a tie, the preference + order is to (1) keep the same order, then (2) decrease the order, + and finally (3) increase the order. If the maximum eta value + is below the threshhold THRESH, the order is kept unchanged and + eta is set to 1. + +******************************************************************/ + +static void CVChooseEta(CVodeMem cv_mem) +{ + realtype etam; + + etam = MAX(etaqm1, MAX(etaq, etaqp1)); + + if (etam < THRESH) { + eta = ONE; + qprime = q; + return; + } + + if (etam == etaq) { + eta = etaq; + qprime = q; + } else if (etam == etaqm1) { + eta = etaqm1; + qprime = q - 1; + } else { + eta = etaqp1; + qprime = q + 1; + if (lmm == BDF) N_VScale(ONE, acor, zn[qmax]); + } +} + +/****************** CVHandleFailure ****************************** + + This routine prints error messages for all cases of failure by + CVStep. It returns to CVode the value that CVode is to return to + the user. + +*****************************************************************/ + +static int CVHandleFailure(CVodeMem cv_mem, int kflag) +{ + char error_string_long[1000]; + /* Set vector of absolute weighted local errors */ + N_VProd(acor, ewt, tempv); + N_VAbs(tempv, tempv); + + /* Depending on kflag, print error message and return error flag */ + switch (kflag) { + case REP_ERR_FAIL: + sprintf(error_string_long, MSG_ERR_FAILS, (double) tn, (double) h); + warning_msg(error_string_long); + return(ERR_FAILURE); + case REP_CONV_FAIL: + sprintf(error_string_long, MSG_CONV_FAILS, (double) tn, (double) h); + warning_msg(error_string_long); + return(CONV_FAILURE); + case SETUP_FAILED: + sprintf(error_string_long, MSG_SETUP_FAILED, (double) tn); + warning_msg(error_string_long); + return(SETUP_FAILURE); + case SOLVE_FAILED: + sprintf(error_string_long, MSG_SOLVE_FAILED, (double) tn); + warning_msg(error_string_long); + return(SOLVE_FAILURE); + } + return(-99); +} + +/****************** CVBDFStab *********************************** + This routine handles the BDF Stability Limit Detection Algorithm + STALD. It is called if lmm = BDF and the SLDET option is on. + If the order is 3 or more, the required norm data is saved. + If a decision to reduce order has not already been made, and + enough data has been saved, CVsldet is called. If it signals + a stability limit violation, the order is reduced, and the step + size is reset accordingly. + +*****************************************************************/ + +void CVBDFStab(CVodeMem cv_mem) +{ + int i,k, ldflag, factorial; + realtype sq, sqm1, sqm2; + + /* If order is 3 or greater, then save scaled derivative data, + push old data down in i, then add current values to top. */ + + if (q >= 3) { + for (k = 1; k <= 3; k++) + { for (i = 5; i >= 2; i--) ssdat[i][k] = ssdat[i-1][k]; } + factorial = 1; + for (i = 1; i <= q-1; i++) factorial *= i; + sq = factorial*q*(q+1)*acnrm/tq[5]; + sqm1 = factorial*q*N_VWrmsNorm(zn[q], ewt); + sqm2 = factorial*N_VWrmsNorm(zn[q-1], ewt); + ssdat[1][1] = sqm2*sqm2; + ssdat[1][2] = sqm1*sqm1; + ssdat[1][3] = sq*sq; + } + + if (qprime >= q) { + + /* If order is 3 or greater, and enough ssdat has been saved, + nscon >= q+5, then call stability limit detection routine. */ + + if ( (q >= 3) && (nscon >= q+5) ) { + ldflag = CVsldet(cv_mem); + if (ldflag > 3) { + /* A stability limit violation is indicated by + a return flag of 4, 5, or 6. + Reduce new order. */ + qprime = q-1; + eta = etaqm1; + eta = MIN(eta,etamax); + eta = eta/MAX(ONE,ABS(h)*hmax_inv*eta); + hprime = h*eta; + iopt[NOR] =iopt[NOR] + 1; + /* output_msg(OUTPUT_CVODE, + " Order reduced to %d by CVBDFStab at nst = %d,\n h = %e hnew = %e\n", + qprime,nst,h,h*eta); */ + } + } + } + else { + /* Otherwise, let order increase happen, and + reset stability limit counter, nscon. */ + nscon = 0; + } +} + +/********************* CVsldet ************************************ + This routine detects stability limitation using stored scaled + derivatives data. CVsldet returns the magnitude of the + dominate characteristic root, rr. The presents of a stability + limit is indicated by rr > "something a little less then 1.0", + and a positive kflag. This routine should only be called if + order is greater than or equal to 3, and data has been collected + for 5 time steps. + + Returned values: + kflag = 1 -> Found stable characteristic root, normal matrix case + kflag = 2 -> Found stable characteristic root, quartic solution + kflag = 3 -> Found stable characteristic root, quartic solution, + with Newton correction + kflag = 4 -> Found stability violation, normal matrix case + kflag = 5 -> Found stability violation, quartic solution + kflag = 6 -> Found stability violation, quartic solution, + with Newton correction + + kflag < 0 -> No stability limitation, + or could not compute limitation. + + kflag = -1 -> Min/max ratio of ssdat too small. + kflag = -2 -> For normal matrix case, vmax > vrrt2*vrrt2 + kflag = -3 -> For normal matrix case, The three ratios + are inconsistent. + kflag = -4 -> Small coefficient prevents elimination of quartics. + kflag = -5 -> R value from quartics not consistent. + kflag = -6 -> No corrected root passes test on qk values + kflag = -7 -> Trouble solving for sigsq. + kflag = -8 -> Trouble solving for B, or R via B. + kflag = -9 -> R via sigsq[k] disagrees with R from data. + +********************************************************************/ + +static int CVsldet(CVodeMem cv_mem) +{ + integertype i, k, j, it, kmin, kflag = 0; + realtype rat[5][4], rav[4], qkr[4], sigsq[4], smax[4], ssmax[4]; + realtype drr[4], rrc[4],sqmx[4], qjk[4][4], vrat[5], qc[6][4], qco[6][4]; + realtype rr, rrcut, vrrtol, vrrt2, sqtol, rrtol; + realtype smink, smaxk, sumrat, sumrsq, vmin, vmax, drrmax, adrr; + realtype small, tem, sqmax, saqk, qp, s, sqmaxk, saqj, sqmin; + realtype rsa, rsb, rsc, rsd, rse, rd1a, rd1b, rd1c, rd1d; + realtype rd2a, rd2b, rd2c, rd3a, rd3b, cest1, corr1; + realtype ratp, ratm, qfac1, qfac2, bb, rrb; + + /* The following are cutoffs and tolerances used by this routine */ + + rrcut = 0.98; + vrrtol = 1.0e-4; + vrrt2 = 5.0e-4; + sqtol = 1.0e-3; + rrtol = 1.0e-2; + + rr = ZERO; + + /* Index k corresponds to the degree of the interpolating polynomial. */ + /* k = 1 -> q-1 */ + /* k = 2 -> q */ + /* k = 3 -> q+1 */ + + /* Index i is a backward-in-time index, i = 1 -> current time, */ + /* i = 2 -> previous step, etc */ + + /* get maxima, minima, and variances, and form quartic coefficients */ + + for (k=1; k<=3; k++) { + smink = ssdat[1][k]; + smaxk = ZERO; + + for (i=1; i<=5; i++) { + smink = MIN(smink,ssdat[i][k]); + smaxk = MAX(smaxk,ssdat[i][k]); + } + + if (smink < TINY*smaxk) { + kflag = -1; + return(kflag); + } + smax[k] = smaxk; + ssmax[k] = smaxk*smaxk; + + sumrat = ZERO; + sumrsq = ZERO; + for (i=1; i<=4; i++) { + rat[i][k] = ssdat[i][k]/ssdat[i+1][k]; + sumrat = sumrat + rat[i][k]; + sumrsq = sumrsq + rat[i][k]*rat[i][k]; + } + rav[k] = FOURTH*sumrat; + vrat[k] = ABS(FOURTH*sumrsq - rav[k]*rav[k]); + + qc[5][k] = ssdat[1][k]*ssdat[3][k] - ssdat[2][k]*ssdat[2][k]; + qc[4][k] = ssdat[2][k]*ssdat[3][k] - ssdat[1][k]*ssdat[4][k]; + qc[3][k] = ZERO; + qc[2][k] = ssdat[2][k]*ssdat[5][k] - ssdat[3][k]*ssdat[4][k]; + qc[1][k] = ssdat[4][k]*ssdat[4][k] - ssdat[3][k]*ssdat[5][k]; + + for (i=1; i<=5; i++) { + qco[i][k] = qc[i][k]; + } + } /* End of k loop */ + + /* Isolate normal or nearly-normal matrix case. Three quartic will + have common or nearly-common roots in this case. + Return a kflag = 1 if this procedure works. If three root + differ more than vrrt2, return error kflag = -3. */ + + vmin = MIN(vrat[1],MIN(vrat[2],vrat[3])); + vmax = MAX(vrat[1],MAX(vrat[2],vrat[3])); + + if(vmin < vrrtol*vrrtol) { + if (vmax > vrrt2*vrrt2) { + kflag = -2; + return(kflag); + } else { + rr = (rav[1] + rav[2] + rav[3])/THREE; + + drrmax = ZERO; + for(k = 1;k<=3;k++) { + adrr = ABS(rav[k] - rr); + drrmax = MAX(drrmax, adrr); + } + if (drrmax > vrrt2) { + kflag = -3; + } + + kflag = 1; + + /* can compute charactistic root, drop to next section */ + + } + } else { + + /* use the quartics to get rr. */ + + if (ABS(qco[1][1]) < TINY*ssmax[1]) { + small = qco[1][1]; + kflag = -4; + return(kflag); + } + + tem = qco[1][2]/qco[1][1]; + for(i=2; i<=5; i++) { + qco[i][2] = qco[i][2] - tem*qco[i][1]; + } + + qco[1][2] = ZERO; + tem = qco[1][3]/qco[1][1]; + for(i=2; i<=5; i++) { + qco[i][3] = qco[i][3] - tem*qco[i][1]; + } + qco[1][3] = ZERO; + + if (ABS(qco[2][2]) < TINY*ssmax[2]) { + small = qco[2][2]; + kflag = -4; + return(kflag); + } + + tem = qco[2][3]/qco[2][2]; + for(i=3; i<=5; i++) { + qco[i][3] = qco[i][3] - tem*qco[i][2]; + } + + if (ABS(qco[4][3]) < TINY*ssmax[3]) { + small = qco[4][3]; + kflag = -4; + return(kflag); + } + + rr = -qco[5][3]/qco[4][3]; + + if (rr < TINY || rr > HUN) { + kflag = -5; + return(kflag); + } + + for(k=1; k<=3; k++) { + qkr[k] = qc[5][k] + rr*(qc[4][k] + rr*rr*(qc[2][k] + rr*qc[1][k])); + } + + sqmax = ZERO; + for(k=1; k<=3; k++) { + saqk = ABS(qkr[k])/ssmax[k]; + if (saqk > sqmax) sqmax = saqk; + } + sqmin = sqmax; + if (sqmax < sqtol) { + kflag = 2; + + /* can compute charactistic root, drop to "given rr,etc" */ + + } else { + + /* do Newton corrections to improve rr. */ + + for(it=1; it<=3; it++) { + for(k=1; k<=3; k++) { + qp = qc[4][k] + rr*rr*(THREE*qc[2][k] + rr*FOUR*qc[1][k]); + drr[k] = ZERO; + if (ABS(qp) > TINY*ssmax[k]) drr[k] = -qkr[k]/qp; + rrc[k] = rr + drr[k]; + } + + for(k=1; k<=3; k++) { + s = rrc[k]; + sqmaxk = ZERO; + for(j=1; j<=3; j++) { + qjk[j][k] = qc[5][j] + s*(qc[4][j] + + s*s*(qc[2][j] + s*qc[1][j])); + saqj = ABS(qjk[j][k])/ssmax[j]; + if (saqj > sqmaxk) sqmaxk = saqj; + } + sqmx[k] = sqmaxk; + } + + sqmin = sqmx[1]; kmin = 1; + for(k=2; k<=3; k++) { + if (sqmx[k] < sqmin) { + kmin = k; + sqmin = sqmx[k]; + } + } + rr = rrc[kmin]; + + if (sqmin < sqtol) { + kflag = 3; + /* can compute charactistic root */ + /* break out of Newton correction loop and drop to "given rr,etc" */ + break; + } else { + for(j=1; j<=3; j++) { + qkr[j] = qjk[j][kmin]; + } + } + } /* end of Newton correction loop */ + + if (sqmin > sqtol) { + kflag = -6; + return(kflag); + } + } /* end of if (sqmax < sqtol) else */ + } /* end of if(vmin < vrrtol*vrrtol) else, quartics to get rr. */ + + /* given rr, find sigsq[k] and verify rr. */ + /* All positive kflag drop to this section */ + + for(k=1; k<=3; k++) { + rsa = ssdat[1][k]; + rsb = ssdat[2][k]*rr; + rsc = ssdat[3][k]*rr*rr; + rsd = ssdat[4][k]*rr*rr*rr; + rse = ssdat[5][k]*rr*rr*rr*rr; + rd1a = rsa - rsb; + rd1b = rsb - rsc; + rd1c = rsc - rsd; + rd1d = rsd - rse; + rd2a = rd1a - rd1b; + rd2b = rd1b - rd1c; + rd2c = rd1c - rd1d; + rd3a = rd2a - rd2b; + rd3b = rd2b - rd2c; + + if (ABS(rd1b) < TINY*smax[k]) { + kflag = -7; + return(kflag); + } + + cest1 = -rd3a/rd1b; + if (cest1 < TINY || cest1 > FOUR) { + kflag = -7; + return(kflag); + } + corr1 = (rd2b/cest1)/(rr*rr); + sigsq[k] = ssdat[3][k] + corr1; + } + + if (sigsq[2] < TINY) { + kflag = -8; + return(kflag); + } + + ratp = sigsq[3]/sigsq[2]; + ratm = sigsq[1]/sigsq[2]; + qfac1 = FOURTH*(q*q - ONE); + qfac2 = TWO/(q - ONE); + bb = ratp*ratm - ONE - qfac1*ratp; + tem = ONE - qfac2*bb; + + if (ABS(tem) < TINY) { + kflag = -8; + return(kflag); + } + + rrb = ONE/tem; + + if (ABS(rrb - rr) > rrtol) { + kflag = -9; + return(kflag); + } + + /* Check to see if rr is above cutoff rrcut */ + if (rr > rrcut) { + if (kflag == 1) kflag = 4; + if (kflag == 2) kflag = 5; + if (kflag == 3) kflag = 6; + } + + /* All positive kflag returned at this point */ + + return(kflag); + +} + + +/*******************************************************************/ +/********* END Private Helper Functions Implementation *************/ +/*******************************************************************/ + + +/***************************************************************/ +/************** END CVODE Implementation ***********************/ +/***************************************************************/ diff --git a/cvode.h b/cvode.h new file mode 100644 index 00000000..0a81b5bd --- /dev/null +++ b/cvode.h @@ -0,0 +1,882 @@ +/******************************************************************* + * * + * File : cvode.h * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, Radu Serban * + * and Dan Shumaker @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/cvode/LICENSE * + *-----------------------------------------------------------------* + * This is the interface file for the main CVODE integrator. * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidcvode[] = "$Id$"; +#endif + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvode_h +#define _cvode_h + + +#include +#include "sundialstypes.h" +#include "nvector.h" + +/****************************************************************** + * * + * CVODE is used to solve numerically the ordinary initial value * + * problem : * + * * + * y' = f(t,y), * + * y(t0) = y0, * + * * + * where t0, y0 in R^N, and f: R x R^N -> R^N are given. * + * * + ******************************************************************/ + + +/****************************************************************** + * * + * Enumerations for inputs to CVodeMalloc, CVReInit, and CVode. * + *----------------------------------------------------------------* + * Symbolic constants for the lmm, iter, and itol input * + * parameters to CVodeMalloc and CVReInit, as well as the input * + * parameter itask to CVode, are given below. * + * * + * lmm : The user of the CVODE package specifies whether to use * + * the ADAMS or BDF (backward differentiation formula) * + * linear multistep method. The BDF method is recommended * + * for stiff problems, and the ADAMS method is recommended * + * for nonstiff problems. * + * * + * iter : At each internal time step, a nonlinear equation must * + * be solved. The user can specify either FUNCTIONAL * + * iteration, which does not require linear algebra, or a * + * NEWTON iteration, which requires the solution of linear * + * systems. In the NEWTON case, the user also specifies a * + * CVODE linear solver. NEWTON is recommended in case of * + * stiff problems. * + * * + * itol : This parameter specifies the relative and absolute * + * tolerance types to be used. The SS tolerance type means * + * a scalar relative and absolute tolerance, while the SV * + * tolerance type means a scalar relative tolerance and a * + * vector absolute tolerance (a potentially different * + * absolute tolerance for each vector component). * + * * + * itask : The itask input parameter to CVode indicates the job * + * of the solver for the next user step. The NORMAL * + * itask is to have the solver take internal steps until * + * it has reached or just passed the user specified tout * + * parameter. The solver then interpolates in order to * + * return an approximate value of y(tout). The ONE_STEP * + * option tells the solver to just take one internal step * + * and return the solution at the point reached by that * + * step. * + * * + ******************************************************************/ + +enum { ADAMS, BDF }; /* lmm */ + +enum { FUNCTIONAL, NEWTON }; /* iter */ + +enum { SS, SV }; /* itol */ + +enum { NORMAL, ONE_STEP }; /* itask */ + + +/****************************************************************** + * * + * Type : RhsFn * + *----------------------------------------------------------------* + * The f function which defines the right hand side of the ODE * + * system y' = f(t,y) must have type RhsFn. * + * f takes as input the problem size N, the independent variable * + * value t, and the dependent variable vector y. It stores the * + * result of f(t,y) in the vector ydot. The y and ydot arguments * + * are of type N_Vector. * + * (Allocation of memory for ydot is handled within CVODE.) * + * The f_data parameter is the same as the f_data * + * parameter passed by the user to the CVodeMalloc routine. This * + * user-supplied pointer is passed to the user's f function * + * every time it is called. * + * A RhsFn f does not have a return value. * + * * + ******************************************************************/ + +typedef void (*RhsFn)(integertype N, realtype t, N_Vector y, + N_Vector ydot, void *f_data); + + +/****************************************************************** + * * + * Function : CVodeMalloc * + *----------------------------------------------------------------* + * CVodeMalloc allocates and initializes memory for a problem to * + * to be solved by CVODE. * + * * + * N is the number of equations in the ODE system. * + * * + * f is the right hand side function in y' = f(t,y). * + * * + * t0 is the initial value of t. * + * * + * y0 is the initial condition vector y(t0). * + * * + * lmm is the type of linear multistep method to be used. * + * The legal values are ADAMS and BDF (see previous * + * description). * + * * + * iter is the type of iteration used to solve the nonlinear * + * system that arises during each internal time step. * + * The legal values are FUNCTIONAL and NEWTON. * + * * + * itol is the type of tolerances to be used. * + * The legal values are: * + * SS (scalar relative and absolute tolerances), * + * SV (scalar relative tolerance and vector * + * absolute tolerance). * + * * + * reltol is a pointer to the relative tolerance scalar. * + * * + * abstol is a pointer to the absolute tolerance scalar or * + * an N_Vector of absolute tolerances. * + * * + * The parameters itol, reltol, and abstol define a vector of * + * error weights, ewt, with components * + * ewt[i] = 1/(reltol*abs(y[i]) + abstol) (if itol = SS), or * + * ewt[i] = 1/(reltol*abs(y[i]) + abstol[i]) (if itol = SV). * + * This vector is used in all error and convergence tests, which * + * use a weighted RMS norm on all error-like vectors v: * + * WRMSnorm(v) = sqrt( (1/N) sum(i=1..N) (v[i]*ewt[i])^2 ). * + * * + * f_data is a pointer to user data that will be passed to the * + * user's f function every time f is called. * + * * + * errfp is the file pointer for an error file where all CVODE * + * warning and error messages will be written. This * + * parameter can be stdout (standard output), stderr * + * (standard error), a file pointer (corresponding to * + * a user error file opened for writing) returned by * + * fopen, or NULL. If the user passes NULL, then all * + * messages will be written to standard output. * + * * + * optIn is a flag indicating whether there are any optional * + * inputs from the user in the arrays iopt and ropt. * + * Pass FALSE to indicate no optional inputs and TRUE * + * to indicate that optional inputs are present. * + * * + * iopt is the user-allocated array (of size OPT_SIZE given * + * later) that will hold optional integer inputs and * + * outputs. The user can pass NULL if he/she does not * + * wish to use optional integer inputs or outputs. * + * If optIn is TRUE, the user should preset to 0 those * + * locations for which default values are to be used. * + * * + * ropt is the user-allocated array (of size OPT_SIZE given * + * later) that will hold optional real inputs and * + * outputs. The user can pass NULL if he/she does not * + * wish to use optional real inputs or outputs. * + * If optIn is TRUE, the user should preset to 0.0 the * + * locations for which default values are to be used. * + * * + * machEnv is a pointer to machine environment-specific * + * information. * + * * + * Note: The tolerance values may be changed in between calls to * + * CVode for the same problem. These values refer to * + * (*reltol) and either (*abstol), for a scalar absolute * + * tolerance, or the components of abstol, for a vector * + * absolute tolerance. * + * * + * If successful, CVodeMalloc returns a pointer to initialized * + * problem memory. This pointer should be passed to CVode. If * + * an initialization error occurs, CVodeMalloc prints an error * + * message to the file specified by errfp and returns NULL. * + * * + ******************************************************************/ + + +void *CVodeMalloc(integertype N, RhsFn f, realtype t0, N_Vector y0, + int lmm, int iter, int itol, realtype *reltol, + void *abstol, void *f_data, FILE *errfp, + booleantype optIn, long int iopt[], realtype ropt[], + M_Env machEnv); + + +/****************************************************************** + * * + * Function : CVReInit * + *----------------------------------------------------------------* + * CVReInit re-initializes CVode for the solution of a problem, * + * where a prior call to CVodeMalloc has been made with the same * + * problem size N. CVReInit performs the same input checking * + * and initializations that CVodeMalloc does (except for N). * + * But it does no memory allocation, assuming that the existing * + * internal memory is sufficient for the new problem. * + * * + * The use of CVReInit requires that the maximum method order, * + * maxord, is no larger for the new problem than for the problem * + * specified in the last call to CVodeMalloc. This condition is * + * automatically fulfilled if the multistep method parameter lmm * + * is unchanged (or changed from ADAMS to BDF) and the default * + * value for maxord is specified. * + * * + * If iter = NEWTON, then following the call to CVReInit, a call * + * to the linear solver specification routine is necessary if a * + * different linear solver is chosen, but may not be otherwise. * + * If the same linear solver is chosen, and there are no changes * + * in the input parameters to the specification routine, then no * + * call to that routine is needed. * + * If there are changes in parameters, but they do not increase * + * the linear solver memory size, then a call to the corresponding* + * CVReInit routine must made to communicate the new * + * parameters; in that case the linear solver memory is reused. * + * If the parameter changes do increase the linear solver memory * + * size, then the main linear solver specification routine must be* + * called. See the linear solver documentation for full details. * + * * + * The first argument to CVReInit is: * + * * + * cvode_mem = pointer to CVODE memory returned by CVodeMalloc. * + * * + * All the remaining arguments to CVReInit have names and * + * meanings identical to those of CVodeMalloc. Note that the * + * problem size N is not passed as an argument to CVReInit, * + * as that is assumed to be unchanged since the CVodeMalloc call. * + * * + * The return value of CVReInit is equal to SUCCESS = 0 if there * + * were no errors; otherwise it is a negative int equal to: * + * CVREI_NO_MEM indicating cvode_mem was NULL, or * + * CVREI_ILL_INPUT indicating an input argument was illegal * + * (including an attempt to increase maxord). * + * In case of an error return, an error message is also printed. * + * * + * Note: the reported workspace sizes iopt[LENRW] and iopt[LENIW] * + * are left unchanged from the values computed by CVodeMalloc, and* + * so may be larger than would be computed for the new problem. * + ******************************************************************/ + +int CVReInit(void *cvode_mem, RhsFn f, realtype t0, N_Vector y0, + int lmm, int iter, int itol, realtype *reltol, + void *abstol, void *f_data, FILE *errfp, + booleantype optIn, long int iopt[], + realtype ropt[], M_Env machEnv); + + +/* CVReInit return values: */ + +/* SUCCESS = 0 (Defined under CVode return values, but listed + here also for completeness) */ +enum {CVREI_NO_MEM = -1, CVREI_ILL_INPUT = -2}; + + +/****************************************************************** + * * + * Function : CVode * + *----------------------------------------------------------------* + * CVode integrates the ODE over an interval in t. * + * If itask is NORMAL, then the solver integrates from its * + * current internal t value to a point at or beyond tout, then * + * interpolates to t = tout and returns y(tout) in the user- * + * allocated vector yout. If itask is ONE_STEP, then the solver * + * takes one internal time step and returns in yout the value of * + * y at the new internal time. In this case, tout is used only * + * during the first call to CVode to determine the direction of * + * integration and the rough scale of the problem. In either * + * case, the time reached by the solver is placed in (*t). The * + * user is responsible for allocating the memory for this value. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * tout is the next time at which a computed solution is desired * + * * + * yout is the computed solution vector. In NORMAL mode with no * + * errors, yout=y(tout). * + * * + * t is a pointer to a real location. CVode sets (*t) to the * + * time reached by the solver and returns yout=y(*t). * + * * + * itask is either NORMAL or ONE_STEP mode. These two modes have * + * been described above. * + * * + * The return values for CVode are defined later in this file. * + * Here is a brief description of each return value: * + * * + * SUCCESS : CVode succeeded. * + * * + * CVODE_NO_MEM : The cvode_mem argument was NULL. * + * * + * ILL_INPUT : One of the inputs to CVode is illegal. This * + * includes the situation when a component of the * + * error weight vectors becomes < 0 during * + * internal time-stepping. The ILL_INPUT flag * + * will also be returned if the linear solver * + * routine CV--- (called by the user after * + * calling CVodeMalloc) failed to set one of the * + * linear solver-related fields in cvode_mem or * + * if the linear solver's init routine failed. In * + * any case, the user should see the printed * + * error message for more details. * + * * + * TOO_MUCH_WORK : The solver took mxstep internal steps but * + * could not reach tout. The default value for * + * mxstep is MXSTEP_DEFAULT = 500. * + * * + * TOO_MUCH_ACC : The solver could not satisfy the accuracy * + * demanded by the user for some internal step. * + * * + * ERR_FAILURE : Error test failures occurred too many times * + * (= MXNEF = 7) during one internal time step or * + * occurred with |h| = hmin. * + * * + * CONV_FAILURE : Convergence test failures occurred too many * + * times (= MXNCF = 10) during one internal time * + * step or occurred with |h| = hmin. * + * * + * SETUP_FAILURE : The linear solver's setup routine failed in an * + * unrecoverable manner. * + * * + * SOLVE_FAILURE : The linear solver's solve routine failed in an * + * unrecoverable manner. * + * * + ******************************************************************/ + + +int CVode(void *cvode_mem, realtype tout, N_Vector yout, + realtype *t, int itask); + + +/* CVode return values */ + +enum { SUCCESS=0, CVODE_NO_MEM=-1, ILL_INPUT=-2, TOO_MUCH_WORK=-3, + TOO_MUCH_ACC=-4, ERR_FAILURE=-5, CONV_FAILURE=-6, + SETUP_FAILURE=-7, SOLVE_FAILURE=-8 }; + + +/****************************************************************** + * * + * Function : CVodeDky * + *----------------------------------------------------------------* + * CVodeDky computes the kth derivative of the y function at * + * time t, where tn-hu <= t <= tn, tn denotes the current * + * internal time reached, and hu is the last internal step size * + * successfully used by the solver. The user may request * + * k=0, 1, ..., qu, where qu is the current order. The * + * derivative vector is returned in dky. This vector must be * + * allocated by the caller. It is only legal to call this * + * function after a successful return from CVode. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * t is the time at which the kth derivative of y is evaluated. * + * The legal range for t is [tn-hu,tn] as described above. * + * * + * k is the order of the derivative of y to be computed. The * + * legal range for k is [0,qu] as described above. * + * * + * dky is the output derivative vector [(D_k)y](t). * + * * + * The return values for CVodeDky are defined later in this file. * + * Here is a brief description of each return value: * + * * + * OKAY : CVodeDky succeeded. * + * * + * BAD_K : k is not in the range 0, 1, ..., qu. * + * * + * BAD_T : t is not in the interval [tn-hu,tn]. * + * * + * BAD_DKY : The dky argument was NULL. * + * * + * DKY_NO_MEM : The cvode_mem argument was NULL. * + * * + ******************************************************************/ + + +int CVodeDky(void *cvode_mem, realtype t, int k, N_Vector dky); + + +/* CVodeDky return values */ + +enum { OKAY=0, BAD_K=-1, BAD_T=-2, BAD_DKY=-3, DKY_NO_MEM=-4 }; + + +/****************************************************************** + * * + * Function : CVodeFree * + *----------------------------------------------------------------* + * CVodeFree frees the problem memory cvode_mem allocated by * + * CVodeMalloc. Its only argument is the pointer cvode_mem * + * returned by CVodeMalloc. * + * * + ******************************************************************/ + +void CVodeFree(void *cvode_mem); + + +/****************************************************************** + * * + * Optional Inputs and Outputs * + *----------------------------------------------------------------* + * The user should declare two arrays for optional input and * + * output, an iopt array for optional integer input and output * + * and an ropt array for optional real input and output. The * + * size of both these arrays should be OPT_SIZE. * + * So the user's declaration should look like: * + * * + * long int iopt[OPT_SIZE]; * + * realtype ropt[OPT_SIZE]; * + * * + * The enumerations below the OPT_SIZE definition * + * are indices into the iopt and ropt arrays. Here is a brief * + * description of the contents of these positions: * + * * + * iopt[MAXORD] : maximum lmm order to be used by the solver. * + * Optional input. (Default = 12 for ADAMS, 5 for * + * BDF). * + * * + * iopt[MXSTEP] : maximum number of internal steps to be taken by * + * the solver in its attempt to reach tout. * + * Optional input. (Default = 500). * + * * + * iopt[MXHNIL] : maximum number of warning messages issued by the* + * solver that t + h = t on the next internal step.* + * A value of -1 means no such messages are issued.* + * Optional input. (Default = 10). * + * * + * iopt[NST] : cumulative number of internal steps taken by * + * the solver (total so far). Optional output. * + * * + * iopt[NFE] : number of calls to the user's f function. * + * Optional output. * + * * + * iopt[NSETUPS] : number of calls made to the linear solver's * + * setup routine. Optional output. * + * * + * iopt[NNI] : number of NEWTON iterations performed. * + * Optional output. * + * * + * iopt[NCFN] : number of nonlinear convergence failures * + * that have occurred. Optional output. * + * * + * iopt[NETF] : number of local error test failures that * + * have occurred. Optional output. * + * * + * iopt[QU] : order used during the last internal step. * + * Optional output. * + * * + * iopt[QCUR] : order to be used on the next internal step. * + * Optional output. * + * * + * iopt[LENRW] : size of required CVODE internal real work * + * space, in realtype words. Optional output. * + * * + * iopt[LENIW] : size of required CVODE internal integer work * + * space, in integertype words. Optional output. * + * * + * iopt[SLDET] : Flag to turn on/off stability limit detection * + * (1 = on, 0 = off). When BDF is used and order * + * is 3 or greater, CVsldet is call to detect * + * stability limit. If limit is detected, the * + * order is reduced. Optional input. * + * * + * iopt[NOR] : Number of order reductions due to * + * stability limit detection. * + * Optional output. * + * * + * ropt[H0] : initial step size. Optional input. * + * * + * ropt[HMAX] : maximum absolute value of step size allowed. * + * Optional input. (Default is infinity). * + * Note: If optIn = TRUE, the value of ropt[HMAX] * + * is examined on every call to CVode, and so can * + * be changed between calls. * + * * + * ropt[HMIN] : minimum absolute value of step size allowed. * + * Optional input. (Default is 0.0). * + * * + * ropt[HU] : step size for the last internal step. * + * Optional output. * + * * + * ropt[HCUR] : step size to be attempted on the next internal * + * step. Optional output. * + * * + * ropt[TCUR] : current internal time reached by the solver. * + * Optional output. * + * * + * ropt[TOLSF] : a suggested factor by which the user's * + * tolerances should be scaled when too much * + * accuracy has been requested for some internal * + * step. Optional output. * + * * + ******************************************************************/ + +/* iopt, ropt array sizes */ + +#define OPT_SIZE 40 + + +/* iopt and ropt offsets * + * The constants CVODE_IOPT_SIZE and CVODE_ROPT_SIZE are equal to * + * the number of integer and real optional inputs and outputs * + * actually accessed in cvode.c. The locations beyond these * + * values are used by the linear solvers. */ + +#define CVODE_IOPT_SIZE 15 +#define CVODE_ROPT_SIZE 7 + +/* iopt indices */ +enum { MAXORD, MXSTEP, MXHNIL, + NST, NFE, NSETUPS, NNI, NCFN, NETF, QU, QCUR, + LENRW, LENIW, SLDET, NOR}; + +/* ropt indices */ + +enum { H0, HMAX, HMIN, + HU, HCUR, TCUR, TOLSF }; + + +/* Basic CVODE constants */ + +#define ADAMS_Q_MAX 12 /* max value of q for lmm == ADAMS */ +#define BDF_Q_MAX 5 /* max value of q for lmm == BDF */ +#define Q_MAX ADAMS_Q_MAX /* max value of q for either lmm */ +#define L_MAX (Q_MAX+1) /* max value of L for either lmm */ +#define NUM_TESTS 5 /* number of error test quantities */ + + +/****************************************************************** + * * + * Types : struct CVodeMemRec, CVodeMem * + *----------------------------------------------------------------* + * The type CVodeMem is type pointer to struct CVodeMemRec. This * + * structure contains fields to keep track of problem state. * + * * + ******************************************************************/ + +typedef struct CVodeMemRec { + + realtype cv_uround; /* machine unit roundoff */ + + /* Problem Specification Data */ + + integertype cv_N; /* ODE system size */ + RhsFn cv_f; /* y' = f(t,y(t)) */ + void *cv_f_data; /* user pointer passed to f */ + int cv_lmm; /* lmm = ADAMS or BDF */ + int cv_iter; /* iter = FUNCTIONAL or NEWTON */ + int cv_itol; /* itol = SS or SV */ + realtype *cv_reltol; /* ptr to relative tolerance */ + void *cv_abstol; /* ptr to absolute tolerance */ + + /* Nordsieck History Array */ + + N_Vector cv_zn[L_MAX]; /* Nordsieck array, of size N x (q+1). */ + /* zn[j] is a vector of length N (j=0,...,q) */ + /* zn[j] = [1/factorial(j)] * h^j * (jth */ + /* derivative of the interpolating polynomial */ + + /* Vectors of length N */ + + N_Vector cv_ewt; /* error weight vector */ + N_Vector cv_y; /* y is used as temporary storage by the solver */ + /* The memory is provided by the user to CVode */ + /* where the vector is named yout. */ + N_Vector cv_acor; /* In the context of the solution of the */ + /* nonlinear equation, acor = y_n(m) - y_n(0). */ + /* On return, this vector is scaled to give */ + /* the estimated local error in y. */ + N_Vector cv_tempv; /* temporary storage vector */ + N_Vector cv_ftemp; /* temporary storage vector */ + + /* Step Data */ + + int cv_q; /* current order */ + int cv_qprime; /* order to be used on the next step */ + /* = q-1, q, or q+1 */ + int cv_qwait; /* number of internal steps to wait before */ + /* considering a change in q */ + int cv_L; /* L = q + 1 */ + + realtype cv_h; /* current step size */ + realtype cv_hprime; /* step size to be used on the next step */ + realtype cv_eta; /* eta = hprime / h */ + realtype cv_hscale; /* value of h used in zn */ + realtype cv_tn; /* current internal value of t */ + + realtype cv_tau[L_MAX+1]; /* array of previous q+1 successful step */ + /* sizes indexed from 1 to q+1 */ + realtype cv_tq[NUM_TESTS+1]; /* array of test quantities indexed from */ + /* 1 to NUM_TESTS(=5) */ + realtype cv_l[L_MAX]; /* coefficients of l(x) (degree q poly) */ + + realtype cv_rl1; /* 1 / l[1] */ + realtype cv_gamma; /* gamma = h * rl1 */ + realtype cv_gammap; /* gamma at the last setup call */ + realtype cv_gamrat; /* gamma / gammap */ + + realtype cv_crate; /* estimated corrector convergence rate */ + realtype cv_acnrm; /* | acor | wrms */ + int cv_mnewt; /* Newton iteration counter */ + + /* Limits */ + + int cv_qmax; /* q <= qmax */ + int cv_mxstep; /* maximum number of internal steps for one user call */ + int cv_maxcor; /* maximum number of corrector iterations for the */ + /* solution of the nonlinear equation */ + int cv_mxhnil; /* maximum number of warning messages issued to the */ + /* user that t + h == t for the next internal step */ + + realtype cv_hmin; /* |h| >= hmin */ + realtype cv_hmax_inv; /* |h| <= 1/hmax_inv */ + realtype cv_etamax; /* eta <= etamax */ + + /* Counters */ + + long int cv_nst; /* number of internal steps taken */ + long int cv_nfe; /* number of f calls */ + long int cv_ncfn; /* number of corrector convergence failures */ + long int cv_netf; /* number of error test failures */ + long int cv_nni; /* number of Newton iterations performed */ + long int cv_nsetups; /* number of setup calls */ + int cv_nhnil; /* number of messages issued to the user that */ + /* t + h == t for the next iternal step */ + long int cv_lrw; /* number of realtype words in CVODE work vectors */ + long int cv_liw; /* no. of integertype words in CVODE work vectors */ + long int cv_nscon; /* counter for STALD method */ + + realtype cv_etaqm1; /* ratio of new to old h for order q-1 */ + realtype cv_etaq; /* ratio of new to old h for order q */ + realtype cv_etaqp1; /* ratio of new to old h for order q+1 */ + realtype cv_ssdat[6][4]; /* scaled data array for STALD */ + + /* Linear Solver Data */ + + /* Linear Solver functions to be called */ + + int (*cv_linit)(struct CVodeMemRec *cv_mem); + + int (*cv_lsetup)(struct CVodeMemRec *cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + int (*cv_lsolve)(struct CVodeMemRec *cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + + void (*cv_lfree)(struct CVodeMemRec *cv_mem); + + /* Linear Solver specific memory */ + + void *cv_lmem; + + /* Saved Values */ + + int cv_qu; /* last successful q value used */ + long int cv_nstlp; /* step number of last setup call */ + realtype cv_hu; /* last successful h value used */ + realtype cv_saved_tq5; /* saved value of tq[5] */ + booleantype cv_jcur; /* Is the Jacobian info used by */ + /* linear solver current? */ + realtype cv_tolsf; /* tolerance scale factor */ + booleantype cv_setupNonNull; /* Does setup do something? */ + + /* Arrays for Optional Input and Optional Output */ + + booleantype cv_optIn; /* boolean input optIn */ + long int *cv_iopt; /* long int optional input, output */ + realtype *cv_ropt; /* real optional input, output */ + + /* Error File */ + + FILE *cv_errfp; /* CVODE error messages are sent to errfp */ + + /* Pointer to Machine Environment-Specific Information */ + + M_Env cv_machenv; + + /* Stability Limit Detection control flag */ + + booleantype cv_sldeton; /* Is Stability Limit Detection on */ + +} *CVodeMem; + + +/****************************************************************** + * * + * Communication between user and a CVODE Linear Solver * + *----------------------------------------------------------------* + * Return values of the linear solver specification routine. * + * The values of these are given in the enum statement below. * + * SUCCESS : The routine was successful. * + * * + * LMEM_FAIL : A memory allocation failed. * + * * + * LIN_ILL_INPUT: Some input was illegal (see message). * + * * + ******************************************************************/ + +/* SUCCESS = 0 (Defined under CVode return values, but listed + here also for completeness) */ +enum {LMEM_FAIL = -1, LIN_ILL_INPUT = -2}; + + +/****************************************************************** + * * + * Communication between cvode.c and a CVODE Linear Solver * + *----------------------------------------------------------------* + * (1) cv_linit return values * + * * + * LINIT_OK : The cv_linit routine succeeded. * + * * + * LINIT_ERR : The cv_linit routine failed. Each linear solver * + * init routine should print an appropriate error * + * message to (cv_mem->errfp). * + * * + * (2) convfail (input to cv_lsetup) * + * * + * NO_FAILURES : Either this is the first cv_setup call for this * + * step, or the local error test failed on the * + * previous attempt at this step (but the Newton * + * iteration converged). * + * * + * FAIL_BAD_J : This value is passed to cv_lsetup if * + * * + * (1) The previous Newton corrector iteration * + * did not converge and the linear solver's * + * setup routine indicated that its Jacobian- * + * related data is not current. * + * or * + * (2) During the previous Newton corrector * + * iteration, the linear solver's solve routine * + * failed in a recoverable manner and the * + * linear solver's setup routine indicated that * + * its Jacobian-related data is not current. * + * * + * FAIL_OTHER : During the current internal step try, the * + * previous Newton iteration failed to converge * + * even though the linear solver was using current * + * Jacobian-related data. * + * * + * (3) Parameter documentation, as well as a brief description * + * of purpose, for each CVODE linear solver routine to be * + * called in cvode.c is given below the constant declarations * + * that follow. * + * * + ******************************************************************/ + +/* cv_linit return values */ + +#define LINIT_OK 0 +#define LINIT_ERR -1 + +/* Constants for convfail (input to cv_lsetup) */ + +#define NO_FAILURES 0 +#define FAIL_BAD_J 1 +#define FAIL_OTHER 2 + + +/******************************************************************* + * * + * int (*cv_linit)(CVodeMem cv_mem); * + *-----------------------------------------------------------------* + * The purpose of cv_linit is to complete initializations for * + * specific linear solver, such as counters and statistics. * + * An LInitFn should return LINIT_OK (= 0) if it has successfully * + * initialized the CVODE linear solver and LINIT_ERR (= -1) * + * otherwise. These constants are defined above. If an error does * + * occur, an appropriate message should be sent to (cv_mem->errfp).* + * * + *******************************************************************/ + +/******************************************************************* + * * + * int (*cv_lsetup)(CVodeMem cv_mem, int convfail, N_Vector ypred, * + * N_Vector fpred, booleantype *jcurPtr, * + * N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); * + *-----------------------------------------------------------------* + * The job of cv_lsetup is to prepare the linear solver for * + * subsequent calls to cv_lsolve. It may re-compute Jacobian- * + * related data is it deems necessary. Its parameters are as * + * follows: * + * * + * cv_mem - problem memory pointer of type CVodeMem. See the big * + * typedef earlier in this file. * + * * + * convfail - a flag to indicate any problem that occurred during * + * the solution of the nonlinear equation on the * + * current time step for which the linear solver is * + * being used. This flag can be used to help decide * + * whether the Jacobian data kept by a CVODE linear * + * solver needs to be updated or not. * + * Its possible values have been documented above. * + * * + * ypred - the predicted y vector for the current CVODE internal * + * step. * + * * + * fpred - f(tn, ypred). * + * * + * jcurPtr - a pointer to a boolean to be filled in by cv_lsetup. * + * The function should set *jcurPtr=TRUE if its Jacobian * + * data is current after the call and should set * + * *jcurPtr=FALSE if its Jacobian data is not current. * + * Note: If cv_lsetup calls for re-evaluation of * + * Jacobian data (based on convfail and CVODE state * + * data), it should return *jcurPtr=TRUE unconditionally;* + * otherwise an infinite loop can result. * + * * + * vtemp1 - temporary N_Vector provided for use by cv_lsetup. * + * * + * vtemp3 - temporary N_Vector provided for use by cv_lsetup. * + * * + * vtemp3 - temporary N_Vector provided for use by cv_lsetup. * + * * + * The cv_lsetup routine should return 0 if successful, * + * a positive value for a recoverable error, and a negative value * + * for an unrecoverable error. * + * * + *******************************************************************/ + +/******************************************************************* + * * + * int (*cv_lsolve)(CVodeMem cv_mem, N_Vector b, N_Vector ycur, * + * N_Vector fcur); * + *-----------------------------------------------------------------* + * cv_lsolve must solve the linear equation P x = b, where * + * P is some approximation to (I - gamma J), J = (df/dy)(tn,ycur) * + * and the RHS vector b is input. The N-vector ycur contains * + * the solver's current approximation to y(tn) and the vector * + * fcur contains the N-vector f(tn,ycur). The solution is to be * + * returned in the vector b. cv_lsolve returns a positive value * + * for a recoverable error and a negative value for an * + * unrecoverable error. Success is indicated by a 0 return value. * + * * + *******************************************************************/ + +/******************************************************************* + * * + * void (*cv_lfree)(CVodeMem cv_mem); * + *-----------------------------------------------------------------* + * cv_lfree should free up any memory allocated by the linear * + * solver. This routine is called once a problem has been * + * completed and the linear solver is no longer needed. * + * * + *******************************************************************/ + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/dense.cpp b/dense.cpp new file mode 100644 index 00000000..a0648504 --- /dev/null +++ b/dense.cpp @@ -0,0 +1,114 @@ +/******************************************************************* + * * + * File : dense.c * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * Radu Serban @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for a generic DENSE linear * + * solver package. * + * * + *******************************************************************/ + +#include +#include +#include "sundialstypes.h" +#include "sundialsmath.h" +#include "dense.h" +#include "smalldense.h" +#include "output.h" +#include "phqalloc.h" +/* WARNING don't include any headers below here */ +#define malloc PHRQ_malloc +static char const svnid[] = "$Id: dense.c 78 2005-02-01 22:47:12Z dlpark $"; + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + + +/* Implementation */ + + +DenseMat DenseAllocMat(integertype N) +{ + DenseMat A; + + if (svnid == NULL) fprintf(stderr," "); + if (N <= 0) return(NULL); + + A = (DenseMat) malloc(sizeof *A); + if (A==NULL) return (NULL); + + A->data = denalloc(N); + if (A->data == NULL) { + free(A); + return(NULL); + } + + A->size = N; + + return(A); +} + + +integertype *DenseAllocPiv(integertype N) +{ + if (N <= 0) return(NULL); + + return((integertype *) malloc(N * sizeof(integertype))); +} + + +integertype DenseFactor(DenseMat A, integertype *p) +{ + return(gefa(A->data, A->size, p)); +} + + +void DenseBacksolve(DenseMat A, integertype *p, realtype *b) +{ + gesl(A->data, A->size, p, b); +} + + +void DenseZero(DenseMat A) +{ + denzero(A->data, A->size); +} + +void DenseCopy(DenseMat A, DenseMat B) +{ + dencopy(A->data, B->data, A->size); +} + +void DenseScale(realtype c, DenseMat A) +{ + denscale(c, A->data, A->size); +} + +void DenseAddI(DenseMat A) +{ + denaddI(A->data, A->size); +} + +void DenseFreeMat(DenseMat A) +{ + denfree(A->data); + free(A); +} + +void DenseFreePiv(integertype *p) +{ + free(p); +} + +void DensePrint(DenseMat A) +{ + denprint(A->data, A->size); +} + diff --git a/dense.h b/dense.h new file mode 100644 index 00000000..c2c019c1 --- /dev/null +++ b/dense.h @@ -0,0 +1,298 @@ +/******************************************************************* + * * + * File : dense.h * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * Radu Serban @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the header file for a generic DENSE linear solver * + * package. The routines listed in this file all use type * + * DenseMat, defined below, for matrices. These routines in turn * + * call routines in the smalldense.h/smalldense.c module, which * + * use the type realtype** for matrices. This separation allows * + * for possible modifications in which matrices of type DenseMat * + * may not be stored contiguously, while small matrices can still * + * be treated with the routines in smalldense. * + * * + * Routines that work with the type DenseMat begin with "Dense". * + * The DenseAllocMat function allocates a dense matrix for use in * + * the other DenseMat routines listed in this file. Matrix * + * storage details are given in the documentation for the type * + * DenseMat. The DenseAllocPiv function allocates memory for * + * pivot information. The storage allocated by DenseAllocMat and * + * DenseAllocPiv is deallocated by the routines DenseFreeMat and * + * DenseFreePiv, respectively. The DenseFactor and DenseBacksolve * + * routines perform the actual solution of a dense linear system. * + * * + * Routines that work with realtype** begin with "den" (except for * + * the factor and solve routines which are called gefa and gesl, * + * respectively). The underlying matrix storage is described in * + * the documentation for denalloc in smalldense.h * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svniddense[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif +#ifndef _dense_h +#define _dense_h + + +#include "sundialstypes.h" +#include "smalldense.h" + + +/****************************************************************** + * * + * Type: DenseMat * + *----------------------------------------------------------------* + * The type DenseMat is defined to be a pointer to a structure * + * with a size and a data field. The size field indicates the * + * number of columns (== number of rows) of a dense matrix, while * + * the data field is a two dimensional array used for component * + * storage. The elements of a dense matrix are stored columnwise * + * (i.e columns are stored one on top of the other in memory). If * + * A is of type DenseMat, then the (i,j)th element of A (with * + * 0 <= i,j <= size-1) is given by the expression (A->data)[j][i] * + * or by the expression (A->data)[0][j*n+i]. The macros below * + * allow a user to access efficiently individual matrix * + * elements without writing out explicit data structure * + * references and without knowing too much about the underlying * + * element storage. The only storage assumption needed is that * + * elements are stored columnwise and that a pointer to the jth * + * column of elements can be obtained via the DENSE_COL macro. * + * Users should use these macros whenever possible. * + * * + ******************************************************************/ + +typedef struct _DenseMat { + integertype size; + realtype **data; +} *DenseMat; + + +/* DenseMat accessor macros */ + + +/****************************************************************** + * * + * Macro : DENSE_ELEM * + * Usage : DENSE_ELEM(A,i,j) = a_ij; OR * + * a_ij = DENSE_ELEM(A,i,j); * + *----------------------------------------------------------------* + * DENSE_ELEM(A,i,j) references the (i,j)th element of the N by N * + * DenseMat A, 0 <= i,j <= N-1. * + * * + ******************************************************************/ + +#define DENSE_ELEM(A,i,j) ((A->data)[j][i]) + + +/****************************************************************** + * * + * Macro : DENSE_COL * + * Usage : col_j = DENSE_COL(A,j); * + *----------------------------------------------------------------* + * DENSE_COL(A,j) references the jth column of the N by N * + * DenseMat A, 0 <= j <= N-1. The type of the expression * + * DENSE_COL(A,j) is realtype *. After the assignment in the usage* + * above, col_j may be treated as an array indexed from 0 to N-1. * + * The (i,j)th element of A is referenced by col_j[i]. * + * * + ******************************************************************/ + +#define DENSE_COL(A,j) ((A->data)[j]) + + +/* Functions that use the DenseMat representation for a dense matrix */ + + +/****************************************************************** + * * + * Function : DenseAllocMat * + * Usage : A = DenseAllocMat(N); * + * if (A == NULL) ... memory request failed * + *----------------------------------------------------------------* + * DenseAllocMat allocates memory for an N by N dense matrix and * + * returns the storage allocated (type DenseMat). DenseAllocMat * + * returns NULL if the request for matrix storage cannot be * + * satisfied. See the above documentation for the type DenseMat * + * for matrix storage details. * + * * + ******************************************************************/ + +DenseMat DenseAllocMat(integertype N); + + +/****************************************************************** + * * + * Function : DenseAllocPiv * + * Usage : p = DenseAllocPiv(N); * + * if (p == NULL) ... memory request failed * + *----------------------------------------------------------------* + * DenseAllocPiv allocates memory for pivot information to be * + * filled in by the DenseFactor routine during the factorization * + * of an N by N dense matrix. The underlying type for pivot * + * information is an array of N integers and this routine returns * + * the pointer to the memory it allocates. If the request for * + * pivot storage cannot be satisfied, DenseAllocPiv returns NULL. * + * * + ******************************************************************/ + +integertype *DenseAllocPiv(integertype N); + + +/****************************************************************** + * * + * Function : DenseFactor * + * Usage : ier = DenseFactor(A, p); * + * if (ier != 0) ... A is singular * + *----------------------------------------------------------------* + * DenseFactor performs the LU factorization of the N by N dense * + * matrix A. This is done using standard Gaussian elimination * + * with partial pivoting. * + * * + * A successful LU factorization leaves the matrix A and the * + * pivot array p with the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., N-1. * + * * + * (2) If the unique LU factorization of A is given by PA = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of A * + * (including its diagonal) contains U and the strictly lower * + * triangular part of A contains the multipliers, I-L. * + * * + * DenseFactor returns 0 if successful. Otherwise it encountered * + * a zero diagonal element during the factorization. In this case * + * it returns the column index (numbered from one) at which * + * it encountered the zero. * + * * + ******************************************************************/ + +integertype DenseFactor(DenseMat A, integertype *p); + + +/****************************************************************** + * * + * Function : DenseBacksolve * + * Usage : DenseBacksolve(A, p, b); * + *----------------------------------------------------------------* + * DenseBacksolve solves the N-dimensional system A x = b using * + * the LU factorization in A and the pivot information in p * + * computed in DenseFactor. The solution x is returned in b. This * + * routine cannot fail if the corresponding call to DenseFactor * + * did not fail. * + * * + ******************************************************************/ + +void DenseBacksolve(DenseMat A, integertype *p, realtype *b); + + +/****************************************************************** + * * + * Function : DenseZero * + * Usage : DenseZero(A); * + *----------------------------------------------------------------* + * DenseZero sets all the elements of the N by N matrix A to 0.0. * + * * + ******************************************************************/ + +void DenseZero(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseCopy * + * Usage : DenseCopy(A, B); * + *----------------------------------------------------------------* + * DenseCopy copies the contents of the N by N matrix A into the * + * N by N matrix B. * + * * + ******************************************************************/ + +void DenseCopy(DenseMat A, DenseMat B); + + +/****************************************************************** + * * + * Function: DenseScale * + * Usage : DenseScale(c, A); * + *----------------------------------------------------------------* + * DenseScale scales the elements of the N by N matrix A by the * + * constant c and stores the result back in A. * + * * + ******************************************************************/ + +void DenseScale(realtype c, DenseMat A); + + +/****************************************************************** + * * + * Function : DenseAddI * + * Usage : DenseAddI(A); * + *----------------------------------------------------------------* + * DenseAddI adds the identity matrix to A and stores the result * + * back in A. * + * * + ******************************************************************/ + +void DenseAddI(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseFreeMat * + * Usage : DenseFreeMat(A); * + *----------------------------------------------------------------* + * DenseFreeMat frees the memory allocated by DenseAllocMat for * + * the N by N matrix A. * + * * + ******************************************************************/ + +void DenseFreeMat(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseFreePiv * + * Usage : DenseFreePiv(p); * + *----------------------------------------------------------------* + * DenseFreePiv frees the memory allocated by DenseAllocPiv for * + * the pivot information array p. * + * * + ******************************************************************/ + +void DenseFreePiv(integertype *p); + + +/****************************************************************** + * * + * Function : DensePrint * + * Usage : DensePrint(A); * + *----------------------------------------------------------------* + * This routine prints the N by N dense matrix A to standard * + * output as it would normally appear on paper. It is intended * + * as a debugging tool with small values of N. The elements are * + * printed using the %g option. A blank line is printed before * + * and after the matrix. * + * * + ******************************************************************/ + +void DensePrint(DenseMat A); + + +#endif +#ifdef __cplusplus +} +#endif diff --git a/distribution.checklist b/distribution.checklist new file mode 100644 index 00000000..86f3bb93 --- /dev/null +++ b/distribution.checklist @@ -0,0 +1,85 @@ +(1) Copy distribution.checklist to checklist.VERSION + +(2) XXX Update version and date in main.c + +(3) XXX Update doc/README.TXT + XXX uname -r + XXX gcc -v + +(4) Update src/revisions + when all_dist is run by make, src/revisions is copied + to doc/RELEASE.TXT + + ( ../doc/phreeqc.txt now static, only RELEASE.TXT + has history 2/2/05) + +(5) Update Makefile and distribution.mk + set VERSION number + set VER_DATE + add any new files to distribution + database files + source files + output files + doc files + +(6) svn status ~/programs/phreeqc -q + svn ci ~/programs/phreeqc + svn update + +(7) remake everything + make clean_all + make output_files (also remakes programs) + +(8) svn status ~/programs/phreeqc -q + should be clean + otherwise commit and restart checklist at item 5 + +(9) make all_dist REVISION=xxx + ls phreeqc_export +Linux/ phreeqc-2.12-577.Linux.tar.gz phreeqc-2.12-577.source.tar.gz Source/ + +(10) test Unix distributions + make test_dist + or + make linux_test, sun_test, source_test + +(11) Scott is making batch windows + +(12) make web + install windows version + copy README.TXT to ~/programs/phreeqc/win + + cp $(DIST_DIR)/phreeqc-$(VERSION)*.tar.gz /var/anonymous/ftp/dlpark/geochem/unix/phreeqc + cp $(EXPORT_DIR)/Linux/doc/README.TXT /var/anonymous/ftp/dlpark/geochem/unix/phreeqc/README.TXT + cp $(EXPORT_DIR)/Linux/doc/README.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/README.Unix.TXT + cp ~/programs/phreeqc/win/README.TXT /var/anonymous/ftp/dlpark/geochem/pc/phreeqc/README.TXT + cp ~/programs/phreeqc/win/README.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/README.Win.TXT + cp $(EXPORT_DIR)/Linux/doc/phreeqc.txt /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/phreeqc.txt + cp $(EXPORT_DIR)/Linux/doc/RELEASE.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/RELEASE.TXT + +(13) check for latest version of Phreeqc For Windows. + +(14) update web page /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/index.html + phreeqci version, date, size + windows batch phreeqc version size + Linux batch phreeqc version size + Generic batch phreeqc version size + phreeqc for windows version, date, size + +(15) update web page /z/linarcolkr/home/www/projects/GWC_coupled/phreeqci/index.html + PhreeqcI version, date, size + +(16) send mail to Brian Marshal + +(17) PHAST + unpack release version in packages + Update table in /z/linarcolkr/home/www/projects/GWC_coupled/phast/index.html + copy release notes + from ~/packages/phast-x.x/doc/RELEASE.TXT + to /z/linarcolkr/home/www/projects/GWC_coupled/phast/RELEASE.TXT + copy readme + from ~/packages/phast-x.x/README + to /z/linarcolkr/home/www/projects/GWC_coupled/phast/README + +(18) Update status.fm + diff --git a/distribution.mk b/distribution.mk new file mode 100644 index 00000000..b1603ed1 --- /dev/null +++ b/distribution.mk @@ -0,0 +1,368 @@ +# Locations to save compressed tar file for distribution +EXPORT=$(TOPDIR)/src/phreeqc_export +EXPORT_DIR=$(EXPORT) +WIN_DIR=$(TOPDIR)/win +DIST_DIR=$(EXPORT_DIR) +DEBUG_DIR=phreeqc_debug +DEBUG_EXE=$(SRC)/$(PROGRAM) +VERSION=2.12 +VER_DATE:=November 10, 2005 +VER_LONG_DATE:=$(shell date -d "$(VER_DATE)" "+%B %e, %G") +V_FIXDATE:=$(shell date -d "$(VER_DATE)" "+%d-%b-%G") +GCC_VER:=$(shell gcc -v 2>&1 | egrep ^gcc | sed "s/version //") +KERNEL_VER:=$(shell uname -r) +ROOTNAME=$(PROGRAM)-$(VERSION)-$(REVISION) +TEXTCP=textcp DOS +SUN_DIR=$(TOPDIR)/src/Sun +UNIX2DOS=unix2dos +CCFLAGS_DBG=-Wall -ansi -g +# list of files for distribution +FILES= \ + src/Makefile \ + src/advection.c \ + src/basic.c \ + src/basicsubs.c \ + src/cl1.c \ + src/cl1mp.c \ + src/cvdense.c \ + src/cvode.c \ + src/dense.c \ + src/dw.c \ + src/input.c \ + src/integrate.c \ + src/inverse.c \ + src/isotopes.c \ + src/kinetics.c \ + src/main.c \ + src/mainsubs.c \ + src/model.c \ + src/nvector.c \ + src/nvector_serial.c \ + src/output.c \ + src/p2clib.c \ + src/parse.c \ + src/phqalloc.c \ + src/phreeqc_files.c \ + src/phreeqc_files.c \ + src/pitzer.c \ + src/pitzer_structures.c \ + src/prep.c \ + src/print.c \ + src/read.c \ + src/readtr.c \ + src/smalldense.c \ + src/spread.c \ + src/step.c \ + src/structures.c \ + src/sundialsmath.c \ + src/tally.c \ + src/tidy.c \ + src/transport.c \ + src/utilities.c \ + src/cvdense.h \ + src/cvode.h \ + src/dense.h \ + src/global.h \ + src/input.h \ + src/kinetics.h \ + src/nvector.h \ + src/nvector_serial.h \ + src/output.h \ + src/p2c.h \ + src/phqalloc.h \ + src/phrqproto.h \ + src/phrqtype.h \ + src/pitzer.h \ + src/smalldense.h \ + src/sundialsmath.h \ + src/sundialstypes.h \ + database/llnl.dat \ + database/minteq.dat \ + database/minteq.v4.dat \ + database/phreeqc.dat \ + database/wateq4f.dat \ + database/iso.dat \ + database/pitzer.dat \ + examples/ex1 examples/ex1.out \ + examples/ex2 examples/ex2.out examples/ex2.sel \ + examples/ex3 examples/ex3.out \ + examples/ex4 examples/ex4.out \ + examples/ex5 examples/ex5.out examples/ex5.sel \ + examples/ex6 examples/ex6.out examples/ex6A-B.sel examples/ex6C.sel \ + examples/ex7 examples/ex7.out examples/ex7.sel \ + examples/ex8 examples/ex8.out examples/ex8.sel \ + examples/ex9 examples/ex9.out examples/ex9.sel \ + examples/ex10 examples/ex10.out examples/ex10.sel \ + examples/ex11 examples/ex11.out examples/ex11adv.sel examples/ex11trn.sel \ + examples/ex12 examples/ex12.out examples/ex12.sel \ + examples/ex12a examples/ex12a.out examples/ex12a.sel \ + examples/ex13a examples/ex13a.out examples/ex13a.sel \ + examples/ex13b examples/ex13b.out examples/ex13b.sel \ + examples/ex13c examples/ex13c.out examples/ex13c.sel \ + examples/ex14 examples/ex14.out examples/ex14.sel \ + examples/ex15 examples/ex15.dat examples/ex15.out examples/ex15.sel \ + examples/ex16 examples/ex16.out \ + examples/ex17 examples/ex17.out \ + examples/ex18 examples/ex18.out \ + doc/NOTICE.TXT \ + doc/README.TXT \ + doc/RELEASE.TXT \ + doc/manual.pdf \ + doc/wrir02-4172.pdf \ + doc/phreeqc.txt \ + bin/phreeqc.orig \ + test/test.sh \ + test/clean.sh \ + test/check.sh + +SED_ARGS= \ + -e "s/@VERSION@/$(VERSION)/" \ + -e "s/@VER_DATE@/$(VER_LONG_DATE)/" \ + -e "s/VERSION_DATE/$(VERSION)/" \ + -e "s^@GCC_VER@^$(GCC_VER)^" \ + -e "s^@KERNEL_VER@^$(KERNEL_VER)^" \ + -e "s/@REVISION@/$(REVISION)/" + +remake_output_files: clean_linux_output_files linux_output_files # clean_sun_output_files sun_output_files + +output_files: linux_output_files # sun_output_files + +# make sure program is compiles, run examples and mytest +linux_output_files: all + cd ../examples; make >& make.out + cd ../mytest; make >& make.out + +clean_linux_output_files: + cd ../examples; make clean + cd ../mytest; make clean + +sun_output_files: phreeqc.sun + ssh u450rcolkr "cd $(SUN_DIR)/examples; make -f $(SUN_DIR)/../../examples/Makefile INPUT=$(SUN_DIR)/../../examples PHREEQCDAT=$(SUN_DIR)/../../database/phreeqc.dat WATEQ4FDAT=$(SUN_DIR)/../../database/wateq4f.dat" + +phreeqc.sun: + ssh u450rcolkr "cd $(SUN_DIR)/src; make -f $(SUN_DIR)/../Makefile SRC=$(SUN_DIR)/.. EXE=$(SUN_DIR)/bin/phreeqc" + +clean_sun_output_files: + cd $(SUN_DIR)/examples; make -f ../../../examples/Makefile clean + +all_dist: clean_dist linux source # win # sun + +test_dist: linux_test source_test # sun_test + +# +#Linux +# +linux: linux_export linux_clean linux_sed_files linux_compile linux_output linux_dist + +source: source_export source_clean source_sed_files source_dist + +linux_export: + mkdir -p $(EXPORT_DIR) + rm -rf $(EXPORT_DIR)/Linux + svn export -r $(REVISION) http://internalbrr/svn_GW/phreeqc/trunk $(EXPORT_DIR)/Linux + +linux_clean: + rm -f $(EXPORT_DIR)/Linux/bin/$(PROGRAM) $(EXPORT_DIR)/Linux/src/*.o + +linux_sed_list= \ + "$(EXPORT_DIR)/Linux/doc/README.TXT \ + $(EXPORT_DIR)/Linux/src/main.c" + +linux_sed_files: + sed $(SED_ARGS) < $(EXPORT_DIR)/Linux/src/revisions > $(EXPORT_DIR)/Linux/doc/RELEASE.TXT + for FILE in "$(linux_sed_list)"; do \ + sed $(SED_ARGS) < $$FILE > t; mv t $$FILE; done + +linux_compile: + make -C $(EXPORT_DIR)/Linux/src + +linux_output: + cd $(EXPORT_DIR)/Linux/examples; make clean; make >& make.out + +linux_dist: + cd $(EXPORT_DIR)/Linux; rm -f $(PROGRAM).tar + cd $(EXPORT_DIR)/Linux; for FILE in $(FILES); do tar -rf $(PROGRAM).tar $$FILE; done + cd $(EXPORT_DIR)/Linux; tar -rf $(PROGRAM).tar bin/$(PROGRAM) + cd $(EXPORT_DIR)/Linux; rm -rf $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Linux; mkdir $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Linux; mv $(PROGRAM).tar $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Linux; cd $(PROGRAM)-$(VERSION); tar -xf $(PROGRAM).tar; rm -f $(PROGRAM).tar + cd $(EXPORT_DIR)/Linux; tar -czf $(PROGRAM).Linux.tar.gz $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Linux; mv $(PROGRAM).Linux.tar.gz $(DIST_DIR)/$(ROOTNAME).Linux.tar.gz + cd $(EXPORT_DIR)/Linux; echo $(ROOTNAME).Linux.tar.gz saved in $(DIST_DIR). + cd $(EXPORT_DIR)/Linux; rm -rf $(PROGRAM)-$(VERSION) + +source_export: + mkdir -p $(EXPORT_DIR) + rm -rf $(EXPORT_DIR)/Source + svn export -r $(REVISION) http://internalbrr/svn_GW/phreeqc/trunk $(EXPORT_DIR)/Source + +source_clean: + rm -f $(EXPORT_DIR/Source/bin/$(PROGRAM) $(EXPORT_DIR/Source/src/*.o + +source_sed_list= \ + "$(EXPORT_DIR)/Source/doc/README.TXT \ + $(EXPORT_DIR)/Source/src/main.c" + +source_sed_files: + sed $(SED_ARGS) < $(EXPORT_DIR)/Source/src/revisions > $(EXPORT_DIR)/Source/doc/RELEASE.TXT + for FILE in "$(source_sed_list)"; do \ + sed $(SED_ARGS) < $$FILE > t; mv t $$FILE; done + +source_dist: + cd $(EXPORT_DIR)/Source; rm -f $(PROGRAM).tar + cd $(EXPORT_DIR)/Source; for FILE in $(FILES); do tar -rf $(PROGRAM).tar $$FILE; done + cd $(EXPORT_DIR)/Source; rm -rf $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Source; mkdir $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Source; mv $(PROGRAM).tar $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Source; cd $(PROGRAM)-$(VERSION); tar -xf $(PROGRAM).tar; rm $(PROGRAM).tar + cd $(EXPORT_DIR)/Source; tar -czf $(PROGRAM).source.tar.gz $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Source; mv $(PROGRAM).source.tar.gz $(DIST_DIR)/$(ROOTNAME).source.tar.gz + cd $(EXPORT_DIR)/Source; echo $(ROOTNAME).source.tar.gz saved in $(DIST_DIR). + cd $(EXPORT_DIR)/Source; rm -rf $(PROGRAM)-$(VERSION) + +linux_test: + rm -rf $(DIST_DIR)/phreeqc-$(VERSION).Linux + cd $(DIST_DIR); tar -xzf phreeqc-$(VERSION)-*.Linux.tar.gz; mv phreeqc-$(VERSION) phreeqc-$(VERSION).Linux + cd $(DIST_DIR)/phreeqc-$(VERSION).Linux/test; ./test.sh + rm -f $(DIST_DIR)/phreeqc-$(VERSION).Linux/bin/phreeqc + cd $(DIST_DIR)/phreeqc-$(VERSION).Linux/src; make -k + cd $(DIST_DIR)/phreeqc-$(VERSION).Linux/test; ./clean.sh; ./test.sh + +source_test: + rm -rf $(DIST_DIR)/phreeqc-$(VERSION).source + cd $(DIST_DIR); tar -xzf phreeqc-$(VERSION)-*.source.tar.gz; mv phreeqc-$(VERSION) phreeqc-$(VERSION).source + cd $(DIST_DIR)/phreeqc-$(VERSION).source/src; make -k + cd $(DIST_DIR)/phreeqc-$(VERSION).source/test; ./test.sh + +# +#Sun +# +sun: sun_export sun_clean sun_sed_files sun_compile sun_output sun_dist + +sun_export: + mkdir -p $(EXPORT_DIR) + rm -rf $(EXPORT_DIR)/Sun + svn export .. $(EXPORT_DIR)/Sun + +sun_clean: + rm -f $(EXPORT_DIR)/Sun/bin/$(PROGRAM) $(EXPORT_DIR)/Sun/src/*.o + +sun_sed_list= \ + "$(EXPORT_DIR)/Sun/doc/README.TXT \ + $(EXPORT_DIR)/Sun/src/main.c" + +sun_sed_files: + sed $(SED_ARGS) < $(EXPORT_DIR)/Sun/src/revisions > $(EXPORT_DIR)/Sun/doc/RELEASE.TXT + for FILE in "$(sun_sed_list)"; do \ + sed $(SED_ARGS) < $$FILE > t; mv t $$FILE; done + +sun_compile: + ssh u450rcolkr "make -C $(EXPORT_DIR)/Sun/src" + +sun_output: + ssh u450rcolkr "make -C $(EXPORT_DIR)/Sun/examples clean" + ssh u450rcolkr "make -C $(EXPORT_DIR)/Sun/examples" > $(EXPORT_DIR)/Sun/examples/make.out 2>> $(EXPORT_DIR)/Sun/examples/make.out + +sun_dist: + cd $(EXPORT_DIR)/Sun; rm -f $(PROGRAM).tar + cd $(EXPORT_DIR)/Sun; for FILE in $(FILES); do tar -rf $(PROGRAM).tar $$FILE; done + cd $(EXPORT_DIR)/Sun; tar -rf $(PROGRAM).tar bin/$(PROGRAM) + cd $(EXPORT_DIR)/Sun; rm -rf $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Sun; mkdir $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Sun; mv $(PROGRAM).tar $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Sun; cd $(PROGRAM)-$(VERSION); tar -xf $(PROGRAM).tar; rm -f $(PROGRAM).tar + cd $(EXPORT_DIR)/Sun; tar -czf $(PROGRAM).Sun.tar.gz $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Sun; mv $(PROGRAM).Sun.tar.gz $(DIST_DIR)/$(ROOTNAME).Sun.tar.gz + cd $(EXPORT_DIR)/Sun; echo $(ROOTNAME).Sun.tar.gz saved in $(DIST_DIR). + cd $(EXPORT_DIR)/Sun; rm -rf $(PROGRAM)-$(VERSION) + +sun_test: + rm -rf $(DIST_DIR)/phreeqc-$(VERSION).Sun + cd $(DIST_DIR); tar -xzf phreeqc-$(VERSION)-*.Sun.tar.gz; mv phreeqc-$(VERSION) phreeqc-$(VERSION).Sun + ssh u450rcolkr "cd $(DIST_DIR)/phreeqc-$(VERSION).Sun/test; ./test.sh" + rm -f $(DIST_DIR)/phreeqc-$(VERSION).Sun/bin/phreeqc + ssh u450rcolkr "cd $(DIST_DIR)/phreeqc-$(VERSION).Sun/src; make -k" + ssh u450rcolkr "cd $(DIST_DIR)/phreeqc-$(VERSION).Sun/test; ./clean.sh; ./test.sh" + +clean_dist: + rm -rf $(EXPORT_DIR) + +clean_all: clean_dist clean_linux_output_files clean # clean_sun_output_files + +# +#Win +# +win: win_export win_sed_files win_dist + +win_export: + mkdir -p $(EXPORT_DIR) + rm -rf $(EXPORT_DIR)/Win + svn export .. $(EXPORT_DIR)/Win + +win_sed_list= \ + "$(EXPORT_DIR)/Win/src/main.c" + +win_sed_files: + sed $(SED_ARGS) < $(EXPORT_DIR)/Win/src/revisions > $(EXPORT_DIR)/Win/doc/RELEASE.TXT + $(UNIX2DOS) $(EXPORT_DIR)/Win/doc/RELEASE.TXT + sed $(SED_ARGS) < $(WIN_DIR)/README.TXT > $(EXPORT_DIR)/Win/doc/README.TXT + $(UNIX2DOS) $(EXPORT_DIR)/Win/doc/README.TXT + for FILE in "$(win_sed_list)"; do \ + sed $(SED_ARGS) < $$FILE > t; \ + mv t $$FILE; \ + $(UNIX2DOS) $$FILE; \ + done + +win_dist: + cd $(EXPORT_DIR)/Win; rm -f $(PROGRAM).tar +# Translate cr/lf + cd $(EXPORT_DIR)/Win; for FILE in $(FILES); do \ + if [ $$FILE = doc/manual.pdf -o $$FILE = doc/wrir02-4172.pdf ]; then cp $$FILE t; mv t $$FILE; \ + else $(TEXTCP) $$FILE t; mv t $$FILE; fi; done + cd $(EXPORT_DIR)/Win; for FILE in $(FILES); do tar -rf $(PROGRAM).tar $$FILE; done + cd $(EXPORT_DIR)/Win; rm -rf $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Win; mkdir $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Win; mv $(PROGRAM).tar $(PROGRAM)-$(VERSION) + cd $(EXPORT_DIR)/Win; cd $(PROGRAM)-$(VERSION); tar -xf $(PROGRAM).tar; rm -f $(PROGRAM).tar +# remove example output + cd $(EXPORT_DIR)/Win; rm -f $(PROGRAM)-$(VERSION)/examples/*.out $(PROGRAM)-$(VERSION)/examples/*.sel +# remove bin directory + cd $(EXPORT_DIR)/Win; rm -rf $(PROGRAM)-$(VERSION)/bin +# remove test directory files + cd $(EXPORT_DIR)/Win; rm -f $(PROGRAM)-$(VERSION)/test/* + cd $(EXPORT_DIR)/Win; $(TEXTCP) $(WIN_DIR)/clean.bat $(PROGRAM)-$(VERSION)/test/clean.bat + cd $(EXPORT_DIR)/Win; $(TEXTCP) $(WIN_DIR)/check.bat $(PROGRAM)-$(VERSION)/test/check.bat + cd $(EXPORT_DIR)/Win; $(TEXTCP) $(WIN_DIR)/test.bat $(PROGRAM)-$(VERSION)/test/test.bat +# copy bat file + cd $(EXPORT_DIR)/Win; $(TEXTCP) $(WIN_DIR)/phreeqc.bat $(PROGRAM)-$(VERSION)/phreeqc.bat + cd $(EXPORT_DIR); rm -f $(PROGRAM).Windows.tar.gz + cd $(EXPORT_DIR)/Win/$(PROGRAM)-$(VERSION); tar -czf $(PROGRAM).Windows.tar.gz . + cd $(EXPORT_DIR)/Win/$(PROGRAM)-$(VERSION); mv $(PROGRAM).Windows.tar.gz $(DIST_DIR)/$(ROOTNAME).Windows.tar.gz + @echo $(ROOTNAME).Windows.tar.gz saved in $(DIST_DIR). + cd $(EXPORT_DIR)/Win; rm -rf $(PROGRAM)-$(VERSION) + +win_echo_files: + @echo $(FILES) + +debug: + echo DEBUG_EXE $(DEBUG_EXE) + echo SRC $(SRC) + echo CURDIR $(CURDIR) + mkdir -p $(DEBUG_DIR) + cd $(DEBUG_DIR); make -f $(SRC)/Makefile SRC=$(SRC) CCFLAGS="$(CCFLAGS_DBG) -DINVERSE_CL1MP" EXE=$(DEBUG_EXE) + +debug_nomp: + mkdir -p $(DEBUG_DIR) + cd $(DEBUG_DIR); make -f $(TOPDIR)/src/Makefile SRC=$(TOPDIR)/src CCFLAGS="$(CCFLAGS_DBG)" INVERSE_CL1MP= EXE=$(DEBUG_EXE) + +web: + cp $(DIST_DIR)/phreeqc-$(VERSION)*.tar.gz /var/anonymous/ftp/dlpark/geochem/unix/phreeqc + cp $(EXPORT_DIR)/Linux/doc/README.TXT /var/anonymous/ftp/dlpark/geochem/unix/phreeqc/README.TXT + cp $(EXPORT_DIR)/Linux/doc/README.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/README.Unix.TXT + cp ~/programs/phreeqc/win/README.TXT /var/anonymous/ftp/dlpark/geochem/pc/phreeqc/README.TXT + cp ~/programs/phreeqc/win/README.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/README.Win.TXT + cp $(EXPORT_DIR)/Linux/doc/phreeqc.txt /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/phreeqc.txt + cp $(EXPORT_DIR)/Linux/doc/RELEASE.TXT /z/linarcolkr/home/www/projects/GWC_coupled/phreeqc/RELEASE.TXT + + diff --git a/dw.cpp b/dw.cpp new file mode 100644 index 00000000..662551a8 --- /dev/null +++ b/dw.cpp @@ -0,0 +1,349 @@ +#define EXTERNAL extern +#include "global.h" +#include "phrqproto.h" +#include "output.h" +#define PITZER_EXTERNAL extern +#include "pitzer.h" + +static int BB (double T); +static double PS (double T); +static double VLEST (double T); +static int DFIND (double *DOUT, double P, double D, double T); +static int QQ (double T, double D); +static double BASE (double D); + +/* COMMON /QQQQ/ */ +static double Q0,Q5; +/* COMMON /ACONST/ */ +static double GASCON=0.461522e0, TZ=647.073e0, AA=1.e0; +static double Z, DZ, Y; +/* COMMON /ELLCON/ */ +static double G1=11.e0,G2=44.333333333333e0,GF=3.5e0; +static double B1, B2, B1T, B2T, B1TT, B2TT; + +/* ---------------------------------------------------------------------- */ +int DW (double T) +/* ---------------------------------------------------------------------- */ +/* +C +C SUBROUTINE TO CALCULATE THE DENSITY OF WATER AS A FUNCTION OF +C TEMPERATURE. T IS IN KELVIN, P IS IN PASCALS, DW0 IS IN G/CM^3 +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + double FP = 9.869232667e0, P, DGSS, D; + + BB (T); + P=1.0e0/FP; + if (T > 373.149e0) P=PS(T); + DGSS=P/T/.4e0; + if (T < TZ) { + DGSS=1.0e0/(VLEST(T)); + } + DFIND (&D,P,DGSS,T); + DW0=D; + VP=P*FP; + return OK; +} + +/* ---------------------------------------------------------------------- */ +static int BB (double T) +/* ---------------------------------------------------------------------- */ +/* + +C +C THIS SUBROUTINE CALCULATES THE B'S NEEDED FOR FUNCTION DW. +C THE B'S CALCULATED HERE ARE IN CM3/G. +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + double V[11]; + int I; + /* COMMON /BCONST/ */ + double P[11]={0, 0.7478629e0, -.3540782e0, 0.e0, 0e0, .007159876e0, 0.e0, + -.003528426e0, 0., 0., 0.}; + double Q[11]={0, 1.1278334e0,0.e0,-.5944001e0,-5.010996e0,0.e0,.63684256e0, + 0., 0., 0., 0.}; + + V[1]=1.0; + for (I = 2; I <= 10; I++) { + V[I]=V[I-1]*TZ/T; + } + B1=P[1]+P[2]*log(1.e0/V[2]); + B2=Q[1]; + B1T=P[2]*V[2]/TZ; + B2T=0.e0; + B1TT=0.e0; + B2TT=0.e0; + for (I = 3; I <= 10; I++) { + B1=B1+P[I]*V[I-1]; + B2=B2+Q[I]*V[I-1]; + B1T=B1T-(I-2)*P[I]*V[I-1]/T; + B2T=B2T-(I-2)*Q[I]*V[I-1]/T; + B1TT=B1TT+P[I]*(I-2)*(I-2)*V[I-1]/T/T; + B2TT=B2TT+Q[I]*(I-2)*(I-2)*V[I-1]/T/T; + } + B1TT=B1TT-B1T/T; + B2TT=B2TT-B2T/T; + return OK; +} +/* ---------------------------------------------------------------------- */ +static double PS (double T) +/* ---------------------------------------------------------------------- */ +/* +C +C THIS FUNCTION CALCULATES AN APPROXIMATION TO THE VAPOR PRESSURE, P +C AS A FUNCTION OF THE INPUT TEMPERATURE. THE VAPOR PRESSURE +C CALCULATED AGREES WITH THE VAPOR PRESSURE PREDICTED BY THE SURFACE +C TO WITHIN .02% TO WITHIN A DEGREE OR SO OF THE CRITICAL TEMPERATUR +C AND CAN SERVE AS AN INITIAL GUESS FOR FURTHER REFINEMENT BY +C IMPOSING THE CONDITION THAT GL=GV. +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + double A[9]={0, -7.8889166e0,2.5514255e0,-6.716169e0, + 33.239495e0,-105.38479e0,174.35319e0,-148.39348e0, + 48.631602e0}; + double PL, V, W, B, Z, Q; + int I; + if(T <= 314.e0) { + PL=6.3573118e0-8858.843e0/T+607.56335e0*pow(T,-.6e0); + return (.1e0*exp(PL)); + } + V=T/647.25e0; + W=fabs(1.e0-V); + B=0.e0; + for (I = 1; I <= 8; I++) { + Z=I; + B=B+A[I]*pow(W,((Z+1.e0)/2.e0)); + } + Q=B/V; + return (22.093e0*exp(Q)); +} +/* ---------------------------------------------------------------------- */ +static double VLEST (double T) +/* ---------------------------------------------------------------------- */ +/* +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + double A=-1.59259e1,B=6.57886e-2,C=-1.12666e-4,D=7.33191e-8, + E=1.60229e3,F=2.88572e0,G=650.0e0; + + return (A+B*T+C*T*T+D*T*T*T+E/T+F/(G-T)); +} +/* ---------------------------------------------------------------------- */ +static int DFIND (double *DOUT, double P, double D, double T) +/* ---------------------------------------------------------------------- */ +/* +C +C ROUTINE TO FIND DENSITY CORRESPONDING TO INPUT PRESSURE P(MPA), AN +C TEMPERATURE T(K), USING INITIAL GUESS DENSITY D(G/CM3). THE OUTPUT +C DENSITY IS IN G/CM3. +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + int L; + double DD, RT, PP_dfind, DPD, DPDX, DP, X; + /* double DD, RT, PP, DPD, DPDX, DP, X; */ + + DD=D; + RT=GASCON*T; + if(DD <= 0.e0) DD=1.e-8; + if(DD > 1.9e0) DD=1.9e0; + L=0; + for (L=1; L <= 30; L++) { + if(DD <= 0.e0) DD=1.e-8; + if(DD > 1.9e0) DD=1.9e0; + QQ(T,DD); + PP_dfind = RT*DD*BASE(DD)+Q0; + DPD=RT*(Z+Y*DZ)+Q5; + /* +C +C THE FOLLOWING 3 LINES CHECK FOR NEGATIVE DP/DRHO, AND IF SO ASSUME +C GUESS TO BE IN 2-PHASE REGION, AND CORRECT GUESS ACCORDINGLY. +C + */ + if(DPD <= 0.e0) { + if(D >= .2967e0) DD=DD*1.02e0; + if(D < .2967e0) DD=DD*.98e0; + if(L <= 10) continue; + } else { +/* 13 */ + DPDX=DPD*1.1e0; + if(DPDX < 0.1e0) DPDX=0.1e0; + DP=fabs(1.e0-PP_dfind/P); + if(DP < 1.e-8) break; + if(D > .3e0 && DP < 1.e-7) break; + if(D > .7e0 && DP < 1.e-6) break; + X=(P-PP_dfind)/DPDX; + if(fabs(X) > .1e0) X=X*.1e0/fabs(X); + DD=DD+X; + if(DD < 0.e0) DD=1.e-8; + } + } + if (L > 30) error_msg("In subroutine DFIND", STOP); +/* 20 CONTINUE */ + *DOUT=DD; + return OK; +} +/* ---------------------------------------------------------------------- */ +static int QQ (double T, double D) +/* ---------------------------------------------------------------------- */ +/* +C +C THIS ROUTINE CALCULATES, FOR A GIVEN T(K) AND D(G/CM3), THE RESIDUL +C CONTRIBUTIONS TO: PRESSURE (Q), DP/DRHO (Q5) +C THIS SUBROUTINE IS USED IN DENSITY OF WATER CALCULATION. +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + /* COMMON /NCONST/ */ + double G[41]={0,-.53062968529023e3,.22744901424408e4,.78779333020687e3 + ,-.69830527374994e2,.17863832875422e5,-.39514731563338e5 + ,.33803884280753e5,-.13855050202703e5,-.25637436613260e6 + ,.48212575981415e6,-.34183016969660e6, .12223156417448e6 + ,.11797433655832e7,-.21734810110373e7, .10829952168620e7 + ,-.25441998064049e6,-.31377774947767e7,.52911910757704e7 + ,-.13802577177877e7,-.25109914369001e6, .46561826115608e7 + ,-.72752773275387e7,.41774246148294e6,.14016358244614e7 + ,-.31555231392127e7,.47929666384584e7,.40912664781209e6 + ,-.13626369388386e7, .69625220862664e6,-.10834900096447e7 + ,-.22722827401688e6,.38365486000660e6,.68833257944332e4 + ,.21757245522644e5,-.26627944829770e4,-.70730418082074e5 + ,-.225e0,-1.68e0,.055e0,-93.0e0}; + /*int II[41]={0,4*0,4*1,4*2,4*3,4*4,4*5,4*6,4*8,2*2,0,4,3*2,4};*/ + int II[41]={0, 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5, 6,6,6,6, 8,8,8,8, 2,2, 0,4, 2,2,2,4}; + /*int JJ[41]={0,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,1,3*4,0,2,0,0};*/ + int JJ[41]={0,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,2,3,5,7,1,4,4,4,0,2,0,0}; + int NC=36; + /* COMMON /ADDCON/ */ + double ATZ[5]={0,64.e1,64.e1,641.6e0,27.e1},ADZ[5]={0,.319e0,.319e0,.319e0,1.55e0}, + AAT[5]={0,2.e4,2.e4,4.e4,25.e0}, AAD[5]={0,34.e0,4.e1,3.e1,1.05e3}; + double *QZT; + double QR[12],QT[11] /*, QZT[10]*/; + /*EQUIVALENCE (QT(2),QZT(1))*/ + + double E, Q10, Q20, V, QP, DDZ, DEL, EX1, DEX, ATT, TX, + TAU, EX2, TEX, QM, FCT, Q5T; + int I, K, L, J, KM; + QZT = &(QT[1]); + QR[1]=0.e0; + Q5=0.e0; + Q0=0.e0; + E=exp(-AA*D); + Q10=D*D*E; + Q20=1.e0-E; + QR[2]=Q10; + V=TZ/T; + QT[1]=T/TZ; + /*DO 4 I=2,10*/ + for (I = 2; I <= 10; I++) { + QR[I+1]=QR[I]*Q20; + /* 4 QT[I]=QT[I-1]*V*/ + QT[I]=QT[I-1]*V; + } + /* DO 10 I=1,NC */ + for (I = 1; I <= NC; I++) { + K=II[I]+1; + L=JJ[I]; + QP=G[I]*AA*QR[K+1]*QZT[L]; + Q0=Q0+QP; + /*10 Q5 = Q5 + AA*(2.e0/D-AA*(1.e0-E*(K-1)/Q20))*QP*/ + Q5 = Q5 + AA*(2.e0/D-AA*(1.e0-E*(K-1)/Q20))*QP; + } + QP=0.e0; + /* DO 20 J=37,40 */ + for (J=37; J <= 40; J++) { + if(fabs(G[J]) < 1.0e-20) continue; + K=II[J]; + KM=JJ[J]; + DDZ = ADZ[J-36]; + DEL = D/DDZ - 1.e0; + if(fabs(DEL) < 1.e-10) DEL=1.e-10; + EX1 = -AAD[J-36]*pow(DEL,K); + if (EX1 <= -88.028e0) { + DEX=0.e0; + } else { + DEX=exp(EX1)*pow(DEL,KM); + } + ATT = AAT[J-36]; + TX = ATZ[J-36]; + TAU = T/TX-1.e0; + EX2 = -ATT*TAU*TAU; + if (EX2 <= -88.028e0) { + TEX=0.e0; + } else { + TEX = exp(EX2); + } + Q10 = DEX*TEX; + QM = KM/DEL - K*AAD[J-36]*pow(DEL,(K-1)); + FCT=QM*D*D*Q10/DDZ; + Q5T = FCT*(2.e0/D+QM/DDZ)-pow((D/DDZ),2)*Q10*(KM/DEL/DEL+ + K*(K-1)*AAD[J-36]*pow(DEL,(K-2))); + Q5 = Q5 + Q5T*G[J]; + QP = QP + G[J]*FCT; + /* 20 CONTINUE */ + } + Q0=Q0+QP; + return OK; +} +/* ---------------------------------------------------------------------- */ +static double BASE (double D) +/* ---------------------------------------------------------------------- */ +/* +C +C THIS FUNCTION CALCULATES THE Z (=PBASE/(DRT)) NEEDED FOR FUNCTION +C +C FROM L. HAAR, J. S. GALLAGHER, AND G. S. KELL, (1984) +C +*/ +{ + double X, Z0, DZ0; +/* +C +C G1,G2 AND GF ARE THE ALPHA, BETA AND GAMMA FOR DENSITY OF WATER +C CALCULATIONS. B1 AND B2 ARE THE 'EXCLUDED VOLUME' AND '2ND VIRIAL +C SUPPLIED BY THE SUBROUTINE BB(T), WHICH ALSO SUPPLIES THE 1ST AND +C 2ND DERIVATIVES WITH RESPECT TO T (B1T,B2T,B1TT,B2TT). +C +*/ + Y=.25e0*B1*D; + X=1.e0-Y; + Z0=(1.e0+G1*Y+G2*Y*Y)/pow(X,3); + Z=Z0+4.e0*Y*(B2/B1-GF); + DZ0=(G1+2.e0*G2*Y)/pow(X,3) + 3.e0*(1.e0+G1*Y+G2*Y*Y)/pow(X,4); + DZ=DZ0+4.e0*(B2/B1-GF); + return(Z); +} +/* ---------------------------------------------------------------------- */ +double DC (double T) +/* ---------------------------------------------------------------------- */ +/* +C +C THIS FUNCTION CALCULATES THE RELATIVE DIELECTRIC CONSTANT AS A +C FUNCTION OF TEMPERATURE, ASSUMING ONE ATMOSPHERE PRESSURE +C ACCORDING TO D. J. BRADLEY AND K. S. PITZER, (1979) +C +*/ +{ + double D1000, C, B; + double U[10]={0, 3.4279e2, -5.0866e-3, 9.4690e-7, -2.0525e0, 3.1159e3, + -1.8289e2, -8.0325e3, 4.2142e6, 2.1417e0}; + D1000=U[1]*exp(U[2]*T+U[3]*T*T); + C=U[4]+U[5]/(U[6]+T); + B=U[7]+U[8]/T+U[9]*T; + return (D1000+C*log((B+VP*1.01325e0)/(B+1000.0e0))); +} diff --git a/ex1 b/ex1 new file mode 100644 index 00000000..8021fa1a --- /dev/null +++ b/ex1 @@ -0,0 +1,77 @@ +PRINT + -status false +TITLE Example 1.--Add uranium and speciate seawater. +SOLUTION 1 SEAWATER FROM NORDSTROM ET AL. (1979) + units ppm + pH 8.22 + pe 8.451 + density 1.023 + temp 25.0 + redox O(0)/O(-2) + Ca 412.3 + Mg 1291.8 + Na 10768.0 + K 399.1 + Fe 0.002 + Mn 0.0002 pe + Si 4.28 + Cl 19353.0 + Alkalinity 141.682 as HCO3 + S(6) 2712.0 + N(5) 0.29 gfw 62.0 + N(-3) 0.03 as NH4 + U 3.3 ppb N(5)/N(-3) + O(0) 1.0 O2(g) -0.7 + 12C 1 .1 +SOLUTION_MASTER_SPECIES + U U+4 0.0 238.0290 238.0290 + U(4) U+4 0.0 238.0290 + U(5) UO2+ 0.0 238.0290 + U(6) UO2+2 0.0 238.0290 +SOLUTION_SPECIES + #primary master species for U + #is also secondary master species for U(4) + U+4 = U+4 + log_k 0.0 + U+4 + 4 H2O = U(OH)4 + 4 H+ + log_k -8.538 + delta_h 24.760 kcal + U+4 + 5 H2O = U(OH)5- + 5 H+ + log_k -13.147 + delta_h 27.580 kcal + #secondary master species for U(5) + U+4 + 2 H2O = UO2+ + 4 H+ + e- + log_k -6.432 + delta_h 31.130 kcal + #secondary master species for U(6) + U+4 + 2 H2O = UO2+2 + 4 H+ + 2 e- + log_k -9.217 + delta_h 34.430 kcal + UO2+2 + H2O = UO2OH+ + H+ + log_k -5.782 + delta_h 11.015 kcal + 2UO2+2 + 2H2O = (UO2)2(OH)2+2 + 2H+ + log_k -5.626 + delta_h -36.04 kcal + 3UO2+2 + 5H2O = (UO2)3(OH)5+ + 5H+ + log_k -15.641 + delta_h -44.27 kcal + UO2+2 + CO3-2 = UO2CO3 + log_k 10.064 + delta_h 0.84 kcal + UO2+2 + 2CO3-2 = UO2(CO3)2-2 + log_k 16.977 + delta_h 3.48 kcal + UO2+2 + 3CO3-2 = UO2(CO3)3-4 + log_k 21.397 + delta_h -8.78 kcal +PHASES + Uraninite + UO2 + 4 H+ = U+4 + 2 H2O + log_k -3.490 + delta_h -18.630 kcal +END +USE solution 1 +REACTION_TEMPERATURE + 30 +END \ No newline at end of file diff --git a/global.h b/global.h new file mode 100644 index 00000000..9fb1f7f9 --- /dev/null +++ b/global.h @@ -0,0 +1,1638 @@ + +#ifdef PHREEQC_IDENT +static char const svnidglobal[] = "$Id$"; +#endif +#ifndef _INC_GLOBAL_H +#define _INC_GLOBAL_H + +#define NO_DOS +/* #define PHREEQ98 */ /* PHREEQ98: code for graphical user interface */ +#ifdef PHREEQ98 +/*#define fprintf fprintf98*/ +#endif +/* + * uncomment following line, to use default DOS file name for + * output file + */ +/*#define DOS*/ +/* + * BUG FIX FOR DGs + */ +#ifndef __OPEN_NAMESPACE__ +#define __OPEN_NAMESPACE__ +#endif +/* ---------------------------------------------------------------------- + * INCLUDE FILES + * ---------------------------------------------------------------------- */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "phrqtype.h" + +/* must be defined here and in cl.c */ +/* #include */ +#ifndef NAN +# define NAN -99999999 +#endif +#define MISSING -9999.999 +/* search.h -- declarations for POSIX/SVID-compatible search functions */ + + /* HSEARCH(3C) */ + typedef struct entry { char *key; void *data; } ENTRY; + typedef enum { FIND, ENTER } ACTION; + + /* TSEARCH(3C) */ + typedef enum { preorder, postorder, endorder, leaf } VISIT; + +/* ---------------------------------------------------------------------- + * DEFINITIONS + * ---------------------------------------------------------------------- */ +#define F_C_MOL 96493.5 /* C/mol or joule/volt-eq*/ +#define F_KJ_V_EQ 96.4935 /* kJ/volt-eq */ +#define F_KCAL_V_EQ 23.0623 /* kcal/volt-eq */ +#define R_LITER_ATM 0.0820597 /* L-atm/deg-mol */ +#define R_KCAL_DEG_MOL 0.00198726 /* kcal/deg-mol */ +#define R_KJ_DEG_MOL 0.00831470 /* kJ/deg-mol */ +#define EPSILON 78.5 /* dialectric constant, dimensionless */ +#define EPSILON_ZERO 8.854e-12 /* permittivity of free space, C/V-m = C**2/m-J */ +#define JOULES_PER_CALORIE 4.1840 + +typedef enum { kcal, cal, kjoules, joules } DELTA_H_UNIT; + +#define TRUE 1 +#define FALSE 0 +#define OK 1 +#define ERROR 0 +#define STOP 1 +#define CONTINUE 0 + +#define DISP 2 +#define STAG 3 +#define NOMIX 4 + +#define CONVERGED 2 +#define MASS_BALANCE 3 +/* +#define OSCILLATE 4 +#define H2O_LIMITS 5 + */ +#define REWRITE 2 +#define INIT -1 + +/* check_line values, plus EMPTY, EOF, OK */ +#define KEYWORD 3 + +/* copy_token values */ +#define EMPTY 2 +#define UPPER 4 +#define LOWER 5 +#define DIGIT 6 +#define UNKNOWN 7 +#define OPTION 8 + +/* species types */ +#define AQ 0 +#define HPLUS 1 +#define H2O 2 +#define EMINUS 3 +#define SOLID 4 +#define EX 5 +#define SURF 6 +#define SURF_PSI 7 + +/* unknown types */ +#define MB 10 +#define ALK 11 +#define CB 12 +#define SOLUTION_PHASE_BOUNDARY 13 +#define MU 14 +#define AH2O 15 +#define MH 16 +#define MH2O 17 +#define PP 18 +#define EXCH 19 +#define SURFACE 20 +#define SURFACE_CB 21 +#define GAS_MOLES 23 +#define S_S_MOLES 24 +#define PITZER_GAMMA 25 +/* state */ +#define INITIALIZE 0 +#define INITIAL_SOLUTION 1 +#define INITIAL_EXCHANGE 2 +#define INITIAL_SURFACE 3 +#define INITIAL_GAS_PHASE 4 +#define REACTION 5 +#define INVERSE 6 +#define ADVECTION 7 +#define TRANSPORT 8 +#define PHAST 9 + +/* constaints in mass balance */ +#define EITHER 0 +#define DISSOLVE 1 +#define PRECIPITATE -1 + +/* gas phase type */ +#define PRESSURE 1 +#define VOLUME 2 + +#define MAX_PP_ASSEMBLAGE 10 /* default estimate of the number of phase assemblages */ +#define MAX_ADD_EQUATIONS 20 /* maximum number of equations added together to reduce eqn to + master species */ +#define MAX_ELEMENTS 50 /* default estimate of the number of elements */ +#define MAX_LENGTH 200 /* maximum number of characters component name */ +#define MAX_LINE 80 /* estimate of maximum line length */ +#define MAX_LM 3.0 /* maximum log molality allowed in intermediate iterations */ +#define MIN_LM -30.0 /* minimum log molality allowed before molality set to zero */ +#define MAX_MASS_BALANCE 10 /* initial guess of number mass balance equations for a solution */ +#define MAX_MASTER 50 /* default estimate of the number of master species */ +#define MAX_ELTS 15 /* default estimate for maximum number of times elements occur in + an equation */ +#define MAX_PHASES 500 /* initial guess of number of phases defined */ +#define MAX_SOLUTION 10 /* The maximum number of solutions allowed */ +#define MAX_S 500 /* default estimate for maximum number of species in aqueous model */ +#define MAX_STRINGS 3000 +#define MAX_SUM_JACOB0 50 /* list used to calculate jacobian */ +#define MAX_SUM_JACOB1 500 /* list used to calculate jacobian */ +#define MAX_SUM_JACOB2 500 /* list used to calculate jacobian */ +#define MAX_SUM_MB 500 /* list used to calculate mass balance sums */ +#define MAX_TRXN 16 /* default estimate for maximum number of components in an eqn */ +#define MAX_UNKNOWNS 15 /* default estimate for maximum number of unknowns in model */ +#define TOL 1e-9 /* tolerance for comparisons of double numbers */ +#define LOG_ZERO_MOLALITY -30 /* molalities <= LOG_ZERO_MOLALITY are considered equal to zero */ +#define MIN_TOTAL 1e-25 +#define MIN_RELATED_SURFACE MIN_TOTAL*100 +#define MIN_RELATED_LOG_ACTIVITY -30 +/* ---------------------------------------------------------------------- + * STRUCTURES + * ---------------------------------------------------------------------- */ +struct model { + int force_prep; + LDBLE temperature; + int count_exchange; + struct master **exchange; + + int count_kinetics; + struct kinetics *kinetics; + + int count_gas_phase; + struct phase **gas_phase; + + int count_s_s_assemblage; + char **s_s_assemblage; + + int count_pp_assemblage; + struct phase **pp_assemblage; + char **add_formula; + LDBLE *si; + + int diffuse_layer; + int count_surface_comp; + struct master **surface_comp; + int count_surface_charge; + struct master **surface_charge; +}; +EXTERNAL struct model last_model; +EXTERNAL int same_model; +EXTERNAL int same_temperature; + +struct name_master { + char *name; + struct master *master; +}; +struct name_species { + char *name; + struct species *s; +}; +struct name_phase { + char *name; + struct phase *phase; +}; +struct punch { + int in; + int new_def; + struct name_master *totals; + int count_totals; + struct name_species *molalities; + int count_molalities; + struct name_species *activities; + int count_activities; + struct name_phase *pure_phases; + int count_pure_phases; + struct name_phase *si; + int count_si; + struct name_phase *gases; + int count_gases; + struct name_phase *s_s; + int count_s_s; + struct name_phase *kinetics; + int count_kinetics; + struct name_master *isotopes; + int count_isotopes; + struct name_master *calculate_values; + int count_calculate_values; + int inverse; + int sim; + int state; + int soln; + int dist; + int time; + int step; + int rxn; + int temp; + int ph; + int pe; + int alk; + int mu; + int water; + int high_precision; + int user_punch; + int charge_balance; + int percent_error; +}; +EXTERNAL struct punch punch; +/* ---------------------------------------------------------------------- + * Temperatures + * ---------------------------------------------------------------------- */ +struct temperature { + int n_user; + int n_user_end; + char *description; + LDBLE *t; + int count_t; +}; +EXTERNAL struct temperature *temperature; +EXTERNAL int count_temperature; +/* ---------------------------------------------------------------------- + * Surface + * ---------------------------------------------------------------------- */ +struct surface { + int n_user; + int n_user_end; + int new_def; + int diffuse_layer; + int edl; + int only_counter_ions; + int donnan; + LDBLE thickness; + LDBLE debye_units; + char *description; + int solution_equilibria; + int n_solution; + int count_comps; + struct surface_comp *comps; + int count_charge; + struct surface_charge *charge; + int related_phases; + int related_rate; + int transport; +}; +struct surface_comp { + char *formula; + LDBLE moles; + struct master *master; + struct elt_list *totals; + LDBLE la; + int charge; + LDBLE cb; + char *phase_name; + LDBLE phase_proportion; + char *rate_name; +}; +struct surface_charge { + char *name; + LDBLE specific_area; + LDBLE grams; + LDBLE charge_balance; + LDBLE mass_water; + struct elt_list *diffuse_layer_totals; + int count_g; + struct surface_diff_layer *g; /* stores g and dg/dXd for each ionic charge */ + struct master *psi_master; + LDBLE la_psi; +}; +struct surface_diff_layer { + LDBLE charge; + LDBLE g; + LDBLE dg; + LDBLE psi_to_z; +}; +EXTERNAL struct surface *surface; +EXTERNAL struct surface *dbg_surface; +EXTERNAL int count_surface; +EXTERNAL int max_surface; +EXTERNAL struct charge_group { + LDBLE z; + LDBLE eq; +} *charge_group; +/* ---------------------------------------------------------------------- + * Exchange + * ---------------------------------------------------------------------- */ +struct exchange { + int n_user; + int n_user_end; + int new_def; + char *description; + int solution_equilibria; + int n_solution; + int count_comps; + struct exch_comp *comps; + int related_phases; + int related_rate; + int pitzer_exchange_gammas; +}; +struct exch_comp { + char *formula; + LDBLE formula_z; + struct elt_list *formula_totals; + LDBLE moles; + struct master *master; + struct elt_list *totals; + LDBLE la; + LDBLE charge_balance; + char *phase_name; + LDBLE phase_proportion; + char *rate_name; +}; +EXTERNAL struct exchange *exchange; +EXTERNAL struct exchange *dbg_exchange; +EXTERNAL int count_exchange; +EXTERNAL int max_exchange; +/* ---------------------------------------------------------------------- + * Kinetics + * ---------------------------------------------------------------------- */ +struct kinetics { + int n_user; + int n_user_end; + char *description; + int count_comps; + struct kinetics_comp *comps; + int count_steps; + LDBLE *steps; + LDBLE step_divide; + /*char *units;*/ + struct elt_list *totals; + int rk; + int bad_step_max; + int use_cvode; +}; +struct kinetics_comp { + char *rate_name; +#ifdef SKIP + char *formula; +#endif + struct name_coef *list; + int count_list; +/* struct phase *phase; */ + LDBLE tol; + LDBLE m; + LDBLE initial_moles; + LDBLE m0; + LDBLE moles; + int count_c_params; + char **c_params; + int count_d_params; + LDBLE *d_params; +}; +EXTERNAL struct kinetics *kinetics; +EXTERNAL struct kinetics *dbg_kinetics; +EXTERNAL int count_kinetics; +EXTERNAL int max_kinetics; + +struct save_values { + LDBLE value; + int count_subscripts; + int *subscripts; +}; +EXTERNAL int count_save_values; +EXTERNAL struct save_values *save_values; + +#ifdef SKIP +struct kin_exch { + char *exch_name; + char *phase_name; + LDBLE phase_proportion; +}; +EXTERNAL struct kin_exch *kin_exch; +EXTERNAL int count_kin_exch; +struct kin_surf { + char *surf_name; + char *phase_name; + LDBLE phase_proportion; +}; +EXTERNAL struct kin_surf *kin_surf; +EXTERNAL int count_kin_surf; +#endif +/*---------------------------------------------------------------------- + * Save + *---------------------------------------------------------------------- */ +struct save { + int solution; + int n_solution_user; + int n_solution_user_end; + int mix; + int n_mix_user; + int n_mix_user_end; + int irrev; + int n_irrev_user; + int n_irrev_user_end; + int pp_assemblage; + int n_pp_assemblage_user; + int n_pp_assemblage_user_end; + int exchange; + int n_exchange_user; + int n_exchange_user_end; + int kinetics; + int n_kinetics_user; + int n_kinetics_user_end; + int surface; + int n_surface_user; + int n_surface_user_end; + int gas_phase; + int n_gas_phase_user; + int n_gas_phase_user_end; + int s_s_assemblage; + int n_s_s_assemblage_user; + int n_s_s_assemblage_user_end; +}; +EXTERNAL struct save save; +/*---------------------------------------------------------------------- + * Use + *---------------------------------------------------------------------- */ +struct use { + int solution_in; + int n_solution_user; + int n_solution; + struct solution *solution_ptr; + + int pp_assemblage_in; + int n_pp_assemblage_user; + int n_pp_assemblage; + struct pp_assemblage *pp_assemblage_ptr; + + int mix_in; + int n_mix_user; + int n_mix; + struct mix *mix_ptr; + int n_mix_user_orig; + + int irrev_in; + int n_irrev_user; + int n_irrev; + struct irrev *irrev_ptr; + + int exchange_in; + int n_exchange_user; + int n_exchange; + struct exchange *exchange_ptr; + + int kinetics_in; + int n_kinetics_user; + int n_kinetics; + struct kinetics *kinetics_ptr; + + int surface_in; + int n_surface_user; + int n_surface; + struct surface *surface_ptr; + + int temperature_in; + int n_temperature_user; + int n_temperature; + struct temperature *temperature_ptr; + + int inverse_in; + int n_inverse_user; + int n_inverse; + struct inverse *inverse_ptr; + + int gas_phase_in; + int n_gas_phase_user; + int n_gas_phase; + struct gas_phase *gas_phase_ptr; + + int s_s_assemblage_in; + int n_s_s_assemblage_user; + int n_s_s_assemblage; + struct s_s_assemblage *s_s_assemblage_ptr; + + int trans_in; + int advect_in; +}; +EXTERNAL struct use use; +EXTERNAL struct use *dbg_use; +/*---------------------------------------------------------------------- + * Copy + *---------------------------------------------------------------------- */ +struct copier { + int count; + int max; + int *n_user; + int *start; + int *end; +}; +EXTERNAL struct copier copy_solution; +EXTERNAL struct copier copy_pp_assemblage; +EXTERNAL struct copier copy_exchange; +EXTERNAL struct copier copy_surface; +EXTERNAL struct copier copy_s_s_assemblage; +EXTERNAL struct copier copy_gas_phase; +EXTERNAL struct copier copy_kinetics; +EXTERNAL struct copier copy_mix; +EXTERNAL struct copier copy_irrev; +EXTERNAL struct copier copy_temperature; + + +/*---------------------------------------------------------------------- + * Inverse + *---------------------------------------------------------------------- */ +struct inverse { + int n_user; + char *description; + int new_def; + int minimal; + int range; + int mp; + LDBLE mp_censor; + LDBLE range_max; + LDBLE tolerance; + LDBLE mp_tolerance; + int count_uncertainties; + LDBLE *uncertainties; + int count_ph_uncertainties; + LDBLE *ph_uncertainties; +#ifdef SKIP + LDBLE *alk_uncertainties; +#endif + LDBLE water_uncertainty; + int mineral_water; + int carbon; + LDBLE *dalk_dph; + LDBLE *dalk_dc; + int count_solns; + int *solns; + int count_force_solns; + int *force_solns; + int count_elts; + struct inv_elts *elts; + int count_phases; + struct inv_phases *phases; + int count_master_list; + struct master **master_list; + int count_redox_rxns; + int count_isotopes; + struct inv_isotope *isotopes; + int count_i_u; + struct inv_isotope *i_u; + int count_isotope_unknowns; + struct isotope *isotope_unknowns; +}; +struct inv_elts { + char *name; + struct master *master; + int row; + int count_uncertainties; + LDBLE *uncertainties; +}; +struct inv_isotope { + char *isotope_name; + LDBLE isotope_number; + char *elt_name; + int count_uncertainties; + LDBLE *uncertainties; +}; +struct inv_phases { + char *name; + struct phase *phase; + int column; + int constraint; + int force; + int count_isotopes; + struct isotope *isotopes; +}; +EXTERNAL struct inverse *inverse; +EXTERNAL int count_inverse; + +/*---------------------------------------------------------------------- + * Mix + *---------------------------------------------------------------------- */ +struct mix { + int n_user; + int n_user_end; + char *description; + int count_comps; + struct mix_comp *comps; +}; +struct mix_comp { + int n_solution; + LDBLE fraction; +}; +EXTERNAL struct mix *mix; +EXTERNAL struct mix *dbg_mix; +EXTERNAL int count_mix; +/*---------------------------------------------------------------------- + * Irreversible reaction + *---------------------------------------------------------------------- */ +struct irrev { + int n_user; + int n_user_end; + char *description; + struct name_coef *list; + struct elt_list *elts; + LDBLE *steps; + char *units; + int count_steps; + int count_list; +}; +struct name_coef { + char *name; + LDBLE coef; +}; +EXTERNAL struct irrev *irrev; +EXTERNAL struct irrev *dbg_irrev; +EXTERNAL int count_irrev; +/*---------------------------------------------------------------------- + * Gas phase + *---------------------------------------------------------------------- */ +struct gas_phase { + int n_user; + int n_user_end; + char *description; + int new_def; + int solution_equilibria; + int n_solution; + int type; + LDBLE total_p; + LDBLE total_moles; + LDBLE volume; + LDBLE temperature; + int count_comps; + struct gas_comp *comps; +}; +struct gas_comp { + struct phase *phase; + char *name; + LDBLE p_read; + LDBLE moles; + LDBLE initial_moles; +}; +EXTERNAL int count_gas_phase; +EXTERNAL int max_gas_phase; +EXTERNAL struct gas_phase *gas_phase; +/*---------------------------------------------------------------------- + * Solid solution + *---------------------------------------------------------------------- */ +struct s_s_assemblage { + int n_user; + int n_user_end; + char *description; + int new_def; +/* int type; */ +/* int solution_equilibria; */ +/* int n_solution; */ + int count_s_s; + struct s_s *s_s; +}; +struct s_s { + char *name; + struct s_s_comp *comps; + int count_comps; + LDBLE total_moles; + LDBLE dn; + LDBLE a0, a1; + LDBLE ag0, ag1; + int s_s_in; + int miscibility; + int spinodal; + LDBLE tk, xb1, xb2; + int input_case; + LDBLE p[4]; +}; +struct s_s_comp { + char *name; + struct phase *phase; + LDBLE initial_moles; + LDBLE moles; + LDBLE init_moles; + LDBLE delta; + LDBLE fraction_x; + LDBLE log10_lambda; + LDBLE log10_fraction_x; + LDBLE dn, dnc, dnb; +}; +EXTERNAL int count_s_s_assemblage; +EXTERNAL int max_s_s_assemblage; +EXTERNAL struct s_s_assemblage *s_s_assemblage; +/*---------------------------------------------------------------------- + * Pure-phase assemblage + *---------------------------------------------------------------------- */ +struct pp_assemblage { + int n_user; + int n_user_end; + char *description; + int new_def; + struct elt_list *next_elt; + int count_comps; + struct pure_phase *pure_phases; +}; +struct pure_phase { + struct phase *phase; + char *name; + char *add_formula; + LDBLE si; + LDBLE moles; + LDBLE delta; + LDBLE initial_moles; + int dissolve_only; +}; +EXTERNAL int count_pp_assemblage; +EXTERNAL int max_pp_assemblage; +EXTERNAL struct pp_assemblage *pp_assemblage; +EXTERNAL struct pp_assemblage *dbg_pp_assemblage; +/*---------------------------------------------------------------------- + * Species_list + *---------------------------------------------------------------------- */ +struct species_list { + struct species *master_s; + struct species *s; + LDBLE coef; +}; +EXTERNAL int count_species_list; +EXTERNAL int max_species_list; +EXTERNAL struct species_list *species_list; +/*---------------------------------------------------------------------- + * Jacobian and Mass balance lists + *---------------------------------------------------------------------- */ +struct list0 { + LDBLE *target; + LDBLE coef; +}; +EXTERNAL int count_sum_jacob0; /* number of elements in sum_jacob0 */ +EXTERNAL int max_sum_jacob0; /* calculated maximum number of elements in sum_jacob0 */ +EXTERNAL struct list0 *sum_jacob0; /* array of pointers to targets and coefficients for array */ + +struct list1 { + LDBLE *source; + LDBLE *target; +}; +EXTERNAL int count_sum_mb1; /* number of elements in sum_mb1 */ +EXTERNAL int max_sum_mb1; /* calculated maximum number of elements in sum_mb1 */ +EXTERNAL struct list1 *sum_mb1; /* array of pointers to sources and targets for mass + balance summations with coef = 1.0 */ +EXTERNAL int count_sum_jacob1; /* number of elements in sum_jacob1 */ +EXTERNAL int max_sum_jacob1; /* calculated maximum number of elements in sum_jacob1 */ +EXTERNAL struct list1 *sum_jacob1; /* array of pointers to sources and targets for array + equations with coef = 1.0 */ +struct list2 { + LDBLE *source; + LDBLE *target; + LDBLE coef; +}; +EXTERNAL int count_sum_mb2; /* number of elements in sum_mb2 */ +EXTERNAL int max_sum_mb2; /* calculated maximum number of elements in sum_mb2 */ +EXTERNAL struct list2 *sum_mb2; /* array of coefficients and pointers to sources and + targets for mass balance summations with coef != 1.0 */ +EXTERNAL int count_sum_jacob2; /* number of elements in sum_jacob2 */ +EXTERNAL int max_sum_jacob2; /* calculated maximum number of elements in sum_jacob2 */ +EXTERNAL struct list2 *sum_jacob2; /* array of coefficients and pointers to sources and + targets, coef != 1.0 */ +EXTERNAL int count_sum_delta; /* number of elements in sum_delta */ +EXTERNAL int max_sum_delta; /* calculated maximum number of elements in sum_delta */ +EXTERNAL struct list2 *sum_delta; /* array of pointers to sources, targets and coefficients for + summing deltas for mass balance equations */ +/*---------------------------------------------------------------------- + * Solution + *---------------------------------------------------------------------- */ +struct solution { + int new_def; + int n_user; + int n_user_end; + char *description; + LDBLE tc; + LDBLE ph; + LDBLE solution_pe; + LDBLE mu; + LDBLE ah2o; + LDBLE density; + LDBLE total_h; + LDBLE total_o; + LDBLE cb; + LDBLE mass_water; + LDBLE total_alkalinity; + /*LDBLE total_co2;*/ + char *units; + struct pe_data *pe; + int default_pe; + struct conc *totals; + struct master_activity *master_activity; + int count_master_activity; + int count_isotopes; + struct isotope *isotopes; + struct master_activity *species_gamma; + int count_species_gamma; +}; +struct master_activity { + char *description; + LDBLE la; +}; +struct conc { + char *description; + /*int skip;*/ + LDBLE moles; + LDBLE input_conc; + char *units; + char *equation_name; + struct phase *phase; + LDBLE phase_si; + int n_pe; + char *as; + LDBLE gfw; +}; +struct pe_data { + char *name; + struct reaction *rxn; +}; +struct isotope { + LDBLE isotope_number; + char *elt_name; + char *isotope_name; + LDBLE total; + LDBLE ratio; + LDBLE ratio_uncertainty; + LDBLE x_ratio_uncertainty; + struct master *master; + struct master *primary; + LDBLE coef; /* coefficient of element in phase */ +}; +EXTERNAL struct solution **solution; +EXTERNAL struct solution **dbg_solution; +EXTERNAL int count_solution; +EXTERNAL int max_solution; +struct iso { + char *name; + LDBLE value; + LDBLE uncertainty; +}; +#ifdef MAINSUBS +struct iso iso_defaults[] = { + {"13C", -10, 1}, + {"13C(4)", -10, 1}, + {"13C(-4)", -50, 5}, + {"34S", 10, 1}, + {"34S(6)", 10, 1}, + {"34S(-2)", -30, 5}, + {"2H", -28, 1}, + {"18O", -5, .1}, + {"87Sr", .71, .01}, + {"11B", 20, 5} +}; +int count_iso_defaults = (sizeof(iso_defaults) / sizeof(struct iso)); +#else +extern struct iso iso_defaults[]; +extern int count_iso_defaults; +#endif +/*---------------------------------------------------------------------- + * Global solution + *---------------------------------------------------------------------- */ +EXTERNAL char *title_x; +EXTERNAL int new_x; +EXTERNAL char *description_x; +EXTERNAL LDBLE tc_x; +EXTERNAL LDBLE tk_x; +EXTERNAL LDBLE ph_x; +EXTERNAL LDBLE solution_pe_x; +EXTERNAL LDBLE mu_x; +EXTERNAL LDBLE ah2o_x; +EXTERNAL LDBLE density_x; +EXTERNAL LDBLE total_h_x; +EXTERNAL LDBLE total_o_x; +EXTERNAL LDBLE cb_x; +EXTERNAL LDBLE total_ions_x; +EXTERNAL LDBLE mass_water_aq_x; +EXTERNAL LDBLE mass_water_surfaces_x; +EXTERNAL LDBLE mass_water_bulk_x; +EXTERNAL char *units_x; +EXTERNAL struct pe_data *pe_x; +EXTERNAL int count_isotopes_x; +EXTERNAL struct isotope *isotopes_x; +EXTERNAL int default_pe_x; +EXTERNAL int diffuse_layer_x; +EXTERNAL LDBLE total_carbon; +EXTERNAL LDBLE total_co2; +EXTERNAL LDBLE total_alkalinity; +EXTERNAL LDBLE gfw_water; +EXTERNAL LDBLE step_x; +EXTERNAL LDBLE kin_time_x; +/*---------------------------------------------------------------------- + * Transport data + *---------------------------------------------------------------------- */ +EXTERNAL int count_cells; +EXTERNAL int count_shifts; +EXTERNAL int ishift; +EXTERNAL int bcon_first; +EXTERNAL int bcon_last; +EXTERNAL int correct_disp; +EXTERNAL LDBLE tempr; +EXTERNAL LDBLE timest; +EXTERNAL int simul_tr; +EXTERNAL LDBLE diffc; +EXTERNAL LDBLE heat_diffc; +EXTERNAL int cell; +/* !!!!! EXTERNAL int count_stag; */ +EXTERNAL struct stag_data { + int count_stag; + LDBLE exch_f; + LDBLE th_m; + LDBLE th_im; +} *stag_data; +EXTERNAL int print_modulus; +EXTERNAL int punch_modulus; +EXTERNAL int dump_in; +EXTERNAL int dump_modulus; +EXTERNAL int transport_warnings; +EXTERNAL struct cell_data { + LDBLE length; + LDBLE mid_cell_x; + LDBLE disp; + LDBLE temp; + int punch; + int print; +} *cell_data; +EXTERNAL int cell_no; +/*---------------------------------------------------------------------- + * Advection data + *---------------------------------------------------------------------- */ +EXTERNAL int count_ad_cells; +EXTERNAL int count_ad_shifts; +EXTERNAL int print_ad_modulus; +EXTERNAL int punch_ad_modulus; +EXTERNAL int *advection_punch, *advection_print; +EXTERNAL LDBLE advection_kin_time; +EXTERNAL LDBLE advection_kin_time_defined; +EXTERNAL int advection_warnings; + +/*---------------------------------------------------------------------- + * Keywords + *---------------------------------------------------------------------- */ +struct key { + char *name; + int keycount; +}; +#ifdef MAINSUBS + /* list of valid keywords */ +struct key keyword[] = { + {"eof", 0}, + {"end", 0}, + {"solution_species", 0}, + {"solution_master_species", 0}, + {"solution", 0}, + {"phases", 0}, + {"pure_phases", 0}, + {"reaction", 0}, + {"mix", 0}, + {"use", 0}, + {"save", 0}, + {"exchange_species", 0}, + {"exchange_master_species", 0}, + {"exchange", 0}, + {"surface_species", 0}, + {"surface_master_species", 0}, + {"surface", 0}, + {"reaction_temperature", 0}, + {"inverse_modeling", 0}, + {"gas_phase", 0}, + {"transport", 0}, + {"debug", 0}, + {"selected_output", 0}, + {"select_output", 0}, + {"knobs", 0}, + {"print", 0}, + {"equilibrium_phases", 0}, + {"equilibria", 0}, + {"equilibrium", 0}, + {"pure", 0}, + {"title", 0}, + {"comment", 0}, + {"advection", 0}, + {"kinetics", 0}, + {"incremental_reactions", 0}, + {"incremental", 0}, + {"rates", 0}, + {"solution_s", 0}, + {"user_print", 0}, + {"user_punch", 0}, + {"solid_solutions", 0}, + {"solid_solution", 0}, + {"solution_spread", 0}, + {"spread_solution", 0}, + {"selected_out", 0}, + {"select_out", 0}, + {"user_graph", 0}, + {"llnl_aqueous_model_parameters", 0}, + {"llnl_aqueous_model", 0}, + {"database", 0}, + {"named_analytical_expression", 0}, + {"named_analytical_expressions", 0}, + {"named_expressions", 0}, + {"named_log_k", 0}, + {"isotopes", 0}, + {"calculate_values", 0}, + {"isotope_ratios", 0}, + {"isotope_alphas", 0}, + {"copy", 0}, + {"pitzer", 0}, + {"solution_raw", 0}, + {"exchange_raw", 0}, + {"surface_raw", 0}, + {"equilibrium_phases_raw", 0}, + {"kinetics_raw", 0}, + {"solid_solutions_raw", 0}, + {"gas_phase_raw", 0}, + {"reaction_raw", 0}, + {"mix_raw", 0}, + {"reaction_temperature_raw", 0} +}; +int NKEYS = (sizeof(keyword) / sizeof(struct key)); /* Number of valid keywords */ +#else + extern struct key keyword[]; + extern int NKEYS; +#endif +EXTERNAL struct key *keyword_hash; +EXTERNAL int new_model, new_exchange, new_pp_assemblage, new_surface, new_reaction, new_temperature, + new_mix, new_solution, new_gas_phase, new_inverse, new_punch, new_s_s_assemblage, + new_kinetics, new_copy, new_pitzer; +/*---------------------------------------------------------------------- + * Elements + *---------------------------------------------------------------------- */ +struct element { + char *name; /* element name */ +/* int in; */ + struct master *master; + struct master *primary; + LDBLE gfw; +}; +EXTERNAL struct element **elements; +EXTERNAL int count_elements; +EXTERNAL int max_elements; +EXTERNAL struct element *element_h_one; + +/*---------------------------------------------------------------------- + * Element List + *---------------------------------------------------------------------- */ +struct elt_list { /* list of name and number of elements in an equation */ + struct element *elt; /* pointer to element structure */ + LDBLE coef; /* number of element e's in eqn */ +}; +EXTERNAL struct elt_list *elt_list; /* structure array of working space while reading equations + names are in "strings", initially in input order*/ +EXTERNAL int count_elts; /* number of elements in elt_list = position of next */ +EXTERNAL int max_elts; +/*---------------------------------------------------------------------- + * Reaction + *---------------------------------------------------------------------- */ +struct reaction { + LDBLE logk[8]; + struct rxn_token *token; +}; +struct rxn_token { + struct species *s; + LDBLE coef; +}; +/*---------------------------------------------------------------------- + * Species + *---------------------------------------------------------------------- */ +struct species { /* all data pertinent to an aqueous species */ + char *name; /* name of species */ + char *mole_balance; /* formula for mole balance */ + int in; /* species used in model if TRUE */ + int number; + struct master *primary; /* points to master species list, NULL if not primary master */ + struct master *secondary; /* points to master species list, NULL if not secondary master */ + LDBLE gfw; /* gram formula wt of species */ + LDBLE z; /* charge of species */ + LDBLE equiv; /* equivalents in exchange species */ + LDBLE alk; /* alkalinity of species, used for cec in exchange */ + LDBLE carbon; /* stoichiometric coefficient of carbon in species */ + LDBLE co2; /* stoichiometric coefficient of C(4) in species */ + LDBLE h; /* stoichiometric coefficient of H in species */ + LDBLE o; /* stoichiometric coefficient of O in species */ + LDBLE dha, dhb; /* WATEQ Debye Huckel a and b-dot */ + LDBLE lk; /* log10 k at working temperature */ + LDBLE logk[8]; /* log kt0, delh, 6 coefficients analalytical expression */ + DELTA_H_UNIT original_units; /* enum with original delta H units */ + int count_add_logk; + struct name_coef *add_logk; + LDBLE lg; /* log10 activity coefficient, gamma */ + LDBLE lg_pitzer; /* log10 activity coefficient, from pitzer calculation */ + LDBLE lm; /* log10 molality */ + LDBLE la; /* log10 activity */ + LDBLE dg; /* gamma term for jacobian */ + LDBLE dg_total_g; + LDBLE moles; /* moles in solution; moles/mass_water = molality */ + int type; /* flag indicating presence in model and types of equations */ + int gflag; /* flag for preferred activity coef eqn */ + int exch_gflag; /* flag for preferred activity coef eqn */ + struct elt_list *next_elt; /* pointer to next element */ + struct elt_list *next_secondary; + struct elt_list *next_sys_total; + int check_equation; /* switch to check equation for charge and element balance */ + struct reaction *rxn; /* pointer to data base reaction */ + struct reaction *rxn_s; /* pointer to reaction converted to secondary and primary + master species */ + struct reaction *rxn_x; /* reaction to be used in model */ + LDBLE tot_g_moles; /* (1 + sum(g)) * moles */ + LDBLE tot_dh2o_moles; /* sum(moles*g*Ws/Waq) */ + struct species_diff_layer *diff_layer; /* information related to diffuse layer factors for each + surface */ +}; +struct logk { /* Named log K's */ + char *name; /* name of species */ + LDBLE lk; /* log10 k at working temperature */ + LDBLE log_k[8]; /* log kt0, delh, 6 coefficients analalytical expression */ + DELTA_H_UNIT original_units; /* enum with original delta H units */ +}; +EXTERNAL struct logk **logk; +EXTERNAL int count_logk; +EXTERNAL int max_logk; +struct species_diff_layer { + struct surface_charge *charge; + int count_g; + LDBLE g_moles; + LDBLE dg_g_moles; /* g_moles*dgterm */ + LDBLE dx_moles; + LDBLE dh2o_moles; /* moles*g*Ws/Waq */ + LDBLE drelated_moles; /* for related phase */ +}; +EXTERNAL char *moles_per_kilogram_string; +EXTERNAL char *pe_string; + +EXTERNAL struct species **s; +EXTERNAL int count_s; +EXTERNAL int max_s; + +EXTERNAL struct species **s_x; +EXTERNAL int count_s_x; +EXTERNAL int max_s_x; + +EXTERNAL struct species *s_h2o; +EXTERNAL struct species *s_hplus ; +EXTERNAL struct species *s_h3oplus ; +EXTERNAL struct species *s_eminus; +EXTERNAL struct species *s_co3; +EXTERNAL struct species *s_h2; +EXTERNAL struct species *s_o2; +/*---------------------------------------------------------------------- + * Phases + *---------------------------------------------------------------------- */ +struct phase { /* all data pertinent to a pure solid phase */ + char *name; /* name of species */ + char *formula; /* chemical formula */ + int in; /* species used in model if TRUE */ + LDBLE lk; /* log10 k at working temperature */ + LDBLE logk[8]; /* log kt0, delh, 6 coefficients analalytical expression */ + DELTA_H_UNIT original_units; /* enum with original delta H units */ + int count_add_logk; + struct name_coef *add_logk; + LDBLE moles_x; + LDBLE p_soln_x; + LDBLE fraction_x; + LDBLE log10_lambda, log10_fraction_x; + LDBLE dn, dnb, dnc; + LDBLE gn, gntot; + LDBLE gn_n, gntot_n; + + int type; /* flag indicating presence in model and types of equations */ + struct elt_list *next_elt; /* pointer to list of elements in phase */ + /* struct elt_list *next_secondary; */ + struct elt_list *next_sys_total; + int check_equation; /* switch to check equation for charge and element balance */ + struct reaction *rxn; /* pointer to data base reaction */ + struct reaction *rxn_s; /* pointer to reaction converted to secondary and primary + master species */ + struct reaction *rxn_x; /* reaction to be used in model */ + int in_system; +}; +EXTERNAL struct phase **phases; +EXTERNAL int count_phases; +EXTERNAL int max_phases; +/*---------------------------------------------------------------------- + * Master species + *---------------------------------------------------------------------- */ +struct master { /* list of name and number of elements in an equation */ + int in; /* TRUE if in model, FALSE if out, REWRITE if other mb eq */ + int number; /* sequence number in list of masters */ + int last_model; /* saved to determine if model has changed */ + int type; /* AQ or EX */ + int primary; /* TRUE if master species is primary */ + LDBLE coef; /* coefficient of element in master species */ + LDBLE total; /* total concentration for element or valence state */ + LDBLE isotope_ratio; + LDBLE isotope_ratio_uncertainty; + int isotope; + LDBLE total_primary; +/* LDBLE la; */ /* initial guess of master species log activity */ + struct element *elt; /* element structure */ + LDBLE alk; /* alkalinity of species */ + LDBLE gfw; /* default gfw for species */ + char *gfw_formula; /* formula from which to calcuate gfw */ + struct unknown *unknown; /* pointer to unknown structure */ + struct species *s; /* pointer to species structure */ + struct reaction *rxn_primary; /* reaction writes master species in terms of primary + master species */ + struct reaction *rxn_secondary; /* reaction writes master species in terms of secondary + master species */ + struct reaction **pe_rxn; /* e- written in terms of redox couple (or e-), points + to location */ + int minor_isotope; +}; +EXTERNAL struct master **master; /* structure array of master species */ +EXTERNAL int count_master; +EXTERNAL int max_master; +/*---------------------------------------------------------------------- + * Unknowns + *---------------------------------------------------------------------- */ +struct unknown { + int type; + LDBLE moles; + LDBLE ln_moles; + LDBLE f; + LDBLE sum; + LDBLE delta; + LDBLE la; + int number; + char *description; + struct master **master; + struct phase *phase; + LDBLE si; + struct gas_phase *gas_phase; + struct conc *total; + struct species *s; + struct exch_comp *exch_comp; + struct pure_phase *pure_phase; + struct s_s *s_s; + struct s_s_comp *s_s_comp; + int s_s_comp_number; + int s_s_in; + struct surface_comp *surface_comp; + LDBLE related_moles; + struct unknown *potential_unknown; + struct unknown *phase_unknown; + struct surface_charge *surface_charge; + LDBLE mass_water; + int dissolve_only; +}; +EXTERNAL struct unknown **x; +EXTERNAL int count_unknowns; +EXTERNAL int max_unknowns; + +EXTERNAL struct unknown *ah2o_unknown; +EXTERNAL struct unknown *alkalinity_unknown; +EXTERNAL struct unknown *carbon_unknown; +EXTERNAL struct unknown *charge_balance_unknown; +EXTERNAL struct unknown *exchange_unknown; +EXTERNAL struct unknown *mass_hydrogen_unknown; +EXTERNAL struct unknown *mass_oxygen_unknown; +EXTERNAL struct unknown *mb_unknown; +EXTERNAL struct unknown *mu_unknown; +EXTERNAL struct unknown *pe_unknown; +EXTERNAL struct unknown *ph_unknown; +EXTERNAL struct unknown *pure_phase_unknown; +EXTERNAL struct unknown *solution_phase_boundary_unknown; +EXTERNAL struct unknown *surface_unknown; +EXTERNAL struct unknown *gas_unknown; +EXTERNAL struct unknown *s_s_unknown; +/*---------------------------------------------------------------------- + * Reaction work space + *---------------------------------------------------------------------- */ +struct reaction_temp { + LDBLE logk[8]; + struct rxn_token_temp *token; +}; +struct rxn_token_temp { /* data for equations, aq. species or minerals */ + char *name; /* pointer to a species name (formula) */ + LDBLE z; /* charge on species */ + struct species *s; + struct unknown *unknown; + LDBLE coef; /* coefficient of species name */ +}; +EXTERNAL struct reaction_temp trxn; /* structure array of working space while reading equations + species names are in "temp_strings" */ +EXTERNAL int count_trxn; /* number of reactants in trxn = position of next */ +EXTERNAL int max_trxn; +struct unknown_list { + struct unknown *unknown; + LDBLE *source; + LDBLE *gamma_source; +/* int row; */ +/* int col; */ + LDBLE coef; +}; +EXTERNAL struct unknown_list *mb_unknowns; +EXTERNAL int count_mb_unknowns; +EXTERNAL int max_mb_unknowns; +/* ---------------------------------------------------------------------- + * Print + * ---------------------------------------------------------------------- */ +struct prints { + int all; + int initial_solutions; + int initial_exchangers; + int reactions; + int gas_phase; + int s_s_assemblage; + int pp_assemblage; + int surface; + int exchange; + int kinetics; + int totals; + int eh; + int species; + int saturation_indices; + int irrev; + int mix; + int reaction; + int use; + int logfile; + int punch; + int status; + int inverse; + int dump; + int user_print; + int headings; + int user_graph; + int echo_input; + int warnings; + int initial_isotopes; + int isotope_ratios; + int isotope_alphas; + int hdf; + int alkalinity; +}; +EXTERNAL struct prints pr; +EXTERNAL int status_on; +EXTERNAL int count_warnings; + +/* ---------------------------------------------------------------------- + * RATES + * ---------------------------------------------------------------------- */ +struct rate { + char *name; + char *commands; + int new_def; + void *linebase; + void *varbase; + void *loopbase; +}; +EXTERNAL struct rate *rates; +EXTERNAL int count_rates; +EXTERNAL LDBLE rate_m, rate_m0, *rate_p, rate_time, rate_sim_time_start, rate_sim_time_end, rate_sim_time, rate_moles, initial_total_time; +EXTERNAL int count_rate_p; +/* ---------------------------------------------------------------------- + * USER PRINT COMMANDS + * ---------------------------------------------------------------------- */ +EXTERNAL struct rate *user_print; +EXTERNAL struct rate *user_punch; +EXTERNAL char **user_punch_headings; +EXTERNAL int user_punch_count_headings; +#ifdef PHREEQ98 +EXTERNAL struct rate *user_graph; +EXTERNAL char **user_graph_headings; +EXTERNAL int user_graph_count_headings; +#endif + +/* ---------------------------------------------------------------------- + * GLOBAL DECLARATIONS + * ---------------------------------------------------------------------- */ +EXTERNAL char error_string[10*MAX_LENGTH]; +EXTERNAL int simulation; +EXTERNAL int state; +EXTERNAL int reaction_step; +EXTERNAL int transport_step; +EXTERNAL int transport_start; +EXTERNAL int advection_step; +EXTERNAL int stop_program; +EXTERNAL int incremental_reactions; + +EXTERNAL int count_strings; +EXTERNAL int max_strings; + +EXTERNAL LDBLE *array; +EXTERNAL LDBLE *delta; +EXTERNAL LDBLE *residual; + +EXTERNAL int input_error; +EXTERNAL int next_keyword; +EXTERNAL int parse_error; +EXTERNAL int paren_count; +EXTERNAL int iterations; +EXTERNAL int gamma_iterations; +EXTERNAL int run_reactions_iterations; + +EXTERNAL int max_line; +EXTERNAL char *line; +EXTERNAL char *line_save; + +EXTERNAL LDBLE LOG_10; + +EXTERNAL int debug_model; +EXTERNAL int debug_prep; +EXTERNAL int debug_set; +EXTERNAL int debug_diffuse_layer; +EXTERNAL int debug_inverse; + +EXTERNAL LDBLE inv_tol_default; +EXTERNAL int itmax; +EXTERNAL LDBLE ineq_tol; +EXTERNAL LDBLE convergence_tolerance; +EXTERNAL LDBLE step_size; +EXTERNAL LDBLE pe_step_size; +EXTERNAL LDBLE step_size_now; +EXTERNAL LDBLE pe_step_size_now; +EXTERNAL LDBLE pp_scale; +EXTERNAL LDBLE pp_column_scale; +EXTERNAL int diagonal_scale; /* 0 not used, 1 used */ +EXTERNAL int mass_water_switch; +EXTERNAL int delay_mass_water; +EXTERNAL LDBLE censor; +EXTERNAL int aqueous_only; +EXTERNAL int negative_concentrations; + +EXTERNAL int count_total_steps; +EXTERNAL int phast; +EXTERNAL LDBLE *llnl_temp, *llnl_adh, *llnl_bdh, *llnl_bdot, *llnl_co2_coefs; +EXTERNAL int llnl_count_temp, llnl_count_adh, llnl_count_bdh, llnl_count_bdot, llnl_count_co2_coefs; + +EXTERNAL char *selected_output_file_name; +EXTERNAL char *dump_file_name; +struct spread_row { + int count; + int empty, string, number; + char **char_vector; + LDBLE *d_vector; + int *type_vector; +}; +struct defaults { + LDBLE temp; + LDBLE density; + char *units; + char *redox; + LDBLE ph; + LDBLE pe; + LDBLE water; + int count_iso; + struct iso *iso; +}; +struct spread_sheet { + struct spread_row *heading; + struct spread_row *units; + int count_rows; + struct spread_row **rows; + struct defaults defaults; +}; +#ifdef PHREEQCI_GUI +EXTERNAL struct spread_sheet g_spread_sheet; +#endif + +/* ---------------------------------------------------------------------- */ +/* + * Hash definitions + */ +/* +** Constants +*/ + +# define SegmentSize 256 +# define SegmentSizeShift 8 /* log2(SegmentSize) */ +# define DirectorySize 256 +# define DirectorySizeShift 8 /* log2(DirectorySize) */ +# define Prime1 37 +# define Prime2 1048583 +# define DefaultMaxLoadFactor 5 + + +typedef struct Element + { + /* + ** The user only sees the first two fields, + ** as we pretend to pass back only a pointer to ENTRY. + ** {S}he doesn't know what else is in here. + */ + char *Key; + char *Data; + struct Element *Next; /* secret from user */ + } Element,*Segment; + +typedef struct + { + short p; /* Next bucket to be split */ + short maxp; /* upper bound on p during expansion */ + long KeyCount; /* current # keys */ + short SegmentCount; /* current # segments */ + short MinLoadFactor; + short MaxLoadFactor; + Segment *Directory[DirectorySize]; + } HashTable; + +typedef unsigned long Address; + +EXTERNAL HashTable *strings_hash_table; +EXTERNAL HashTable *elements_hash_table; +EXTERNAL HashTable *species_hash_table; +EXTERNAL HashTable *phases_hash_table; +EXTERNAL HashTable *keyword_hash_table; +EXTERNAL HashTable *logk_hash_table; +EXTERNAL HashTable *master_isotope_hash_table; + +#if defined(PHREEQCI_GUI) +#include "../../phreeqci_gui.h" +#endif /* defined(PHREEQCI_GUI) */ + +EXTERNAL struct name_coef match_tokens[50]; +EXTERNAL int count_match_tokens; +struct master_isotope { + char *name; + struct master *master; + struct element *elt; + char *units; + LDBLE standard; + LDBLE ratio; + LDBLE moles; + int total_is_major; + int minor_isotope; +}; +EXTERNAL int count_master_isotope; +EXTERNAL struct master_isotope **master_isotope; +EXTERNAL int max_master_isotope; +EXTERNAL int initial_solution_isotopes; + +#define OPTION_EOF -1 +#define OPTION_KEYWORD -2 +#define OPTION_ERROR -3 +#define OPTION_DEFAULT -4 +#define OPT_1 -5 + +struct calculate_value { + char *name; + LDBLE value; + char *commands; + int new_def; + int calculated; + void *linebase; + void *varbase; + void *loopbase; +}; +EXTERNAL int count_calculate_value; +EXTERNAL struct calculate_value **calculate_value; +EXTERNAL int max_calculate_value; +EXTERNAL HashTable *calculate_value_hash_table; + +struct isotope_ratio { + char *name; + char *isotope_name; + LDBLE ratio; + LDBLE converted_ratio; +}; +EXTERNAL int count_isotope_ratio; +EXTERNAL struct isotope_ratio **isotope_ratio; +EXTERNAL int max_isotope_ratio; +EXTERNAL HashTable *isotope_ratio_hash_table; +struct isotope_alpha { + char *name; + char *named_logk; + LDBLE value; +}; +EXTERNAL int count_isotope_alpha; +EXTERNAL struct isotope_alpha **isotope_alpha; +EXTERNAL int max_isotope_alpha; +EXTERNAL HashTable *isotope_alpha_hash_table; + +EXTERNAL int phreeqc_mpi_myself; + +enum entity_type { Solution, Reaction, Exchange, Surface, Gas_phase, Pure_phase, Ss_phase, Kinetics, Mix, Temperature, UnKnown }; + +EXTERNAL int first_read_input; +EXTERNAL char *user_database; +EXTERNAL int pitzer_model; +EXTERNAL int full_pitzer, always_full_pitzer, ICON, IC; +EXTERNAL double COSMOT; +EXTERNAL double AW; + +EXTERNAL jmp_buf mark; + +#if defined(WIN32) +#include +#endif + +#if defined(WIN32_MEMORY_DEBUG) +#define _CRTDBG_MAP_ALLOC +#include +#endif + +#endif /* _INC_GLOBAL_H */ diff --git a/input.cpp b/input.cpp new file mode 100644 index 00000000..812a92ba --- /dev/null +++ b/input.cpp @@ -0,0 +1,249 @@ +#define EXTERNAL extern +#include +#include "global.h" +#include "input.h" +#include "output.h" +#include "phrqproto.h" +#include "phqalloc.h" + +static char const svnid[] = "$Id: input.c 78 2005-02-01 22:47:12Z dlpark $"; + +int check_line_return; + +static struct read_callback s_read_callback; + + +/* ---------------------------------------------------------------------- */ +int set_read_callback(PFN_READ_CALLBACK pfn, void *cookie, int database) +/* ---------------------------------------------------------------------- */ +{ + if (svnid == NULL) fprintf(stderr," "); + s_read_callback.callback = pfn; + s_read_callback.cookie = cookie; + s_read_callback.database = database; + return OK; +} +/* ---------------------------------------------------------------------- */ +int reading_database(void) +/* ---------------------------------------------------------------------- */ +{ + return s_read_callback.database; +} +/* ---------------------------------------------------------------------- */ +int check_line(const char *string, int allow_empty, int allow_eof, int allow_keyword, int print) +/* ---------------------------------------------------------------------- */ +{ + assert(s_read_callback.callback != NULL); + if (s_read_callback.callback == NULL) return EOF; + if (reading_database()) print = FALSE; + return check_line_impl(s_read_callback.callback, s_read_callback.cookie, string, allow_empty, allow_eof, allow_keyword, print); +} +/* ---------------------------------------------------------------------- */ +int check_line_impl(PFN_READ_CALLBACK pfn, void *cookie, const char *string, int allow_empty, int allow_eof, int allow_keyword, int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function gets a new line and checks for empty, eof, and keywords. + * + * Arguments: + * string Input, character string used in printing error message + * allow_empty Input, True or false, if a blank line is accepable + * if false, another line is read + * allow_eof Input, True or false, if EOF is acceptable + * allow_keyword Input, True or false, if a keyword is acceptable + * + * Returns: + * EMPTY if empty line read and allow_empty == true + * KEYWORD if line begins with keyword + * EOF if eof and allow_eof == true + * OK otherwise + * OPTION if line begins with -[alpha] + * + * Terminates if EOF and allow_eof == false. + */ + int i; + + +/* Get line */ + do { + i = get_line(pfn, cookie); + if ((print == TRUE && i != EOF) || i == KEYWORD) { + output_msg(OUTPUT_CHECKLINE,"\t%s\n",line_save); + } + } while ( i == EMPTY && allow_empty == FALSE ); +/* Check eof */ + if ( i == EOF && allow_eof == FALSE ) { + sprintf(error_string,"Unexpected eof while reading %s\nExecution terminated.\n",string); + error_msg(error_string, STOP); + } +/* Check keyword */ + if (i == KEYWORD && allow_keyword == FALSE ) { + sprintf(error_string, "Expected data for %s, but got a keyword ending data block.", string); + error_msg(error_string, CONTINUE); + input_error++; + } + check_line_return = i; + return (i); +} +/* ---------------------------------------------------------------------- */ +int get_line(PFN_READ_CALLBACK pfn, void *cookie) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read a line from input file put in "line". + * Copy of input line is stored in "line_save". + * Characters after # are discarded in line but retained in "line_save" + * + * Arguments: + * fp is file name + * Returns: + * EMPTY, + * EOF, + * KEYWORD, + * OK, + * OPTION + */ + int i, j, return_value, empty, l; + char *ptr; + char token[MAX_LENGTH]; + + return_value = EMPTY; + while (return_value == EMPTY) { +/* + * Eliminate all characters after # sign as a comment + */ + i=-1; + empty=TRUE; +/* + * Get line, check for eof + */ + if (get_logical_line(pfn, cookie, &l) == EOF) { + next_keyword=0; + return (EOF); + } +/* + * Get long lines + */ + j = l; + ptr = strchr (line_save, '#'); + if (ptr != NULL) { + j = ptr - line_save; + } + strncpy(line, line_save, (unsigned) j); + line[j] = '\0'; + for (i = 0; i < j; i++) { + if (! isspace((int) line[i]) ) { + empty = FALSE; + break; + } + } +/* + * New line character encountered + */ + + if (empty == TRUE) { + return_value=EMPTY; + } else { + return_value=OK; + } + } +/* + * Determine return_value + */ + if (return_value == OK) { + if ( check_key(line) == TRUE) { + return_value=KEYWORD; + } else { + ptr = line; + copy_token(token, &ptr, &i); + if (token[0] == '-' && isalpha((int) token[1])) { + return_value = OPTION; + } + } + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int get_logical_line(PFN_READ_CALLBACK pfn, void *cookie, int *l) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads file fp until end of line, ";", or eof + * stores characters in line_save + * reallocs line_save and line if more space is needed + * + * returns: + * EOF on empty line on end of file or + * OK otherwise + * *l returns length of line + */ + int i, j; + int pos; + char c; + i = 0; + if (!pfn) return EOF; + while ((j = pfn(cookie)) != EOF) { + c = (char) j; + if (c == '#') { + /* ignore all chars after # until newline */ + do { + c = (char) j; + if (c == '\n') { + break; + } + add_char_to_line(&i, c); + } while ((j = pfn(cookie)) != EOF); + } + if (c == ';') break; + if (c == '\n') { + break; + } + if (c == '\\') { + pos = i; + add_char_to_line(&i, c); + while ((j = pfn(cookie)) != EOF) { + c = (char) j; + if (c == '\\') { + pos = i; + add_char_to_line(&i, c); + continue; + } + if (c == '\n') { + /* remove '\\' */ + for (; pos < i; pos++) { + line_save[pos] = line_save[pos+1]; + } + i--; + break; + } + add_char_to_line(&i, c); + if (!isspace(j)) break; + } + } else { + add_char_to_line(&i, c); + } + } + if (j == EOF && i == 0) { + *l = 0; + line_save[i] = '\0'; + return(EOF); + } + line_save[i] = '\0'; + *l = i; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_char_to_line(int *i, char c) +/* ---------------------------------------------------------------------- */ +{ + if ( *i + 20 >= max_line) { + max_line *= 2; + line_save = (char *) PHRQ_realloc(line_save, (size_t) max_line * sizeof(char)); + if (line_save == NULL) malloc_error(); + line = (char *) PHRQ_realloc(line, (size_t) max_line * sizeof(char)); + if (line == NULL) malloc_error(); + } + line_save[*i] = c; + *i += 1; + return(OK); +} diff --git a/input.h b/input.h new file mode 100644 index 00000000..ed35503f --- /dev/null +++ b/input.h @@ -0,0 +1,24 @@ +#ifndef _INC_INPUT_H +#define _INC_INPUT_H + +#ifdef PHREEQC_IDENT +static char const svnidinput[] = "$Id$"; +#endif +typedef int (*PFN_READ_CALLBACK)(void *cookie); + +struct read_callback { + PFN_READ_CALLBACK callback; + void *cookie; + int database; +}; + +int add_char_to_line(int *i, char c); +int check_line_impl(PFN_READ_CALLBACK pfn, void *cookie, const char *string, int allow_empty, int allow_eof, int allow_keyword, int print); +int get_line(PFN_READ_CALLBACK pfn, void *cookie); +int get_logical_line(PFN_READ_CALLBACK pfn, void *cookie, int *l); +int read_database(PFN_READ_CALLBACK pfn, void *cookie); +int run_simulations(PFN_READ_CALLBACK pfn, void *cookie); +int set_read_callback(PFN_READ_CALLBACK pfn, void *cookie, int database); + + +#endif /* _INC_INPUT_H */ diff --git a/integrate.cpp b/integrate.cpp new file mode 100644 index 00000000..86245c73 --- /dev/null +++ b/integrate.cpp @@ -0,0 +1,851 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: integrate.c 78 2005-02-01 22:47:12Z dlpark $"; + +#define MAX_QUAD 20 +#define K_POLY 5 +static LDBLE g_function(LDBLE x_value); +static LDBLE midpnt (LDBLE x1, LDBLE x2, int n); +static void polint(LDBLE *xa, LDBLE *ya, int n, LDBLE xv, LDBLE *yv, LDBLE *dy); +static LDBLE qromb_midpnt (LDBLE x1, LDBLE x2); +static LDBLE z, xd, alpha, G_TOL; +static struct surface_charge *surface_charge_ptr; + +/*static LDBLE calc_psi_avg(char *name);*/ +static LDBLE calc_psi_avg(LDBLE surf_chrg_eq); + +/* ---------------------------------------------------------------------- */ +int calc_all_g( void ) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + int converge, converge1; + int count_g, count_charge; + LDBLE new_g, xd1; + LDBLE epsilon; + + if (svnid == NULL) fprintf(stderr," "); + if (use.surface_ptr == NULL) return(OK); +/* + * calculate g for each surface + */ +#ifdef SKIP + if (punch.high_precision == FALSE) { + epsilon = 1e-8; + G_TOL = 1e-9; + } else { + epsilon = 1.e-12; + G_TOL = 1e-10; + } +#endif + epsilon = convergence_tolerance; + if (convergence_tolerance >= 1e-8) { + G_TOL = 1e-9; + } else { + G_TOL = 1e-10; + } + + converge = TRUE; + count_charge = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + if (debug_diffuse_layer == TRUE) output_msg(OUTPUT_MESSAGE, "Calc_all_g, X[%d]\n", j); + surface_charge_ptr = x[j]->surface_charge; + count_g = 1; + x[j]->surface_charge->g[0].charge = 0.0; + x[j]->surface_charge->g[0].g = 0.0; + x[j]->surface_charge->g[0].dg = 0.0; + xd = exp(-2 * x[j]->master[0]->s->la * LOG_10); + /* alpha = 0.02935 @ 25; (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ + /* 1000 J/kJ and 1000 L/m**3 */ + alpha = sqrt( EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * 1000.0 * tk_x * 0.5); +/* + * calculate g for given surface for each species + */ + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type > HPLUS) continue; + for (k=0; k < count_g; k++) { + if (equal(x[j]->surface_charge->g[k].charge, s_x[i]->z, G_TOL) == TRUE) { + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = k; + break; + } + } + if (k < count_g) continue; + + if (x[j]->surface_charge->grams > 0.0) { + z = s_x[i]->z; + if ((use.surface_ptr->only_counter_ions == FALSE) || + (((x[j]->master[0]->s->la > 0) && (z < 0)) || ((x[j]->master[0]->s->la < 0) && (z > 0)))) { + if (xd > 0.1) { + new_g = qromb_midpnt( 1.0, xd); + } else if (xd > 0.01) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, xd); + } else if (xd > 0.001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, xd); + } else if (xd > 0.0001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, xd); + } else if (xd > 0.00001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, .0001); + new_g += qromb_midpnt( 0.0001, xd); + } else if (xd > 0.000001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, .0001); + new_g += qromb_midpnt( 0.0001, .00001); + new_g += qromb_midpnt( 0.00001, xd); + } else if (xd > 0.0000001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, .0001); + new_g += qromb_midpnt( 0.0001, .00001); + new_g += qromb_midpnt( 0.00001, .000001); + new_g += qromb_midpnt( 0.000001, xd); + } else if (xd > 0.00000001) { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, .0001); + new_g += qromb_midpnt( 0.0001, .00001); + new_g += qromb_midpnt( 0.00001, .000001); + new_g += qromb_midpnt( 0.000001, .0000001); + new_g += qromb_midpnt( 0.0000001, xd); + } else { + new_g = qromb_midpnt( 1.0, 0.1); + new_g += qromb_midpnt( 0.1, 0.01); + new_g += qromb_midpnt( 0.01, .001); + new_g += qromb_midpnt( 0.001, .0001); + new_g += qromb_midpnt( 0.0001, .00001); + new_g += qromb_midpnt( 0.00001, .000001); + new_g += qromb_midpnt( 0.000001, .0000001); + new_g += qromb_midpnt( 0.0000001, .00000001); + new_g += qromb_midpnt( 0.00000001, xd); + } + } else { + new_g = 0; + } + } else { + new_g = 0.0; + } + if ((use.surface_ptr->only_counter_ions == TRUE) && new_g < 0) new_g = 0; + x[j]->surface_charge->g[count_g].charge = s_x[i]->z; + converge1 = TRUE; + if (fabs(new_g) >= 1.) { + if (fabs((new_g - x[j]->surface_charge->g[count_g].g)/new_g) > epsilon) { + converge1 = FALSE; + } + } else { + if (fabs(new_g - x[j]->surface_charge->g[count_g].g) > epsilon) { + converge1 = FALSE; + } + } + if (converge1 == FALSE) { + converge = FALSE; + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\t%12.4e\n", + (double) x[j]->surface_charge->g[count_g].charge, + (double) x[j]->surface_charge->g[count_g].g, + (double) new_g, + (double) (new_g - x[j]->surface_charge->g[count_g].g) ); + } + } + x[j]->surface_charge->g[count_g].g = new_g; + if (new_g == 0) { + x[j]->surface_charge->g[count_g].dg = 0; + } else { + if (x[j]->surface_charge->grams > 0.0) { + x[j]->surface_charge->g[count_g].dg = surface_charge_ptr->grams * surface_charge_ptr->specific_area * alpha * g_function(xd) / F_C_MOL; + x[j]->surface_charge->g[count_g].dg *= -2. / + (exp(x[j]->master[0]->s->la * LOG_10) * + exp(x[j]->master[0]->s->la * LOG_10)); + if ((xd - 1) < 0.0) { + x[j]->surface_charge->g[count_g].dg *= -1.0; + } + if (fabs(x[j]->surface_charge->g[count_g].dg) < 1e-8) { + xd1 = exp(-2 * 1e-3 * LOG_10); + + + new_g = qromb_midpnt( 1.0, xd1); + x[j]->surface_charge->g[count_g].dg = new_g/.001; + } + } else { + x[j]->surface_charge->g[count_g].dg = 0.0; + } + } + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = count_g; + count_g++; + + } + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nSurface component %d: charge,\tg,\tdg/dlny,\txd\n", count_charge); + for (i = 0; i < count_g; i++) { + output_msg(OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\t%12.4e\n", + (double) x[j]->surface_charge->g[i].charge, + (double) x[j]->surface_charge->g[i].g, + (double) x[j]->surface_charge->g[i].dg, + (double) xd); + } + } + count_charge++; + } + return (converge); +} +/* ---------------------------------------------------------------------- */ +LDBLE g_function(LDBLE x_value) +/* ---------------------------------------------------------------------- */ +{ + LDBLE sum, return_value, sum1; + int i, j; + LDBLE ln_x_value; + + if (equal(x_value, 1.0, G_TOL*100) == TRUE) return(0.0); + sum = 0.0; + ln_x_value = log(x_value); + for (j = 0; j < use.surface_ptr->charge[0].count_g; j++) { + use.surface_ptr->charge[0].g[j].psi_to_z = + exp(ln_x_value * use.surface_ptr->charge[0].g[j].charge) - 1.0; + } + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type < H2O && s_x[i]->z != 0.0) { + for(j = 0; j < use.surface_ptr->charge[0].count_g; j++) { + if(use.surface_ptr->charge[0].g[j].charge == s_x[i]->z) { + sum += s_x[i]->moles * use.surface_ptr->charge[0].g[j].psi_to_z; + break; + } + } + } + } + if (sum < 0.0) { + sum = 0.0; + sum1 = 0.0; + output_msg(OUTPUT_MESSAGE, "Species\tmoles\tX**z-1\tsum\tsum charge\n"); + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type < H2O && s_x[i]->z != 0.0) { + sum += s_x[i]->moles * (pow(x_value, s_x[i]->z) - 1.0); + sum1 += s_x[i]->moles * s_x[i]->z; + output_msg(OUTPUT_MESSAGE, "%s\t%e\t%e\t%e\t%e\n", s_x[i]->name, (double) s_x[i]->moles, (double) (pow(x_value, (double) s_x[i]->z) - 1.0), (double) sum, (double) sum1); + } + } + sprintf(error_string, "Negative sum in g_function, %e\t%e.", (double) sum, (double) x_value); + error_msg(error_string, CONTINUE); + sprintf(error_string, "Solutions must be charge balanced, charge imbalance is %e\n", (double) sum1); + error_msg(error_string, STOP); + } + + return_value = ( exp (ln_x_value * z) - 1) / sqrt((x_value * x_value * mass_water_aq_x * sum )); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +void polint(LDBLE *xa, LDBLE *ya, int n, LDBLE xv, LDBLE *yv, LDBLE *dy) +/* ---------------------------------------------------------------------- */ +{ + int i, m, ns; + LDBLE den, dif, dift, ho, hp, w; + LDBLE *c, *d; + + ns = 1; + dif = fabs(xv-xa[1]); +/* + * Malloc work space + */ + c = (double *) PHRQ_malloc((size_t) (n + 1) * sizeof (LDBLE) ); + if (c == NULL) malloc_error(); + d = (double *) PHRQ_malloc((size_t) (n + 1) * sizeof (LDBLE) ); + if (d == NULL) malloc_error(); + + + + for (i=1; i <= n; i++) { + dift = fabs(xv-xa[i]); + if ( dift < dif ) { + ns = i; + dif = dift; + } + c[i] = ya[i]; + d[i] = ya[i]; + } + + *yv = ya[ns--]; + for (m = 1; m < n; m++) { + for (i=1; i <= n - m; i++) { + ho = xa[i] - xv; + hp = xa[i+m] - xv; + w = c[i+1] - d[i]; + if ( (den=ho-hp) == 0.0) { + error_msg("In subroutine polint.", STOP); + } + den = w/den; + d[i] = hp*den; + c[i] = ho*den; + } + if (2 * ns < (n-m) ) { + *dy = c[ns+1]; + } else { + *dy = d[ns--]; + } + *yv += *dy; + +/* *yv += (*dy = (2 * ns < (n-m) ? c[ns+1] : d[ns--])); */ + } + c = (double *) free_check_null(c); + d = (double *) free_check_null(d); + return; +} +/* ---------------------------------------------------------------------- */ +LDBLE midpnt (LDBLE x1, LDBLE x2, int n) +/* ---------------------------------------------------------------------- */ +{ + LDBLE xv, tnm, sum, del, ddel; + static LDBLE sv; + int it, j; + + if (n == 1) { + sv = (x2-x1) * g_function(0.5 * (x1 + x2)); + return(sv); + } else { + for (it=1, j=1; jgrams * surface_charge_ptr->specific_area * + alpha / F_C_MOL; /* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ + if ((x2 - 1) < 0.0) sv[j] *= -1.0; + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j); + } + return(sv[j]); + } + + if (j >= K_POLY - 1) { + polint( &h[j - K_POLY], &sv[j - K_POLY], K_POLY, 0.0, &ss, &dss); + if (fabs(dss) <= G_TOL * fabs(ss) || fabs(dss) < G_TOL) { + ss *= surface_charge_ptr->grams * surface_charge_ptr->specific_area * + alpha / F_C_MOL; /* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ + if ((x2 - 1) < 0.0) ss *= -1.0; + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j); + } + return(ss); + } + } + + } + sprintf(error_string, "\nToo many iterations integrating diffuse layer.\n"); + error_msg(error_string, STOP); + return(-999.9); +} +/* ---------------------------------------------------------------------- */ +int calc_init_g(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + int count_g, count_charge; + + if (use.surface_ptr == NULL) return(OK); + +/* + * calculate g for each surface + */ + count_charge = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + surface_charge_ptr = x[j]->surface_charge; + count_g = 0; + if (x[j]->surface_charge->g != NULL) { + count_g = x[j]->surface_charge->count_g; + } + if( count_g == 0 ) { + x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_malloc((size_t) sizeof(struct surface_diff_layer)); + if (x[j]->surface_charge->g == NULL) malloc_error(); + x[j]->surface_charge->g[0].charge = 0.0; + x[j]->surface_charge->g[0].g = 0.0; + x[j]->surface_charge->g[0].dg = 0.0; + xd = exp(-2 * x[j]->master[0]->s->la * LOG_10); + /* alpha = 0.02935 @ 25; (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ + /* second 1000 is liters/m**3 */ + alpha = sqrt( EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * 1000.0 * tk_x * 0.5); + } +/* + * calculate g for given surface for each species + */ + count_g = 1; + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type > HPLUS) continue; + for (k=0; k < count_g; k++) { + if (equal(x[j]->surface_charge->g[k].charge, s_x[i]->z, G_TOL) == TRUE) { + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = k; + s_x[i]->diff_layer[count_charge].g_moles = 0.0; + s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; + break; + } + } + if (k >= count_g) { + + /* malloc space to save g for charge */ + x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_realloc(x[j]->surface_charge->g, + (size_t) (count_g + 1) * + sizeof(struct surface_diff_layer)); + if (x[j]->surface_charge->g == NULL) malloc_error(); + + /* save g for charge */ + x[j]->surface_charge->g[count_g].charge = s_x[i]->z; + if (x[j]->surface_charge->grams > 0.0) { + x[j]->surface_charge->g[count_g].g = 2 * alpha * sqrt(mu_x) * (pow(xd, s_x[i]->z / 2.0) - 1) *surface_charge_ptr->grams * surface_charge_ptr->specific_area / F_C_MOL; + x[j]->surface_charge->g[count_g].dg = -s_x[i]->z; + if ((use.surface_ptr->only_counter_ions == TRUE) && + x[j]->surface_charge->g[count_g].g < 0) { + x[j]->surface_charge->g[count_g].g = 0; + x[j]->surface_charge->g[count_g].dg = 0; + } + } else { + x[j]->surface_charge->g[count_g].g = 0.0; + x[j]->surface_charge->g[count_g].dg = -s_x[i]->z; + } + /* save g for species */ + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = count_g; + s_x[i]->diff_layer[count_charge].g_moles = 0.0; + s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; + count_g++; + } + } + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nSurface component %d: charge,\tg,\tdg\n", count_charge); + for (i = 0; i < count_g; i++) { + output_msg(OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\n", + (double) x[j]->surface_charge->g[i].charge, (double) x[j]->surface_charge->g[i].g, (double) x[j]->surface_charge->g[i].dg ); + } + } + count_charge++; + x[j]->surface_charge->count_g = count_g; + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int initial_surface_water(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * In initial surface calculation, need to calculate + * mass of water in diffuse layer. + * diffuse layer water + aqueous solution water = bulk water. + * Ionic strength is fixed, so diffuse-layer water will not change + */ + int i; +/*#define DEBYE*/ +#ifdef DEBYE + LDBLE debye_length; + LDBLE volume_diffuse_layer; +#endif + LDBLE mass_water_surface; +/* + * Debye length = 1/k = sqrt[eta*eta_zero*R*T/(2*F**2*mu_x*1000)], Dzombak and Morel, p 36 + * + * 1000 converts kJ to J; 1000 converts Liters to meter**3; debye_length is in meters. + */ +#ifdef DEBYE + debye_length = (EPSILON * EPSILON_ZERO * R_KJ_DEG_MOL * 1000.0 * tk_x) + / (2. * F_C_MOL * F_C_MOL * mu_x * 1000.); + debye_length = sqrt(debye_length); +#endif +/* + * Loop through all surface components, calculate each H2O surface (diffuse layer), + * H2O aq, and H2O bulk (diffuse layers plus aqueous). + */ + mass_water_surfaces_x = 0.0; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != SURFACE_CB) continue; +#ifdef DEBYE + /* 1000 converts volume from m**3 to Liters */ + volume_diffuse_layer = x[i]->surface_charge->specific_area * + x[i]->surface_charge->grams * debye_length * 1000; + + /* Assume mol/L = mol/kgw */ + mass_water_surface = volume_diffuse_layer; +#else + /* make constant thickness of, default 1e-8 m (100 Angstroms) */ + mass_water_surface = x[i]->surface_charge->specific_area * + x[i]->surface_charge->grams * use.surface_ptr->thickness * 1000; +#endif + x[i]->surface_charge->mass_water = mass_water_surface; + mass_water_surfaces_x += mass_water_surface; + } + mass_water_bulk_x = mass_water_aq_x + mass_water_surfaces_x; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int sum_diffuse_layer(struct surface_charge *surface_charge_ptr1) +/* ---------------------------------------------------------------------- */ +{ + int i, j, count_g; + LDBLE mass_water_surface; + LDBLE molality, moles_excess, moles_surface; + + if (use.surface_ptr == NULL) return(OK); +/* + * Find position of component in list of components + */ + i = 0; + + for (j =0; j < use.surface_ptr->count_charge; j++) { + if (&(use.surface_ptr->charge[j]) == surface_charge_ptr1) { + i = j; + break; + } + } + if (j >= use.surface_ptr->count_charge) { + sprintf(error_string, "In sum_diffuse_layer, component not found, %s.", surface_charge_ptr1->name); + error_msg(error_string, STOP); + } +/* + * Loop through all surface components, calculate each H2O surface (diffuse layer), + * H2O aq, and H2O bulk (diffuse layers plus aqueous). + */ + count_elts = 0; + paren_count = 0; + mass_water_surface = surface_charge_ptr1->mass_water; + for (j = 0; j < count_s_x; j++) { + if (s_x[j]->type > HPLUS) continue; + molality = under(s_x[j]->lm); + count_g = s_x[j]->diff_layer[i].count_g; +#ifdef SKIP + moles_excess = mass_water_bulk_x * +/* s_x[j]->diff_layer[i].charge->g[count_g].g * molality; */ + surface_charge_ptr1->g[count_g].g * molality; +#endif + moles_excess = mass_water_aq_x * molality * surface_charge_ptr1->g[count_g].g; + + moles_surface = mass_water_surface * molality + moles_excess; +/* + * Accumulate elements in diffuse layer + */ + add_elt_list(s_x[j]->next_elt, moles_surface); + } + add_elt_list(s_h2o->next_elt, mass_water_surface / gfw_water); + + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int calc_all_donnan(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + int count_g, count_charge, converge; + char name[MAX_LENGTH]; + LDBLE new_g, f_psi, surf_chrg_eq, psi_avg, f_sinh, A_surf, ratio_aq; + LDBLE new_g2, f_psi2, surf_chrg_eq2, psi_avg2, dif; + + if (use.surface_ptr == NULL) return(OK); + f_sinh = sqrt(8000.0 * EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * tk_x * mu_x); +/* + * calculate g for each surface... + */ + converge = TRUE; + count_charge = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + surface_charge_ptr = x[j]->surface_charge; + + if (debug_diffuse_layer == TRUE) output_msg(OUTPUT_MESSAGE, "Calc_all_g, X[%d]\n", j); +/* + * sum eq of each charge number in solution... + */ + count_g = x[j]->surface_charge->count_g; + for (i = 0; i < count_g; i++) { + charge_group[i].eq = 0.0; + } + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type > HPLUS) continue; + for (k = 0; k < count_g; k++) { + if (equal(charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { + charge_group[k].eq += s_x[i]->z * s_x[i]->moles; + break; + } + } + } + /* find surface charge from potential... */ + A_surf = x[j]->surface_charge->specific_area * x[j]->surface_charge->grams; + f_psi = x[j]->master[0]->s->la * LOG_10; + surf_chrg_eq = A_surf * f_sinh * sinh(f_psi) / F_C_MOL; + /* also for the derivative... */ + dif = 1e-5; + f_psi2 = f_psi + dif; + surf_chrg_eq2 = A_surf * f_sinh * sinh(f_psi2) / F_C_MOL; + + + /* find psi_avg that matches surface charge... */ + psi_avg = calc_psi_avg(surf_chrg_eq); + psi_avg2 = calc_psi_avg(surf_chrg_eq2); + + /* fill in g's */ + ratio_aq = surface_charge_ptr->mass_water / mass_water_aq_x; + + for (k = 0; k < count_g; k++) { + x[j]->surface_charge->g[k].charge = charge_group[k].z; + + new_g = exp(-charge_group[k].z * psi_avg) - 1; + if (new_g <= - ratio_aq) new_g = G_TOL; + new_g2 = exp(-charge_group[k].z * psi_avg2) - 1; + if (new_g2 <= - ratio_aq) new_g2 = G_TOL; + + if (fabs(new_g) >= 1) { + if (fabs((new_g - x[j]->surface_charge->g[k].g) / new_g) > convergence_tolerance) { + converge = FALSE; + } + } else { + if (fabs(new_g - x[j]->surface_charge->g[k].g) > convergence_tolerance) { + converge = FALSE; + } + } + x[j]->surface_charge->g[k].g = new_g; + if (new_g != 0) { + x[j]->surface_charge->g[k].dg = (new_g2 - new_g) / dif; + } else { + x[j]->surface_charge->g[k].dg = -charge_group[k].z; + } + /* save g for species */ + for (i = 0; i < count_s_x; i++) { + if (equal(charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = k; + } + } + } + if (debug_diffuse_layer == TRUE) { + strcpy(name, x[j]->master[0]->elt->name); + replace ("_psi", "", name); +/* surf_chrg_eq = calc_surface_charge(name); + */ + output_msg(OUTPUT_MESSAGE, "\nDonnan all on %s (%d): charge, \tg, \tdg, Psi_surface = %8f V. \n", name, count_charge, + x[j]->master[0]->s->la * 2 * LOG_10 * R_KJ_DEG_MOL * tk_x / F_KJ_V_EQ); + for (i = 0; i < count_g; i++) { + output_msg(OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\n", + (double) x[j]->surface_charge->g[i].charge, + (double) x[j]->surface_charge->g[i].g, + (double) x[j]->surface_charge->g[i].dg); + } + } + count_charge++; + } + return (converge); +} +/* ---------------------------------------------------------------------- */ +int calc_init_donnan(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + int count_g, count_charge; + char name[MAX_LENGTH]; + LDBLE f_psi, surf_chrg_eq, psi_avg, f_sinh, A_surf, ratio_aq; + + if (use.surface_ptr == NULL) return(OK); + f_sinh = sqrt(8000.0 * EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * tk_x * mu_x); +/* + * sum eq of each charge number in solution... + */ + charge_group = (struct charge_group *) free_check_null(charge_group); + charge_group = (struct charge_group *) PHRQ_malloc((size_t) sizeof(struct charge_group)); + if (charge_group == NULL) malloc_error(); + charge_group[0].z = 0.0; + charge_group[0].eq = 0.0; + + count_g = 1; + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->type > HPLUS) continue; + for (k = 0; k < count_g; k++) { + if (equal(charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { + charge_group[k].eq += s_x[i]->z * s_x[i]->moles; + break; + } + } + if (k >= count_g) { + charge_group = (struct charge_group *) PHRQ_realloc(charge_group, (size_t) (count_g + 1) * + sizeof(struct charge_group)); + if (charge_group == NULL) malloc_error(); + charge_group[count_g].z = s_x[i]->z; + charge_group[count_g].eq = s_x[i]->z * s_x[i]->moles; + + count_g++; + } + } +/* + * calculate g for each surface... + */ + count_charge = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + surface_charge_ptr = x[j]->surface_charge; + + x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_malloc((size_t) count_g * sizeof(struct surface_diff_layer)); + if (x[j]->surface_charge->g == NULL) malloc_error(); + x[j]->surface_charge->count_g = count_g; + + /* find surface charge from potential... */ + A_surf = x[j]->surface_charge->specific_area * x[j]->surface_charge->grams; + f_psi = x[j]->master[0]->s->la * LOG_10; + surf_chrg_eq = A_surf * f_sinh * sinh(f_psi) / F_C_MOL; + + /* find psi_avg that matches surface charge... */ + psi_avg = calc_psi_avg(surf_chrg_eq); + + /* fill in g's */ + ratio_aq = surface_charge_ptr->mass_water / mass_water_aq_x; + + for (k = 0; k < count_g; k++) { + x[j]->surface_charge->g[k].charge = charge_group[k].z; + x[j]->surface_charge->g[k].g = exp(-charge_group[k].z * psi_avg) - 1; + if (x[j]->surface_charge->g[k].g != 0) { + x[j]->surface_charge->g[k].dg = - A_surf * f_sinh * cosh(f_psi) / + (charge_group[k].eq * F_C_MOL); + } else { + x[j]->surface_charge->g[k].dg = -charge_group[k].z; + } + /* save g for species */ + for (i = 0; i < count_s_x; i++) { + if (equal(charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { + s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; + s_x[i]->diff_layer[count_charge].count_g = k; + s_x[i]->diff_layer[count_charge].g_moles = 0.0; + s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; + } + } + } + if (debug_diffuse_layer == TRUE) { + strcpy(name, x[j]->master[0]->elt->name); + replace ("_psi", "", name); +/* surf_chrg_eq = calc_surface_charge(name); + */ + output_msg(OUTPUT_MESSAGE, "\nDonnan init on %s : charge, \tg, \tdg, Psi_surface = %8f V. \n", name, + x[j]->master[0]->s->la * 2 * LOG_10 * R_KJ_DEG_MOL * tk_x / F_KJ_V_EQ); + for (i = 0; i < count_g; i++) { + output_msg(OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\n", + (double) x[j]->surface_charge->g[i].charge, (double) x[j]->surface_charge->g[i].g, (double) x[j]->surface_charge->g[i].dg ); + } + } + count_charge++; + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_psi_avg(LDBLE surf_chrg_eq) +/* ---------------------------------------------------------------------- */ +{ +/* + * calculate the average (F * Psi / RT) that lets the DL charge counter the surface charge + */ + int i, iter, count_g; + LDBLE fd, fd1, p, temp, ratio_aq; +/* LDBLE dif; + */ + count_g = surface_charge_ptr->count_g; + if (convergence_tolerance >= 1e-8) { + G_TOL = 1e-9; + } else { + G_TOL = 1e-10; + } + ratio_aq = surface_charge_ptr->mass_water / mass_water_aq_x; + p = 0; + if (surf_chrg_eq == 0) { + return(0.0); + } else if (surf_chrg_eq < 0) { + p = -0.5 * log(-surf_chrg_eq * ratio_aq / mu_x + 1); + } else if (surf_chrg_eq > 0) { + p = 0.5 * log(surf_chrg_eq * ratio_aq / mu_x + 1); + } +/* + * Optimize p in SS{s_x[i]->moles * z_i * g(p)} = -surf_chrg_eq + * g(p) = exp(-p * z_i) - 1 + */ + iter = 0; + do { + fd = surf_chrg_eq; + fd1 = 0.0; + for (i = 1; i < count_g; i++) { + temp = exp(-charge_group[i].z * p); + if (temp > 1 - ratio_aq) { + fd += charge_group[i].eq * (temp - 1); + fd1 -= charge_group[i].z * charge_group[i].eq * temp; + } + } +/* fd1 = surf_chrg_eq * ratio_aq; + dif = 1e-5; + p += dif; + for (i = 1; i < count_g; i++) { + temp = exp(-charge_group[i].z * p); + fd1 += charge_group[i].eq * temp; + } + fd /= -(fd1 - fd) / dif; + p -= dif; + p += (fd > 1) ? 1 : ((fd < -1) ? -1 : fd); + */ + fd /= -fd1; + p += (fd > 1) ? 1 : ((fd < -1) ? -1 : fd); + if (fabs(p) < G_TOL) p = 0.0; + iter++; + if (iter > 50) { + sprintf(error_string, "\nToo many iterations for surface in subroutine calc_psi_avg.\n"); + error_msg(error_string, STOP); + } + } while (fabs(fd) > G_TOL && p != 0.0); + if (debug_diffuse_layer == TRUE) + output_msg(OUTPUT_MESSAGE, "iter in calc_psi_avg = %d. g(+1) = %8f. surface charge = %8f.\n", + iter, (double) (exp(-p) - 1), (double) surf_chrg_eq); + + return(p); +} diff --git a/inverse.cpp b/inverse.cpp new file mode 100644 index 00000000..a1227358 --- /dev/null +++ b/inverse.cpp @@ -0,0 +1,3014 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: inverse.c 588 2005-10-11 20:29:31Z dlpark $"; + +#define MAX_MODELS 20 +#define MIN_TOTAL_INVERSE 1e-14 + +#ifdef INVERSE_CL1MP +/* cl1mp.c */ +extern int cl1mp(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q_arg, + int *kode, LDBLE toler, + int *iter, LDBLE *x_arg, LDBLE *res_arg, LDBLE *error, + LDBLE *cu_arg, int *iu, int *s, int check, LDBLE censor_arg); +#endif + +/* variables local to module */ + +int max_row_count, max_column_count; +static int carbon; +char **col_name, **row_name; +static int count_rows, count_optimize; +static int col_phases, col_redox, col_epsilon, col_ph, col_water, col_isotopes, col_phase_isotopes; +static int row_mb, row_fract, row_charge, row_carbon, row_isotopes, row_epsilon, row_isotope_epsilon, row_water; +static LDBLE *zero, *array1, *res, *delta1, *delta2, *delta3, *cu, *delta_save; +static LDBLE *min_delta, *max_delta; +static int *iu, *is; +static int klmd, nklmd, n2d, kode, iter; +static LDBLE toler, error, max_pct, scaled_error; +static struct master *master_alk; +int *row_back, *col_back; + +static unsigned long *good, *bad, *minimal; +static int max_good, max_bad, max_minimal; +static int count_good, count_bad, count_minimal, count_calls; +static unsigned long soln_bits, phase_bits, current_bits, temp_bits; + +/* subroutines */ + +static int bit_print(unsigned long bits, int l); +static int carbon_derivs(struct inverse *inv_ptr); +static int check_isotopes(struct inverse *inv_ptr); +static int check_solns(struct inverse *inv_ptr); +static int count_isotope_unknowns(struct inverse *inv_ptr, struct isotope **isotope_unknowns); +static int isotope_balance_equation(struct inverse *inv_ptr, int row, int n); +static int post_mortem(void); +static unsigned long get_bits(unsigned long bits, int position, int number); +static unsigned long minimal_solve(struct inverse *inv_ptr, unsigned long minimal_bits); +static int next_set_phases(struct inverse *inv_ptr, + int first_of_model_size, + int model_size); +static int phase_isotope_inequalities(struct inverse *inv_ptr); +static int print_model(struct inverse *inv_ptr); +static int punch_model_heading(struct inverse *inv_ptr); +static int punch_model(struct inverse *inv_ptr); +static int range(struct inverse *inv_ptr, unsigned long cur_bits); +static int save_bad(unsigned long bits); +static int save_good(unsigned long bits); +static int save_minimal(unsigned long bits); +static unsigned long set_bit(unsigned long bits, int position, int value); +static int setup_inverse(struct inverse *inv_ptr); +static int set_ph_c(struct inverse *inv_ptr, + int i, + struct solution *soln_ptr_orig, + int n_user_new, + LDBLE d_alk, + LDBLE ph_factor, + LDBLE alk_factor); +static int shrink(struct inverse *inv_ptr, LDBLE *array_in, LDBLE *array_out, + int *k, int *l, int *m, int *n, + unsigned long cur_bits, + LDBLE *delta_l, int *col_back_l, int *row_back_l); +static int solve_inverse(struct inverse *inv_ptr); +static int solve_with_mask(struct inverse *inv_ptr, unsigned long cur_bits); +static int subset_bad(unsigned long bits); +static int subset_minimal(unsigned long bits); +static int superset_minimal(unsigned long bits); +static int write_optimize_names(struct inverse *inv_ptr); + +#ifdef SKIP +#define SCALE_EPSILON .0009765625 +#define SCALE_WATER .0009765625 +#define SCALE_ALL 16 +#endif +#define SCALE_EPSILON .0009765625 +#define SCALE_WATER 1. +#define SCALE_ALL 1. + +/* ---------------------------------------------------------------------- */ +int inverse_models(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through list of inverse models, make calculations + * for any marked "new". + */ + int n, print1; + + if (svnid == NULL) fprintf(stderr," "); + array1 = NULL; + zero = NULL; + res = NULL; + delta1 = NULL; + delta2 = NULL; + delta3 = NULL; + delta_save = NULL; + cu = NULL; + iu = NULL; + is = NULL; + col_name = NULL; + row_name = NULL; + min_delta = NULL; + max_delta = NULL; + good = NULL; + bad = NULL; + minimal = NULL; + + print1 = TRUE; + state = INVERSE; + diffuse_layer_x = FALSE; + for (n=0; n < count_inverse; n++) { + if (inverse[n].new_def == TRUE) { +/* + * Fill in stucture "use". + */ + use.inverse_in = TRUE; + use.inverse_ptr = &inverse[n]; + use.n_inverse_user = inverse[n].n_user; +/* + * Initial prints + */ + sprintf(error_string,"Beginning of inverse modeling %d calculations.", inverse[n].n_user); + dup_print(error_string, TRUE); + + if (inverse[n].mp == TRUE) { + output_msg(OUTPUT_MESSAGE, "Using Cl1MP multiprecision optimization routine.\n"); + + } else { + output_msg(OUTPUT_MESSAGE, "Using Cl1 standard precision optimization routine.\n"); + } + status(0, NULL); + +/* + * Setup and solve + */ + count_calls = 0; + setup_inverse(&(inverse[n])); + punch_model_heading(&inverse[n]); + solve_inverse(&(inverse[n])); + if (inverse[n].count_isotope_unknowns > 0 ) { + inverse[n].isotope_unknowns = (struct isotope *) free_check_null(inverse[n].isotope_unknowns); + } + inverse[n].new_def = FALSE; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_inverse(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in array for an inverse problem + */ + int i, j, k, i_alk, i_carb; + int max; + int count_rows_t; + int column, row; + int temp, temppun; + LDBLE isotope_number; + LDBLE f, coef, cb, conc; + char token[MAX_LENGTH]; + struct phase *phase_ptr; + struct solution *solution_ptr; + struct reaction *rxn_ptr; + struct master *master_ptr; +/* + * Determine array sizes, row and column positions + */ + toler = inv_ptr->tolerance; + if (inv_ptr->mp == TRUE) { + toler = inv_ptr->mp_tolerance; + } +/* + * Alkalinity derivatives with pH and carbon + */ + carbon = 1; + temp = pr.status; + pr.status = FALSE; + temppun = punch.in; + punch.in = FALSE; + carbon_derivs(inv_ptr); + pr.status = temp; + punch.in = temppun; + state = INVERSE; +/* + * tidy isotopes if necessary + */ + inv_ptr->count_isotope_unknowns = 0; + if (inv_ptr->count_isotopes > 0) { + inv_ptr->count_isotope_unknowns = count_isotope_unknowns(inv_ptr, &inv_ptr->isotope_unknowns); + if (input_error > 0) { + error_msg("Stopping because of input errors.", STOP); + } + check_isotopes(inv_ptr); + if (input_error > 0) { + error_msg("Stopping because of input errors.", STOP); + } + } + +/* + * count unknowns + */ + max_column_count = inv_ptr->count_elts * inv_ptr->count_solns + /* epsilons */ + inv_ptr->count_solns + /* solutions */ + inv_ptr->count_phases + /* phases */ + inv_ptr->count_redox_rxns + /* redox reactions */ + carbon * inv_ptr->count_solns + /* pH */ + 1 + /* water */ + inv_ptr->count_isotope_unknowns * inv_ptr->count_solns + /* isotopes in solution*/ + inv_ptr->count_isotopes * inv_ptr->count_phases + /* isotopes in phases */ + 1 + 1; /* rhs, ineq */ + count_unknowns = max_column_count - 2; + col_phases = inv_ptr->count_solns; + col_redox = col_phases + inv_ptr->count_phases; + col_epsilon = col_redox + inv_ptr->count_redox_rxns; + col_ph = col_epsilon + inv_ptr->count_elts * inv_ptr->count_solns; + col_water = col_ph + carbon * inv_ptr->count_solns; + col_isotopes = col_water + 1; + col_phase_isotopes = col_isotopes + inv_ptr->count_isotope_unknowns * inv_ptr->count_solns; + max_row_count = + inv_ptr->count_solns * inv_ptr->count_elts + /* optimize */ + carbon * inv_ptr->count_solns + /* optimize ph */ + 1 + /* optimize water */ + inv_ptr->count_solns * inv_ptr->count_isotope_unknowns + /* optimize isotopes */ + inv_ptr->count_isotopes * inv_ptr->count_phases + /* optimize phase isotopes */ + inv_ptr->count_elts + /* mass balances */ + 1 + 1 + /* fractions, init and final */ + inv_ptr->count_solns + /* charge balances */ + carbon * inv_ptr->count_solns + /* dAlk = dC + dph */ + inv_ptr->count_isotopes + /* isotopes */ + 2 * inv_ptr->count_solns * inv_ptr->count_elts + /* epsilon constraints */ + 2 * carbon * inv_ptr->count_solns + /* epsilon on ph */ + 2 + /* epsilon for water */ + 2 * inv_ptr->count_isotope_unknowns * inv_ptr->count_solns + /* epsilon for isotopes */ + 2 * inv_ptr->count_isotopes * inv_ptr->count_phases + /* epsilon for isotopes in phases */ + 2; /* work space */ + + row_mb =inv_ptr->count_solns * inv_ptr->count_elts + + carbon * inv_ptr->count_solns + 1 + + inv_ptr->count_solns * inv_ptr->count_isotope_unknowns + + inv_ptr->count_isotopes * inv_ptr->count_phases; + row_fract = row_mb + inv_ptr->count_elts; + row_charge = row_fract + 2; + row_carbon = row_charge + inv_ptr->count_solns; + row_isotopes = row_carbon + carbon * inv_ptr->count_solns; + row_epsilon = row_isotopes + inv_ptr->count_isotopes; +/* The next three are not right, some rows of epsilon are deleted */ +/* + row_ph_epsilon = row_epsilon + 2 * inv_ptr->count_solns * inv_ptr->count_elts; + row_water_epsilon = row_ph + 2 * carbon * inv_ptr->count_solns; + row_isotope_epsilon + row_isotope_phase_epsilon + */ +/* + * Malloc space for arrays + */ + array = (LDBLE *) free_check_null(array); + array = (LDBLE *) PHRQ_malloc((size_t) max_column_count * max_row_count * sizeof(LDBLE)); + if (array == NULL) malloc_error(); + + array1 = (LDBLE *) PHRQ_malloc((size_t) max_column_count * max_row_count * sizeof(LDBLE)); + if (array1 == NULL) malloc_error(); + + col_name = (char **) PHRQ_malloc((size_t) max_column_count * sizeof(char *)); + if (col_name == NULL) malloc_error(); + + row_name = (char **) PHRQ_malloc((size_t) max_row_count * sizeof(char *)); + if (row_name == NULL) malloc_error(); + + delta = (LDBLE *) free_check_null (delta); + delta = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (delta == NULL) malloc_error(); + + delta1 = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (delta1 == NULL) malloc_error(); + + delta2 = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (delta2 == NULL) malloc_error(); + + delta3 = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (delta3 == NULL) malloc_error(); + + delta_save = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (delta_save == NULL) malloc_error(); + + min_delta = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (min_delta == NULL) malloc_error(); + + max_delta = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (max_delta == NULL) malloc_error(); + + res = (LDBLE *) PHRQ_malloc((size_t) max_row_count*sizeof(LDBLE)); + if (res == NULL) malloc_error(); + + if (max_column_count < max_row_count) { + max = max_row_count; + } else { + max = max_column_count; + } + zero = (LDBLE *) PHRQ_malloc((size_t) max * sizeof(LDBLE)); + if (zero == NULL) malloc_error(); +/* + * Define zero and zero array, delta + */ + for (i = 0; i < max; i++) zero[i] = 0.0; + + memcpy((void *) &(delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(min_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(max_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + for (i = 0; i < max_row_count; i++) { + memcpy((void *) &(array[i*max_column_count]), (void *) &(zero[0]), + (size_t) max_column_count * sizeof(LDBLE)); + } +/* + * begin filling array + */ + count_rows = 0; +/* + * optimization + */ + count_optimize = inv_ptr->count_solns * inv_ptr->count_elts + /* optimize */ + carbon * inv_ptr->count_solns + /* optimize ph */ + 1 + /* optimize water */ + inv_ptr->count_solns * inv_ptr->count_isotope_unknowns + /* optimize isotopes */ + inv_ptr->count_isotopes * inv_ptr->count_phases; /* optimize phase isotopes */ + + for (i = 0; i < count_optimize; i++) { + row_name[count_rows] = string_hsave("optimize"); + count_rows++; + } + write_optimize_names(inv_ptr); +/* + * equalities + */ + +/* + * Mass_balance: solution data + */ + + /* initialize master species */ + for (i = 0; i < count_master; i++) { + master[i]->in = -1; + if (strstr(master[i]->elt->name, "Alk") == master[i]->elt->name) { + master_alk = master[i]; + } + } + /* mark master species included in model, write row names*/ + count_rows_t = count_rows; + i_alk = -1; + i_carb = -1; + for (i = 0; i < inv_ptr->count_elts; i++) { + master_ptr = inv_ptr->elts[i].master; + if (master_ptr == master_alk) i_alk = i; + if (strcmp(master_ptr->elt->name,"C(4)") == 0) i_carb = i; + inv_ptr->elts[i].master->in = count_rows_t; + row_name[count_rows_t] = inv_ptr->elts[i].master->elt->name; + count_rows_t++; + } + /* put concentrations in array */ + for (i=0; i < inv_ptr->count_solns; i++) { + xsolution_zero(); + solution_ptr = solution_bsearch(inv_ptr->solns[i], &j, TRUE); + if (solution_ptr == NULL) { + sprintf(error_string, "Solution number %d not found.", + inv_ptr->solns[i]); + error_msg(error_string, STOP); + } + /* write master species concentrations */ + for (j=0; solution_ptr->totals[j].description != NULL; j++) { + master_ptr = master_bsearch(solution_ptr->totals[j].description); + master_ptr->total += solution_ptr->totals[j].moles; + /* List elements not included in model */ + if (master_ptr->in < 0) { + sprintf(error_string, "%s is included in solution %d, but is not included as a mass-balance constraint.", + solution_ptr->totals[j].description, + inv_ptr->solns[i]); + warning_msg(error_string); + } + } + master_alk->total = solution_ptr->total_alkalinity; + f = 1.0; + if (i == (inv_ptr->count_solns - 1)) { + f = -1.0; + } + column = i; + sprintf(token, "soln %d", i); + col_name[column] = string_hsave(token); + for(j=0; j < count_master; j++) { + if (master[j]->in >= 0) { + array[master[j]->in * max_column_count + i] = f * master[j]->total; + if (master[j]->s == s_eminus) { + array[master[j]->in * max_column_count + i] = 0.0; + } + } + } + /* calculate charge balance for elements in model */ + cb = 0; + for(j=0; j < count_master; j++) { + if (master[j]->in >= 0) { + if (master[j]->s == s_eminus) { + coef = 0.0; + } else if (master[j] == master_alk) { + coef = -1.0; + } else { + coef = master[j]->s->z + master[j]->s->alk; + } + cb += coef * master[j]->total; + } + } + if (fabs(cb) < toler) cb = 0.0; + array[(row_charge + i) * max_column_count + i] = cb; + } + +/* mass_balance: phase data */ + + for (i = 0; i < inv_ptr->count_phases; i++) { + phase_ptr = inv_ptr->phases[i].phase; + rxn_ptr = phase_ptr->rxn_s; + column = col_phases + i; + col_name[column] = phase_ptr->name; + for (j = 1; rxn_ptr->token[j].s != NULL; j++) { + if (rxn_ptr->token[j].s->secondary != NULL) { + master_ptr = rxn_ptr->token[j].s->secondary; + } else { + master_ptr = rxn_ptr->token[j].s->primary; + } + if (master_ptr == NULL) { + sprintf(error_string, "Setup_inverse, reaction for phase, %s.", phase_ptr->name); + error_msg(error_string, STOP); + } + if (master_ptr->s == s_hplus) continue; + if (master_ptr->s == s_h2o) { + row = row_fract; +/* turn off h2o from minerals in water mass balance */ + if (inv_ptr->mineral_water != TRUE) continue; + + } else { + row = master_ptr->in; + } + /* e- has coef of 0 for some reason */ + coef = master_ptr->coef; + if (coef <= 0) coef = 1.0; + array[row*max_column_count + column] = rxn_ptr->token[j].coef * coef; + } + row = master_alk->in; /* include alkalinity for phase */ + array[row * max_column_count + column] = calc_alk(rxn_ptr); + } + +/* mass balance: redox reaction data */ + + k = 0; + for (i = 0; i < inv_ptr->count_elts; i++) { + if (inv_ptr->elts[i].master->s->primary == NULL) { + coef = inv_ptr->elts[i].master->coef ; + rxn_ptr = inv_ptr->elts[i].master->rxn_primary; + column = col_redox + k; + col_name[column] = inv_ptr->elts[i].master->elt->name; + k++; + for (j = 0; rxn_ptr->token[j].s != NULL; j++) { + if (rxn_ptr->token[j].s->secondary != NULL) { + master_ptr = rxn_ptr->token[j].s->secondary; + } else { + master_ptr = rxn_ptr->token[j].s->primary; + } + if (master_ptr == NULL) { + sprintf(error_string, "Subroutine setup_inverse, element not found, %s.", rxn_ptr->token[j].s->name); + error_msg(error_string, STOP); + } + if (master_ptr->s == s_hplus) continue; + if (master_ptr->s == s_h2o) { + row = row_fract; +/* turn off h2o from minerals in water mass balance */ + if (inv_ptr->mineral_water != TRUE) continue; + } else { + row = master_ptr->in; + } + array[row*max_column_count + column] = rxn_ptr->token[j].coef; + /* if coefficient of element is not 1.0 in master species */ + if (j != 0) array[row*max_column_count + column] /= coef; + } + row = master_alk->in; /* include alkalinity for redox reaction */ + array[row * max_column_count + column] = ( calc_alk(rxn_ptr) - inv_ptr->elts[i].master->s->alk ) / coef; + } + } + +/* mass-balance: epsilons */ + + column = col_epsilon; + for (i = 0; i < inv_ptr->count_elts; i++) { + row = inv_ptr->elts[i].master->in; + for (j = 0; j < inv_ptr->count_solns; j++) { + if (j < (inv_ptr->count_solns - 1)) { + array[row * max_column_count + column] = 1.0; + } else { + array[row * max_column_count + column] = -1.0; + } + if (inv_ptr->elts[i].master->s == s_eminus) { + array[row * max_column_count + column] = 0.0; + } + sprintf(token, "%s %d", row_name[row], j); + col_name[column] = string_hsave(token); + column++; + } + } + count_rows += inv_ptr->count_elts; + +/* put names in col_name for ph */ + + for (i = 0; i < inv_ptr->count_solns; i++) { + sprintf(token, "ph %d", i); + col_name[column] = string_hsave(token); + column++; + } +/* put names in col_name for water */ + + sprintf(token, "water"); + col_name[column] = string_hsave(token); + column++; + +/* put names of isotopes in col_name */ + for (i = 0; i < inv_ptr->count_solns; i++) { + for (j = 0; j < inv_ptr->count_isotope_unknowns; j++) { + sprintf(token, "%d%s %d", + (int) inv_ptr->isotope_unknowns[j].isotope_number, + inv_ptr->isotope_unknowns[j].elt_name, i); + col_name[column] = string_hsave(token); + column++; + } + } + +/* put phase isotopes in col_name */ + + if (inv_ptr->count_isotopes > 0) { + /* isotopes of phases phases */ + for (i = 0; i < inv_ptr->count_phases; i++) { + for (j = 0; j < inv_ptr->count_isotopes; j++) { + sprintf(token, "%d%s %s", + (int) inv_ptr->isotopes[j].isotope_number, + inv_ptr->isotopes[j].elt_name, + inv_ptr->phases[i].phase->name); + col_name[column] = string_hsave(token); + column++; + } + } + } +/* + * Initial solution mixing fractions or water mass balance + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + solution_ptr = solution_bsearch(inv_ptr->solns[i], &j, TRUE); + if (i < inv_ptr->count_solns - 1) { + array[count_rows * max_column_count + i] = 1.0 / gfw_water * solution_ptr->mass_water; + } else { + array[count_rows * max_column_count + inv_ptr->count_solns - 1] = - 1.0 / gfw_water * solution_ptr->mass_water; + } + } + /* coefficient for water uncertainty */ + if (inv_ptr->water_uncertainty > 0 ) { + array[count_rows * max_column_count + col_water] = 1.0; + } + row_name[count_rows] = string_hsave("H2O"); + row_water = count_rows; + count_rows++; + +/* + * Final solution fraction equals 1.0 + */ + + array[count_rows * max_column_count + inv_ptr->count_solns - 1] = 1.0 ; + array[count_rows * max_column_count + count_unknowns] = 1.0; + row_name[count_rows] = string_hsave("fract, final"); + count_rows++; + +/* + * Charge balance: + */ + + for (i = 0; i < inv_ptr->count_solns; i++) { +/* solution_ptr = solution_bsearch(inv_ptr->solns[i], &j, TRUE); */ +/* array[count_rows * max_column_count + i] = solution_ptr->cb; */ + for (j = 0; j < inv_ptr->count_elts; j++) { + column = col_epsilon + j * inv_ptr->count_solns + i; + coef = inv_ptr->elts[j].master->s->z + inv_ptr->elts[j].master->s->alk; + if (inv_ptr->elts[j].master == master_alk) { + coef = -1.0; + } + array[count_rows * max_column_count + column] = coef; + if (inv_ptr->elts[j].master->s == s_eminus) { + array[count_rows * max_column_count + column] = 0.0; + } + } + sprintf(token, "%s %d", "charge", i); + row_name[count_rows] = string_hsave(token); + count_rows++; + } +/* + * dC = (dC/dph)*dph + (dC/dAlk)*dAlk for each solution + */ +/* + * dAlk = (dAlk/dC)*dC + (dAlk/dpH)*dpH for each solution + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + if (inv_ptr->dalk_dph[i] != 0 || inv_ptr->dalk_dc[i] != 0) { + column = col_ph + i; + array[count_rows * max_column_count + column] = inv_ptr->dalk_dph[i]; + column = col_epsilon + i_alk * inv_ptr->count_solns + i; + array[count_rows * max_column_count + column] = -1.0; + column = col_epsilon + i_carb * inv_ptr->count_solns + i; + array[count_rows * max_column_count + column] = inv_ptr->dalk_dc[i]; + } + sprintf(token, "%s %d", "dAlk", i); + row_name[count_rows] = string_hsave(token); + count_rows++; + } +/* + * Isotope mass balances + */ + if (input_error > 0) { + error_msg("Stopping because of input errors.", STOP); + } + if (inv_ptr->count_isotopes != 0) { + for (j = 0; j < inv_ptr->count_isotopes; j++) { + isotope_balance_equation(inv_ptr, count_rows, j); + sprintf(token,"%d%s", (int) inv_ptr->isotopes[j].isotope_number, + inv_ptr->isotopes[j].elt_name); + row_name[count_rows] = string_hsave(token); + count_rows++; + } + } +/* + * inequalities + */ + row_epsilon = count_rows; + for (i = 0; i < inv_ptr->count_solns; i++) { + for (j = 0; j < inv_ptr->count_elts; j++) { + if (inv_ptr->elts[j].master->s == s_eminus) continue; + column = col_epsilon + j*inv_ptr->count_solns + i; + +/* calculate magnitude of bound */ + + coef = inv_ptr->elts[j].uncertainties[i]; + if (coef <= 0.0) { + coef = -coef; + } else { + coef = array[inv_ptr->elts[j].master->in * max_column_count + i] * coef; + coef = fabs(coef); + } + + if (coef < toler) coef = 0; + +/* zero column if uncertainty is zero */ + if (coef == 0.0) { + for(k = 0; k < count_rows; k++) { + array[k * max_column_count + column] = 0.0; + } + continue; + } + +/* this statement probably obviates some of the following logic. */ +/* coef += toler; */ + +/* scale epsilon optimization equation */ + + if (coef < toler) { + array[(column - col_epsilon) * max_column_count + column] = SCALE_EPSILON/toler; + } else { + array[(column - col_epsilon) * max_column_count + column] = SCALE_EPSILON/coef; + } + +/* set upper limit of change in positive direction */ + if (coef < toler) { + coef = toler; + f = 10; + } else { + f = 1.0; + } + array[count_rows * max_column_count + column] = 1.0 * f; + array[count_rows * max_column_count + i] = -coef * f; + sprintf(token, "%s %s", inv_ptr->elts[j].master->elt->name, "eps+"); + row_name[count_rows] = string_hsave(token); + count_rows++; + +/* set lower limit of change in negative direction */ + conc = array[inv_ptr->elts[j].master->in * max_column_count + i]; + + /* if concentration is zero, only positive direction allowed */ + if (conc == 0.0) { + delta[column] = 1.0; + continue; + } + /* if uncertainty is less than tolerance, set uncertainty to toler */ + if (coef <= toler) { +/* f = 10 * toler / coef; */ + coef = toler; + f = 10; + } else { + f = 1.0; + } + /* if uncertainty is greater than concentration, + maximum negative is equal to concentrations, + except alkalinity */ + if (coef > fabs(conc) && + (strstr(inv_ptr->elts[j].master->elt->name,"Alkalinity") != inv_ptr->elts[j].master->elt->name)) coef = fabs(conc) + toler; + + array[count_rows * max_column_count + i] = -coef * f ; + array[count_rows * max_column_count + column] = -1.0 * f; + sprintf(token, "%s %s", inv_ptr->elts[j].master->elt->name, "eps-"); + row_name[count_rows] = string_hsave(token); + count_rows++; + } + } +/* + * inequalities for pH + */ + /* row_ph_epsilon = count_rows; */ + if (inv_ptr->carbon == TRUE) { + for (i = 0; i < inv_ptr->count_solns; i++) { + column = col_ph + i; + coef = inv_ptr->ph_uncertainties[i]; + +/* scale epsilon in optimization equation */ + + array[(column - col_epsilon) * max_column_count + column] = SCALE_EPSILON/coef; + +/* set upper limit of change in positive direction */ + + array[count_rows * max_column_count + column] = 1.0; + array[count_rows * max_column_count + i] = -coef; + sprintf(token, "%s %s", "pH", "eps+"); + row_name[count_rows] = string_hsave(token); + count_rows++; + +/* set lower limit of change in negative direction */ + + array[count_rows * max_column_count + column] = -1.0; + array[count_rows * max_column_count + i] = -coef; + sprintf(token, "%s %s", "pH", "eps-"); + row_name[count_rows] = string_hsave(token); + count_rows++; + } + } +/* + * inequalities for water + */ + column = col_water; + coef = inv_ptr->water_uncertainty; + /* row_water_epsilon = count_rows; */ + if (coef > 0.0) { +/* set upper limit of change in positive direction */ + array[count_rows * max_column_count + column] = 1.0; + array[count_rows * max_column_count + count_unknowns] = coef; + sprintf(token, "%s %s", "water", "eps+"); + row_name[count_rows] = string_hsave(token); + count_rows++; + +/* set lower limit of change in negative direction */ + + array[count_rows * max_column_count + column] = -1.0; + array[count_rows * max_column_count + count_unknowns] = coef; + sprintf(token, "%s %s", "water", "eps-"); + row_name[count_rows] = string_hsave(token); + count_rows++; + } +/* + * inequalities for isotopes + */ + row_isotope_epsilon = count_rows; + if (inv_ptr->count_isotopes > 0) { + for (i = 0; i < inv_ptr->count_solns; i++) { + solution_ptr = solution_bsearch(inv_ptr->solns[i], &k, TRUE); + for (j = 0; j < inv_ptr->count_isotope_unknowns; j++) { + column = col_isotopes + (i * inv_ptr->count_isotope_unknowns) + j; + master_ptr = inv_ptr->isotope_unknowns[j].master; + isotope_number = inv_ptr->isotope_unknowns[j].isotope_number; + for (k = 0; k < solution_ptr->count_isotopes; k++) { + if (solution_ptr->isotopes[k].master == master_ptr && + solution_ptr->isotopes[k].isotope_number == isotope_number) { + coef = solution_ptr->isotopes[k].x_ratio_uncertainty; + +/* scale epsilon in optimization equation */ + + array[(column - col_epsilon) * max_column_count + column] = SCALE_EPSILON/coef; + +/* set upper limit of change in positive direction */ + array[count_rows * max_column_count + column] = 1.0; + array[count_rows * max_column_count + i] = -coef; + sprintf(token, "%d%s %s", + (int) solution_ptr->isotopes[k].isotope_number, + solution_ptr->isotopes[k].elt_name, + "eps+"); + row_name[count_rows] = string_hsave(token); + count_rows++; + +/* set lower limit of change in negative direction */ + + array[count_rows * max_column_count + column] = -1.0; + array[count_rows * max_column_count + i] = -coef; + sprintf(token, "%d%s %s", + (int) solution_ptr->isotopes[k].isotope_number, + solution_ptr->isotopes[k].elt_name, + "eps-"); + row_name[count_rows] = string_hsave(token); + count_rows++; + break; + } + } + } + } + } +/* + * inequalities for isotopes in phases + */ + /* row_isotope_phase_epsilon = count_rows; */ + phase_isotope_inequalities(inv_ptr); + if (input_error > 0) { + error_msg("Stopping because of input errors.", STOP); + } +/* + * Set non-negativity constraints + */ + + for (i = 0; i < inv_ptr->count_phases; i++) { + if (inv_ptr->phases[i].constraint == PRECIPITATE) { + delta[col_phases + i] = -1.0; + } else if (inv_ptr->phases[i].constraint == DISSOLVE) { + delta[col_phases + i] = 1.0; + } + } + for (i = 0; i < (inv_ptr->count_solns - 1); i++) { + delta[i] = 1.0; + } +/* + * Scale water equation + */ + for (i = 0; i < max_column_count; i++) { + array[row_water * max_column_count + i] *= SCALE_WATER; + } +/* + * Arrays are complete + */ + if (debug_inverse == TRUE ) { + for (i = 0; i < count_unknowns; i++) { + output_msg(OUTPUT_MESSAGE, "%d\t%s\n", i, col_name[i]); + } + for (i = 0; i < count_rows; i++) { + k = 0; + output_msg(OUTPUT_MESSAGE,"%d\t%s\n", i, row_name[i]); + for (j=0; j < count_unknowns + 1; j++) { + if (k > 7) { + output_msg(OUTPUT_MESSAGE,"\n"); + k = 0; + } + output_msg(OUTPUT_MESSAGE,"%11.2e", (double) array[i*max_column_count + j]); + k++; + } + if (k != 0) { + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE, "row_mb %d\n", row_mb); + output_msg(OUTPUT_MESSAGE, "row_fract %d\n", row_fract); + output_msg(OUTPUT_MESSAGE, "row_charge %d\n", row_charge); + output_msg(OUTPUT_MESSAGE, "row_carbon %d\n", row_carbon); + output_msg(OUTPUT_MESSAGE, "row_isotopes %d\n", row_isotopes); + output_msg(OUTPUT_MESSAGE, "row_epsilon %d\n", row_epsilon); + + output_msg(OUTPUT_MESSAGE, "col_phases %d\n", col_phases); + output_msg(OUTPUT_MESSAGE, "col_redox %d\n", col_redox); + output_msg(OUTPUT_MESSAGE, "col_epsilon %d\n", col_epsilon); + output_msg(OUTPUT_MESSAGE, "col_ph %d\n", col_ph); + output_msg(OUTPUT_MESSAGE, "col_water %d\n", col_water); + output_msg(OUTPUT_MESSAGE, "col_isotopes %d\n", col_isotopes); + output_msg(OUTPUT_MESSAGE, "col_phase_isotopes %d\n", col_phase_isotopes); + output_msg(OUTPUT_MESSAGE, "count_unknowns %d\n", count_unknowns); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solve_inverse(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Exhaustively search for mass-balance models with two options + * -minimal on or off + * -range on or off + * + */ + int i, j, n; + int quit, print, first; + int first_of_model_size, model_size; + unsigned long minimal_bits, good_bits; + char token[MAX_LENGTH]; + + n = count_unknowns; /* columns in A, C, E */ + klmd = max_row_count - 2; + nklmd = n + klmd; + n2d = n + 2; + + max_good = MAX_MODELS; + max_bad = MAX_MODELS; + max_minimal = MAX_MODELS; + + good = (unsigned long *) PHRQ_malloc( (size_t) max_good * sizeof(unsigned long)); + if (good == NULL) malloc_error(); + count_good = 0; + + bad = (unsigned long *) PHRQ_malloc( (size_t) max_bad * sizeof(unsigned long)); + if (bad == NULL) malloc_error(); + count_bad = 0; + + minimal = (unsigned long *) PHRQ_malloc( (size_t) max_minimal * sizeof(unsigned long)); + if (minimal == NULL) malloc_error(); + count_minimal = 0; + + col_back = (int *) PHRQ_malloc((size_t) max_column_count * sizeof(int)); + if (col_back == NULL) malloc_error(); + + row_back = (int *) PHRQ_malloc((size_t) max_row_count * sizeof(int)); + if (row_back == NULL) malloc_error(); + +/* + * Allocate space for arrays + */ + cu = (LDBLE *) PHRQ_malloc((size_t) 2*nklmd*sizeof(LDBLE)); + if (cu == NULL) malloc_error(); + iu = (int *) PHRQ_malloc((size_t) 2*nklmd*sizeof(int)); + if (iu == NULL) malloc_error(); + is = (int *) PHRQ_malloc((size_t) klmd*sizeof(int)); + if (is == NULL) malloc_error(); + + for(i = 0; i < 79; i++) token[i] = '='; + token[79] = '\0'; +/* + * Set solutions, largest bit is final solution, smallest bit is initial solution 1 + * Set phases, largest bit is last phase, smallest bit is first phase + * Set current bits to complete list. + */ + soln_bits = 0; + if (inv_ptr->count_solns + inv_ptr->count_phases > 32) { + error_msg("For inverse modeling, sum of initial solutions and phases must be <= 32.\n\tFor all reasonable calculations, the sum should be much less than 32.", STOP); + } + for (i = inv_ptr->count_solns ; i > 0; i--) { + temp_bits = 1 << (i - 1); + soln_bits += temp_bits; + } + if (check_solns(inv_ptr) == ERROR) { + error_msg("Calculations terminating.", STOP); + } +/* + * solutions are in highest bits, phases are in lower bits; + */ +/* + * All combinations of solutions + */ + first = TRUE; + for ( ; get_bits(soln_bits, inv_ptr->count_solns - 2, inv_ptr->count_solns - 1) > 0; soln_bits--) { +/* + * Loop through all models of of descending size + */ + for (model_size = inv_ptr->count_phases; model_size >= 0; model_size--) { + first_of_model_size = TRUE; + quit = TRUE; + while ( next_set_phases(inv_ptr, first_of_model_size, model_size) == TRUE) { + first_of_model_size = FALSE; + current_bits = (soln_bits << inv_ptr->count_phases) + phase_bits; + + if (subset_bad(current_bits) == TRUE || subset_minimal(current_bits) == TRUE) continue; + quit = FALSE; +/* + * Switch for finding minimal models only + */ + if (inv_ptr->minimal == TRUE && superset_minimal(current_bits) == TRUE) continue; +/* + * Solve for minimum epsilons, continue if no solution found. + */ + if (solve_with_mask(inv_ptr, current_bits) == ERROR) { + save_bad(current_bits); + if (first == TRUE) { + post_mortem(); + quit = TRUE; + break; + } else { + continue; + } + } + first = FALSE; +/* + * Model has been found, set bits + */ + good_bits = current_bits; + for(i = 0; i < inv_ptr->count_phases; i++) { + if (equal(delta1[i + inv_ptr->count_solns], 0.0, TOL) == TRUE) { + good_bits = set_bit(good_bits, i, 0); + } + } + for(i = 0; i < inv_ptr->count_solns; i++) { + if (equal(delta1[i], 0.0, TOL) == TRUE) { + good_bits = set_bit(good_bits, i + inv_ptr->count_phases, 0); + } + } +/* + * Determine if model is new + */ + for (j = 0; j < count_good; j++) { + if ( good_bits == good[j]) break; + } +/* + * Calculate ranges and print model only if NOT looking for minimal models + */ + print = FALSE; + if ( j >= count_good && inv_ptr->minimal == FALSE) { + print = TRUE; + save_good(good_bits); + if (inv_ptr->range == TRUE) { + range(inv_ptr, good_bits); + } + print_model(inv_ptr); + punch_model(inv_ptr); + } +/* + * If superset of a minimal model continue + */ + minimal_bits = good_bits; + if (superset_minimal(minimal_bits) == TRUE) { + if (print == TRUE) { + if (pr.inverse == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE,"%s\n\n", token); + } + } + continue; + } +/* + * If not superset of minimal model, find minimal model + */ + minimal_bits = minimal_solve(inv_ptr, minimal_bits); + if (minimal_bits == good_bits && print == TRUE) { + if (pr.inverse == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nModel contains minimum number of phases.\n"); + } + } + if (print == TRUE) { + if (pr.inverse == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE,"%s\n\n", token); + } + } + for (j = 0; j < count_good; j++) { + if ( minimal_bits == good[j]) break; + } + if (j >= count_good) { + save_good(minimal_bits); + if (inv_ptr->range == TRUE) { + range(inv_ptr, minimal_bits); + } + print_model(inv_ptr); + if (pr.inverse == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nModel contains minimum number of phases.\n"); + output_msg(OUTPUT_MESSAGE,"%s\n\n", token); + } + punch_model(inv_ptr); + } + save_minimal(minimal_bits); + } + if (quit == TRUE) break; + } + } +/* + * Summary print + */ + if (pr.inverse == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nSummary of inverse modeling:\n\n"); + output_msg(OUTPUT_MESSAGE,"\tNumber of models found: %d\n", count_good); + output_msg(OUTPUT_MESSAGE,"\tNumber of minimal models found: %d\n", count_minimal); + output_msg(OUTPUT_MESSAGE,"\tNumber of infeasible sets of phases saved: %d\n", count_bad); + output_msg(OUTPUT_MESSAGE,"\tNumber of calls to cl1: %d\n", count_calls); + } + array = (LDBLE *) free_check_null(array); + delta = (LDBLE *) free_check_null(delta); + array1 = (LDBLE *) free_check_null(array1); + zero = (LDBLE *) free_check_null(zero); + res = (LDBLE *) free_check_null(res); + delta1 = (LDBLE *) free_check_null(delta1); + delta2 = (LDBLE *) free_check_null(delta2); + delta3 = (LDBLE *) free_check_null(delta3); + delta_save = (LDBLE *) free_check_null(delta_save); + cu = (LDBLE *) free_check_null(cu); + iu = (int *) free_check_null(iu); + is = (int *) free_check_null(is); + col_name = (char **) free_check_null(col_name); + row_name = (char **) free_check_null(row_name); + col_back = (int *) free_check_null(col_back); + row_back = (int *) free_check_null(row_back); + min_delta = (LDBLE *) free_check_null(min_delta); + max_delta = (LDBLE *) free_check_null(max_delta); + good = (unsigned long *) free_check_null(good); + bad = (unsigned long *) free_check_null(bad); + minimal = (unsigned long *) free_check_null(minimal); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +unsigned long minimal_solve(struct inverse *inv_ptr, unsigned long minimal_bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Starting with phases indicated in minimal bits, sequentially + * remove phases to find minimal solution + */ + int i; + unsigned long temp_bits_l; + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "Beginning minimal solve: \n"); + bit_print(minimal_bits, inv_ptr->count_phases + inv_ptr->count_solns); + } + for (i = 0; i < inv_ptr->count_phases + inv_ptr->count_solns - 1; i++) { + if (get_bits(minimal_bits, i, 1) == 0) continue; + temp_bits_l = 1 << i; /* 0's and one 1 */ + temp_bits_l = ~temp_bits_l; /* 1's and one 0 */ + minimal_bits = minimal_bits & temp_bits_l; + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "Solving for minimal\n"); + bit_print(minimal_bits, inv_ptr->count_phases + inv_ptr->count_solns); + } + +/* + * minimal_bits can not be superset of a minimal model, but + * could be subset of one of the sets of minerals with no feasible solution + * If it is a subset, then replace mineral and go on to next + */ + if ( subset_bad(minimal_bits) == TRUE) { + /* put bit back */ + minimal_bits = minimal_bits | ~temp_bits_l; /* 0's and one 1 */ + continue; + } + if (solve_with_mask (inv_ptr, minimal_bits) == ERROR) { + save_bad(minimal_bits); + /* put bit back */ + minimal_bits = minimal_bits | ~temp_bits_l; /* 0's and one 1 */ + } + + } + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE,"\n\nMINIMAL MODEL\n\n"); + bit_print(minimal_bits, inv_ptr->count_phases + inv_ptr->count_solns); + } + solve_with_mask (inv_ptr, minimal_bits); + return(minimal_bits); +} + +/* ---------------------------------------------------------------------- */ +int solve_with_mask(struct inverse *inv_ptr, unsigned long cur_bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Uses cur_bits to zero out columns of the array and then solves. + */ + int i, k, l, m, n; + +/* + * Calculate dimensions + */ + k = row_mb; /* rows in A */ + l = row_epsilon - row_mb; /* rows in C */ + m = count_rows - row_epsilon; /* rows in E */ + n = count_unknowns; + + + + memcpy( (void *) &(res[0]), (void *) &(zero[0]), (size_t) max_row_count * sizeof(LDBLE)); + memcpy( (void *) &(delta2[0]), (void *) &(delta[0]), (size_t) max_column_count * sizeof(LDBLE)); + memcpy( (void *) &(delta_save[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + + shrink(inv_ptr, array, array1, + &k, &l, &m, &n, + cur_bits, + delta2, col_back, row_back); + /* + * Save delta constraints + */ + for (i=0; i < n; i++) { + delta_save[col_back[i]] = delta2[i]; + } + + + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nColumns\n"); + for (i = 0; i < n; i++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", i, col_name[col_back[i]]); + } + + output_msg(OUTPUT_MESSAGE, "\nRows\n"); + for (i = 0; i < k + l + m; i++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", i, row_name[row_back[i]]); + } + + output_msg(OUTPUT_MESSAGE, "\nA and B arrays:\n\n"); + array_print(array1, k + l + m, n + 1, max_column_count); + + output_msg(OUTPUT_MESSAGE, "\nInput delta vector:\n"); + for (i=0; i < n; i++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", i, col_name[col_back[i]], (double) delta2[i]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + + for (i=0; i < k + l + m; i++) { + if (res[i] == 0) continue; + output_msg(OUTPUT_MESSAGE, "\nInput res is non zero:\n"); + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", i, row_name[row_back[i]], (double) res[i]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + } +/* + * Call CL1 + */ + + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "k, l, m, n, max_col, max_row\t%d\t%d\t%d\t%d\t%d\t%d\n", + k, l, m, n, max_column_count, max_row_count); + } + + kode = 1; + iter = 1000; + count_calls++; + +#ifdef INVERSE_CL1MP + if(inv_ptr->mp == TRUE) { + cl1mp(k, l, m, n, + nklmd, n2d, array1, + &kode, inv_ptr->mp_tolerance, &iter, + delta2, res, &error, cu, iu, is, TRUE, inv_ptr->mp_censor); + } else { + cl1(k, l, m, n, + nklmd, n2d, array1, + &kode, toler, &iter, + delta2, res, &error, cu, iu, is, TRUE); + } +#else + cl1(k, l, m, n, + nklmd, n2d, array1, + &kode, toler, &iter, + delta2, res, &error, cu, iu, is, TRUE); +#endif + if (kode == 3) { + sprintf(error_string, "Exceeded maximum iterations in inverse modeling: %d.\n" + "Recompile program with larger limit.", iter); + error_msg(error_string, STOP); + } + memcpy( (void *) &(delta1[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + for(i = 0; i < n; i++) { + delta1[col_back[i]] = delta2[i]; + } + +/* + * Debug, write results + */ + + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "kode: %d\titer: %d\terror: %e\n", kode, iter, (double) error); + output_msg(OUTPUT_MESSAGE, "\nsolution vector:\n"); + for (i=0; i < n; i++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", i, col_name[col_back[i]], (double) delta2[i]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + + output_msg(OUTPUT_MESSAGE, "\nresidual vector:\n"); + for (i=0; i < (k + l + m); i++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e\n",i, row_name[row_back[i]], (double) res[i]); + } + } + + if (kode != 0) { + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +unsigned long get_bits(unsigned long bits, int position, int number) +/* ---------------------------------------------------------------------- */ +{ +/* + * Returns number of bits from position and below. + * position begins at 0. + */ + return( (bits >> (position + 1 - number)) & ~(~0 << number)); +} +/* ---------------------------------------------------------------------- */ +int save_minimal(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Keeps list of minimal models + */ + minimal[count_minimal] = bits; + count_minimal++; + if (count_minimal >= max_minimal) { + max_minimal *= 2; + minimal = (unsigned long *) PHRQ_realloc(minimal, (size_t) max_minimal * sizeof (unsigned long)); + if (minimal == NULL) malloc_error(); + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int save_good(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Keeps list of good models, not necessarily minimal + */ + good[count_good] = bits; + count_good++; + if (count_good >= max_good) { + max_good *= 2; + good = (unsigned long *) PHRQ_realloc(good, (size_t) max_good * sizeof (unsigned long)); + if (good == NULL) malloc_error(); + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int save_bad(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Keeps list of sets of phases with no feasible solution + */ + bad[count_bad] = bits; + count_bad++; + if (count_bad >= max_bad) { + max_bad *= 2; + bad = (unsigned long *) PHRQ_realloc(bad, (size_t) max_bad * sizeof (unsigned long)); + if (bad == NULL) malloc_error(); + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int superset_minimal(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks whether bits is a superset of any of the minimal models + */ + int i; + unsigned long temp_bits_l; + for (i=0; i < count_minimal; i++) { + temp_bits_l = bits | minimal[i]; + if (temp_bits_l == bits) { + return(TRUE); + } + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +int subset_bad(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks whether bits is a superset of any of the bad models + */ + int i; + unsigned long temp_bits_l; + for (i=0; i < count_bad; i++) { + temp_bits_l = bits | bad[i]; + if (temp_bits_l == bad[i]) { + return(TRUE); + } + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +int subset_minimal(unsigned long bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks whether bits is a subset of any of the minimal models + */ + int i; + unsigned long temp_bits_l; + for (i=0; i < count_minimal; i++) { + temp_bits_l = bits | minimal[i]; + if (temp_bits_l == minimal[i]) { + return(TRUE); + } + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +int bit_print(unsigned long bits, int l) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints l bits of an unsigned long + */ + int i; + + for (i = l - 1; i >= 0; i--) { + output_msg(OUTPUT_MESSAGE,"%lu ", get_bits(bits, i, 1)); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_model(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints model + */ + int i, j, k; + int column; + int print_msg; + struct solution *solution_ptr; + struct master *master_ptr; + struct isotope *isotope_ptr; + LDBLE d1, d2, d3, d4; + char token[MAX_LENGTH]; +/* + * Update screen + */ + status(count_good, NULL); +/* + * print solution data, epsilons, and revised data + */ + if (pr.inverse == FALSE || pr.all == FALSE) return(OK); + max_pct = 0; + scaled_error = 0; + for (i = 0; i < inv_ptr->count_solns; i++) { + if (equal(delta1[i], 0.0, toler) == TRUE) continue; + solution_ptr = solution_bsearch(inv_ptr->solns[i], &j, TRUE); + xsolution_zero(); + for (j=0; solution_ptr->totals[j].description != NULL; j++) { + master_ptr = master_bsearch(solution_ptr->totals[j].description); + master_ptr->total = solution_ptr->totals[j].moles; + } + + output_msg(OUTPUT_MESSAGE,"\nSolution %d: %s\n", inv_ptr->solns[i], solution_ptr->description); + output_msg(OUTPUT_MESSAGE,"\n%15.15s %12.12s %12.12s %12.12s\n", + " ", "Input", "Delta", "Input+Delta"); + master_alk->total = solution_ptr->total_alkalinity; + if (inv_ptr->carbon == TRUE) { + d1 = solution_ptr->ph; + d2 = delta1[col_ph + i] / delta1[i]; + d3 = d1 + d2; + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + output_msg(OUTPUT_MESSAGE,"%15.15s %12.3e +%12.3e =%12.3e\n", + "pH", (double) d1, (double) d2, (double) d3); + if (inv_ptr->ph_uncertainties[i] > 0) { + scaled_error += fabs(d2) / inv_ptr->ph_uncertainties[i]; +/* debug + output_msg(OUTPUT_MESSAGE, "%e\t%e\t%e\n", fabs(d2) / inv_ptr->ph_uncertainties[i], fabs(d2), inv_ptr->ph_uncertainties[i]); + */ + } else if (d2 != 0.0) { + error_msg("Computing delta pH/uncertainty", CONTINUE); + } + } + for (j = 0; j < inv_ptr->count_elts; j++) { + if (inv_ptr->elts[j].master->s == s_eminus) continue; + d1 = inv_ptr->elts[j].master->total; + d2 = delta1[col_epsilon + j * inv_ptr->count_solns + i] / delta1[i]; + d3 = d1 + d2; + + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + + output_msg(OUTPUT_MESSAGE,"%15.15s %12.3e +%12.3e =%12.3e\n", + inv_ptr->elts[j].master->elt->name, (double) d1, (double) d2, (double) d3); + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == FALSE ) { + d3 = fabs(d2/d1); + if (d3 > max_pct) max_pct = d3; + } + d4 = 0; + if (inv_ptr->elts[j].uncertainties[i] > 0) { + d4 = fabs(inv_ptr->elts[j].uncertainties[i] * d1); + } else if (inv_ptr->elts[j].uncertainties[i] < 0) { + d4 = -inv_ptr->elts[j].uncertainties[i]; + } + if (d4 > 0) { + scaled_error += fabs(d2) / d4; +/* debug + output_msg(OUTPUT_MESSAGE, "%e\t%e\t%e\n", fabs(d2) / d4, fabs(d2), d4); + */ + } else if (d2 != 0.0) { + error_msg("Computing delta element/uncertainty", CONTINUE); + } + } + if (inv_ptr->count_isotopes > 0) { + /* adjustments to solution isotope composition */ + for (j = 0; j < inv_ptr->count_isotope_unknowns; j++) { + for (k = 0; k < solution_ptr->count_isotopes; k++) { + if (inv_ptr->isotope_unknowns[j].elt_name != + solution_ptr->isotopes[k].elt_name || + inv_ptr->isotope_unknowns[j].isotope_number != + solution_ptr->isotopes[k].isotope_number) continue; + d1 = solution_ptr->isotopes[k].ratio; + d2 = delta1[col_isotopes + i * inv_ptr->count_isotope_unknowns + j] / delta1[i]; + d3 = d1 + d2; + + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + sprintf(token, "%d%s", + (int) inv_ptr->isotope_unknowns[j].isotope_number, + inv_ptr->isotope_unknowns[j].elt_name); + output_msg(OUTPUT_MESSAGE,"%15.15s %12g +%12g =%12g\n", token, + (double) d1, (double) d2, (double) d3); +/* + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == FALSE ) { + d3 = fabs(d2/d1); + if (d3 > max_pct) max_pct = d3; + } + */ + if (solution_ptr->isotopes[k].x_ratio_uncertainty > 0) { + scaled_error += fabs(d2) / solution_ptr->isotopes[k].x_ratio_uncertainty; +/* debug + output_msg(OUTPUT_MESSAGE, "%e\t%e\t%e\n", fabs(d2) / solution_ptr->isotopes[k].x_ratio_uncertainty , fabs(d2), solution_ptr->isotopes[k].x_ratio_uncertainty); + */ + } else if (d2 != 0.0) { + error_msg("Computing delta solution isotope/uncertainty", CONTINUE); + } + } + } + } + } + +/* + * Adjustments to phases + */ + print_msg = FALSE; + if (inv_ptr->count_isotopes > 0) { + output_msg(OUTPUT_MESSAGE,"\nIsotopic composition of phases:\n"); + for (i = 0; i < inv_ptr->count_phases; i++) { + if (inv_ptr->phases[i].count_isotopes == 0) continue; + j = col_phases + i; + if (equal(delta1[j], 0.0, toler) == TRUE && + equal(min_delta[j], 0.0, toler) == TRUE && + equal(max_delta[j], 0.0, toler) == TRUE ) continue; + isotope_ptr = inv_ptr->phases[i].isotopes; + for (j = 0; j < inv_ptr->count_isotopes; j++) { + for (k = 0; k < inv_ptr->phases[i].count_isotopes; k++) { + if (inv_ptr->isotopes[j].elt_name != + isotope_ptr[k].elt_name || + inv_ptr->isotopes[j].isotope_number != + isotope_ptr[k].isotope_number) continue; + d1 = isotope_ptr[k].ratio; + column = col_phase_isotopes + i * inv_ptr->count_isotopes + j; + if (delta1[col_phases + i] != 0.0) { + d2 = delta1[column] / delta1[col_phases + i]; + } else { + continue; + } + d3 = d1 + d2; + if (equal(d1, 0.0, 1e-7) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, 1e-7) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, 1e-7) == TRUE) d3 = 0.0; + sprintf(token, "%d%s %s", + (int) inv_ptr->isotopes[j].isotope_number, + inv_ptr->isotopes[j].elt_name, + inv_ptr->phases[i].phase->name); + output_msg(OUTPUT_MESSAGE,"%15.15s %12g +%12g =%12g", token, + (double) d1, (double) d2, (double) d3); + if (fabs(d2) > (isotope_ptr[k].ratio_uncertainty + toler)) { + output_msg(OUTPUT_MESSAGE," **"); + print_msg = TRUE; + } + output_msg(OUTPUT_MESSAGE,"\n"); + if (isotope_ptr[k].ratio_uncertainty > 0) { + scaled_error += fabs(d2) / isotope_ptr[k].ratio_uncertainty; +/* debug + output_msg(OUTPUT_MESSAGE, "%e\t%e\t%e\n", fabs(d2) / isotope_ptr[k].ratio_uncertainty, fabs(d2), isotope_ptr[k].ratio_uncertainty); + */ + } else if (d2 != 0.0) { + error_msg("Computing delta phase isotope/uncertainty", CONTINUE); + } + } + } + } + } + if (print_msg == TRUE) { + output_msg(OUTPUT_MESSAGE,"\n**\tWARNING: The adjustment to at least one isotopic" + "\n\tcomposition of a phase exceeded the specified uncertainty" + "\n\tfor the phase. If the phase is not constrained to dissolve" + "\n\tor precipitate, then the isotopic composition of the phase" + "\n\tis also unconstrained.\n"); + } + output_msg(OUTPUT_MESSAGE,"\n%-20.20s %7s %12.12s %12.12s\n", "Solution fractions:", " ", "Minimum","Maximum"); + for (i = 0; i < inv_ptr->count_solns; i++) { + d1 = delta1[i]; + d2 = min_delta[i]; + d3 = max_delta[i]; + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + output_msg(OUTPUT_MESSAGE, "%11s%4d %12.3e %12.3e %12.3e\n", "Solution", + inv_ptr->solns[i], (double) d1, (double) d2, (double) d3); + } + + output_msg(OUTPUT_MESSAGE,"\n%-25.25s %2s %12.12s %12.12s\n", + "Phase mole transfers:", " ", "Minimum","Maximum"); + for (i = col_phases; i < col_redox; i++) { + if (equal(delta1[i], 0.0, toler) == TRUE && + equal(min_delta[i], 0.0, toler) == TRUE && + equal(max_delta[i], 0.0, toler) == TRUE ) continue; + d1 = delta1[i]; + d2 = min_delta[i]; + d3 = max_delta[i]; + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + output_msg(OUTPUT_MESSAGE, "%15.15s %12.3e %12.3e %12.3e %s\n", col_name[i], (double) d1, + (double) d2, (double) d3, inv_ptr->phases[i - col_phases].phase->formula); + } + + output_msg(OUTPUT_MESSAGE,"\n%-25.25s\n", "Redox mole transfers:"); + for (i = col_redox; i < col_epsilon; i++) { + if (equal(delta1[i], 0.0, toler) == TRUE) continue; + output_msg(OUTPUT_MESSAGE, "%15.15s %12.3e\n", col_name[i], (double) delta1[i]); + } + + output_msg(OUTPUT_MESSAGE,"\nSum of residuals (epsilons in documentation): %12.3e\n", ((double) error/SCALE_EPSILON)); + output_msg(OUTPUT_MESSAGE, "Sum of delta/uncertainty limit: %12.3e\n", (double) scaled_error); + output_msg(OUTPUT_MESSAGE, "Maximum fractional error in element concentration: %12.3e\n", (double) max_pct); +/* + * Flush buffer after each model + */ + output_fflush(OUTPUT_MESSAGE); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_model_heading(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints model headings to selected output file + */ + int i; + char token[MAX_LENGTH]; + if (punch.in == FALSE || pr.punch == FALSE || punch.inverse == FALSE) return(OK); +/* + * Print sum of residuals and maximum fractional error + */ + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH,"%12s\t%12s\t%12s\t","Sum_resid", "Sum_Delta/U","MaxFracErr"); + } else { + output_msg(OUTPUT_PUNCH,"%20s\t%20s\t%20s\t","Sum_resid", "Sum_Delta/U","MaxFracErr"); + } +/* + * Print solution numbers + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + sprintf(token, "Soln %d", inv_ptr->solns[i]); + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH,"%12s\t%12s\t%12s\t", token, "min", "max"); + } else { + output_msg(OUTPUT_PUNCH,"%20s\t%20s\t%20s\t", token, "min","max"); + } + } +/* + * Print phase names + */ + for (i = col_phases; i < col_redox; i++) { + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH, "%12s\t%12s\t%12s\t", col_name[i], " min", " max"); + } else { + output_msg(OUTPUT_PUNCH, "%20s\t%20s\t%20s\t", col_name[i], " min", " max"); + } + } + output_msg(OUTPUT_PUNCH, "\n"); +/* + * Flush buffer after each model + */ + output_fflush(OUTPUT_PUNCH); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_model(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints model to selected output file + */ + int i; + LDBLE d1, d2, d3; + if (punch.in == FALSE || pr.punch == FALSE || punch.inverse == FALSE) return(OK); +/* + * write residual info + */ + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH,"%12.4e\t", ((double) error/SCALE_EPSILON)); + output_msg(OUTPUT_PUNCH,"%12.4e\t", (double) scaled_error); + output_msg(OUTPUT_PUNCH,"%12.4e\t", (double) max_pct); + } else { + output_msg(OUTPUT_PUNCH,"%20.12e\t", ((double) error/SCALE_EPSILON)); + output_msg(OUTPUT_PUNCH,"%20.12e\t", (double) scaled_error); + output_msg(OUTPUT_PUNCH,"%20.12e\t", (double) max_pct); + } +/* + * write solution fractions + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + d1 = delta1[i]; + d2 = min_delta[i]; + d3 = max_delta[i]; + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH, "%12.4e\t%12.4e\t%12.4e\t", (double) d1, (double) d2, (double) d3); + } else { + output_msg(OUTPUT_PUNCH, "%20.12e\t%20.12e\t%20.12e\t", (double) d1, (double) d2, (double) d3); + } + } +/* + * write phase transfers + */ + for (i = col_phases; i < col_redox; i++) { + d1 = delta1[i]; + d2 = min_delta[i]; + d3 = max_delta[i]; + if (equal(d1, 0.0, MIN_TOTAL_INVERSE) == TRUE) d1 = 0.0; + if (equal(d2, 0.0, MIN_TOTAL_INVERSE) == TRUE) d2 = 0.0; + if (equal(d3, 0.0, MIN_TOTAL_INVERSE) == TRUE) d3 = 0.0; + if (punch.high_precision == FALSE) { + output_msg(OUTPUT_PUNCH, "%12.4e\t%12.4e\t%12.4e\t", (double) d1, (double) d2, (double) d3); + } else { + output_msg(OUTPUT_PUNCH, "%20.12e\t%20.12e\t%20.12e\t", (double) d1, (double) d2, (double) d3); + } + } + output_msg(OUTPUT_PUNCH, "\n"); +/* + * Flush buffer after each model + */ + output_fflush(OUTPUT_PUNCH); + return(OK); +} +/* ---------------------------------------------------------------------- */ +unsigned long set_bit(unsigned long bits, int position, int value) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sets a single bit + */ + unsigned long temp_bits_l; + + temp_bits_l = 1 << position; + if (value == 0) { + temp_bits_l = ~temp_bits_l; + temp_bits_l = bits & temp_bits_l; + } else { + temp_bits_l = bits | temp_bits_l; + } + return(temp_bits_l); +} +/* ---------------------------------------------------------------------- */ +int next_set_phases(struct inverse *inv_ptr, + int first_of_model_size, + int model_size) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + unsigned long temp_bits_l; + static int min_position[32], max_position[32], now[32]; + +/* + * min_ and max_position are arrays, logically with length + * of model_size, that contain minimum and maximum + * phase numbers that can be in that model position. + * + * now contains a list of phase numbers to mark as in for this + * model + */ + +/* + * Initialize for a given model_size + */ + if (first_of_model_size == TRUE) { + for (i = 0; i < model_size; i++) { + min_position[i] = i; + now[i] = i; + max_position[i] = inv_ptr->count_phases - model_size + i; + } + } else { +/* + * Determine next combination of phases for fixed model_size + */ + for (i = (model_size - 1); i >= 0; i--) { + if (now[i] < max_position[i]) { + now[i]++; + if (i < (model_size - 1) ) { + k = now[i]; + for (j = (i + 1); j < model_size; j++) { + k++; + now[j] = k; + } + } + break; + } + } + if (i < 0) return(FALSE); + } +/* + * Set bits which switch in phases + */ + temp_bits_l = 0; + for (j = 0; j < model_size; j++) { + temp_bits_l += (1 << now[j]); + } + phase_bits = temp_bits_l; + return(TRUE); +} + +/* ---------------------------------------------------------------------- */ +int range(struct inverse *inv_ptr, unsigned long cur_bits) +/* ---------------------------------------------------------------------- */ +{ +/* + * Takes the model from cur_bits and sequentially determines the + * minimum and maximum values for each solution fraction and + * each phase mass transfer. + */ + int i, j; + int k, l, m, n; + int f; + unsigned long bits; + LDBLE error2; +/* + * Include forced solutions and phases in range calculation + */ + for (i = 0; i < inv_ptr->count_solns + inv_ptr->count_phases; i++) { + if (i < inv_ptr->count_phases) { + if (inv_ptr->phases[i].force == TRUE) { + cur_bits = set_bit(cur_bits, i , 1); + } + } else { + if (inv_ptr->force_solns[i - inv_ptr->count_phases] == TRUE) { + cur_bits = set_bit(cur_bits, i, 1); + } + } + } + + memcpy((void *) &(min_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(max_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); +/* + * Switch bits so that phases are high and solutions are low + */ + bits = get_bits(cur_bits, inv_ptr->count_phases + inv_ptr->count_solns - 1, inv_ptr->count_solns); + bits += (get_bits(cur_bits, inv_ptr->count_phases - 1, inv_ptr->count_phases) << inv_ptr->count_solns); +/* + * Do range calculation + */ + for (i = 0; i < inv_ptr->count_solns + inv_ptr->count_phases; i++) { + if (inv_ptr->count_solns == i + 1) { + min_delta[i] = 1.0; + max_delta[i] = 1.0; + continue; + } + if (get_bits(bits, i, 1) == 0) continue; +/* + * Calculate min and max + */ + for (f = -1; f < 2; f += 2) { + k = row_mb; /* rows in A */ + l = row_epsilon - row_mb; /* rows in C */ + m = count_rows - row_epsilon; /* rows in E */ + n = count_unknowns; /* number of variables */ +/* + * Copy equations + */ + memcpy((void *) &(array1[0]), (void *) &(array[0]), + (size_t) max_column_count * max_row_count * sizeof(LDBLE)); + memcpy((void *) &(delta2[0]), (void *) &(delta[0]), + (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(delta3[0]), (void *) &(zero[0]), + (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(delta_save[0]), (void *) &(zero[0]), + (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(res[0]), (void *) &(zero[0]), + (size_t) max_row_count * sizeof(LDBLE)); + +/* + * Change optimization + */ + for (j = 0; j < k; j++) { + memcpy((void *) &(array1[j * max_column_count]), (void *) &(zero[0]), + (size_t) max_column_count * sizeof(LDBLE)); + } + array1[i] = 1.0; + if (f < 1) { + array1[n] = -fabs(inv_ptr->range_max); + } else { + array1[n] = fabs(inv_ptr->range_max); + } + shrink(inv_ptr, array1, array1, + &k, &l, &m, &n, + cur_bits, + delta2, col_back, row_back); + /* + * Save delta constraints + */ + for (j=0; j < n; j++) { + delta_save[col_back[j]] = delta2[j]; + } + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nInput delta:\n\n"); + for (j = 0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d %s\t%g\n", j, col_name[col_back[j]], (double) delta2[j]); + } + output_msg(OUTPUT_MESSAGE, "\nA and B arrays:\n\n"); + array_print(array1, k + l + m, + n + 1, max_column_count); + } + kode = 1; + iter = 200; + count_calls++; +#ifdef INVERSE_CL1MP + if(inv_ptr->mp == TRUE) { + cl1mp(k, l, m, n, + nklmd, n2d, array1, + &kode, inv_ptr->mp_tolerance, &iter, + delta2, res, &error2, cu, iu, is, TRUE, inv_ptr->mp_censor); + } else { + cl1(k, l, m, n, + nklmd, n2d, array1, + &kode, toler, &iter, + delta2, res, &error2, cu, iu, is, TRUE); + } +#else + cl1(k, l, m, n, + nklmd, n2d, array1, + &kode, toler, &iter, + delta2, res, &error2, cu, iu, is, TRUE); +#endif + if (kode != 0) { + output_msg(OUTPUT_MESSAGE, "Error in subroutine range. Kode = %d\n", kode); + } + + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "kode: %d\titer: %d\terror: %e\n", kode, iter, (double) error2); + output_msg(OUTPUT_MESSAGE, "k, l, m, n: %d\t%d\t%d\t%d\n", k, l, m, n); + output_msg(OUTPUT_MESSAGE, "\nsolution vector %s\n", col_name[i]); + for (j = 0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", j, col_name[col_back[j]], (double) delta2[j]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + + output_msg(OUTPUT_MESSAGE, "\nresidual vector:\n"); + for (j = 0; j < (k + l + m); j++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e\n", j, row_name[row_back[j]], (double) res[j]); + } + } + for(j = 0; j < n; j++) { + if (col_back[j] == i) break; + } + if (f < 0) { + min_delta[i] = delta2[j]; + } else { + max_delta[i] = delta2[j]; + } + for(j = 0; j < n; j++) { + delta3[col_back[j]] = delta2[j]; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int shrink(struct inverse *inv_ptr, LDBLE *array_in, LDBLE *array_out, + int *k, int *l, int *m, int *n, + unsigned long cur_bits, + LDBLE *delta_l, int *col_back_l, int *row_back_l) +/* ---------------------------------------------------------------------- */ +{ +/* + * Shrink eliminates any rows that are all zeros and any columns + * that are not in cur_bits, result is put in array_out + * + * k, l, m, n return the new sizes of the array. + * delta is remapped to retain any non-negativity constraints + * Col_back maps columns that remain back to original columns + * Row_back maps rows that remain back to original rows + */ + int i, j, row; + int k1, l1, m1; + int cur_col, column; + int nonzero; +/* + * Copy array_in to array_out + */ + if (array_in != array_out) { + for (i = 0; i < (*k + *l + *m); i++) { + memcpy(&(array_out[i * max_column_count]), &(array_in[i * max_column_count]), + (size_t) max_column_count * sizeof(LDBLE)); + } + } +/* + * Determine columns to eliminate + */ + for (i = 0; i < (*n + 1); i++) col_back_l[i] = i; + +/* + * Drop phases not in model + */ + for (i = 0; i < inv_ptr->count_phases; i++) { + if (get_bits(cur_bits, i, 1) == 0) { + col_back_l[col_phases + i] = -1; + /* drop isotopes */ + if (inv_ptr->count_isotopes > 0 ) { + for (j =0; j < inv_ptr->count_isotopes; j++) { + column = col_phase_isotopes + i * inv_ptr->count_isotopes + j; + col_back_l[column] = -1; + } + } + } + } +/* + * Drop solutions not in model + */ + for (i = 0; i < (inv_ptr->count_solns - 1) ; i++) { + if (get_bits(cur_bits, inv_ptr->count_phases + i, 1) == 0) { + col_back_l[i] = -1; + /* drop all epsilons for the solution */ + for(j = 0; j < inv_ptr->count_elts; j++) { + column = col_epsilon + j * inv_ptr->count_solns + i; + col_back_l[column] = -1; + } + /* drop pH for the solution */ + if (inv_ptr->carbon == TRUE) { + column = col_ph + i; + col_back_l[column] = -1; + } + /* drop isotopes */ + if (inv_ptr->count_isotopes > 0) { + for (j = 0; j < inv_ptr->count_isotope_unknowns; j++) { + column = col_isotopes + i * inv_ptr->count_isotope_unknowns + j; + col_back_l[column] = -1; + } + } + } + } + +/* + * Drop epsilons not used + */ + for (i = col_epsilon; i < *n; i++) { + if (col_back_l[i] < 0) continue; + for (j = 0; j < (*k + *l + *m); j++) { + if (array_out[j * max_column_count + i] != 0) break; + } + if (j == (*k + *l + *m)) { + col_back_l[i] = -1; + } + } +/* + * rewrite array_out + */ + cur_col = 0; + for (i = 0; i < (*n + 1); i++) { + if (col_back_l[i] < 0) continue; + if (cur_col == col_back_l[i]) { + cur_col++; + continue; + } + for (j=0; j < (*k + *l + *m); j++) { + array_out[j * max_column_count + cur_col] = array_out[j * max_column_count + i]; + } + col_back_l[cur_col] = col_back_l[i]; + delta_l[cur_col] = delta_l[i]; + cur_col++; + } + *n = cur_col - 1; +/* + * Eliminate unnecessary optimization eqns + */ + row = 0; + k1 = 0; + for(i=0; i < *k; i++) { + if (memcmp(&(array_out[i*max_column_count]), &(zero[0]), + (size_t) (*n) * sizeof(LDBLE)) == 0) { + continue; + } +/* + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) max_column_count * sizeof(LDBLE)); + */ + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) (*n + 1) * sizeof(LDBLE)); + row_back_l[row] = i; + row++; + k1++; + } + +/* + * Eliminate unnecessary equality eqns + */ + l1 = 0; + for (i = *k; i < (*k + *l); i++) { + nonzero = FALSE; + for (j = 0; j < *n; j++) { + if (equal(array_out[i * max_column_count + j], 0.0, toler) == FALSE) { + nonzero = TRUE; + break; + } + } + if (nonzero == FALSE) continue; +/* + if (memcmp(&(array_out[i * max_column_count]), &(zero[0]), + (size_t) (*n) * sizeof(LDBLE)) == 0) { + continue; + } + */ +/* + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) max_column_count * sizeof(LDBLE)); + */ + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) (*n + 1) * sizeof(LDBLE)); + row_back_l[row] = i; + row++; + l1++; + } +/* + * Eliminate unnecessary inequality eqns + */ + m1 = 0; + for (i = (*k + *l); i < (*k + *l + *m); i++) { + nonzero = FALSE; + for (j = 0; j < *n; j++) { + if (equal(array_out[i * max_column_count + j], 0.0, toler) == FALSE) { + nonzero = TRUE; + break; + } + } + if (nonzero == FALSE) continue; +/* + if (memcmp(&(array_out[i * max_column_count]), &(zero[0]), + (size_t) (*n) * sizeof(LDBLE)) == 0) { + continue; + } + */ +/* + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) max_column_count * sizeof(LDBLE)); + */ + memcpy(&(array_out[row * max_column_count]), &(array_out[i * max_column_count]), + (size_t) (*n + 1) * sizeof(LDBLE)); + row_back_l[row] = i; + row++; + m1++; + } + + *k = k1; + *l = l1; + *m = m1; +/* + * Scale all inequality rows + */ + + for (i = *k + *l; i < *k + *l + *m; i++) { + for (j = 0; j < *n + 1; j++) { + array_out[i*max_column_count + j] *= SCALE_ALL; + } + } + + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int check_solns(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check_solns checks that each solution can be charge balanced within + * the given constraints. If not, it is an error and the program will + * terminate. + */ + int i, j; + int k, l, m, n; + int return_value; + unsigned long bits; + LDBLE error2; + + memcpy((void *) &(min_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(max_delta[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + +/* + * Switch bits so that phases are high and solutions are low + */ + return_value = OK; + for (i = 0; i < inv_ptr->count_solns; i++) { + bits = 0; + bits += 1 << (inv_ptr->count_phases + i); +/* + * Check for feasibility of charge balance with given uncertainties + */ + k = row_mb; /* rows in A */ + l = row_epsilon - row_mb; /* rows in C */ + m = count_rows - row_epsilon; /* rows in E */ + n = count_unknowns; /* number of variables */ +/* debug + output_msg(OUTPUT_MESSAGE, "\nColumns\n"); + for (j = 0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", j, col_name[j]); + } + + output_msg(OUTPUT_MESSAGE, "\nRows\n"); + for (j = 0; j < k + l + m; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", j, row_name[j]); + } + + output_msg(OUTPUT_MESSAGE, "\nA and B arrays:\n\n"); + array_print(array, k + l + m, + n + 1, max_column_count); + */ +/* + * Copy equations + */ + memcpy((void *) &(array1[0]), (void *) &(array[0]), + (size_t) max_column_count * max_row_count * sizeof(LDBLE)); + memcpy((void *) &(delta2[0]), (void *) &(delta[0]), + (size_t) max_column_count * sizeof(LDBLE)); + memcpy((void *) &(res[0]), (void *) &(zero[0]), + (size_t) max_row_count * sizeof(LDBLE)); + +/* + * Keep optimization + */ +/* + * Zero out mass balance rows and fraction rows + */ + for (j = row_mb; j < row_charge; j++) { + memcpy((void *) &(array1[j * max_column_count]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + } +/* + * Set fraction of solution to 1.0 + */ + array1[(row_charge - 1) * max_column_count + i] = 1.0; + array1[(row_charge - 1) * max_column_count + n] = 1.0; + +/* + * Zero out charge balance rows for other solutions + */ + for (j = 0; j < inv_ptr->count_solns; j++) { + if ( j == i ) continue; + memcpy((void *) &(array1[(row_charge + j) * max_column_count]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + } + +/* + * Zero out isotope mole balance + */ + for (j = row_isotopes; j < row_epsilon; j++) { + memcpy((void *) &(array1[ j * max_column_count]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + } + +/* + * Zero out isotope uncertainties + */ + for (j = row_isotope_epsilon; j < count_rows; j++) { + memcpy((void *) &(array1[ j * max_column_count]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); + } +/* + * Can't Zero out epsilon constraint rows for other solutions because not sure which + * are which + */ + + shrink(inv_ptr, array1, array1, + &k, &l, &m, &n, + bits, + delta2, col_back, row_back); +/* Debug + + output_msg(OUTPUT_MESSAGE, "\nColumns\n"); + for (j = 0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", j, col_name[col_back[j]]); + } + + output_msg(OUTPUT_MESSAGE, "\nRows\n"); + for (j = 0; j < k + l + m; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", j, row_name[row_back[j]]); + } + + output_msg(OUTPUT_MESSAGE, "\nA and B arrays:\n\n"); + array_print(array1, k + l + m, + n + 1, max_column_count); + + output_msg(OUTPUT_MESSAGE, "\nInput delta vector:\n"); + for (j=0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", j, col_name[col_back[j]], delta2[j]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + */ + + kode = 1; + iter = 200; + count_calls++; + cl1(k, l, m, n, + nklmd, n2d, array1, + &kode, toler, &iter, + delta2, res, &error2, cu, iu, is, TRUE); + + if (kode != 0) { + sprintf(error_string, "Not possible to balance solution %d with input uncertainties.", inv_ptr->solns[i]); + error_msg(error_string, CONTINUE); + return_value = ERROR; + } + +/* Debug + output_msg(OUTPUT_MESSAGE, "kode: %d\titer: %d\terror: %e\n", kode, iter, error); + output_msg(OUTPUT_MESSAGE, "k, l, m, n: %d\t%d\t%d\t%d\n", k, l, m, n); + + output_msg(OUTPUT_MESSAGE, "\nsolution vector %s\n", col_name[i]); + for (j = 0; j < n; j++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e", j, col_name[col_back[j]], delta2[j]); + output_msg(OUTPUT_MESSAGE, "\n"); + } + + output_msg(OUTPUT_MESSAGE, "\nresidual vector:\n"); + for (j = 0; j < (k + l + m); j++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e\n", j, row_name[row_back[j]], res[j]); + } + */ + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int post_mortem(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Post_mortem simply identifies which equality and inequality of the + * array have not been satisfied. + * + */ + int i, j; + LDBLE sum; +/* + * Check equalities + */ + output_msg(OUTPUT_MESSAGE, "\nPost_mortem examination of inverse modeling:\n\n"); + for (i = row_mb; i < row_epsilon; i++) { + sum = 0; + for (j = 0; j < count_unknowns; j++) { + sum += delta1[j] * array[i * max_column_count + j]; + } + + if ( equal(sum, array[(i * max_column_count) + count_unknowns], toler) == FALSE) { + output_msg(OUTPUT_MESSAGE, "\tERROR: equality not satisfied for %s, %e.\n", row_name[i], sum - array[(i * max_column_count) + count_unknowns]); + } + } +/* + * Check inequalities + */ + for (i = row_epsilon; i < count_rows; i++) { + sum = 0; + for (j = 0; j < count_unknowns; j++) { + sum += delta1[j] * array[i * max_column_count + j]; + } + + if ( sum > array[(i * max_column_count) + count_unknowns] + toler) { + output_msg(OUTPUT_MESSAGE, "\tERROR: inequality not satisfied for %s, %e\n", row_name[i], sum - array[(i * max_column_count) + count_unknowns]); + } + } +/* + * Check dissolution/precipitation constraints + */ + for (i = 0; i < count_unknowns; i++) { + if (delta_save[i] > 0.5 && delta1[i] < -toler) { + output_msg(OUTPUT_MESSAGE, "\tERROR: Dissolution/precipitation constraint not satisfied for column %d, %s, %e.\n", i, col_name[i], delta1[i]); + } else if (delta_save[i] < -0.5 && delta1[i] > toler) { + output_msg(OUTPUT_MESSAGE, "\tERROR: Dissolution/precipitation constraint not satisfied for column %d, %s, %e.\n", i, col_name[i], delta1[i]); + } + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int carbon_derivs(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, n, temp; + LDBLE c_uncertainty, d_carbon, alk_plus, alk_minus; + struct solution *solution_ptr_orig, *solution_ptr; + + inv_ptr->dalk_dph = (LDBLE *) free_check_null(inv_ptr->dalk_dph); + inv_ptr->dalk_dph = (LDBLE *) PHRQ_malloc( (size_t) inv_ptr->count_solns * sizeof(LDBLE) ); + if (inv_ptr->dalk_dph == NULL) malloc_error(); + + inv_ptr->dalk_dc = (LDBLE *) free_check_null(inv_ptr->dalk_dc); + inv_ptr->dalk_dc = (LDBLE *) PHRQ_malloc( (size_t) inv_ptr->count_solns * sizeof(LDBLE) ); + if (inv_ptr->dalk_dc == NULL) malloc_error(); + + for (i = 0; i < inv_ptr->count_solns; i++) { + solution_ptr_orig = solution_bsearch(inv_ptr->solns[i], &n, TRUE); + if (solution_ptr_orig == NULL) { + sprintf(error_string, "Solution %d for inverse " + "modeling not found.", inv_ptr->solns[i]); + error_msg(error_string, STOP); + } +/* + * Find carbon uncertainty + */ + c_uncertainty = 0; + d_carbon = 0; + for (j = 0; j < inv_ptr->count_elts; j++) { + if (inv_ptr->elts[j].master == s_co3->secondary) { + c_uncertainty = inv_ptr->elts[j].uncertainties[i]; + break; + } + } + if (c_uncertainty < 0.0) { + d_carbon = -c_uncertainty; + } else if (c_uncertainty > 0.0) { + for (k = 0; solution_ptr_orig->totals[k].description != NULL; k++) { + if (strcmp(solution_ptr_orig->totals[k].description, "C(4)") == 0) { + d_carbon = solution_ptr_orig->totals[k].moles / + solution_ptr_orig->mass_water * c_uncertainty; + break; + } + + } + } + +/* + * Make four copies of solution + * Modify ph and carbon in solutions + */ + set_ph_c(inv_ptr, i, solution_ptr_orig, -5, 0.0, 1.0, 0.0); + set_ph_c(inv_ptr, i, solution_ptr_orig, -4, 0.0, -1.0, 0.0); + if (c_uncertainty != 0) { + set_ph_c(inv_ptr, i, solution_ptr_orig, -3, d_carbon, 0.0, 1.0); + set_ph_c(inv_ptr, i, solution_ptr_orig, -2, d_carbon, 0.0, -1.0); + } +/* */ + temp = pr.all; + pr.all = FALSE; + initial_solutions(FALSE); + pr.all = temp; +/* + * dAlk/dpH + */ + solution_ptr = solution_bsearch(-5, &n, TRUE); + alk_plus = solution_ptr->total_alkalinity; + solution_ptr = solution_bsearch(-4, &n, TRUE); + alk_minus = solution_ptr->total_alkalinity; + inv_ptr->dalk_dph[i] = (alk_plus - alk_minus) / + (2.0 * inv_ptr->ph_uncertainties[i]); +/* + * dAlk/dC + */ + if (d_carbon != 0) { + solution_ptr = solution_bsearch(-3, &n, TRUE); + alk_plus = solution_ptr->total_alkalinity; + solution_ptr = solution_bsearch(-2, &n, TRUE); + alk_minus = solution_ptr->total_alkalinity; + inv_ptr->dalk_dc[i] = (alk_plus - alk_minus) / (2.0 * d_carbon); + } else { + inv_ptr->dalk_dc[i] = 0.0; + } + if (debug_inverse == TRUE) { + output_msg(OUTPUT_MESSAGE, "dAlk/dph = %e\tdAlk/dC = %e\n", + (double) inv_ptr->dalk_dph[i], (double) inv_ptr->dalk_dc[i]); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_ph_c(struct inverse *inv_ptr, + int i, + struct solution *solution_ptr_orig, + int n_user_new, + LDBLE d_carbon, + LDBLE ph_factor, + LDBLE c_factor) +/* ---------------------------------------------------------------------- */ +{ + int j, n_user_orig; + struct solution *solution_ptr; + struct conc *conc_ptr; + + n_user_orig = inv_ptr->solns[i]; + solution_duplicate(n_user_orig, n_user_new); + solution_ptr = solution_bsearch(n_user_new, &j, TRUE); + solution_ptr->new_def = TRUE; + solution_ptr->n_user_end = n_user_new; + solution_ptr->ph += inv_ptr->ph_uncertainties[i] * ph_factor; + for (j = 0; solution_ptr->totals[j].description != NULL; j++) { + conc_ptr = &solution_ptr->totals[j]; + conc_ptr->input_conc = conc_ptr->moles / + solution_ptr_orig->mass_water; + conc_ptr->units = string_hsave("Mol/kgw"); + if (strcmp(conc_ptr->description, "C(4)") == 0) { + conc_ptr->input_conc += d_carbon * c_factor; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int isotope_balance_equation(struct inverse *inv_ptr, int row, int n) +/* ---------------------------------------------------------------------- */ +/* + * routine fills in an isotope balance equation + * + * row is the row in array that needs to be filled + * n is the isotope number in inv_ptr + */ +{ + int i, j, k; + LDBLE isotope_number; + int column; + LDBLE f; + struct master *primary_ptr; + struct solution *solution_ptr; + struct isotope *isotope_ptr; +/* + * Determine primary master species and isotope number for + * isotope mass-balance equation + */ + column = 0; + primary_ptr = master_bsearch_primary(inv_ptr->isotopes[n].elt_name); + isotope_number = inv_ptr->isotopes[n].isotope_number; + /* isotope element must be defined */ + if (primary_ptr == NULL) { + sprintf(error_string, "In isotope calculation: element not defined: %s.", + inv_ptr->isotopes[n].elt_name); + error_msg(error_string, CONTINUE); + input_error++; + } + + /* isotope element must be primary */ + if (primary_ptr->primary != TRUE) { + sprintf(error_string, "Isotope mass-balance may only be used" + " for total element concentrations.\n" + "Secondary species not allowed: %s.", + inv_ptr->isotopes[n].elt_name); + error_msg(error_string, CONTINUE); + input_error++; + } + +/* + * Fill in terms for each solution + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + if (i == (inv_ptr->count_solns - 1)) { + f = -1.0; + } else { + f = 1.0; + } + + /* mixing fraction term */ + solution_ptr = solution_bsearch(inv_ptr->solns[i], &j, TRUE); + isotope_ptr = solution_ptr->isotopes; + for (j = 0; j < solution_ptr->count_isotopes; j++) { + if (isotope_ptr[j].primary == primary_ptr && + isotope_ptr[j].isotope_number == isotope_number) { + array[row * max_column_count + i] += f * isotope_ptr[j].total * isotope_ptr[j].ratio; + } + } + + /* epsilon of total moles of element valence * ratio */ + for (j = 0; j < solution_ptr->count_isotopes; j++) { + + /* What to do with H and O, skip for now ??? */ + if (primary_ptr == s_hplus->primary || + primary_ptr == s_h2o->primary) continue; + + if (isotope_ptr[j].primary == primary_ptr && + isotope_ptr[j].isotope_number == isotope_number) { + + /* find column of master for solution i*/ + for (k = 0; k < inv_ptr->count_elts; k++) { + if (isotope_ptr[j].master == inv_ptr->elts[k].master) break; + } + column = col_epsilon + (k * inv_ptr->count_solns) + i; + array[row * max_column_count + column] += f * isotope_ptr[j].ratio; + } + } + + /* epsilon of ratio * total of element valence */ + for (j = 0; j < solution_ptr->count_isotopes; j++) { + + if (isotope_ptr[j].primary == primary_ptr && + isotope_ptr[j].isotope_number == isotope_number) { + + /* find column of epsilon for ratio of valence */ + for (k = 0; k < inv_ptr->count_isotope_unknowns; k++) { + if (isotope_ptr[j].master == inv_ptr->isotope_unknowns[k].master && + isotope_ptr[j].isotope_number == inv_ptr->isotope_unknowns[k].isotope_number) { + column = col_isotopes + (i * inv_ptr->count_isotope_unknowns) + k; + } + } + array[row * max_column_count + column] += f * isotope_ptr[j].total; + } + } + } +/* + * Fill in terms for each phase + */ + for (i = 0; i < inv_ptr->count_phases; i++) { + if (inv_ptr->phases[i].count_isotopes <= 0) continue; + isotope_ptr = inv_ptr->phases[i].isotopes; + for (j = 0; j < inv_ptr->phases[i].count_isotopes; j++) { + if (isotope_ptr[j].primary == primary_ptr && + isotope_ptr[j].isotope_number == isotope_number) { + /* term for alpha phase unknowns */ + column = col_phases + i; + array[row * max_column_count + column] = isotope_ptr[j].ratio * isotope_ptr[j].coef; + /* term for phase isotope uncertainty unknown */ + column = col_phase_isotopes + i * inv_ptr->count_isotopes + n; + array[row * max_column_count + column] = isotope_ptr[j].coef; + break; + } + } + + } + return OK; +} +/* ---------------------------------------------------------------------- */ +int count_isotope_unknowns(struct inverse *inv_ptr, struct isotope **isotope_unknowns) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through elements for which isotope balances are requested + * and make a array of isotope structures + * return total number of isotope unknowns and structure array + */ + int i, k; + LDBLE isotope_number; + struct master *primary_ptr; + int count_isotopes; + struct isotope *isotopes; + + if (inv_ptr->count_isotopes == 0) { + *isotope_unknowns = NULL; + return(0); + } + isotopes = (struct isotope *) PHRQ_malloc((size_t) sizeof(struct isotope)); + if (isotopes == NULL) malloc_error(); + count_isotopes = 0; + + for (i = 0; i < inv_ptr->count_isotopes; i++) { + primary_ptr = master_bsearch(inv_ptr->isotopes[i].elt_name); + isotope_number = inv_ptr->isotopes[i].isotope_number; + if (primary_ptr == NULL) { + sprintf(error_string, "Element not found for isotope calculation: %s.", + inv_ptr->isotopes[i].elt_name); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (primary_ptr->primary != TRUE) { + sprintf(error_string, "Isotope mass-balance may only be used" + " for total element concentrations.\n" + "Secondary species not allowed: %s.", + inv_ptr->isotopes[i].elt_name); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + + /* nonredox element */ + if (primary_ptr->s->secondary == NULL) { + isotopes = (struct isotope *) PHRQ_realloc(isotopes, (size_t) (count_isotopes + 1) * sizeof(struct isotope)); + if (isotopes == NULL) malloc_error(); + isotopes[count_isotopes].primary = primary_ptr; + isotopes[count_isotopes].master = primary_ptr; + isotopes[count_isotopes].isotope_number = isotope_number; + isotopes[count_isotopes].elt_name = primary_ptr->elt->name; + count_isotopes++; + + /* redox element */ + } else { + + /* find master */ + for (k = 0; k < count_master; k++) { + if (master[k] == primary_ptr) break; + } + + /* sum all secondary for master */ + k++; + for ( ; k < count_master; k++) { + if (master[k]->elt->primary != primary_ptr) break; + isotopes = (struct isotope *) PHRQ_realloc(isotopes, (size_t) (count_isotopes + 1) * sizeof(struct isotope)); + if (isotopes == NULL) malloc_error(); + isotopes[count_isotopes].primary = primary_ptr; + isotopes[count_isotopes].master = master[k]; + isotopes[count_isotopes].isotope_number = isotope_number; + isotopes[count_isotopes].elt_name = master[k]->elt->name; + count_isotopes++; + } + } + } + *isotope_unknowns = isotopes; + return (count_isotopes); +} +/* ---------------------------------------------------------------------- */ +int check_isotopes(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through elements for which isotope balances are requested + * and make sure each solution has isotope ratios defined + */ + int i, ii, j, k, l; + int err, found_isotope; + LDBLE isotope_number; + struct master *master_ptr, *primary_ptr; + struct solution *solution_ptr; + struct phase *phase_ptr; + char token[MAX_LENGTH]; + +/* + * Check solutions for necessary isotope data + */ + for (j = 0; j < inv_ptr->count_solns; j++) { + solution_ptr = solution_bsearch(inv_ptr->solns[j], &i, TRUE); + xsolution_zero(); + add_solution (solution_ptr, 1.0, 1.0); +/* + * Go through inverse isotopes and make sure isotope data for each solution + * inv_ptr->isotopes has elements; inv_ptr->i_u has redox states and uncertainties + */ + for (i = 0; i < inv_ptr->count_isotopes; i++) { + err = FALSE; + primary_ptr = master_bsearch(inv_ptr->isotopes[i].elt_name); + isotope_number = inv_ptr->isotopes[i].isotope_number; + found_isotope = FALSE; + for (k = 0; k < solution_ptr->count_isotopes; k++) { + if (solution_ptr->isotopes[k].primary == primary_ptr && + solution_ptr->isotopes[k].isotope_number == isotope_number) { + found_isotope = TRUE; + break; + } + } + if (found_isotope == TRUE) continue; + + /* did not find isotope, which is ok if element not in solution */ + if (primary_ptr == s_h2o->primary || primary_ptr == s_hplus->primary) { + err = TRUE; + } else if (primary_ptr->total > 0) { + err = TRUE; + } + if (err == TRUE) { + sprintf(error_string, + "In solution %d, isotope ratio(s) are needed for element: %g%s.", + solution_ptr->n_user, (double) isotope_number, primary_ptr->elt->name); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + } +/* + * Go through solution isotopes and set uncertainties + */ + for (k = 0; k < solution_ptr->count_isotopes; k++) { + solution_ptr->isotopes[k].x_ratio_uncertainty = NAN; +/* + * Search for secondary or primary master in inverse uncertainties + */ + ii = -1; + for (i = 0; i < inv_ptr->count_i_u; i++) { + master_ptr = master_bsearch(inv_ptr->i_u[i].elt_name); + if (master_ptr == solution_ptr->isotopes[k].master) { + ii = i; + break; + } + if (master_ptr == solution_ptr->isotopes[k].primary) { + ii = i; + } + } + /* solution isotope data not being used in inverse */ + if (ii == -1) continue; + + i = ii; + /* use inverse-defined uncertainties first */ + if (j < inv_ptr->i_u[i].count_uncertainties && inv_ptr->i_u[i].uncertainties[j] != NAN) { + solution_ptr->isotopes[k].x_ratio_uncertainty = inv_ptr->i_u[i].uncertainties[j]; + + /* use solution-defined uncertainties second */ + } else if (solution_ptr->isotopes[k].ratio_uncertainty != NAN) { + solution_ptr->isotopes[k].x_ratio_uncertainty = solution_ptr->isotopes[k].ratio_uncertainty; + /* use isotope defaults third */ + } else { + sprintf(token,"%g%s", (double) solution_ptr->isotopes[k].isotope_number, solution_ptr->isotopes[k].elt_name); + for (l = 0; l < count_iso_defaults; l++) { + if (strcmp(token, iso_defaults[l].name) == 0) { + solution_ptr->isotopes[k].x_ratio_uncertainty = iso_defaults[l].uncertainty; + sprintf(error_string, "Solution %d, element %g%s: default isotope ratio uncertainty is used, %g.", solution_ptr->n_user, (double) solution_ptr->isotopes[k].isotope_number, solution_ptr->isotopes[k].elt_name, (double) solution_ptr->isotopes[k].x_ratio_uncertainty); + warning_msg(error_string); + break; + } + } + } + if (solution_ptr->isotopes[k].x_ratio_uncertainty == NAN) { + sprintf(error_string, + "In solution %d, isotope ratio uncertainty is needed for element: %g%s.", solution_ptr->n_user, (double) solution_ptr->isotopes[k].isotope_number, solution_ptr->isotopes[k].elt_name); + error_msg(error_string, CONTINUE); + input_error++; + } + } + } +/* + * Check phases for necessary isotope data + */ + for (j = 0; j < inv_ptr->count_phases; j++) { + for (i = 0; i < inv_ptr->count_isotopes; i++) { + primary_ptr = master_bsearch(inv_ptr->isotopes[i].elt_name); + isotope_number = inv_ptr->isotopes[i].isotope_number; + found_isotope = FALSE; + for (k = 0; k < inv_ptr->phases[j].count_isotopes; k++) { + if (inv_ptr->phases[j].isotopes[k].primary == primary_ptr && + inv_ptr->phases[j].isotopes[k].isotope_number == isotope_number) { + found_isotope = TRUE; + break; + } + } + if (found_isotope == TRUE) continue; + + /* did not find isotope, which is ok if element not in solution */ + phase_ptr = inv_ptr->phases[j].phase; + k = 0; + while (phase_ptr->next_elt[k].elt != NULL) { + if (phase_ptr->next_elt[k].elt->primary == primary_ptr) { + if (s_hplus->primary == primary_ptr || + s_h2o->primary == primary_ptr) { + k++; + continue; + } else { + sprintf(error_string, + "In phase %s, isotope ratio(s) are needed for element: %g%s.", + phase_ptr->name, (double) isotope_number, primary_ptr->elt->name); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + } + k++; + } + } + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int phase_isotope_inequalities(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + int column; + char token[MAX_LENGTH]; + if (inv_ptr->count_isotopes <= 0 ) return OK; + for (i = 0; i < inv_ptr->count_phases; i++) { + if (inv_ptr->phases[i].count_isotopes <= 0) continue; + + for (j = 0; j < inv_ptr->phases[i].count_isotopes; j++) { + /* find index number */ + for (k = 0; k < inv_ptr->count_isotopes; k++) { + if (inv_ptr->phases[i].isotopes[j].elt_name == inv_ptr->isotopes[k].elt_name && + inv_ptr->phases[i].isotopes[j].isotope_number == inv_ptr->isotopes[k].isotope_number) { + break; + } + } + if (k >= inv_ptr->count_isotopes) break; + column = col_phase_isotopes + i * inv_ptr->count_isotopes + k; +/* + * zero column if uncertainty is zero + */ + if (inv_ptr->phases[i].isotopes[j].ratio_uncertainty == 0) { + for (k = 0; k < count_rows; k++) { + array[k * max_column_count + column] = 0.0; + } + continue; + } + +/* + * optimization + */ + array[(column - col_epsilon) * max_column_count + column] = SCALE_EPSILON / inv_ptr->phases[i].isotopes[j].ratio_uncertainty; +/* + * two inequalities to account for absolute value + */ + /* for phases constrained to precipitate */ + if (inv_ptr->phases[i].constraint == PRECIPITATE) { + array[count_rows * max_column_count + col_phases + i] = + inv_ptr->phases[i].isotopes[j].ratio_uncertainty; + array[count_rows * max_column_count + column] = 1.0; + sprintf(token, "%s %s", + inv_ptr->phases[i].phase->name, + "iso pos"); + row_name[count_rows] = string_hsave(token); + count_rows++; + + array[count_rows * max_column_count + col_phases + i] = + inv_ptr->phases[i].isotopes[j].ratio_uncertainty; + array[count_rows * max_column_count + column] = -1.0; + sprintf(token, "%s %s", + inv_ptr->phases[i].phase->name, + "iso neg"); + row_name[count_rows] = string_hsave(token); + count_rows++; + + /* for phases constrained to dissolve */ + } else if (inv_ptr->phases[i].constraint == DISSOLVE) { + array[count_rows * max_column_count + col_phases + i] = + -inv_ptr->phases[i].isotopes[j].ratio_uncertainty; + array[count_rows * max_column_count + column] = -1.0; + sprintf(token, "%s %s", + inv_ptr->phases[i].phase->name, + "iso pos"); + row_name[count_rows] = string_hsave(token); + count_rows++; + + array[count_rows * max_column_count + col_phases + i] = + -inv_ptr->phases[i].isotopes[j].ratio_uncertainty; + array[count_rows * max_column_count + column] = 1.0; + sprintf(token, "%s %s", + inv_ptr->phases[i].phase->name, + "iso neg"); + row_name[count_rows] = string_hsave(token); + count_rows++; + + /* Error if phase is not constrained*/ + } else { + sprintf(error_string, + "In isotope calculations, all phases containing isotopes must be" + " constrained.\nPhase %s is not constrained.\n", + inv_ptr->phases[i].phase->name); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + } + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int write_optimize_names(struct inverse *inv_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, j, row; + char token[MAX_LENGTH]; + row = 0; +/* + * epsilons for analytical data + */ + for (j = 0; j < inv_ptr->count_elts; j++) { + for (i = 0; i < inv_ptr->count_solns; i++) { + sprintf(token,"%s %s %d","optimize", + inv_ptr->elts[j].master->elt->name, + inv_ptr->solns[i]); + row_name[row] = string_hsave(token); + row++; + } + } +/* + * pH + */ + if (carbon > 0) { + for (i = 0; i < inv_ptr->count_solns; i++) { + sprintf(token,"%s %s %d","optimize", + "pH", + inv_ptr->solns[i]); + row_name[row] = string_hsave(token); + row++; + } + } +/* + * water + */ + sprintf(token,"%s %s","optimize", "water"); + row_name[row] = string_hsave(token); + row++; +/* + * solution isotopes + */ + for (i = 0; i < inv_ptr->count_solns; i++) { + for (j = 0; j < inv_ptr->count_isotope_unknowns; j++) { + sprintf(token,"%s %d%s %d","optimize", + (int) inv_ptr->isotope_unknowns[j].isotope_number, + inv_ptr->isotope_unknowns[j].elt_name, + inv_ptr->solns[i]); + row_name[row] = string_hsave(token); + row++; + } + } +/* + * phase isotopes + */ + + for (i = 0; i < inv_ptr->count_phases; i++) { + for (j = 0; j < inv_ptr->count_isotopes; j++) { + sprintf(token,"%s %s %d%s","optimize", + inv_ptr->phases[i].phase->name, + (int) inv_ptr->isotopes[j].isotope_number, + inv_ptr->isotopes[j].elt_name); + row_name[row] = string_hsave(token); + row++; + } + } + return OK; +} diff --git a/isotopes.cpp b/isotopes.cpp new file mode 100644 index 00000000..885b19bc --- /dev/null +++ b/isotopes.cpp @@ -0,0 +1,1540 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: isotopes.c 402 2005-07-25 23:26:07Z dlpark $"; + +static int calculate_value_init(struct calculate_value *calculate_value_ptr); +static int isotope_alpha_init(struct isotope_alpha *isotope_alpha_ptr); +static int isotope_ratio_init(struct isotope_ratio *isotope_ratio_ptr); +static int master_isotope_init(struct master_isotope *master_isotope_ptr); + +/* ---------------------------------------------------------------------- */ +int 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 j, l; + struct master_isotope *master_isotope_ptr, *master_isotope_ptr_major; + char token[MAX_LENGTH]; + struct element *elt_ptr; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "isotope", /* 0 */ + "total_is_major" /* 1 */ + }; + int count_opt_list = 2; + if (svnid == NULL) fprintf(stderr," "); + + 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) { + sprintf(error_string, "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; + j = 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) { + sprintf(error_string, "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) { + sprintf(error_string, "Expecting isotope ratio of standard, %s. ISOTOPES data block.", line); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + sscanf(token,SCANFORMAT, &(master_isotope_ptr->standard)); + opt_save = OPTION_DEFAULT; + break; + case 1: /* total_is_major_isotope */ +#ifdef SKIP + if (elt_ptr == NULL) { + sprintf(error_string, "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; + } + master_isotope_ptr_major->total_is_major = get_true_false(next_char, TRUE); +#endif + sprintf(error_string, "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) { + sprintf(error_string, "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_major = master_isotope_ptr; + 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 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 + * + */ + char *ptr; + int l, length, line_length, n; + int return_value, opt, opt_save; + char token[MAX_LENGTH]; + struct calculate_value *calculate_value_ptr; + char *description; + int n_user, n_user_end; + char *next_char; + const char *opt_list[] = { + "start", /* 0 */ + "end" /* 1 */ + }; + int count_opt_list = 2; +/* + * Read advection number (not currently used) + */ + n = -1; + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); + 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) { + sprintf(error_string, "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 = (char *) PHRQ_malloc(sizeof(char)); + if (calculate_value_ptr->commands == NULL) malloc_error(); + calculate_value_ptr->commands[0] = '\0'; + 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 */ + length = strlen(calculate_value_ptr->commands); + line_length = strlen(line); + calculate_value_ptr->commands = (char *) PHRQ_realloc(calculate_value_ptr->commands, (size_t) (length + line_length + 2) * sizeof(char)); + if (calculate_value_ptr->commands == NULL) malloc_error(); + calculate_value_ptr->commands[length] = ';'; + calculate_value_ptr->commands[length + 1] = '\0'; + strcat((calculate_value_ptr->commands), line); + opt_save = OPT_1; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* output_msg(OUTPUT_MESSAGE, "%s", calculate_value[0].commands); + */ return(return_value); +} +/* ---------------------------------------------------------------------- */ +int 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 + * + */ + char *ptr; + int l, n; + int return_value, opt, opt_save; + char token[MAX_LENGTH]; + struct isotope_ratio *isotope_ratio_ptr; + char *description; + int n_user, n_user_end; + char *next_char; + const char *opt_list[] = { + "no_options" /* 0 */ + }; + int count_opt_list = 0; +/* + * Read number (not currently used) + */ + n = -1; + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); + 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) { + sprintf(error_string, "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) { + sprintf(error_string, "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 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 + * + */ + char *ptr; + int l, n; + int return_value, opt, opt_save; + char token[MAX_LENGTH]; + struct isotope_alpha *isotope_alpha_ptr; + char *description; + int n_user, n_user_end; + char *next_char; + const char *opt_list[] = { + "no_options" /* 0 */ + }; + int count_opt_list = 0; +/* + * Read number (not currently used) + */ + n = -1; + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); + 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) { + sprintf(error_string, "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 add_isotopes(struct solution *solution_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; + char *ptr; + struct master_isotope *master_isotope_ptr; + LDBLE total_moles; + /* + * zero out isotopes + */ + for (i = 0; i < count_master_isotope; 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_ptr, 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_ptr, total_moles); + } + for (i = 0; solution_ptr->totals[i].description != NULL; i++ ) { + ptr=solution_ptr->totals[i].description; + master_isotope_ptr = master_isotope_search(ptr); + if (master_isotope_ptr == NULL) continue; + if (master_isotope_ptr->minor_isotope == FALSE) { + total_moles = total(master_isotope_ptr->name); + calculate_isotope_moles(master_isotope_ptr->elt, solution_ptr, total_moles); + } + } + /* + * Set isotopes flag + */ + initial_solution_isotopes = FALSE; + for (i= 0; i < count_master_isotope; i++) { + if (master_isotope[i]->minor_isotope == TRUE && master_isotope[i]->moles > 0) { + initial_solution_isotopes = TRUE; + } + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int calculate_isotope_moles(struct element *elt_ptr, struct solution *solution_ptr, LDBLE total_moles) +/* ---------------------------------------------------------------------- */ +{ + int i, j, iter; + int count_isotopes, total_is_major; + char *ptr; + struct master_isotope *master_isotope_ptr, *master_isotope_ptr1; + struct master_isotope list[MAX_ELTS]; + LDBLE m_major, tot; +#ifdef SKIP + struct elt_list *iso_elt_list; + struct master *master_ptr; +#endif + /* + * Get total concentration of elt_ptr + */ + if (total_moles <= 0) { + sprintf(error_string, "Can not 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(struct master_isotope)); + 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(struct master_isotope)); + list[count_isotopes].ratio = 1.0; + if (list[count_isotopes].minor_isotope == FALSE) { + total_is_major = list[count_isotopes].total_is_major; + } + count_isotopes++; + } + for (i = 0; solution_ptr->totals[i].description != NULL; i++ ) { + ptr=solution_ptr->totals[i].description; + master_isotope_ptr = master_isotope_search(ptr); + if (master_isotope_ptr == NULL) continue; + if (master_isotope_ptr->elt != elt_ptr) continue; + memcpy(&(list[count_isotopes]), master_isotope_ptr, sizeof(struct master_isotope)); + if (list[count_isotopes].minor_isotope == FALSE) { + total_is_major = list[count_isotopes].total_is_major; + } + count_isotopes++; + } + /* + * Loop to calculate isotope molalities + */ + for (iter = 0; iter < itmax; 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; + } + sprintf(error_string, "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 (iter >= itmax) { + error_msg("Failed to converge in CALCULATE_ISOTOPE_MOLES.", STOP); + } + /* + * Update master_isotope + */ + for (j = 0; j < count_master_isotope; j++) { + for (i = 0; i < count_isotopes; i++) { + if (list[i].name== master_isotope[j]->name) { + memcpy(master_isotope[j], &(list[i]), sizeof(struct master_isotope)); + } + } + } + /* + * 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; + } + for (i = 0; solution_ptr->totals[i].description != NULL; i++ ) { + ptr=solution_ptr->totals[i].description; + master_isotope_ptr = master_isotope_search(ptr); + if (master_isotope_ptr == NULL) continue; + if (master_isotope_ptr->elt != elt_ptr) continue; + solution_ptr->totals[i].moles = master_isotope_ptr->moles; + solution_ptr->totals[i].input_conc = master_isotope_ptr->moles; + } + +#ifdef SKIP + /* + * make elt list + */ + iso_elt_list = PHRQ_malloc((size_t) (count_isotopes + 1)*sizeof(struct elt_list)); + if (iso_elt_list == NULL) malloc_error(); + for (i = 0; i < count_isotopes; i++) { + master_ptr = master_bsearch(list[i].name); + if (master_ptr == NULL) { + sprintf(error_string, "Did not find element in CALCULATE_ISOTOPES, %s.", list[i].name); + error_msg(error_string, STOP); + } + iso_elt_list[i].elt = master_ptr->elt; + iso_elt_list[i].coef = list[i].moles; + } + iso_elt_list[i].elt = NULL; +#endif + return(OK); +} +/* ---------------------------------------------------------------------- */ +int from_permil(struct 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 from_pct(struct 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 from_tu(struct 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 from_pcil(struct 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 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(OUTPUT_MESSAGE,"%10s\t%12s\t%12s\t%12s\t%12s\n\n", "Isotope","Molality","Moles","Ratio", "Units"); + for (i = 0; i < count_master_isotope; i++) { + if (master_isotope[i]->minor_isotope == FALSE) { + print_isotope = FALSE; + for (j = 0; j < count_master_isotope; 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(OUTPUT_MESSAGE,"%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 < count_master_isotope; j++) { + if (i == j) continue; + if ((master_isotope[j]->elt == master_isotope[i]->elt) && + (master_isotope[j]->minor_isotope == TRUE)) { + output_msg(OUTPUT_MESSAGE,"%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(OUTPUT_MESSAGE,"\n"); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_isotopes(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Punch isotope ratios relative to standards + */ + int i; + LDBLE iso; + struct isotope_ratio *isotope_ratio_ptr; + struct master_isotope *master_isotope_ptr; + + if (punch.in == FALSE || punch.isotopes == FALSE) return(OK); + if (punch.count_isotopes == 0) return(OK); + for (i = 0; i < punch.count_isotopes; i++) { + iso = MISSING; + if (state == INITIAL_SOLUTION) { + isotope_ratio_ptr = isotope_ratio_search(punch.isotopes[i].name); + 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(punch.isotopes[i].name); + if (isotope_ratio_ptr != NULL) { + iso = isotope_ratio_ptr->converted_ratio; + } + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("I_%s",punch.isotopes[i].name),"%12.4e\t", iso); + } else { + fpunchf(sformatf("I_%s",punch.isotopes[i].name),"%20.12e\t", iso); + } + + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_calculate_values(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Punch calculate values + */ + int i; + LDBLE result; + struct calculate_value *calculate_value_ptr; + + if (punch.in == FALSE || punch.calculate_values == FALSE) return(OK); + if (punch.count_calculate_values == 0) return(OK); + for (i = 0; i < punch.count_calculate_values; i++) { + result = MISSING; + calculate_value_ptr = calculate_value_search(punch.calculate_values[i].name); + if (calculate_value_ptr != NULL) { + result = calculate_value_ptr->value; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("V_%s",punch.calculate_values[i].name),"%12.4e\t", result); + } else { + fpunchf(sformatf("V_%s",punch.calculate_values[i].name),"%20.12e\t", result); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_isotope_ratios(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print isotopes for initial solution + */ + int i, j; + int print_isotope; + struct master *master_ptr; + struct master_isotope *master_isotope_ptr; + struct isotope_ratio *isotope_ratio_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 < count_master_isotope; 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(OUTPUT_MESSAGE,"%25s\t%12s\t%15s\n\n", "Isotope Ratio","Ratio","Input Units"); + + for (j = 0; j < count_isotope_ratio; j++) { + if (isotope_ratio[j]->ratio == MISSING) continue; + isotope_ratio_ptr = isotope_ratio[j]; + master_isotope_ptr = master_isotope_search(isotope_ratio[j]->isotope_name); + /* + * Print isotope ratio + */ + strcpy(token, isotope_ratio[j]->name); + while(replace("_"," ",token) == TRUE); + output_msg(OUTPUT_MESSAGE," %-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(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_isotope_alphas(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print isotopes for initial solution + */ + int i, j; + int print_isotope; + struct master *master_ptr; + struct isotope_alpha *isotope_alpha_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 < count_master_isotope; 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(OUTPUT_MESSAGE,"%75s\n", "1000ln(Alpha)"); + output_msg(OUTPUT_MESSAGE,"%79s\n", "----------------------"); + output_msg(OUTPUT_MESSAGE,"%-37s%14s%14s%12.1f C\n\n", " Isotope Ratio", "Solution alpha", "Solution", (double) tc_x); + + for (j = 0; j < count_isotope_alpha; j++) { + if (isotope_alpha[j]->value == MISSING) continue; + isotope_alpha_ptr = isotope_alpha[j]; + /* + * Print isotope ratio + */ + strcpy(token, 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(OUTPUT_MESSAGE,"%-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(OUTPUT_MESSAGE,"%-37s%14.5g%14.5g\n", token, (double) isotope_alpha[j]->value, (double) (1000*log(isotope_alpha[j]->value))); + } + + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int calculate_values(void) +/* ---------------------------------------------------------------------- */ +{ + int j; + struct calculate_value *calculate_value_ptr; + struct isotope_ratio *isotope_ratio_ptr; + struct isotope_alpha *isotope_alpha_ptr; + struct master_isotope *master_isotope_ptr; + char command[] = "run"; + + + /* + * initialize ratios as missing + */ + for (j = 0; j < count_calculate_value; j++) { + calculate_value[j]->calculated = FALSE; + calculate_value[j]->value = MISSING; + } + + for (j = 0; j < count_calculate_value; j++) { + calculate_value_ptr = calculate_value[j]; + rate_moles = NAN; + if (calculate_value_ptr->new_def == TRUE) { + if (basic_compile(calculate_value[j]->commands, &calculate_value[j]->linebase, &calculate_value[j]->varbase, &calculate_value[j]->loopbase) != 0) { + sprintf (error_string, "Fatal Basic error in CALCULATE_VALUES %s.", calculate_value[j]->name); + error_msg(error_string, STOP); + } + calculate_value_ptr->new_def = FALSE; + } + if (basic_run(command, calculate_value[j]->linebase, calculate_value[j]->varbase, calculate_value[j]->loopbase) != 0) { + sprintf (error_string, "Fatal Basic error in calculate_value %s.", calculate_value[j]->name); + error_msg(error_string, STOP); + } + if (rate_moles == NAN) { + sprintf(error_string, "Calculated value not SAVE'd for %s.", calculate_value[j]->name); + error_msg(error_string, STOP); + } else { + calculate_value[j]->calculated = TRUE; + calculate_value[j]->value = rate_moles; + } + } + for (j = 0; j < count_isotope_ratio; j++) { + isotope_ratio_ptr = isotope_ratio[j]; + master_isotope_ptr = master_isotope_search(isotope_ratio_ptr->isotope_name); + calculate_value_ptr = calculate_value_search(isotope_ratio_ptr->name); + /* + * 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); + } + } + for (j = 0; j < count_isotope_alpha; 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->value == MISSING) { + isotope_alpha_ptr->value = MISSING; + } else { + isotope_alpha_ptr->value = calculate_value_ptr->value; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE convert_isotope(struct master_isotope *master_isotope_ptr, LDBLE ratio) +/* ---------------------------------------------------------------------- */ +{ + 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); + } + sprintf(error_string, "Did not recognize isotope units in convert_isotope, %s", units); + error_msg(error_string, STOP); + return (-99.0); +} +/* + * Utility routines for master_isotope + */ + +/* ---------------------------------------------------------------------- */ +struct master_isotope *master_isotope_store (char *name, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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 hash table. 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; + struct master_isotope *master_isotope_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + + item.key = name; + item.data = NULL; + found_item = hsearch_multi(master_isotope_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + master_isotope_ptr = (struct master_isotope *) (found_item->data); + return (master_isotope_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + master_isotope_ptr = (struct master_isotope *) (found_item->data); + master_isotope_init(master_isotope_ptr); + } else { + n = count_master_isotope++; + /* make sure there is space in s */ + if (count_master_isotope >= max_master_isotope) { + space ((void **) ((void *) &master_isotope), count_master_isotope, &max_master_isotope, sizeof(struct master_isotope *)); + } + /* 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 hash table + */ + item.key = master_isotope_ptr->name; + item.data = (void *) master_isotope_ptr; + found_item = hsearch_multi(master_isotope_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in master_isotope_store."); + error_msg(error_string, CONTINUE); + } + + return (master_isotope_ptr); +} +/* ---------------------------------------------------------------------- */ +struct master_isotope *master_isotope_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a master_isotope structure, initializes + * arguments: void + * return: pointer to a master_isotope structure + */ +{ + struct master_isotope *master_isotope_ptr; + master_isotope_ptr=(struct master_isotope *) PHRQ_malloc(sizeof(struct master_isotope)); + if (master_isotope_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + master_isotope_init(master_isotope_ptr); + + return(master_isotope_ptr); +} +/* ---------------------------------------------------------------------- */ +static int master_isotope_init(struct master_isotope *master_isotope_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a master_isotope structure + */ +{ +/* + * set pointers in structure to NULL + */ + master_isotope_ptr->name=NULL; + master_isotope_ptr->units=NULL; + master_isotope_ptr->standard=0; + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct master_isotope *master_isotope_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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. + */ + struct master_isotope *master_isotope_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + item.key = name; + item.data = NULL; + found_item = hsearch_multi(master_isotope_hash_table, item, FIND); + + if (found_item != NULL) { + master_isotope_ptr = (struct master_isotope *) (found_item->data); + return (master_isotope_ptr); + } + return(NULL); +} +/* + * Utility routines for calculate_value + */ + +/* ---------------------------------------------------------------------- */ +struct calculate_value *calculate_value_store (char *name, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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 hash table. 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. + */ + int n; + struct calculate_value *calculate_value_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(calculate_value_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + calculate_value_ptr = (struct calculate_value *) (found_item->data); + return (calculate_value_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + calculate_value_ptr = (struct calculate_value *) (found_item->data); + calculate_value_free(calculate_value_ptr); + calculate_value_init(calculate_value_ptr); + } else { + n = count_calculate_value++; + /* make sure there is space in s */ + if (count_calculate_value >= max_calculate_value) { + space ((void **) ((void *) &calculate_value), count_calculate_value, &max_calculate_value, sizeof(struct calculate_value *)); + } + /* Make new calculate_value structure */ + calculate_value[n] = calculate_value_alloc(); + calculate_value_ptr = calculate_value[n]; + } + /* set name and z in pointer in calculate_value structure */ + calculate_value_ptr->name = string_hsave( name ); +/* + * Update hash table + */ + item.key = string_hsave(token); + item.data = (void *) calculate_value_ptr; + found_item = hsearch_multi(calculate_value_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in calculate_value_store."); + error_msg(error_string, CONTINUE); + } + + return (calculate_value_ptr); +} +/* ---------------------------------------------------------------------- */ +struct calculate_value *calculate_value_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a calculate_value structure, initializes + * arguments: void + * return: pointer to a calculate_value structure + */ +{ + struct calculate_value *calculate_value_ptr; + calculate_value_ptr=(struct calculate_value *) PHRQ_malloc(sizeof(struct calculate_value)); + if (calculate_value_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + calculate_value_init(calculate_value_ptr); + + return(calculate_value_ptr); +} +/* ---------------------------------------------------------------------- */ +static int calculate_value_init(struct calculate_value *calculate_value_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a calculate_value structure + */ +{ +/* + * set pointers in structure to NULL + */ + calculate_value_ptr->name=NULL; + calculate_value_ptr->commands=NULL; + calculate_value_ptr->linebase=NULL; + calculate_value_ptr->varbase=NULL; + calculate_value_ptr->loopbase=NULL; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct calculate_value *calculate_value_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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. + */ + struct calculate_value *calculate_value_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(calculate_value_hash_table, item, FIND); + + if (found_item != NULL) { + calculate_value_ptr = (struct calculate_value *) (found_item->data); + return (calculate_value_ptr); + } + return(NULL); +} +/* ---------------------------------------------------------------------- */ +int calculate_value_free(struct 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 = (char *) free_check_null(calculate_value_ptr->commands); + 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 + */ + +/* ---------------------------------------------------------------------- */ +struct isotope_ratio *isotope_ratio_store (char *name, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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 hash table. 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. + */ + int n; + struct isotope_ratio *isotope_ratio_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(isotope_ratio_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + isotope_ratio_ptr = (struct isotope_ratio *) (found_item->data); + return (isotope_ratio_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + isotope_ratio_ptr = (struct isotope_ratio *) (found_item->data); + isotope_ratio_init(isotope_ratio_ptr); + } else { + n = count_isotope_ratio++; + /* make sure there is space in s */ + if (count_isotope_ratio >= max_isotope_ratio) { + space ((void **) ((void *) &isotope_ratio), count_isotope_ratio, &max_isotope_ratio, sizeof(struct isotope_ratio *)); + } + /* 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 ); +/* + * Update hash table + */ + item.key = string_hsave(token); + item.data = (void *) isotope_ratio_ptr; + found_item = hsearch_multi(isotope_ratio_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in isotope_ratio_store."); + error_msg(error_string, CONTINUE); + } + + return (isotope_ratio_ptr); +} +/* ---------------------------------------------------------------------- */ +struct isotope_ratio *isotope_ratio_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a isotope_ratio structure, initializes + * arguments: void + * return: pointer to a isotope_ratio structure + */ +{ + struct isotope_ratio *isotope_ratio_ptr; + isotope_ratio_ptr=(struct isotope_ratio *) PHRQ_malloc(sizeof(struct isotope_ratio)); + if (isotope_ratio_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + isotope_ratio_init(isotope_ratio_ptr); + + return(isotope_ratio_ptr); +} +/* ---------------------------------------------------------------------- */ +static int isotope_ratio_init(struct isotope_ratio *isotope_ratio_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a isotope_ratio structure + */ +{ +/* + * set pointers in structure to NULL + */ + isotope_ratio_ptr->name=NULL; + isotope_ratio_ptr->isotope_name=NULL; + isotope_ratio_ptr->ratio = MISSING; + isotope_ratio_ptr->converted_ratio = MISSING; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct isotope_ratio *isotope_ratio_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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. + */ + struct isotope_ratio *isotope_ratio_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(isotope_ratio_hash_table, item, FIND); + + if (found_item != NULL) { + isotope_ratio_ptr = (struct isotope_ratio *) (found_item->data); + return (isotope_ratio_ptr); + } + return(NULL); +} +/* + * Utility routines for isotope_alpha + */ + +/* ---------------------------------------------------------------------- */ +struct isotope_alpha *isotope_alpha_store (char *name, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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 hash table. 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. + */ + int n; + struct isotope_alpha *isotope_alpha_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(isotope_alpha_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + isotope_alpha_ptr = (struct isotope_alpha *) (found_item->data); + return (isotope_alpha_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + isotope_alpha_ptr = (struct isotope_alpha *) (found_item->data); + isotope_alpha_init(isotope_alpha_ptr); + } else { + n = count_isotope_alpha++; + /* make sure there is space in s */ + if (count_isotope_alpha >= max_isotope_alpha) { + space ((void **) ((void *) &isotope_alpha), count_isotope_alpha, &max_isotope_alpha, sizeof(struct isotope_alpha *)); + } + /* 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 ); +/* + * Update hash table + */ + item.key = string_hsave(token); + item.data = (void *) isotope_alpha_ptr; + found_item = hsearch_multi(isotope_alpha_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in isotope_alpha_store."); + error_msg(error_string, CONTINUE); + } + + return (isotope_alpha_ptr); +} +/* ---------------------------------------------------------------------- */ +struct isotope_alpha *isotope_alpha_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a isotope_alpha structure, initializes + * arguments: void + * return: pointer to a isotope_alpha structure + */ +{ + struct isotope_alpha *isotope_alpha_ptr; + isotope_alpha_ptr=(struct isotope_alpha *) PHRQ_malloc(sizeof(struct isotope_alpha)); + if (isotope_alpha_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + isotope_alpha_init(isotope_alpha_ptr); + + return(isotope_alpha_ptr); +} +/* ---------------------------------------------------------------------- */ +static int isotope_alpha_init(struct isotope_alpha *isotope_alpha_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a isotope_alpha structure + */ +{ +/* + * set pointers in structure to NULL + */ + isotope_alpha_ptr->name=NULL; + isotope_alpha_ptr->named_logk=NULL; + isotope_alpha_ptr->value = MISSING; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct isotope_alpha *isotope_alpha_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table 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. + */ + struct isotope_alpha *isotope_alpha_ptr; + char token[MAX_LENGTH]; + ENTRY item, *found_item; +/* + * Search list + */ + strcpy(token, name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(isotope_alpha_hash_table, item, FIND); + + if (found_item != NULL) { + isotope_alpha_ptr = (struct isotope_alpha *) (found_item->data); + return (isotope_alpha_ptr); + } + return(NULL); +} diff --git a/kinetics.cpp b/kinetics.cpp new file mode 100644 index 00000000..0f5c751a --- /dev/null +++ b/kinetics.cpp @@ -0,0 +1,2288 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +#include "sundialstypes.h" /* definitions of types realtype and */ + /* integertype, and the constant FALSE */ +#include "cvode.h" /* prototypes for CVodeMalloc, CVode, and */ + /* CVodeFree, constants OPT_SIZE, BDF, NEWTON, */ + /* SV, SUCCESS, NST,NFE,NSETUPS, NNI, NCFN, NETF */ +#include "cvdense.h" /* prototype for CVDense, constant DENSE_NJE */ +#include "nvector_serial.h" /* definitions of type N_Vector and macro */ + /* NV_Ith_S, prototypes for N_VNew, N_VFree */ +#include "dense.h" /* definitions of type DenseMat, macro DENSE_ELEM*/ +#define KINETICS_EXTERNAL extern +#include "kinetics.h" +/* These macros are defined in order to write code which exactly matches + the mathematical problem description given above. + + Ith(v,i) references the ith component of the vector v, where i is in + the range [1..NEQ] and NEQ is defined below. The Ith macro is defined + using the N_VIth macro in nvector.h. N_VIth numbers the components of + a vector starting from 0. + + IJth(A,i,j) references the (i,j)th element of the dense matrix A, where + i and j are in the range [1..NEQ]. The IJth macro is defined using the + DENSE_ELEM macro in dense.h. DENSE_ELEM numbers rows and columns of a + dense matrix starting from 0. */ + +#define Ith(v,i) NV_Ith_S(v,i-1) /* Ith numbers components 1..NEQ */ +#define IJth(A,i,j) DENSE_ELEM(A,i-1,j-1) /* IJth numbers rows,cols 1..NEQ */ + +static void f(integertype N, realtype t, N_Vector y, N_Vector ydot, + void *f_data); + +static void Jac(integertype N, DenseMat J, RhsFn f, void *f_data, realtype t, + N_Vector y, N_Vector fy, N_Vector ewt, realtype h, + realtype uround, void *jac_data, long int *nfePtr, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); + +static char const svnid[] = "$Id: kinetics.c 738 2006-01-26 17:22:32Z dlpark $"; +static int calc_final_kinetic_reaction(struct kinetics *kinetics_ptr); +static int calc_kinetic_reaction(struct kinetics *kinetics_ptr, LDBLE time_step); +static int rk_kinetics(int i, LDBLE kin_time, int use_mix, int nsaver, LDBLE step_fraction); +static int set_reaction(int i, int use_mix, int use_kinetics); +static int set_transport(int i, int use_mix, int use_kinetics, int nsaver); +static int store_get_equi_reactants(int k, int kin_end); + +#define MAX_DIVIDE 2 +#define KINETICS_TOL 1e-8; + +LDBLE *m_original; +LDBLE *m_temp; + +extern LDBLE min_value; +extern int count_total_steps; + +/* ---------------------------------------------------------------------- */ +int calc_kinetic_reaction(struct kinetics *kinetics_ptr, LDBLE time_step) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through kinetic components to + * determine rates and + * a list of elements and amounts in + * the reaction. + */ + int i, j, return_value; + LDBLE coef; +/* char token[MAX_LENGTH]; + char *ptr; + struct phase *phase_ptr; + */ char command[] = "run"; + struct rate *rate_ptr; +/* LDBLE t1, t2; */ + if (svnid == NULL) fprintf(stderr," "); +/* + * Go through list and generate list of elements and + * coefficient of elements in reaction + */ + return_value = OK; + count_elts = 0; + paren_count = 0; + + rate_time = time_step; + +/* t1 = clock(); */ + for (i=0; i < kinetics_ptr->count_comps; i++) { + coef = 0.0; +/* + * Send command to basic interpreter + */ + rate_ptr = rate_search (kinetics_ptr->comps[i].rate_name, &j); + if (rate_ptr == NULL) { + sprintf(error_string,"Rate not found for %s",kinetics_ptr->comps[i].rate_name); + error_msg(error_string, STOP); + } else { + rate_moles = NAN; + rate_m = kinetics_ptr->comps[i].m; + rate_m0 = kinetics_ptr->comps[i].m0; + rate_p = kinetics_ptr->comps[i].d_params; + count_rate_p = kinetics_ptr->comps[i].count_d_params; + if (rate_ptr->new_def == TRUE) { + if (basic_compile(rates[j].commands, &rates[j].linebase, &rates[j].varbase, &rates[j].loopbase) != 0) { + sprintf (error_string, "Fatal Basic error in rate %s.",kinetics_ptr->comps[i].rate_name); + error_msg(error_string, STOP); + } + + rate_ptr->new_def = FALSE; + } + if (basic_run(command, rates[j].linebase, rates[j].varbase, rates[j].loopbase) != 0) { + sprintf (error_string, "Fatal Basic error in rate %s.",kinetics_ptr->comps[i].rate_name); + error_msg(error_string, STOP); + } + if (rate_moles == NAN) { + sprintf(error_string, "Moles of reaction not SAVE'd for %s.",kinetics_ptr->comps[i].rate_name); + error_msg(error_string, STOP); + } else { + + coef = rate_moles; + } + } +/* + * Accumulate moles of reaction for component + */ + kinetics_ptr->comps[i].moles += coef; + if (coef == 0.0) continue; + } +/* t2=clock(); + printf("secs in reac %e, t2 %e\n", t2-t1, t1); + */ + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int calc_final_kinetic_reaction(struct kinetics *kinetics_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through kinetic components to + * using extrapolated values, which were + * stored in moles in run_kinetics + */ + int i, j, k; + LDBLE coef; + char token[MAX_LENGTH]; + char *ptr; + struct phase *phase_ptr; + struct master *master_ptr; +/* + * Go through list and generate list of elements and + * coefficient of elements in reaction + */ + kinetics_ptr->totals = (struct elt_list *) free_check_null(kinetics_ptr->totals); + count_elts = 0; + paren_count = 0; + for (i=0; i < kinetics_ptr->count_comps; i++) { + if (kinetics_ptr->comps[i].moles > m_temp[i]) { + kinetics_ptr->comps[i].moles = m_temp[i]; + kinetics_ptr->comps[i].m = 0; + } + coef = kinetics_ptr->comps[i].moles; + if (coef == 0.0) continue; +/* + * Reactant is a pure phase, copy formula into token + */ + for (j = 0; j < kinetics_ptr->comps[i].count_list; j++) { + phase_ptr = NULL; + strcpy(token, kinetics_ptr->comps[i].list[j].name); + phase_ptr = phase_bsearch(token, &k, FALSE); + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, coef * kinetics_ptr->comps[i].list[j].coef); + } else { + ptr = kinetics_ptr->comps[i].list[j].name; + get_elts_in_species (&ptr, coef * kinetics_ptr->comps[i].list[j].coef); + } + } +#ifdef SKIP + phase_ptr = NULL; + if (kinetics_ptr->comps[i].count_list == 1) { + strcpy(token, kinetics_ptr->comps[i].list[0].name); + phase_ptr = phase_bsearch(token, &j, FALSE); + } + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, coef * kinetics_ptr->comps[i].list[0].coef); + } else { + for (j = 0; j < kinetics_ptr->comps[i].count_list; j++) { + ptr = kinetics_ptr->comps[i].list[j].name; + get_elts_in_species (&ptr, coef * kinetics_ptr->comps[i].list[j].coef); + } + } +#endif + if (use.exchange_ptr != NULL && use.exchange_ptr->related_rate == TRUE) { + for (j = 0; j < use.exchange_ptr->count_comps; j++) { + if (use.exchange_ptr->comps[j].rate_name != NULL) { + if (strcmp_nocase(kinetics_ptr->comps[i].rate_name, use.exchange_ptr->comps[j].rate_name) == 0) { + /* found kinetics component */ + add_elt_list(use.exchange_ptr->comps[j].formula_totals, -coef * use.exchange_ptr->comps[j].phase_proportion); + } + } + } + } + if (use.surface_ptr != NULL && use.surface_ptr->related_rate == TRUE) { + for (j = 0; j < use.surface_ptr->count_comps; j++) { + if (use.surface_ptr->comps[j].rate_name != NULL) { + if (strcmp_nocase(kinetics_ptr->comps[i].rate_name, use.surface_ptr->comps[j].rate_name) == 0) { + /* found kinetics component */ + ptr = use.surface_ptr->comps[j].formula; +/* Surface = 0 when m becomes low ... + */ + if (0.9 * use.surface_ptr->comps[j].phase_proportion * (kinetics_ptr->comps[i].m) < MIN_RELATED_SURFACE) { + master_ptr = master_bsearch(ptr); + master_ptr->total = 0.0; + } else { + get_elts_in_species (&ptr, -coef * use.surface_ptr->comps[j].phase_proportion); + } + } + } + } + } + } + kinetics_ptr->totals = elt_list_save(); + /* + output_msg(OUTPUT_MESSAGE, "Calc_final_kinetic_reaction \n"); + elt_list_print(kinetics_ptr->totals); + */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int rk_kinetics(int i, LDBLE kin_time, int use_mix, int nsaver, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ +/* + * Runge-Kutta-Fehlberg method; 6 evaluations of the derivative + * give O(h^5) global error and error estimate + * calc_kinetic_reaction(.., ..) calculates moles of intermediate derivatives; + * these are calc'd for the whole step h. + * calc_final_kinetic reaction(..) translates moles to PHREEQC reaction. + */ + int j, k, m, save_old; + int bad, step_bad, step_ok; + int n_reactions; + LDBLE h, h_old, h_sum; + LDBLE *rk_moles; + LDBLE error, error_max, safety, moles_max, moles_reduction; + struct kinetics *kinetics_ptr; + int equal_rate, zero_rate; + + struct pp_assemblage *pp_assemblage_save = NULL; + struct s_s_assemblage *s_s_assemblage_save = NULL; + +#ifdef SKIP + struct gas_phase *gas_phase_save = NULL; + struct solution *solution_save = NULL; + struct exchange *exchange_save = NULL; + struct surface *surface_save = NULL; +#endif + + static LDBLE b31 = 3./40., b32 = 9./40., + b51 = -11./54., b53 = -70./27., b54 = 35./27., + b61 = 1631./55296., b62 = 175./512., b63 = 575./13824., b64 = 44275./110592., b65 = 253./4096., + c1 = 37./378., c3 = 250./621., c4 = 125./594., c6 = 512./1771., + dc5 = -277./14336.; + LDBLE dc1 = c1 - 2825./27648., dc3 = c3 - 18575./48384., + dc4 = c4 - 13525./55296., dc6 = c6 - 0.25; +/* + * Save kinetics i and solution i, if necessary + */ + save_old = -2 - (count_cells + 1); + kinetics_duplicate(i, save_old); + if (nsaver != i) { + solution_duplicate(i, save_old); + } + +/* + * Malloc some space + */ + if (kinetics_bsearch(i, &m) == NULL) return(OK); + n_reactions = kinetics[m].count_comps; + rk_moles = (LDBLE *) PHRQ_malloc((size_t) 6 * n_reactions * sizeof(LDBLE)); + if (rk_moles == NULL) malloc_error(); + + /*if (use_mix != NOMIX) last_model.force_prep = TRUE;*/ + set_and_run_wrapper(i, use_mix, FALSE, i, step_fraction); + run_reactions_iterations += iterations; + saver(); + + if (state == TRANSPORT || state == PHAST) { + set_transport(i, NOMIX, TRUE, i); + } else if (state == ADVECTION) { + set_advection(i, NOMIX, TRUE, i); + } else if (state == REACTION) { + set_reaction(i, NOMIX, TRUE); + } + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_save = (struct pp_assemblage *) PHRQ_malloc(sizeof(struct pp_assemblage)); + if (pp_assemblage_save == NULL) malloc_error(); + } + if (use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_save = (struct s_s_assemblage *) PHRQ_malloc(sizeof(struct s_s_assemblage)); + if (s_s_assemblage_save == NULL) malloc_error(); + } + + kinetics_ptr = kinetics_bsearch(i, &m); + + step_bad = step_ok = 0; + bad = FALSE; + h_sum = 0.; + h = h_old = kin_time; + moles_max = 0.1; + moles_reduction = 1.0; + safety = 0.7; + if (kinetics_ptr->rk < 1) { + kinetics_ptr->rk = 1; + } else if (kinetics_ptr->rk > 3 && kinetics_ptr->rk < 6) { + kinetics_ptr->rk = 6; + } else if (kinetics_ptr->rk > 6) { + kinetics_ptr->rk = 6; + } + if (kinetics_ptr->rk == 6) equal_rate = FALSE; else equal_rate = TRUE; +/* + * if step_divide > 1, initial timestep is divided + * if < 1, step_divide indicates maximal reaction... + */ + if (kinetics_ptr->step_divide > 1.0) { + h = h_old = kin_time / kinetics_ptr->step_divide; + equal_rate = FALSE; + } else if (kinetics_ptr->step_divide < 1.0) { + moles_max = kinetics_ptr->step_divide; + } + + rate_sim_time = rate_sim_time_start + h_sum; + + status(0, NULL); + while (h_sum < kin_time) { + + if (step_bad > kinetics_ptr->bad_step_max) { + sprintf(error_string,"Bad RK steps > %d. Please decrease (time)step or increase -bad_step_max.", + kinetics_ptr->bad_step_max); + error_msg(error_string, STOP); + } + + MOLES_TOO_LARGE: + if (moles_reduction > 1.0) { + h_old = h; + h = safety * h / (1.0 + moles_reduction); + moles_reduction = 1.0; + equal_rate = FALSE; + bad = TRUE; + } +/* + * find k1 + */ + if (bad == TRUE) { + for (j=0; j < n_reactions; j++) { + rk_moles[j] *= (h / h_old); + kinetics_ptr->comps[j].moles = rk_moles[j] * 0.2; + kinetics_ptr->comps[j].m = m_temp[j]; + } + bad = FALSE; + } else { +/* + * define pointers for calc_kinetic_, they are lost after saver()... + */ + if (state == TRANSPORT || state == PHAST) { + set_transport(i, NOMIX, TRUE, i); + } else if (state == ADVECTION) { + set_advection(i, NOMIX, TRUE, i); + } else if (state == REACTION) { + set_reaction(i, NOMIX, TRUE); + } + /* + * Moles of minerals and solid solutions may change to make positive + * concentrations. Reactions may take out more than is present in + * solution. + */ + if (pp_assemblage_save != NULL) { + pp_assemblage_copy(use.pp_assemblage_ptr, pp_assemblage_save, use.pp_assemblage_ptr->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_copy(use.s_s_assemblage_ptr, s_s_assemblage_save, use.s_s_assemblage_ptr->n_user); + } + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = 0.; + m_temp[j] = kinetics_ptr->comps[j].m; + } + + rate_sim_time = rate_sim_time_start + h_sum; + calc_kinetic_reaction(kinetics_ptr, h); + + /* store k1 in rk_moles ... */ + for (j=0; j < n_reactions; j++) { + if (moles_reduction * moles_max < fabs(kinetics_ptr->comps[j].moles)) { + moles_reduction = fabs(kinetics_ptr->comps[j].moles) / moles_max; + } + /* define reaction for calculating k2 ... */ + rk_moles[j] = kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles *= 0.2; + } + if (moles_reduction > 1.0) goto MOLES_TOO_LARGE; + } +/* + * Quit rk with rk = 1 and equal rates ... + */ + if (kinetics_ptr->rk == 1 && equal_rate) { + zero_rate = TRUE; + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = rk_moles[j]; + if (fabs (kinetics_ptr->comps[j].moles) > MIN_TOTAL) zero_rate = FALSE; + } + + if (zero_rate == FALSE) { + calc_final_kinetic_reaction(kinetics_ptr); + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + if (kinetics_ptr->comps[j].m < 1.e-30) kinetics_ptr->comps[j].m = 0; + kinetics_ptr->comps[j].moles = 0.; + } + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; + calc_kinetic_reaction(kinetics_ptr, h); + for (j=0; j < n_reactions; j++) { + if (fabs( rk_moles[j] - kinetics_ptr->comps[j].moles) > kinetics_ptr->comps[j].tol) { + equal_rate = FALSE; + break; + } + } + } + if (zero_rate || equal_rate) { + saver(); + + /* Free space */ + + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + } + goto EQUAL_RATE_OUT; + } else { + kinetics_ptr->rk = 3; + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = 0.2 * rk_moles[j]; + } + } + } +/* + * Continue with rk ... + */ + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; + +/* + * find k2 + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = 0.; + } + rate_sim_time = rate_sim_time_start + h_sum + 0.2 * h; + calc_kinetic_reaction(kinetics_ptr, h); + + /* Reset to values of last saver() */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + + /* store k2 in rk_moles */ + k = n_reactions; + for (j=0; j < n_reactions; j++) { + if (moles_reduction * moles_max < fabs(kinetics_ptr->comps[j].moles)) { + moles_reduction = fabs(kinetics_ptr->comps[j].moles) / moles_max; + } + /* define reaction for calculating k3 */ + rk_moles[k+j] = kinetics_ptr->comps[j].moles; + + kinetics_ptr->comps[j].moles = b31 * rk_moles[j] + + b32 * rk_moles[k+j]; +/* + * check for equal_rate ... + */ + if (equal_rate && fabs( rk_moles[j] - rk_moles[k + j]) > kinetics_ptr->comps[j].tol) { + equal_rate = FALSE; + } + } + if (moles_reduction > 1.0) goto MOLES_TOO_LARGE; +/* + * Quit rk with rk = 2 and equal rates ... + */ + if (kinetics_ptr->rk == 2 && equal_rate) { + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = 0.3 * rk_moles[j] + 0.7 * rk_moles[k + j]; + } + calc_final_kinetic_reaction(kinetics_ptr); + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + if (kinetics_ptr->comps[j].m < 1.e-30) kinetics_ptr->comps[j].m = 0; + kinetics_ptr->comps[j].moles = 0.; + } + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * Move next calc'n to rk = 1 when initial rate equals final rate ... + */ + calc_kinetic_reaction(kinetics_ptr, h); + for (j=0; j < n_reactions; j++) { + if (fabs( rk_moles[j] - kinetics_ptr->comps[j].moles) > kinetics_ptr->comps[j].tol) { + equal_rate = FALSE; + break; + } + } + if (equal_rate) kinetics_ptr->rk = 1; + + saver(); + + /* Free space */ + + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + } + goto EQUAL_RATE_OUT; + } +/* + * Continue runge_kutta.. + */ + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * find k3 + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = 0.; + } + rate_sim_time = rate_sim_time_start + h_sum + 0.3 * h; + calc_kinetic_reaction(kinetics_ptr, h); + + /* Reset to values of last saver() */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + + /* store k3 in rk_moles */ + k = 2 * n_reactions; + for (j=0; j < n_reactions; j++) { + if (moles_reduction * moles_max < fabs(kinetics_ptr->comps[j].moles)) { + moles_reduction = fabs(kinetics_ptr->comps[j].moles) / moles_max; + } + /* define reaction for calculating k4 ... */ + rk_moles[k+j] = kinetics_ptr->comps[j].moles; + + kinetics_ptr->comps[j].moles = 0.3 * rk_moles[j] + - 0.9 * rk_moles[ n_reactions + j ] + + 1.2 * rk_moles[k+j]; +/* + * check for equal_rate ... + */ + if (equal_rate && fabs ( rk_moles[j] - rk_moles[k+j]) > kinetics_ptr->comps[j].tol) + equal_rate = FALSE; + } + if (moles_reduction > 1.0) goto MOLES_TOO_LARGE; +/* + * Quit rk with rk = 3 and equal rates ... + */ + if (kinetics_ptr->rk == 3 && equal_rate) { + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = 0.5 * rk_moles[j] + - 1.5 * rk_moles[n_reactions + j] + + 2 * rk_moles[k + j]; + } + calc_final_kinetic_reaction(kinetics_ptr); + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + if (kinetics_ptr->comps[j].m < 1.e-30) kinetics_ptr->comps[j].m = 0; + kinetics_ptr->comps[j].moles = 0.; + } + + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * Move next calc'n to rk = 1 when initial rate equals final rate ... + */ + calc_kinetic_reaction(kinetics_ptr, h); + for (j=0; j < n_reactions; j++) { + if (fabs( rk_moles[j] - kinetics_ptr->comps[j].moles) > kinetics_ptr->comps[j].tol) { + equal_rate = FALSE; + break; + } + } + if (equal_rate) kinetics_ptr->rk = 1; + + saver(); + + /* Free space */ + + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + } + goto EQUAL_RATE_OUT; + } +/* + * Continue runge_kutta.. + */ + + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * find k4 + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = 0.; + } + rate_sim_time = rate_sim_time_start + h_sum + 0.6 * h; + calc_kinetic_reaction(kinetics_ptr, h); + + /* Reset to values of last saver() */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + + /* store k4 in rk_moles */ + k = 3 * n_reactions; + for (j=0; j < n_reactions; j++) { + if (moles_reduction * moles_max < fabs(kinetics_ptr->comps[j].moles)) { + moles_reduction = fabs(kinetics_ptr->comps[j].moles) / moles_max; + } + + /* define reaction for calculating k5 */ + rk_moles[k+j] = kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = b51 * rk_moles[j] + + 2.5 * rk_moles[ n_reactions + j ] + + b53 * rk_moles[ 2*n_reactions + j ] + + b54 * rk_moles[ k + j ]; + } + if (moles_reduction > 1.0) goto MOLES_TOO_LARGE; + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * find k5 + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = 0.; + } + rate_sim_time = rate_sim_time_start + h_sum + h; + calc_kinetic_reaction(kinetics_ptr, h); + + /* Reset to values of last saver() */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + + /* store k5 in rk_moles */ + k = 4 * n_reactions; + for (j=0; j < n_reactions; j++) { + if (moles_reduction * moles_max < fabs(kinetics_ptr->comps[j].moles)) { + moles_reduction = fabs(kinetics_ptr->comps[j].moles) / moles_max; + } + + /* define reaction for calculating k6 */ + rk_moles[k+j] = kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = b61 * rk_moles[j] + + b62 * rk_moles[ n_reactions + j ] + + b63 * rk_moles[ 2*n_reactions + j ] + + b64 * rk_moles[ 3*n_reactions + j ] + + b65 * rk_moles[ k + j ]; + } + if (moles_reduction > 1.0) goto MOLES_TOO_LARGE; + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * find k6 + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + kinetics_ptr->comps[j].moles = 0.; + } + rate_sim_time = rate_sim_time_start + h_sum + 0.875 * h; + calc_kinetic_reaction(kinetics_ptr, h); + + /* Reset to values of last saver() */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + + /* store k6 in rk_moles */ + k = 5 * n_reactions; + for (j=0; j < n_reactions; j++) { + rk_moles[k+j] = kinetics_ptr->comps[j].moles; + } + +/* + * Evaluate error + */ + error_max = 0.; + for (j=0; j < n_reactions; j++) { + error = fabs ( dc1 * rk_moles[j] + + dc3 * rk_moles[ 2*n_reactions + j ] + + dc4 * rk_moles[ 3*n_reactions + j ] + + dc5 * rk_moles[ 4*n_reactions + j ] + + dc6 * rk_moles[ 5*n_reactions + j ] ); + + /* tol is in moles/l */ + error /= kinetics_ptr->comps[j].tol; + if (error > error_max) error_max = error; + } + +/* + * repeat with smaller step + */ +/* printf("timest %g ; error_max %g\n", h, error_max); */ + if (error_max > 1) { + h_old = h; + if (step_ok == 0) + h = h * safety / error_max; + else h = h * safety * pow(error_max, -0.25); + bad = TRUE; + step_bad ++; + } else { +/* + * OK, calculate result + */ + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = c1 * rk_moles[j] + + c3 * rk_moles[ 2*n_reactions + j ] + + c4 * rk_moles[ 3*n_reactions + j ] + + c6 * rk_moles[ 5*n_reactions + j ]; + } + calc_final_kinetic_reaction(kinetics_ptr); + for (j=0; j < n_reactions; j++) { + kinetics_ptr->comps[j].m = m_temp[j] - kinetics_ptr->comps[j].moles; + if (kinetics_ptr->comps[j].m < 1.e-30) kinetics_ptr->comps[j].m = 0; + kinetics_ptr->comps[j].moles = 0.; + } + + if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE) { + run_reactions_iterations += iterations; + moles_reduction = 9; + goto MOLES_TOO_LARGE; + } + run_reactions_iterations += iterations; +/* + * Move next calc'n to rk = 1 when initial rate equals final rate ... + */ + calc_kinetic_reaction(kinetics_ptr, h); + for (j=0; j < n_reactions; j++) { + if (fabs( rk_moles[j] - kinetics_ptr->comps[j].moles) > kinetics_ptr->comps[j].tol) { + equal_rate = FALSE; + break; + } + } + if (equal_rate && kinetics_ptr->rk < 6) kinetics_ptr->rk = 1; + + saver(); + + step_ok ++; + h_sum += h; + /* Free space */ + + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + } +/* + * and increase step size ... + */ + if (h_sum < kin_time) { + if (error_max > 0.000577) { + h = h * safety * pow(error_max, -0.2); + } else { + h *= 4; + } + if (h > (kin_time - h_sum)) h = (kin_time - h_sum); + } + } +#if !defined(PHREEQCI_GUI) +#ifndef PHREEQ98 + if (pr.status == TRUE && status_on == TRUE) { + char str[MAX_LENGTH]; + backspace_screen(37); + sprintf(str, "RK-steps: Bad%4d. OK%5d. Time %3d%%", step_bad, step_ok, (int) (100*h_sum/kin_time)); + output_msg(OUTPUT_SCREEN, "%-37s", str); + } +#endif +#endif + } + + EQUAL_RATE_OUT: + +/* + * Run one more time to get distribution of species + */ + if (state >= REACTION || nsaver != i) { + set_and_run_wrapper(i, NOMIX, FALSE, nsaver, 0.); + run_reactions_iterations += iterations; + } + /* reset for printing */ + if (use_mix == DISP) { + use.mix_ptr = &mix[count_mix - count_cells + i - 1]; + use.mix_in = TRUE; + use.n_mix_user = i; + } else if ((use_mix == STAG || use_mix == TRUE) && state == TRANSPORT) { + use.mix_ptr = mix_search (i, &use.n_mix, FALSE); + if (use.mix_ptr != NULL) { + use.mix_in = TRUE; + use.n_mix_user = i; + } + } +/* + * Restore solution i, if necessary + */ + if (nsaver != i) { + solution_duplicate(save_old, i); + } + rk_moles = (LDBLE *) free_check_null(rk_moles); + +#ifdef SKIP + if (state != TRANSPORT) { +#ifdef DOS + output_msg(OUTPUT_SCREEN, "\n"); +#else + output_msg(OUTPUT_SCREEN, "\n%-80s", " "); +#endif + } +#endif + rate_sim_time = rate_sim_time_start + kin_time; + use.kinetics_in = TRUE; + + /* Free space */ + + if (pp_assemblage_save != NULL) { + pp_assemblage_save = (struct pp_assemblage *) free_check_null(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(s_s_assemblage_save); + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int set_and_run_wrapper(int i, int use_mix, int use_kinetics, int nsaver, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ + int j, converge, max_try; + int old_diag, old_itmax; + LDBLE old_tol, old_min_value, old_step, old_pe, old_pp_column_scale; + LDBLE small_pe_step, small_step; + struct pp_assemblage *pp_assemblage_save = NULL; + struct s_s_assemblage *s_s_assemblage_save = NULL; + struct kinetics *kinetics_save = NULL; + + /* 0 -- normal */ + /* 1 -- try smaller step size, more iterations */ + /* 2 -- try diagonal scaling */ + /* 3 -- try smaller tolerance */ + /* 4 -- try alternate scaling */ + small_pe_step = 5.; + small_step = 10.; + converge = FALSE; + + old_diag = diagonal_scale; + old_itmax = itmax; + old_tol = ineq_tol; + old_step = step_size; + old_pe = pe_step_size; + old_min_value = min_value; + old_pp_column_scale = pp_column_scale; + + if (state == TRANSPORT || state == PHAST) { + set_transport(i, use_mix, use_kinetics, i); + } else if (state == ADVECTION) { + set_advection(i, use_mix, use_kinetics, i); + } else if (state == REACTION) { + set_reaction(i, use_mix, use_kinetics); + } + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_save = (struct pp_assemblage *) PHRQ_malloc(sizeof(struct pp_assemblage)); + if (pp_assemblage_save == NULL) malloc_error(); + pp_assemblage_copy(use.pp_assemblage_ptr, pp_assemblage_save, use.pp_assemblage_ptr->n_user); + } + if (use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_save = (struct s_s_assemblage *) PHRQ_malloc(sizeof(struct s_s_assemblage)); + if (s_s_assemblage_save == NULL) malloc_error(); + s_s_assemblage_copy(use.s_s_assemblage_ptr, s_s_assemblage_save, use.s_s_assemblage_ptr->n_user); + } + if (use.kinetics_ptr != NULL) { + kinetics_save = (struct kinetics *) PHRQ_malloc(sizeof(struct kinetics)); + if (kinetics_save == NULL) malloc_error(); + kinetics_copy(use.kinetics_ptr, kinetics_save, use.kinetics_ptr->n_user); + } + + if (pitzer_model == TRUE) { + diagonal_scale = TRUE; + always_full_pitzer = FALSE; + max_try = 2; + } else { + max_try = 11; + } + for (j = 0; j < max_try; j++) { + if (j == 1) { + always_full_pitzer = TRUE; + if (pe_step_size <= small_pe_step && step_size <= small_step) continue; + itmax *= 2; + step_size = small_step; + pe_step_size = small_pe_step; + sprintf(error_string, "Trying smaller step size, pe step size %g, %g ... \n", (double) step_size, (double) pe_step_size); + warning_msg(error_string); + } else if (j == 2) { + itmax *= 2; + if (diagonal_scale == TRUE) { + diagonal_scale = FALSE; + } else { + diagonal_scale = TRUE; + } + sprintf(error_string, "Trying diagonal scaling ...\n"); + warning_msg(error_string); + } else if (j == 3) { + itmax *= 2; + ineq_tol /= 10.; + sprintf(error_string, "Trying reduced tolerance %g ...\n", (double) ineq_tol); + warning_msg(error_string); + } else if (j == 4) { + itmax *= 2; + ineq_tol *= 10.; + sprintf(error_string, "Trying increased tolerance %g ...\n", (double) ineq_tol); + warning_msg(error_string); + } else if (j == 5) { + itmax *= 2; + if (diagonal_scale == TRUE) { + diagonal_scale = FALSE; + } else { + diagonal_scale = TRUE; + } + ineq_tol /= 10.; + sprintf(error_string, "Trying diagonal scaling and reduced tolerance %g ...\n", (double) ineq_tol); + warning_msg(error_string); + } else if (j == 6) { + itmax *= 2; + pp_column_scale = 1e-10; + sprintf(error_string, "Trying scaling pure_phase columns %g ...\n", (double) pp_column_scale); + warning_msg(error_string); + } else if (j == 7) { + itmax *= 2; + pp_column_scale = 1e-10; + if (diagonal_scale == TRUE) { + diagonal_scale = FALSE; + } else { + diagonal_scale = TRUE; + } + sprintf(error_string, "Trying scaling pure_phase columns and diagonal scale %g ...\n", (double) pp_column_scale); + warning_msg(error_string); + } else if (j == 8) { + itmax *= 2; + min_value *= 10; + sprintf(error_string, "Trying increased scaling %g ...\n", (double) min_value); + warning_msg(error_string); + } else if (j == 9) { + aqueous_only = 5; + sprintf(error_string, "Skipping optimize equations for first %d iterations ...\n", aqueous_only); + warning_msg(error_string); + } else if (j == 10) { + negative_concentrations = TRUE; + sprintf(error_string, "Adding inequality to make concentrations greater than zero.\n"); + warning_msg(error_string); + } + if (j > 0) { + if (pp_assemblage_save != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, pp_assemblage_save->n_user); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, s_s_assemblage_save->n_user); + } + if (kinetics_save != NULL) { + kinetics_free(use.kinetics_ptr); + kinetics_copy(kinetics_save, use.kinetics_ptr, kinetics_save->n_user); + } + } + + converge = set_and_run(i, use_mix, use_kinetics, nsaver, step_fraction); + /* reset values */ + diagonal_scale = old_diag; + itmax = old_itmax; + ineq_tol = old_tol; + step_size = old_step; + pe_step_size = old_pe; + min_value = old_min_value; + pp_column_scale = old_pp_column_scale; + aqueous_only = 0; + negative_concentrations = FALSE; + if (converge == TRUE) { + break; + } else if (converge == MASS_BALANCE) { + break; + } + warning_msg("Numerical method failed with this set of convergence parameters.\n"); + } + if (converge == FALSE && use.kinetics_ptr != NULL && use.kinetics_ptr->use_cvode == TRUE) { + sprintf(error_string, "Numerical method failed on all parameter combinations, retrying integration"); + /*output_msg(OUTPUT_MESSAGE, "Numerical method failed on all parameter combinations, retrying integration\n"); */ + warning_msg(error_string); + converge = MASS_BALANCE; + } + if (converge == FALSE) { +/* + * write to error.inp what failed to converge. + */ + if( output_open(OUTPUT_DUMP, "error.inp") != OK) { + sprintf(error_string, "Can't open file, %s.", "error.inp"); + error_msg(error_string, CONTINUE); + input_error++; + } else { + if (use.irrev_in == TRUE) { + dump_reaction(use.n_mix_user); + } + if (use.kinetics_ptr != NULL) { + dump_kinetics(use.kinetics_ptr->n_user); + } + output_msg(OUTPUT_DUMP, "END\n"); + if (use.solution_ptr != NULL) { + dump_solution(use.n_solution_user); + } else if (use.mix_ptr != NULL) { + dump_mix(use.n_mix_user); + } + if (use.pp_assemblage_in == TRUE) { + dump_pp_assemblage(use.n_pp_assemblage_user); + } + if (use.exchange_in == TRUE) { + dump_exchange(use.n_exchange_user); + } + if (use.surface_in == TRUE) { + dump_surface(use.n_surface_user); + } + if (use.gas_phase_in == TRUE) { + dump_gas_phase(use.n_gas_phase_user); + } + if (use.s_s_assemblage_in == TRUE) { + dump_s_s_assemblage(use.n_s_s_assemblage_user); + } + output_msg(OUTPUT_DUMP, "END\n"); + } + /* if (state == TRANSPORT && dump_modulus == 0) dump(); */ + check_residuals(); + pr.all = TRUE; + pr.gas_phase = use.gas_phase_in; + pr.pp_assemblage = use.pp_assemblage_in; + pr.s_s_assemblage = use.s_s_assemblage_in; + pr.surface = use.surface_in; + pr.exchange = use.exchange_in; + pr.totals = TRUE; + pr.species = TRUE; + pr.saturation_indices = TRUE; + pr.irrev = use.irrev_in; + pr.mix = use.mix_in; + pr.reaction = TRUE; + pr.use = TRUE; + sum_species(); + print_all(); + sprintf(error_string, "Numerical method failed on all combinations of convergence parameters"); + error_msg(error_string, STOP); + } + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + pp_assemblage_save = (struct pp_assemblage *) free_check_null(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(s_s_assemblage_save); + } + if (kinetics_save != NULL) { + kinetics_free(kinetics_save); + kinetics_save = (struct kinetics *) free_check_null(kinetics_save); + } + if (converge == MASS_BALANCE) { + return(MASS_BALANCE); + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int set_and_run(int i, int use_mix, int use_kinetics, int nsaver, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ +/* + * i --user number for soln, reaction, etc. + * use_mix --integer flag + state == TRANSPORT: DISP, STAG, NOMIX + state == REACTION: TRUE, FALSE + * use_kinetics --true or false flag to calculate kinetic reactions + * nsaver --user number to store solution + * step_fraction--fraction of irreversible reaction to add + */ + int n, n1, n2, converge; + if (state == TRANSPORT || state == PHAST) { + set_transport(i, use_mix, use_kinetics, nsaver); + } else if (state == ADVECTION) { + set_advection(i, use_mix, use_kinetics, nsaver); + } else if (state == REACTION) { + set_reaction(i, use_mix, use_kinetics); + } + cell = i; +/* + * Take step + */ + if (state >= REACTION) { + if (step(step_fraction) == MASS_BALANCE) { + return(MASS_BALANCE); + } +/* + * Always use solution, exchange, and surface -1 + */ + use.solution_ptr = solution_bsearch(-1, &n, TRUE); + + /* new */ + if (use.exchange_ptr != NULL) { + use.exchange_ptr = exchange_bsearch(-1, &n1); + } + if (use.surface_ptr != NULL) { + use.surface_ptr = surface_bsearch(-1, &n2); + } + } + /* end new */ +#ifdef SKIP +/* a quick one ...*/ + if (state == TRANSPORT /*&& ishift == 0*/ && + (cell == 1 || cell == count_cells)) last_model.force_prep = TRUE; +#endif + if (use.surface_ptr != NULL ) { + diffuse_layer_x = use.surface_ptr->diffuse_layer; + } + if (use.surface_ptr != NULL && diffuse_layer_x == TRUE) { + converge = surface_model(); + } else { + prep(); +#ifdef SKIP + k_temp(solution[n]->tc); +#endif + k_temp(use.solution_ptr->tc); + set(FALSE); + converge = model(); + } + sum_species(); + return(converge); +} +/* ---------------------------------------------------------------------- */ +int set_transport(int i, int use_mix, int use_kinetics, int nsaver) +/* ---------------------------------------------------------------------- */ +{ +/* + * i --user number for soln, reaction, etc. + * use_mix --integer flag + state == TRANSPORT: DISP, STAG, NOMIX + state == REACTION: TRUE, FALSE + * use_kinetics --true or false flag to calculate kinetic reactions + * nsaver --user number to store solution + */ + int n; + + cell = i; + reaction_step = 1; +#ifdef SKIP + if (pr.use == TRUE && pr.all == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nCell %d\n", i); + } +#endif +/* + * Find mixture or solution + */ + + use.mix_ptr = NULL; + use.mix_in = FALSE; + if (use_mix == DISP) { + use.mix_ptr = &mix[count_mix - count_cells + i - 1]; + use.mix_in = TRUE; + use.n_mix_user = i; + use.n_mix_user_orig = i; + } else if (use_mix == STAG) { + use.mix_ptr = mix_search (i, &use.n_mix, FALSE); + if (use.mix_ptr != NULL) { + use.mix_in = TRUE; + use.n_mix_user = i; + use.n_mix_user_orig = i; + } else { + use.solution_ptr = solution_bsearch (i, &use.n_solution, FALSE); + if (use.solution_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", use.n_solution_user); + error_msg(error_string, STOP); + } + use.n_solution_user = i; + use.solution_in = TRUE; + } + } else { + use.solution_ptr = solution_bsearch (i, &use.n_solution, FALSE); + if (use.solution_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", use.n_solution_user); + error_msg(error_string, STOP); + } + use.n_solution_user = i; + use.solution_in = TRUE; + } + save.solution = TRUE; + save.n_solution_user = nsaver; + save.n_solution_user_end = nsaver; +/* + * Find pure phase assemblage + */ + + use.pp_assemblage_ptr = pp_assemblage_bsearch (i, &use.n_pp_assemblage); + if (use.pp_assemblage_ptr != NULL) { + use.pp_assemblage_in = TRUE; + use.n_pp_assemblage_user = i; + save.pp_assemblage = TRUE; + save.n_pp_assemblage_user = i; + save.n_pp_assemblage_user_end = i; + } else { + use.pp_assemblage_in = FALSE; + save.pp_assemblage = FALSE; + } +/* + * Find irreversible reaction + */ + use.irrev_ptr = irrev_bsearch(i, &use.n_irrev); + if (use.irrev_ptr != NULL) { + use.irrev_in = TRUE; + use.n_irrev_user = i; + } else { + use.irrev_in = FALSE; + } +/* + * Find exchange + */ + use.exchange_ptr = exchange_bsearch(i, &use.n_exchange); + if (use.exchange_ptr != NULL) { + use.exchange_in = TRUE; + use.n_exchange_user = i; + save.exchange = TRUE; + save.n_exchange_user = i; + save.n_exchange_user_end = i; + } else { + use.exchange_in = FALSE; + save.exchange = FALSE; + } + +/* + * Find surface + */ + use.surface_ptr = surface_bsearch(i, &use.n_surface); + if (use.surface_ptr != NULL) { + use.surface_in = TRUE; + use.n_surface_user = i; + save.surface = TRUE; + save.n_surface_user = i; + save.n_surface_user_end = i; + } else { + use.surface_in = FALSE; + save.surface = FALSE; + } +/* + * Find temperature; temp retardation is done in step + */ + use.temperature_ptr = temperature_bsearch(i, &use.n_temperature); + if (use.temperature_ptr != NULL) { + use.temperature_in = TRUE; + use.n_temperature_user = i; + } else { + use.temperature_in = FALSE; + } +/* + * Find gas + */ + use.gas_phase_ptr = gas_phase_bsearch(i, &use.n_gas_phase); + if (use.gas_phase_ptr != NULL) { + use.gas_phase_in = TRUE; + use.n_gas_phase_user = i; + save.gas_phase = TRUE; + save.n_gas_phase_user = i; + save.n_gas_phase_user_end = i; + } else { + use.gas_phase_in = FALSE; + save.gas_phase = FALSE; + } +/* + * Find s_s_assemblage + */ + use.s_s_assemblage_ptr = s_s_assemblage_bsearch(i, &use.n_s_s_assemblage); + if (use.s_s_assemblage_ptr != NULL) { + use.s_s_assemblage_in = TRUE; + use.n_s_s_assemblage_user = i; + save.s_s_assemblage = TRUE; + save.n_s_s_assemblage_user = i; + save.n_s_s_assemblage_user_end = i; + } else { + use.s_s_assemblage_in = FALSE; + save.s_s_assemblage = FALSE; + } +/* + * Find kinetics + */ + if (use_kinetics == TRUE && (use.kinetics_ptr = kinetics_bsearch(i, &n)) != NULL) { + use.n_kinetics_user = i; + use.n_kinetics = n; + use.kinetics_in = TRUE; + save.kinetics = TRUE; + save.n_kinetics_user = i; + save.n_kinetics_user_end = i; + } else { + use.kinetics_ptr = NULL; + use.kinetics_in = FALSE; + save.kinetics = FALSE; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_reaction(int i, int use_mix, int use_kinetics) +/* ---------------------------------------------------------------------- */ +{ +/* + * i --user number for soln, reaction, etc. + * use_mix --integer flag + state == TRANSPORT: DISP, STAG, NOMIX + state == REACTION: TRUE, FALSE + * use_kinetics --true or false flag to calculate kinetic reactions + */ +/* + * Find mixture or solution + */ + use.mix_ptr = NULL; + use.solution_ptr = NULL; + if (use_mix == TRUE && use.mix_in == TRUE) { + use.mix_ptr = mix_bsearch (i, &use.n_mix); + if (use.mix_ptr == NULL) { + sprintf(error_string, "MIX %d not found.", i); + error_msg(error_string, STOP); + } + } else { + use.solution_ptr = solution_bsearch (i, &use.n_solution, FALSE); + if (use.solution_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find pure phase assemblage + */ + if (use.pp_assemblage_in == TRUE) { + use.pp_assemblage_ptr = pp_assemblage_bsearch (i, &use.n_pp_assemblage); + if (use.pp_assemblage_ptr == NULL) { + sprintf(error_string, "PP_ASSEMBLAGE %d not found.", i); + error_msg(error_string, STOP); + } + } + +/* + * Find irreversible reaction + */ + if (use.irrev_in == TRUE) { + use.irrev_ptr = irrev_bsearch (i, &use.n_irrev); + if (use.irrev_ptr == NULL) { + sprintf(error_string, "REACTION %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find exchange + */ + if (use.exchange_in == TRUE) { + use.exchange_ptr = exchange_bsearch (i, &use.n_exchange); + if (use.exchange_ptr == NULL) { + sprintf(error_string, "EXCHANGE %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find surface + */ + if (use.surface_in == TRUE) { + use.surface_ptr = surface_bsearch (i, &use.n_surface); + if (use.surface_ptr == NULL) { + sprintf(error_string, "SURFACE %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find temperature; temp retardation is done in step + */ + if (use.temperature_in == TRUE) { + use.temperature_ptr = temperature_bsearch (i, &use.n_temperature); + if (use.temperature_ptr == NULL) { + sprintf(error_string, "TEMPERATURE %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find gas + */ + if (use.gas_phase_in == TRUE) { + use.gas_phase_ptr = gas_phase_bsearch (i, &use.n_gas_phase); + if (use.gas_phase_ptr == NULL) { + sprintf(error_string, "GAS_PHASE %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find s_s_assemblage + */ + if (use.s_s_assemblage_in == TRUE) { + use.s_s_assemblage_ptr = s_s_assemblage_bsearch (i, &use.n_s_s_assemblage); + if (use.s_s_assemblage_ptr == NULL) { + sprintf(error_string, "Solid-solution Assemblage %d not found.", i); + error_msg(error_string, STOP); + } + } +/* + * Find kinetics + */ + if (use_kinetics == TRUE && use.kinetics_in == TRUE) { + use.kinetics_ptr = kinetics_bsearch (i, &use.n_kinetics); + if (use.kinetics_ptr == NULL) { + sprintf(error_string, "KINETICS %d not found.", i); + error_msg(error_string, STOP); + } + } else { + use.kinetics_ptr = NULL; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int run_reactions(int i, LDBLE kin_time, int use_mix, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ +/* + * Kinetics calculations + * Rates and moles of each reaction are calculated in calc_kinetic_reaction + * Total number of moles in reaction is stored in kinetics[i].totals + */ + + int j, n, converge, iter; + int pr_all_save; + int nsaver; + struct kinetics *kinetics_ptr; + struct pp_assemblage *pp_assemblage_ptr; + struct s_s_assemblage *s_s_assemblage_ptr; + + int save_old, m, n_reactions /*, nok, nbad */; + + /* CVODE definitions */ + realtype ropt[OPT_SIZE], reltol, t, tout, tout1, sum_t; + long int iopt[OPT_SIZE]; + int flag; +/* + * Set nsaver + */ + run_reactions_iterations = 0; + kin_time_x = kin_time; + nsaver = i; + if (state == TRANSPORT || state == PHAST) { + if (use_mix == DISP) { + nsaver = -2; + } else if (use_mix == STAG) { + nsaver = -2-i; + } + } if (state == ADVECTION) { + nsaver = -2; + } +/* + * Check that reaction exists for this cell .. + */ + if (kin_time <= 0 || + (state == REACTION && use.kinetics_in == FALSE) || + (state == TRANSPORT && kinetics_bsearch(i, &n) == NULL) || + (state == PHAST && kinetics_bsearch(i, &n) == NULL) || + (state == ADVECTION && kinetics_bsearch(i, &n) == NULL)) { + converge = set_and_run_wrapper(i, use_mix, FALSE, nsaver, step_fraction); + if (converge == MASS_BALANCE) error_msg("Negative concentration in system. Stopping calculation.",STOP); + run_reactions_iterations += iterations; + } else { +/* + * Save moles of kinetic reactants for printout... + */ + kinetics_ptr = kinetics_bsearch(i, &n); + + m_temp = (LDBLE *) PHRQ_malloc((size_t) kinetics_ptr->count_comps * sizeof(LDBLE)); + if (m_temp == NULL) malloc_error(); + + m_original = (LDBLE *) PHRQ_malloc((size_t) kinetics_ptr->count_comps * sizeof(LDBLE)); + if (m_original == NULL) malloc_error(); + + for (j = 0; j < kinetics_ptr->count_comps; j++) { + m_original[j] = kinetics_ptr->comps[j].m; + m_temp[j] = kinetics_ptr->comps[j].m; + } +/* + * Start the loop for timestepping ... + * Use either Runge-Kutta-Fehlberg, or final result extrapolation + */ + pr_all_save = pr.all; + pr.all = FALSE; +/* + * This condition makes output equal for incremental_reactions TRUE/FALSE... + * (if (incremental_reactions == FALSE || reaction_step == 1) + */ + store_get_equi_reactants(i, FALSE); + if (kinetics_ptr->use_cvode == FALSE) { + rk_kinetics(i, kin_time, use_mix, nsaver, step_fraction); + } else { + save_old = -2 - (count_cells + 1); + if (nsaver != i) { + solution_duplicate(i, save_old); + } + for (j = 0; j < OPT_SIZE; j++) { + iopt[j] = 0; + ropt[j] = 0; + } + +/* + * Do mix first + */ + kinetics_ptr = kinetics_bsearch(i, &m); + n_reactions = kinetics_ptr->count_comps; + cvode_n_user = i; + cvode_kinetics_ptr = (void *) kinetics_ptr; + cvode_n_reactions = n_reactions; + cvode_rate_sim_time_start = rate_sim_time_start; + cvode_rate_sim_time = rate_sim_time; + + converge = set_and_run_wrapper(i, use_mix, FALSE, i, 0.0); + if (converge == MASS_BALANCE) error_msg("Negative concentration in system. Stopping calculation.",STOP); + saver(); + pp_assemblage_ptr = pp_assemblage_bsearch(i, &n); + s_s_assemblage_ptr = s_s_assemblage_bsearch(i, &n); + if (pp_assemblage_ptr != NULL) { + cvode_pp_assemblage_save = (struct pp_assemblage *) PHRQ_malloc(sizeof(struct pp_assemblage)); + if (cvode_pp_assemblage_save == NULL) malloc_error(); + pp_assemblage_copy(pp_assemblage_ptr, cvode_pp_assemblage_save, pp_assemblage_ptr->n_user); + } + if (s_s_assemblage_ptr != NULL) { + cvode_s_s_assemblage_save = (struct s_s_assemblage *) PHRQ_malloc(sizeof(struct s_s_assemblage)); + if (cvode_s_s_assemblage_save == NULL) malloc_error(); + s_s_assemblage_copy(s_s_assemblage_ptr, cvode_s_s_assemblage_save, s_s_assemblage_ptr->n_user); + } + + /* allocate space for CVODE */ + kinetics_machEnv = M_EnvInit_Serial(n_reactions); + kinetics_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */ + if (kinetics_y == NULL) malloc_error(); + cvode_last_good_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */ + if (cvode_last_good_y == NULL) malloc_error(); + cvode_prev_good_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */ + if (cvode_prev_good_y == NULL) malloc_error(); + kinetics_abstol = N_VNew(n_reactions, kinetics_machEnv); + if (kinetics_abstol == NULL) malloc_error(); + +/* + * Set y to 0.0 + */ + for (j = 0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = 0.0; + Ith(kinetics_y,j+1) = 0.0; + Ith(kinetics_abstol,j+1) = kinetics_ptr->comps[j].tol; + /*Ith(abstol,j+1) = 1e-8; */ + /* m_temp[j] = kinetics_ptr->comps[j].m; */ + } + reltol = 0.0; + + /* Call CVodeMalloc to initialize CVODE: + + NEQ is the problem size = number of equations + f is the user's right hand side function in y'=f(t,y) + T0 is the initial time + y is the initial dependent variable vector + BDF specifies the Backward Differentiation Formula + NEWTON specifies a Newton iteration + SV specifies scalar relative and vector absolute tolerances + &reltol is a pointer to the scalar relative tolerance + abstol is the absolute tolerance vector + FALSE indicates there are no optional inputs in iopt and ropt + iopt is an array used to communicate optional integer input and output + ropt is an array used to communicate optional real input and output + + A pointer to CVODE problem memory is returned and stored in cvode_mem. */ + /* Don't know what this does */ + /* + iopt[SLDET] = TRUE; + cvode_mem = CVodeMalloc(n_reactions, f, 0.0, y, BDF, NEWTON, SV, &reltol, abstol, NULL, NULL, TRUE, iopt, ropt, machEnv); + cvode_mem = CVodeMalloc(n_reactions, f, 0.0, y, ADAMS, FUNCTIONAL, SV, &reltol, abstol, NULL, NULL, FALSE, iopt, ropt, machEnv); + */ + kinetics_cvode_mem = CVodeMalloc(n_reactions, f, 0.0, kinetics_y, BDF, NEWTON, SV, &reltol, kinetics_abstol, NULL, NULL, TRUE, iopt, ropt, kinetics_machEnv); + if (kinetics_cvode_mem == NULL) malloc_error(); + + /* Call CVDense to specify the CVODE dense linear solver with the + user-supplied Jacobian routine Jac. */ + + flag = CVDense(kinetics_cvode_mem, Jac, NULL); + if (flag != SUCCESS) { + error_msg("CVDense failed.", STOP); + } + t = 0; + tout = kin_time; + /*ropt[HMAX] = tout/10.;*/ + /*ropt[HMIN] = 1e-17;*/ + flag = CVode(kinetics_cvode_mem, tout, kinetics_y, &t, NORMAL); + rate_sim_time = rate_sim_time_start + t; + /* + printf("At t = %0.4e y =%14.6e %14.6e %14.6e\n", + t, Ith(y,1), Ith(y,2), Ith(y,3)); + */ + iter = 0; + sum_t = 0; + RESTART: + while (flag != SUCCESS) { + sum_t += cvode_last_good_time; + cvode_last_good_time = 0; + if (++iter >= 200) { + m_temp = (LDBLE *) free_check_null(m_temp); + m_original = (LDBLE *) free_check_null(m_original); + error_msg("Repeated restart of integration.", STOP); + } + tout1 = tout - sum_t; + t = 0; + N_VScale(1.0, cvode_last_good_y, kinetics_y); + for (j = 0; j < OPT_SIZE; j++) { + iopt[j] = 0; + ropt[j] = 0; + } + CVodeFree(kinetics_cvode_mem); /* Free the CVODE problem memory */ + kinetics_cvode_mem = CVodeMalloc(n_reactions, f, 0.0, kinetics_y, BDF, NEWTON, SV, &reltol, kinetics_abstol, NULL, NULL, FALSE, iopt, ropt, kinetics_machEnv); + if (kinetics_cvode_mem == NULL) malloc_error(); + + /* Call CVDense to specify the CVODE dense linear solver with the + user-supplied Jacobian routine Jac. */ + + flag = CVDense(kinetics_cvode_mem, Jac, NULL); + if (flag != SUCCESS) { + error_msg("CVDense failed.", STOP); + } + flag = CVode(kinetics_cvode_mem, tout1, kinetics_y, &t, NORMAL); + /* + sprintf(error_string, "CVode failed, flag=%d.\n", flag); + error_msg(error_string, STOP); + */ + } + + + /* + odeint(&ystart[-1], n_reactions, 0, kin_time, kinetics_ptr->comps[0].tol, kin_time/kinetics_ptr->step_divide, 0.0, &nok, &nbad, i, nsaver ); + */ + for (j = 0; j < n_reactions; j++) { + kinetics_ptr->comps[j].moles = Ith(kinetics_y,j+1); + kinetics_ptr->comps[j].m = m_original[j] - kinetics_ptr->comps[j].moles; + if (kinetics_ptr->comps[j].m < 0) { + kinetics_ptr->comps[j].moles = m_original[j]; + kinetics_ptr->comps[j].m = 0.0; + } + /* output_msg(OUTPUT_MESSAGE,"%d y[%d] %g\n", i, j, ystart[j]); */ + } + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(cvode_pp_assemblage_save, use.pp_assemblage_ptr, i); + } + if (use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(cvode_s_s_assemblage_save, use.s_s_assemblage_ptr, i); + } + calc_final_kinetic_reaction(kinetics_ptr); + if (set_and_run_wrapper(i, NOMIX, TRUE, nsaver, 1.0) == MASS_BALANCE) { + /*error_msg("FAIL 2 after successful integration in CVode", CONTINUE);*/ + warning_msg("FAIL 2 after successful integration in CVode"); + flag = -1; + goto RESTART; + } + for (j = 0; j < kinetics_ptr->count_comps; j++) { + kinetics_ptr->comps[j].m = m_original[j] - kinetics_ptr->comps[j].moles; + } +/* + * Restore solution i, if necessary + */ + if (nsaver != i) { + solution_duplicate(save_old, i); + } + free_cvode(); + } + + store_get_equi_reactants(i, TRUE); + pr.all = pr_all_save; + + kinetics_ptr = kinetics_bsearch(i, &n); + for (j = 0; j < kinetics_ptr->count_comps; j++) { + kinetics_ptr->comps[j].moles = m_original[j] - kinetics_ptr->comps[j].m; +/* if (kinetics_ptr->comps[j].moles < 1.e-15) kinetics_ptr->comps[j].moles = 0.0; + */ } + m_temp = (LDBLE *) free_check_null(m_temp); + m_original = (LDBLE *) free_check_null(m_original); + } + iterations = run_reactions_iterations; + if (cvode_pp_assemblage_save != NULL) { + pp_assemblage_free(cvode_pp_assemblage_save); + cvode_pp_assemblage_save = (struct pp_assemblage *) free_check_null(cvode_pp_assemblage_save); + } + if (cvode_s_s_assemblage_save != NULL) { + s_s_assemblage_free(cvode_s_s_assemblage_save); + cvode_s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(cvode_s_s_assemblage_save); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int free_cvode(void) +/* ---------------------------------------------------------------------- */ +{ + if (kinetics_y != NULL) N_VFree(kinetics_y); /* Free vector */ + kinetics_y = NULL; + if (cvode_last_good_y != NULL) N_VFree(cvode_last_good_y); /* Free vector */ + cvode_last_good_y = NULL; + if (cvode_prev_good_y != NULL) N_VFree(cvode_prev_good_y); /* Free vector */ + cvode_prev_good_y = NULL; + if (kinetics_abstol != NULL) N_VFree(kinetics_abstol); /* Free vector */ + kinetics_abstol = NULL; + if (kinetics_cvode_mem != NULL) CVodeFree(kinetics_cvode_mem); /* Free the CVODE problem memory */ + kinetics_cvode_mem = NULL; + if (kinetics_machEnv != NULL) M_EnvFree_Serial(kinetics_machEnv); /* Free the machine environment memory */ + kinetics_machEnv = NULL; + if (cvode_pp_assemblage_save != NULL) { + pp_assemblage_free(cvode_pp_assemblage_save); + cvode_pp_assemblage_save = (struct pp_assemblage *) free_check_null(cvode_pp_assemblage_save); + } + if (cvode_s_s_assemblage_save != NULL) { + s_s_assemblage_free(cvode_s_s_assemblage_save); + cvode_s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(cvode_s_s_assemblage_save); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_advection(int i, int use_mix, int use_kinetics, int nsaver) +/* ---------------------------------------------------------------------- */ +{ +/* + * i --user number for soln, reaction, etc. + * use_mix --integer flag + state == TRANSPORT: DISP, STAG, NOMIX + state == REACTION: TRUE, FALSE + state == ADVECTION: TRUE, FALSE + * use_kinetics --true or false flag to calculate kinetic reactions + * nsaver --user number to store solution + */ + int n; + + cell = i; + reaction_step = 1; +/* + * Find mixture or solution + */ + + use.mix_ptr = NULL; + use.mix_in = FALSE; + if (use_mix == TRUE && + (use.mix_ptr = mix_search (i, &use.n_mix, FALSE)) != NULL) { + use.mix_in = TRUE; + use.n_mix_user = i; + use.n_mix_user_orig = i; + use.n_solution_user = i; + } else { + use.solution_ptr = solution_bsearch (i, &use.n_solution, FALSE); + if (use.solution_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", use.n_solution_user); + error_msg(error_string, STOP); + } + use.n_solution_user = i; + use.solution_in = TRUE; + } + save.solution = TRUE; + save.n_solution_user = nsaver; + save.n_solution_user_end = nsaver; +/* + * Find pure phase assemblage + */ + + use.pp_assemblage_ptr = pp_assemblage_bsearch (i, &use.n_pp_assemblage); + if (use.pp_assemblage_ptr != NULL) { + use.pp_assemblage_in = TRUE; + use.n_pp_assemblage_user = i; + save.pp_assemblage = TRUE; + save.n_pp_assemblage_user = i; + save.n_pp_assemblage_user_end = i; + } else { + use.pp_assemblage_in = FALSE; + save.pp_assemblage = FALSE; + } +/* + * Find irreversible reaction + */ + use.irrev_ptr = irrev_bsearch(i, &use.n_irrev); + if (use.irrev_ptr != NULL) { + use.irrev_in = TRUE; + use.n_irrev_user = i; + } else { + use.irrev_in = FALSE; + } +/* + * Find exchange + */ + use.exchange_ptr = exchange_bsearch(i, &use.n_exchange); + if (use.exchange_ptr != NULL) { + use.exchange_in = TRUE; + use.n_exchange_user = i; + save.exchange = TRUE; + save.n_exchange_user = i; + save.n_exchange_user_end = i; + } else { + use.exchange_in = FALSE; + save.exchange = FALSE; + } + +/* + * Find surface + */ + use.surface_ptr = surface_bsearch(i, &use.n_surface); + if (use.surface_ptr != NULL) { + use.surface_in = TRUE; + use.n_surface_user = i; + save.surface = TRUE; + save.n_surface_user = i; + save.n_surface_user_end = i; + } else { + use.surface_in = FALSE; + save.surface = FALSE; + } +/* + * Find temperature; temp retardation is done in step + */ + use.temperature_ptr = temperature_bsearch(i, &use.n_temperature); + if (use.temperature_ptr != NULL) { + use.temperature_in = TRUE; + use.n_temperature_user = i; + } else { + use.temperature_in = FALSE; + } +/* + * Find gas + */ + use.gas_phase_ptr = gas_phase_bsearch(i, &use.n_gas_phase); + if (use.gas_phase_ptr != NULL) { + use.gas_phase_in = TRUE; + use.n_gas_phase_user = i; + save.gas_phase = TRUE; + save.n_gas_phase_user = i; + save.n_gas_phase_user_end = i; + } else { + use.gas_phase_in = FALSE; + save.gas_phase = FALSE; + } +/* + * Find s_s_assemblage + */ + use.s_s_assemblage_ptr = s_s_assemblage_bsearch(i, &use.n_s_s_assemblage); + if (use.s_s_assemblage_ptr != NULL) { + use.s_s_assemblage_in = TRUE; + use.n_s_s_assemblage_user = i; + save.s_s_assemblage = TRUE; + save.n_s_s_assemblage_user = i; + save.n_s_s_assemblage_user_end = i; + } else { + use.s_s_assemblage_in = FALSE; + save.s_s_assemblage = FALSE; + } +/* + * Find kinetics + */ + if (use_kinetics == TRUE && (use.kinetics_ptr = kinetics_bsearch(i, &n)) != NULL) { + use.n_kinetics_user = i; + use.n_kinetics = n; + use.kinetics_in = TRUE; + save.kinetics = TRUE; + save.n_kinetics_user = i; + save.n_kinetics_user_end = i; + } else { + use.kinetics_ptr = NULL; + use.kinetics_in = FALSE; + save.kinetics = FALSE; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_get_equi_reactants(int l, int kin_end) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + static int count_pp, count_pg, count_s_s; + static LDBLE *x0_moles; + + if (use.pp_assemblage_in == TRUE) { + use.pp_assemblage_ptr = pp_assemblage_bsearch (l, &use.n_pp_assemblage); + } else use.pp_assemblage_ptr = NULL; + if (use.gas_phase_in == TRUE) { + use.gas_phase_ptr = gas_phase_bsearch(l, &use.n_gas_phase); + } else use.gas_phase_ptr = NULL; + if (use.s_s_assemblage_in == TRUE) { + use.s_s_assemblage_ptr = s_s_assemblage_bsearch(l, &use.n_s_s_assemblage); + } else use.s_s_assemblage_ptr = NULL; + + if (kin_end == FALSE) { + count_pp = count_s_s = count_pg = 0; + if (use.pp_assemblage_ptr != NULL) count_pp = use.pp_assemblage_ptr->count_comps; + if (use.gas_phase_ptr != NULL) count_pg = use.gas_phase_ptr->count_comps; + if (use.s_s_assemblage_ptr != NULL) { + for( j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + count_s_s++; + } + } + } + k = count_pp + count_s_s + count_pg; + x0_moles = NULL; + if (k == 0) return(OK); + x0_moles = (LDBLE *) PHRQ_malloc((size_t) k * sizeof(LDBLE)); + if (x0_moles == NULL) malloc_error(); + + k = -1; + for (j = 0; j < count_pp; j++) { + x0_moles[++k] = use.pp_assemblage_ptr->pure_phases[j].moles; + } + for (j = 0; j < count_pg; j++) { + x0_moles[++k] = use.gas_phase_ptr->comps[j].moles; + } + if (count_s_s != 0) { + for(j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + x0_moles[++k] = use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + } +/*!!!! also miscibility gap comps ?? + */ + } + } + } else { + k = -1; + for (j = 0; j < count_pp; j++) { + use.pp_assemblage_ptr->pure_phases[j].moles = x0_moles[++k]; + use.pp_assemblage_ptr->pure_phases[j].delta = 0.0; + } + for (j = 0; j < count_pg; j++) { + use.gas_phase_ptr->comps[j].moles = x0_moles[++k]; + } + if (count_s_s != 0) { + for(j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + use.s_s_assemblage_ptr->s_s[j].comps[i].initial_moles = x0_moles[++k]; + } +/*!!!! also miscibility gap comps ?? + */ + } + } +/* + * This condition makes output equal for incremental_reactions TRUE/FALSE... + * if (incremental_reactions == FALSE || reaction_step == count_total_steps) + */ + x0_moles = (LDBLE *) free_check_null(x0_moles); + } + return(OK); +} +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +static void derivs (LDBLE x, LDBLE y[], LDBLE dydx[], int n_reactions, int n_user, struct kinetics *kinetics_ptr, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +#endif +static void f(integertype N, realtype t, N_Vector y, N_Vector ydot, + void *f_data) +{ + int i, n_reactions, n_user; + LDBLE step_fraction; + struct kinetics *kinetics_ptr; + + cvode_error = FALSE; + n_reactions = cvode_n_reactions; + n_user = cvode_n_user; + kinetics_ptr = (struct kinetics *) cvode_kinetics_ptr; + step_fraction = cvode_step_fraction; + rate_sim_time = cvode_rate_sim_time; + + for (i = 0; i < n_reactions; i++) { + /* + kinetics_ptr->comps[i].moles = y[i + 1]; + kinetics_ptr->comps[i].m = m_original[i] - y[i + 1]; + */ + kinetics_ptr->comps[i].moles = Ith(y,i + 1); + kinetics_ptr->comps[i].m = m_original[i] - Ith(y,i + 1); + if (kinetics_ptr->comps[i].m < 0) { + /* + NOTE: y is not correct if it is greater than m_original + However, it seems to work to let y wander off, but use + .moles as the correct integral. + It does not work to reset Y to m_original, presumably + because the rational extrapolation gets screwed up. + */ + + /* + Ith(y,i + 1) = m_original[i]; + */ + kinetics_ptr->comps[i].moles = m_original[i]; + kinetics_ptr->comps[i].m = 0.0; + } + } + calc_final_kinetic_reaction(kinetics_ptr); + /* if (set_and_run(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) { */ + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(cvode_pp_assemblage_save, use.pp_assemblage_ptr, n_user); + } + if (use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(cvode_s_s_assemblage_save, use.s_s_assemblage_ptr, n_user); + } + + if (set_and_run_wrapper(n_user, FALSE, TRUE, n_user, 0.0) == MASS_BALANCE) { + run_reactions_iterations += iterations; + cvode_error = TRUE; + /* + error_msg("Mass balance error in f", CONTINUE); + */ + return; + } + if (cvode_test == TRUE) { + return; + } + run_reactions_iterations += iterations; + for (i = 0; i < n_reactions; i++) { + kinetics_ptr->comps[i].moles = 0.0; + } + calc_kinetic_reaction(kinetics_ptr, 1.0); + for (i = 0; i < n_reactions; i++) { + /* + dydx[i + 1] = kinetics_ptr->comps[i].moles; + */ + Ith(ydot,i + 1) = kinetics_ptr->comps[i].moles; + } + return; +} + +/* +static void Jac(integertype N, DenseMat J, RhsFn f, void *f_data, realtype t, + N_Vector y, N_Vector fy, N_Vector ewt, realtype h, + realtype uround, void *jac_data, long int *nfePtr, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); +*/ +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +void jacobn (LDBLE x, LDBLE y[], LDBLE dfdx[], LDBLE **dfdy, int n_reactions, int n_user, struct kinetics *kinetics_ptr, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +#endif +static void Jac(integertype N, DenseMat J, RhsFn f, void *f_data, realtype t, + N_Vector y, N_Vector fy, N_Vector ewt, realtype h, + realtype uround, void *jac_data, long int *nfePtr, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) +{ + int count_cvode_errors; + int i, j, n_reactions, n_user; + LDBLE *initial_rates, del; + struct kinetics *kinetics_ptr; + LDBLE step_fraction; + + cvode_error = FALSE; + n_reactions = cvode_n_reactions; + n_user = cvode_n_user; + kinetics_ptr = (struct kinetics *) cvode_kinetics_ptr; + step_fraction = cvode_step_fraction; + rate_sim_time = cvode_rate_sim_time; + + initial_rates = (LDBLE *) PHRQ_malloc((size_t) n_reactions * sizeof(LDBLE)); + if (initial_rates == NULL) malloc_error(); + + for (i = 0; i < n_reactions; i++) { + /* + kinetics_ptr->comps[i].moles = y[i + 1]; + kinetics_ptr->comps[i].m = m_original[i] - y[i + 1]; + */ + kinetics_ptr->comps[i].moles = Ith(y, i + 1); + kinetics_ptr->comps[i].m = m_original[i] - Ith(y, i + 1); + if (kinetics_ptr->comps[i].m < 0) { + /* + NOTE: y is not correct if it is greater than m_original + However, it seems to work to let y wander off, but use + .moles as the correct integral. + It does not work to reset Y to m_original, presumably + because the rational extrapolation gets screwed up. + */ + + /* + Ith(y,i + 1) = m_original[i]; + */ + kinetics_ptr->comps[i].moles = m_original[i]; + kinetics_ptr->comps[i].m = 0.0; + } + } + calc_final_kinetic_reaction(kinetics_ptr); + /* if (set_and_run(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) {*/ + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(cvode_pp_assemblage_save, use.pp_assemblage_ptr, n_user); + } + if (set_and_run_wrapper(n_user, FALSE, TRUE, n_user, 0.0) == MASS_BALANCE) { + run_reactions_iterations += iterations; + cvode_error = TRUE; + /* + error_msg("Mass balance error in jacobian", CONTINUE); + */ + initial_rates = (LDBLE *) free_check_null(initial_rates); + return; + } + run_reactions_iterations += iterations; + for (i = 0; i < n_reactions; i++) kinetics_ptr->comps[i].moles = 0.0; + calc_kinetic_reaction(kinetics_ptr, 1.0); + for (i = 0; i < n_reactions; i++) { + initial_rates[i] = kinetics_ptr->comps[i].moles; + } + for (i = 0; i < n_reactions; i++) { + /* calculate reaction up to current time */ + del = 1e-12; + cvode_error = TRUE; + count_cvode_errors = 0; + while (cvode_error == TRUE) { + del /= 10.; + for (j = 0; j < n_reactions; j++) { + /* + kinetics_ptr->comps[j].moles = y[j + 1]; + kinetics_ptr->comps[j].m = m_original[j] - y[j + 1]; + */ + kinetics_ptr->comps[j].moles = Ith(y, j+1); + kinetics_ptr->comps[j].m = m_original[j] - Ith(y,j + 1); + if (kinetics_ptr->comps[i].m < 0) { + /* + NOTE: y is not correct if it is greater than m_original + However, it seems to work to let y wander off, but use + .moles as the correct integral. + It does not work to reset Y to m_original, presumably + because the rational extrapolation gets screwed up. + */ + + /* + Ith(y,i + 1) = m_original[i]; + */ + kinetics_ptr->comps[i].moles = m_original[i]; + kinetics_ptr->comps[i].m = 0.0; + } + } + + /* Add small amount of ith reaction */ + kinetics_ptr->comps[i].m -= del; + if (kinetics_ptr->comps[i].m < 0) { + kinetics_ptr->comps[i].m = 0; + } + kinetics_ptr->comps[i].moles += del; + calc_final_kinetic_reaction(kinetics_ptr); + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(cvode_pp_assemblage_save, use.pp_assemblage_ptr, n_user); + } +#ifdef SKIP + if (set_and_run_wrapper(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) { + run_reactions_iterations += iterations; + /* + error_msg("Mass balance error in jacobian 2", CONTINUE); + */ + cvode_error = TRUE; + initial_rates = (LDBLE *) free_check_null(initial_rates); + return; + } +#endif + if (set_and_run_wrapper(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) { + count_cvode_errors++; + cvode_error = TRUE; + if (count_cvode_errors > 30) { + initial_rates = (LDBLE *) free_check_null(initial_rates); + return; + } + run_reactions_iterations += iterations; + continue; + } + cvode_error = FALSE; + run_reactions_iterations += iterations; + /*kinetics_ptr->comps[i].moles -= del;*/ + for (j = 0; j < n_reactions; j++) kinetics_ptr->comps[j].moles = 0.0; + calc_kinetic_reaction(kinetics_ptr, 1.0); + + /* calculate new rates for df/dy[i] */ + /* dfdx[i + 1] = 0.0; */ + for (j = 0; j < n_reactions; j++) { + IJth(J,j+1,i+1) = (kinetics_ptr->comps[j].moles - initial_rates[j])/del; + } + } + } + for (i = 0; i < n_reactions; i++) { + kinetics_ptr->comps[i].moles = 0; + } + initial_rates = (LDBLE *) free_check_null(initial_rates); + return; +} + +void cvode_init(void) +{ + cvode_kinetics_ptr = NULL; + cvode_test = 0; + cvode_error = 0; + cvode_n_user = -99; + cvode_n_reactions = -99; + cvode_step_fraction = 0.0; + cvode_rate_sim_time = 0.0; + cvode_rate_sim_time_start = 0.0; + cvode_last_good_time = 0.0; + cvode_prev_good_time = 0.0; + cvode_last_good_y = NULL; + cvode_prev_good_y = NULL; + kinetics_machEnv = NULL; + kinetics_y = kinetics_abstol = NULL; + kinetics_cvode_mem = NULL; + cvode_pp_assemblage_save = NULL; + cvode_s_s_assemblage_save = NULL; + return; +} diff --git a/kinetics.h b/kinetics.h new file mode 100644 index 00000000..60df9d12 --- /dev/null +++ b/kinetics.h @@ -0,0 +1,21 @@ +#ifdef PHREEQC_IDENT +static char const svnidkinetics[] = "$Id$"; +#endif +KINETICS_EXTERNAL void *cvode_kinetics_ptr; +KINETICS_EXTERNAL int cvode_test; +KINETICS_EXTERNAL int cvode_error; +KINETICS_EXTERNAL int cvode_n_user; +KINETICS_EXTERNAL int cvode_n_reactions; +KINETICS_EXTERNAL realtype cvode_step_fraction; +KINETICS_EXTERNAL realtype cvode_rate_sim_time; +KINETICS_EXTERNAL realtype cvode_rate_sim_time_start; +KINETICS_EXTERNAL realtype cvode_last_good_time; +KINETICS_EXTERNAL realtype cvode_prev_good_time; +KINETICS_EXTERNAL N_Vector cvode_last_good_y; +KINETICS_EXTERNAL N_Vector cvode_prev_good_y; +KINETICS_EXTERNAL M_Env kinetics_machEnv; +KINETICS_EXTERNAL N_Vector kinetics_y, kinetics_abstol; +KINETICS_EXTERNAL void *kinetics_cvode_mem; +KINETICS_EXTERNAL struct pp_assemblage *cvode_pp_assemblage_save; +KINETICS_EXTERNAL struct s_s_assemblage *cvode_s_s_assemblage_save; + diff --git a/main.cpp b/main.cpp new file mode 100644 index 00000000..073e5d25 --- /dev/null +++ b/main.cpp @@ -0,0 +1,140 @@ +#define EXTERNAL +#include "global.h" +#include "output.h" +#include "phrqproto.h" +#include "input.h" + +/*#define PHREEQC_XML*/ +#ifdef PHREEQC_XML +#include "SAXPhreeqc.h" +extern void SAX_cleanup(void); +#endif + +static char const svnid[] = "$Id: main.c 715 2006-01-18 01:26:29Z dlpark $"; + +#ifdef DOS +static int write_banner(void); +#endif + +/* ---------------------------------------------------------------------- + * MAIN + * ---------------------------------------------------------------------- */ +int main(int argc, char *argv[]) +/* + * Main program for PHREEQC + */ +{ + int errors; + void *db_cookie = NULL; + void *input_cookie = NULL; + if (svnid == NULL) fprintf(stderr," "); + phast = FALSE; +/* + * Add callbacks for error_msg and warning_msg + */ + if (add_output_callback(phreeqc_handler, NULL) != OK) { + fprintf(stderr, "ERROR: %s\n", "NULL pointer returned from malloc or realloc."); + fprintf(stderr, "ERROR: %s\n", "Program terminating."); + return -1; + } + +/* + * Open input/output files + */ + errors = process_file_names(argc, argv, &db_cookie, &input_cookie, TRUE); + if (errors != 0) { + clean_up(); + return errors; + } +#ifdef DOS + write_banner(); +#endif + +/* + * Initialize arrays + */ + errors = do_initialize(); + if (errors != 0) { + clean_up(); + return errors; + } + +/* + * Load database into memory + */ + errors = read_database(getc_callback, db_cookie); + if (errors != 0) { + clean_up(); + return errors; + } + +/* + * Read input data for simulation + */ + errors = run_simulations(getc_callback, input_cookie); + if (errors != 0) { + clean_up(); + return errors; + } + + +/* + * Display successful status + */ + errors = do_status(); + if (errors != 0) { + clean_up(); + return errors; + } +#ifdef PHREEQC_XML +{ + int n; + SAX_StartSystem(); + for (n = 0; n < count_solution; ++n) + { + SAX_AddSolution(solution[n]); + } + SAX_EndSystem(); + SAX_UnpackSolutions(SAX_GetXMLStr(), SAX_GetXMLLength()); + } +#endif + + clean_up(); + close_input_files(); + close_output_files(); +#ifdef PHREEQC_XML + SAX_cleanup(); +#endif + return 0; +} +/* ---------------------------------------------------------------------- */ +int write_banner(void) +/* ---------------------------------------------------------------------- */ +{ + char buffer[80]; + int len, indent; + output_msg(OUTPUT_SCREEN, " ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ\n"); + output_msg(OUTPUT_SCREEN, " º º\n"); + + /* version */ + len = sprintf(buffer, "* PHREEQC-%s *", "@VERSION@"); + indent = (44 - len) / 2; + output_msg(OUTPUT_SCREEN, "%14cº%*c%s%*cº\n", ' ', indent, ' ', buffer, 44 - indent - len, ' '); + + output_msg(OUTPUT_SCREEN, " º º\n"); + output_msg(OUTPUT_SCREEN, " º A hydrogeochemical transport model º\n"); + output_msg(OUTPUT_SCREEN, " º º\n"); + output_msg(OUTPUT_SCREEN, " º by º\n"); + output_msg(OUTPUT_SCREEN, " º D.L. Parkhurst and C.A.J. Appelo º\n"); + output_msg(OUTPUT_SCREEN, " º º\n"); + + + /* date */ + len = sprintf(buffer, "%s", "@VER_DATE@"); + indent = (44 - len) / 2; + output_msg(OUTPUT_SCREEN, "%14cº%*c%s%*cº\n", ' ', indent, ' ', buffer, 44 - indent - len, ' '); + + output_msg(OUTPUT_SCREEN, " ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ\n\n"); + +return 0; +} diff --git a/mainsubs.cpp b/mainsubs.cpp new file mode 100644 index 00000000..8c1d6df2 --- /dev/null +++ b/mainsubs.cpp @@ -0,0 +1,2486 @@ +#define EXTERNAL extern +#define MAINSUBS +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +#include "input.h" + +extern void test_classes(void); +#define PHREEQC_XML +#ifdef PHREEQC_XML +#include "SAXPhreeqc.h" +extern void SAX_cleanup(void); +#endif + +static char const svnid[] = "$Id: mainsubs.c 715 2006-01-18 01:26:29Z dlpark $"; + +#if defined(WINDOWS) || defined(_WINDOWS) +#include +#endif + +static int copy_use (int i); +static int set_use(void); +static int xexchange_save(int n_user); +static int xgas_save(int n_user); +static int xpp_assemblage_save(int n_user); +static int xs_s_assemblage_save(int n_user); +static int xsurface_save(int n_user); + +#ifdef PHREEQ98 +extern int phreeq98_debug; +extern int AddSeries, connect_simulations; +#endif +/* ---------------------------------------------------------------------- */ +void initialize(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Initialize global variables + */ + ENTRY item, *found_item; + int i; + struct logk *logk_ptr; + char token[MAX_LENGTH]; + if (svnid == NULL) fprintf(stderr," "); + + moles_per_kilogram_string = string_duplicate("Mol/kgw"); + pe_string = string_duplicate("pe"); + + debug_model = FALSE; + debug_prep = FALSE; + debug_set = FALSE; + debug_diffuse_layer = FALSE; + debug_inverse = FALSE; + itmax=100; +#ifdef USE_LONG_LDBLE + /* from float.h, sets tolerance for cl1 routine */ + ineq_tol = pow(10, -LDBL_DIG); +#else + ineq_tol = pow(10, -DBL_DIG); +#endif + convergence_tolerance = 1e-8; +#ifdef USE_LONG_LDBLE + /* from float.h, sets tolerance for cl1 routine */ + inv_tol_default = pow(10, -LDBL_DIG+5); +#else + inv_tol_default = pow(10, -DBL_DIG+5); +#endif + step_size = 100.; + pe_step_size = 10.; + pp_scale = 1.0; + pp_column_scale = 1.0; + diagonal_scale = FALSE; + censor = 0.0; + mass_water_switch = FALSE; + /* mass_water_switch = TRUE; */ + delay_mass_water = FALSE; + incremental_reactions = FALSE; + aqueous_only = 0; + negative_concentrations = FALSE; + + LOG_10 = log(10.0); + /* Use space for all memory allocation */ + max_solution=MAX_SOLUTION; + max_pp_assemblage = MAX_PP_ASSEMBLAGE; + max_exchange = MAX_PP_ASSEMBLAGE; + max_surface = MAX_PP_ASSEMBLAGE; + max_gas_phase = MAX_PP_ASSEMBLAGE; + max_kinetics = MAX_PP_ASSEMBLAGE; + max_s_s_assemblage = MAX_PP_ASSEMBLAGE; + + max_elements = MAX_ELEMENTS; + max_elts = MAX_ELTS; + max_line = MAX_LINE; + max_master = MAX_MASTER; + max_mb_unknowns = MAX_TRXN; + max_phases = MAX_PHASES; + max_s = MAX_S; + max_strings = MAX_STRINGS; + max_trxn = MAX_TRXN; + max_logk = MAX_S; + max_master_isotope = MAX_ELTS; + + count_solution = 0; + count_pp_assemblage = 0; + count_exchange = 0; + count_surface = 0; + count_gas_phase = 0; + count_kinetics = 0; + count_s_s_assemblage = 0; + + count_elements = 0; + count_irrev = 0; + count_master = 0; + count_mix = 0; + count_phases=0; + count_s = 0; + count_temperature = 0; + count_logk = 0; + count_master_isotope = 0; +/* + * Initialize advection + */ + count_ad_cells = 1; + count_ad_shifts = 1; + print_ad_modulus = 1; + punch_ad_modulus = 1; + advection_punch = (int *) PHRQ_malloc(sizeof(int)); + if (advection_punch == NULL) malloc_error(); + advection_punch[0] = TRUE; + advection_kin_time = 0.0; + advection_kin_time_defined = FALSE; + advection_print = (int *) PHRQ_malloc(sizeof(int)); + if (advection_print == NULL) malloc_error(); + advection_print[0] = TRUE; + advection_warnings = TRUE; +/* + * Initialize transport + */ + count_cells = 1; + count_shifts = 1; + ishift = 1; + bcon_first = bcon_last = 3; + diffc = 0.3e-9; + simul_tr = 0; + tempr = 2.0; + heat_diffc = -0.1; + timest = 0.0; +/* !!!! count_stag = 0; */ + + print_modulus = 1; + punch_modulus = 1; + dump_modulus = 0; + dump_in = FALSE; + transport_warnings = TRUE; +/* + * Allocate space + */ + space ((void **) ((void *) &pp_assemblage), INIT, &max_pp_assemblage, sizeof(struct pp_assemblage)); + + space ((void **) ((void *) &exchange), INIT, &max_exchange, sizeof(struct exchange)); + + space ((void **) ((void *) &surface), INIT, &max_surface, sizeof(struct surface)); + + space ((void **) ((void *) &gas_phase), INIT, &max_gas_phase, sizeof(struct gas_phase)); + + space ((void **) ((void *) &kinetics), INIT, &max_kinetics, sizeof(struct kinetics)); + + space ((void **) ((void *) &s_s_assemblage), INIT, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + + space ((void **) ((void *) &cell_data), INIT, &count_cells, + sizeof(struct cell_data)); + + space ((void **) ((void *) &elements), INIT, &max_elements, sizeof(struct element *)); + + space ((void **) ((void *) &elt_list), INIT, &max_elts, sizeof(struct elt_list)); + + + inverse = (struct inverse *) PHRQ_malloc( (size_t) sizeof (struct inverse) ); + if (inverse == NULL) malloc_error(); + count_inverse = 0; + + irrev = (struct irrev *) PHRQ_malloc( (size_t) sizeof (struct irrev) ); + if (irrev == NULL) malloc_error(); + + space ((void **) ((void *) &line), INIT, &max_line, sizeof(char)); + + space ((void **) ((void *) &line_save), INIT, &max_line, sizeof(char)); + + space ((void **) ((void *) &master), INIT, &max_master, sizeof(struct master *)); + + space ((void **) ((void *) &mb_unknowns), INIT, &max_mb_unknowns, sizeof(struct unknown_list)); + + mix = (struct mix *) PHRQ_malloc((size_t) sizeof(struct mix)); + if (mix == NULL) malloc_error(); + count_mix = 0; +/* !!!! */ + stag_data = (struct stag_data *) PHRQ_calloc (1, sizeof(struct stag_data)); + if (stag_data == NULL) malloc_error(); + stag_data->count_stag = 0; + stag_data->exch_f = 0; + stag_data->th_m = 0; + stag_data->th_im = 0; + + space ((void **) ((void *) &phases), INIT, &max_phases, sizeof(struct phase *)); + + space ((void **) &trxn.token, INIT, &max_trxn, + sizeof(struct rxn_token_temp)); + + space ((void **) ((void *) &s), INIT, &max_s, sizeof(struct species *)); + + space ((void **) ((void *) &logk), INIT, &max_logk, sizeof(struct logk *)); + + space ((void **) ((void *) &master_isotope), INIT, &max_master_isotope, sizeof(struct master_isotope *)); + + solution = (struct solution **) PHRQ_malloc((size_t) MAX_SOLUTION * sizeof(struct solution *)); + if (solution == NULL) malloc_error(); + + temperature = (struct temperature *) PHRQ_malloc((size_t) sizeof (struct temperature)); + if (temperature == NULL) malloc_error(); + + title_x = NULL; + pe_x = NULL; + description_x = NULL; + units_x = NULL; + s_x = NULL; +/* SRC ADDED */ + sum_mb1 = NULL; + sum_mb2 = NULL; + sum_jacob0 = NULL; + sum_jacob1 = NULL; + sum_jacob2 = NULL; + sum_delta = NULL; +/* SRC ADDED */ + isotopes_x = (struct isotope *) PHRQ_malloc((size_t) sizeof(struct isotope)); + if (isotopes_x == NULL) malloc_error(); + x = NULL; + max_unknowns = 0; + + array = NULL; + delta = NULL; + residual = NULL; + s_h2o = NULL; + s_hplus = NULL; + s_h3oplus = NULL; + s_eminus = NULL; + s_co3 = NULL; + s_h2 = NULL; + s_o2 = NULL; + + hcreate_multi((unsigned) max_logk, &logk_hash_table); + hcreate_multi((unsigned) max_master_isotope, &master_isotope_hash_table); +/* + * Create hash table for strings + */ + hcreate_multi((unsigned) max_strings, &strings_hash_table); + hcreate_multi((unsigned) max_elements, &elements_hash_table); + hcreate_multi((unsigned) max_s, &species_hash_table); + hcreate_multi((unsigned) max_phases, &phases_hash_table); + hcreate_multi((unsigned) 2*NKEYS, &keyword_hash_table); +/* + * Initialize use pointers + */ + use.solution_in = FALSE; + use.pp_assemblage_in = FALSE; + use.mix_in = FALSE; + use.irrev_in = FALSE; +/* + * Initialize punch + */ + punch.in = FALSE; + punch.count_totals = 0; + punch.totals = (struct name_master *) PHRQ_malloc(sizeof(struct name_master)); + if (punch.totals == NULL) malloc_error(); + punch.count_molalities = 0; + punch.molalities = (struct name_species *) PHRQ_malloc(sizeof(struct name_species)); + if (punch.molalities == NULL) malloc_error(); + punch.count_activities = 0; + punch.activities = (struct name_species *) PHRQ_malloc(sizeof(struct name_species)); + if (punch.activities == NULL) malloc_error(); + punch.count_pure_phases = 0; + punch.pure_phases = (struct name_phase *) PHRQ_malloc(sizeof(struct name_phase)); + if (punch.pure_phases == NULL) malloc_error(); + punch.count_si = 0; + punch.si = (struct name_phase *) PHRQ_malloc(sizeof(struct name_phase)); + if (punch.si == NULL) malloc_error(); + punch.count_gases = 0; + punch.gases = (struct name_phase *) PHRQ_malloc(sizeof(struct name_phase)); + if (punch.gases == NULL) malloc_error(); + punch.count_s_s = 0; + punch.s_s = (struct name_phase *) PHRQ_malloc(sizeof(struct name_phase)); + if (punch.s_s == NULL) malloc_error(); + + punch.count_kinetics = 0; + punch.kinetics = (struct name_phase *) PHRQ_malloc(sizeof(struct name_phase)); + if (punch.kinetics == NULL) malloc_error(); + + punch.count_isotopes = 0; + punch.isotopes = (struct name_master *) PHRQ_malloc(sizeof(struct name_master)); + if (punch.isotopes == NULL) malloc_error(); + + punch.count_calculate_values = 0; + punch.calculate_values = (struct name_master *) PHRQ_malloc(sizeof(struct name_master)); + if (punch.calculate_values == NULL) malloc_error(); + + count_save_values = 0; + save_values = (struct save_values *) PHRQ_malloc(sizeof(struct save_values)); + if (save_values == NULL) malloc_error(); + + punch.inverse = TRUE; + + punch.sim = TRUE; + punch.state = TRUE; + punch.soln = TRUE; + punch.dist = TRUE; + punch.time = TRUE; + punch.step = TRUE; + punch.rxn = FALSE; + punch.temp = FALSE; + punch.ph = TRUE; + punch.pe = TRUE; + punch.alk = FALSE; + punch.mu = FALSE; + punch.water = FALSE; + punch.high_precision = FALSE; + punch.user_punch = TRUE; + punch.charge_balance = FALSE; + punch.percent_error = FALSE; +/* + * last model + */ + last_model.exchange = NULL; + last_model.gas_phase = NULL; + last_model.s_s_assemblage = NULL; + last_model.kinetics = NULL; + last_model.pp_assemblage = NULL; + last_model.add_formula = NULL; + last_model.si = NULL; + last_model.surface_comp = NULL; + last_model.surface_charge = NULL; +/* + * Update hash table + */ + keyword_hash = (struct key *) PHRQ_malloc((size_t) NKEYS * sizeof(struct key)); + if (keyword_hash == NULL) malloc_error(); + for (i = 0; i < NKEYS; i++) { + keyword_hash[i].name = string_hsave(keyword[i].name); + keyword_hash[i].keycount = i; + item.key = keyword_hash[i].name; + item.data = (void *) &keyword_hash[i]; + found_item = hsearch_multi(keyword_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in keyword initialization."); + error_msg(error_string, STOP); + } + } +/* + * rates + */ + rates = (struct rate *) PHRQ_malloc(sizeof(struct rate)); + if (rates == NULL) malloc_error(); + count_rates = 0; + initial_total_time = 0; + rate_m = 0; + rate_m0 = 0; + rate_p = NULL; + rate_time = 0; + rate_sim_time_start = 0; + rate_sim_time_end = 0; + rate_sim_time = 0; + rate_moles = 0; + initial_total_time = 0; + +/* + * user_print, user_punch + */ + user_print = (struct rate *) PHRQ_malloc((size_t) sizeof (struct rate)); + if (user_print == NULL) malloc_error(); + user_print->commands = NULL; + user_print->linebase = NULL; + user_print->varbase = NULL; + user_print->loopbase = NULL; + user_punch = (struct rate *) PHRQ_malloc((size_t) sizeof (struct rate)); + if (user_punch == NULL) malloc_error(); + user_punch->commands = NULL; + user_punch->linebase = NULL; + user_punch->varbase = NULL; + user_punch->loopbase = NULL; + user_punch_headings = (char **) PHRQ_malloc(sizeof(char *)); + if (user_punch_headings == NULL) malloc_error(); + user_punch_count_headings = 0; +#ifdef PHREEQ98 +/* + * user_graph + */ + user_graph = PHRQ_malloc((size_t) sizeof (struct rate)); + if (user_graph == NULL) malloc_error(); + user_graph->commands = NULL; + user_graph->linebase = NULL; + user_graph->varbase = NULL; + user_graph->loopbase = NULL; + user_graph_headings = (char **) PHRQ_malloc(sizeof(char *)); + if (user_graph_headings == NULL) malloc_error(); + user_graph_count_headings = 0; +#endif + /* + Initialize llnl aqueous model parameters + */ + llnl_temp = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (llnl_temp == NULL) malloc_error(); + llnl_count_temp = 0; + llnl_adh = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (llnl_adh == NULL) malloc_error(); + llnl_count_adh = 0; + llnl_bdh = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (llnl_bdh == NULL) malloc_error(); + llnl_count_bdh = 0; + llnl_bdot = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (llnl_bdot == NULL) malloc_error(); + llnl_count_bdot = 0; + llnl_co2_coefs = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (llnl_co2_coefs == NULL) malloc_error(); + llnl_count_co2_coefs = 0; +/* + * + */ + cmd_initialize(); +#if defined(WINDOWS) || defined(_WINDOWS) + /* SRC pr.status = FALSE; */ +#endif + /* Initialize print here, not in global.h */ + pr.all = TRUE; + pr.initial_solutions = TRUE; + pr.initial_exchangers = TRUE; + pr.reactions = TRUE; + pr.gas_phase = TRUE; + pr.s_s_assemblage = TRUE; + pr.pp_assemblage = TRUE; + pr.surface = TRUE; + pr.exchange = TRUE; + pr.kinetics = TRUE; + pr.totals = TRUE; + pr.eh = TRUE; + pr.species = TRUE; + pr.saturation_indices = TRUE; + pr.irrev = TRUE; + pr.mix = TRUE; + pr.reaction = TRUE; + pr.use = TRUE; + pr.logfile = FALSE; + pr.punch = TRUE; + if (phast == TRUE) { + pr.status = FALSE; + } else { + pr.status = TRUE; + } + pr.inverse = TRUE; + pr.dump = TRUE; + pr.user_print = TRUE; + pr.headings = TRUE; + pr.user_graph = TRUE; + pr.echo_input = TRUE; + count_warnings = 0; + pr.warnings = 100; + pr.initial_isotopes = TRUE; + pr.isotope_ratios = TRUE; + pr.isotope_alphas = TRUE; + pr.hdf = FALSE; + pr.alkalinity = FALSE; + + species_list = NULL; + + user_database = NULL; + first_read_input = TRUE; + selected_output_file_name = NULL; + dump_file_name = NULL; + +#ifdef PHREEQCI_GUI + g_spread_sheet.heading = NULL; + g_spread_sheet.units = NULL; + g_spread_sheet.count_rows = 0; + g_spread_sheet.rows = NULL; + g_spread_sheet.defaults.units = NULL; + g_spread_sheet.defaults.count_iso = 0; + g_spread_sheet.defaults.iso = NULL; +#endif + /* calculate_value */ + max_calculate_value = MAX_ELTS; + count_calculate_value = 0; + space ((void **) ((void *) &calculate_value), INIT, &max_calculate_value, sizeof(struct calculate_value *)); + hcreate_multi((unsigned) max_calculate_value, &calculate_value_hash_table); + + /* isotope_ratio */ + max_isotope_ratio = MAX_ELTS; + count_isotope_ratio = 0; + space ((void **) ((void *) &isotope_ratio), INIT, &max_isotope_ratio, sizeof(struct isotope_ratio *)); + hcreate_multi((unsigned) max_isotope_ratio, &isotope_ratio_hash_table); + + /* isotope_value */ + max_isotope_alpha = MAX_ELTS; + count_isotope_alpha = 0; + space ((void **) ((void *) &isotope_alpha), INIT, &max_isotope_alpha, sizeof(struct isotope_alpha *)); + hcreate_multi((unsigned) max_isotope_alpha, &isotope_alpha_hash_table); + + /* + * define constant named log_k + */ + strcpy(token, "XconstantX"); + logk_ptr = logk_store(token, TRUE); + read_log_k_only("1.0", &logk_ptr->log_k[0]); + + phreeqc_mpi_myself = 0; + + copier_init(©_solution); + copier_init(©_pp_assemblage); + copier_init(©_exchange); + copier_init(©_surface); + copier_init(©_s_s_assemblage); + copier_init(©_gas_phase); + copier_init(©_kinetics); + copier_init(©_mix); + copier_init(©_irrev); + copier_init(©_temperature); + + set_forward_output_to_log(FALSE); + simulation = 0; + /* + * cvode + */ + cvode_init(); + /* + * Pitzer + */ + pitzer_init(); + /* + * to facilitate debuging + */ + dbg_use = &use; + dbg_solution = solution; + dbg_exchange = exchange; + dbg_surface = surface; + dbg_pp_assemblage = pp_assemblage; + dbg_kinetics = kinetics; + dbg_irrev = irrev; + dbg_mix = mix; + return; +} +/* ---------------------------------------------------------------------- */ +static int set_use(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Structure "use" has list of solution, ex, surf, pp_assemblage, + * gas_phase and solid solution to use in current calculations, + * also mix, irrev, and temp. + * This routine searches for the user numbers in each list + * (solution, ex, ...) and sets a pointer in structure use + */ + +/* + * Initial solution case + */ + use.pp_assemblage_ptr = NULL; + use.mix_ptr = NULL; + use.irrev_ptr = NULL; + use.exchange_ptr = NULL; + use.kinetics_ptr = NULL; + use.surface_ptr = NULL; + use.temperature_ptr = NULL; + use.gas_phase_ptr = NULL; + use.s_s_assemblage_ptr = NULL; + + if (state < REACTION) { + return(OK); + } +/* + * Reaction case + */ + if (use.pp_assemblage_in == FALSE && + use.irrev_in == FALSE && + use.mix_in == FALSE && + use.exchange_in == FALSE && + use.kinetics_in == FALSE && + use.surface_in == FALSE && + use.temperature_in == FALSE && + use.gas_phase_in == FALSE && + use.s_s_assemblage_in == FALSE) { + return (FALSE); + } + if (use.solution_in == FALSE && use.mix_in == FALSE) return(FALSE); +/* + * Find solution + */ + if (use.solution_in == TRUE) { + use.solution_ptr = solution_bsearch (use.n_solution_user, &use.n_solution, FALSE); + if (use.solution_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", use.n_solution_user); + error_msg(error_string, STOP); + } + } +/* + * Find mixture + */ + if (use.mix_in == TRUE) { + use.mix_ptr = mix_bsearch(use.n_mix_user, &use.n_mix); + use.n_mix_user_orig = use.n_mix_user; + if (use.mix_ptr == NULL) { + sprintf(error_string, "Mixture %d not found.", use.n_mix_user); + error_msg(error_string, STOP); + } + } else { + use.mix_ptr = NULL; + } +/* + * Find pure phase assemblage + */ + if (use.pp_assemblage_in == TRUE) { + use.pp_assemblage_ptr = pp_assemblage_bsearch (use.n_pp_assemblage_user, &use.n_pp_assemblage); + if (use.pp_assemblage_ptr == NULL) { + sprintf(error_string, "Pure phase assemblage %d not found.", use.n_pp_assemblage_user); + error_msg(error_string, STOP); + } + } else { + use.pp_assemblage_ptr = NULL; + } +/* + * Find irrev reaction + */ + if (use.irrev_in == TRUE) { + use.irrev_ptr = irrev_bsearch(use.n_irrev_user, &use.n_irrev); + if (use.irrev_ptr == NULL) { + sprintf(error_string, "Irreversible reaction %d not found.", use.n_irrev_user); + error_msg(error_string, STOP); + } + } else { + use.irrev_ptr = NULL; + } +/* + * Find exchange + */ + if (use.exchange_in == TRUE) { + use.exchange_ptr = exchange_bsearch(use.n_exchange_user, &use.n_exchange); + if (use.exchange_ptr == NULL) { + sprintf(error_string, "Exchange %d not found.", use.n_exchange_user); + error_msg(error_string, STOP); + } + } else { + use.exchange_ptr = NULL; + } +/* + * Find kinetics + */ + if (use.kinetics_in == TRUE) { + use.kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &use.n_kinetics); + if (use.kinetics_ptr == NULL) { + sprintf(error_string, "Kinetics %d not found.", use.n_kinetics_user); + error_msg(error_string, STOP); + } + } else { + use.kinetics_ptr = NULL; + } +/* + * Find surface + */ + diffuse_layer_x = FALSE; + if (use.surface_in == TRUE) { + use.surface_ptr = surface_bsearch(use.n_surface_user, &use.n_surface); + if (use.surface_ptr == NULL) { + sprintf(error_string, "Surface %d not found.", use.n_surface_user); + error_msg(error_string, STOP); + } + } else { + use.surface_ptr = NULL; + } +/* + * Find temperature + */ + if (use.temperature_in == TRUE) { + use.temperature_ptr = temperature_bsearch(use.n_temperature_user, &use.n_temperature); + if (use.temperature_ptr == NULL) { + sprintf(error_string, "Temperature %d not found.", use.n_temperature_user); + error_msg(error_string, STOP); + } + } else { + use.temperature_ptr = NULL; + } +/* + * Find gas + */ + if (use.gas_phase_in == TRUE) { + use.gas_phase_ptr = gas_phase_bsearch(use.n_gas_phase_user, &use.n_gas_phase); + if (use.gas_phase_ptr == NULL) { + sprintf(error_string, "Gas_phase %d not found.", use.n_gas_phase_user); + error_msg(error_string, STOP); + } + } else { + use.gas_phase_ptr = NULL; + } +/* + * Find s_s_assemblage + */ + if (use.s_s_assemblage_in == TRUE) { + use.s_s_assemblage_ptr = s_s_assemblage_bsearch(use.n_s_s_assemblage_user, &use.n_s_s_assemblage); + if (use.s_s_assemblage_ptr == NULL) { + sprintf(error_string, "s_s_assemblage %d not found.", use.n_s_s_assemblage_user); + error_msg(error_string, STOP); + } + } else { + use.s_s_assemblage_ptr = NULL; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_solutions(int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through list of solutions, make initial solution calculations + * for any marked "new". + */ + int i, converge, converge1; + int n, last, n_user, print1; + char token[2*MAX_LENGTH]; + + state = INITIAL_SOLUTION; + set_use(); + print1 = TRUE; + diffuse_layer_x = FALSE; + for (n=0; n < count_solution; n++) { + initial_solution_isotopes = FALSE; + if (solution[n] != NULL && solution[n]->new_def == TRUE) { + if (print1 == TRUE && print == TRUE) { + dup_print("Beginning of initial solution calculations.", TRUE); + print1 = FALSE; + } + if (print == TRUE) { + sprintf(token, "Initial solution %d.\t%.350s", solution[n]->n_user, solution[n]->description); + dup_print(token, FALSE); + } + use.solution_ptr = solution[n]; + prep(); + k_temp(solution[n]->tc); + set(TRUE); + converge = model(); + converge1 = check_residuals(); + sum_species(); + add_isotopes(solution[n]); + punch_all(); + print_all(); + /* free_model_allocs(); */ + if (converge == ERROR || converge1 == ERROR) { + error_msg("Model failed to converge for initial solution.", STOP); + } + n_user = solution[n]->n_user; + last = solution[n]->n_user_end; + /* copy isotope data */ + if (solution[n]->count_isotopes > 0) { + count_isotopes_x = solution[n]->count_isotopes; + isotopes_x = (struct isotope *) PHRQ_realloc(isotopes_x, (size_t) count_isotopes_x * sizeof(struct isotope)); + if (isotopes_x == NULL) malloc_error(); + memcpy(isotopes_x, solution[n]->isotopes, (size_t) count_isotopes_x * sizeof(struct isotope)); + } else { + count_isotopes_x = 0; + } + xsolution_save(n_user); + for (i = n_user + 1; i <= last; i++) { + solution_duplicate(n_user, i); + } + } + } + initial_solution_isotopes = FALSE; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_exchangers(int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through list of exchangers, make initial calculations + * for any marked "new" that are defined to be in equilibrium with a + * solution. + */ + int i, converge, converge1; + int n, last, n_user, print1; + char token[2*MAX_LENGTH]; + + state = INITIAL_EXCHANGE; + set_use(); + print1 = TRUE; + diffuse_layer_x = FALSE; + for (n=0; n < count_exchange; n++) { + if (exchange[n].new_def != TRUE) continue; + n_user = exchange[n].n_user; + last = exchange[n].n_user_end; + exchange[n].n_user_end = n_user; + if (exchange[n].solution_equilibria == TRUE) { + if (print1 == TRUE && print == TRUE) { + dup_print("Beginning of initial exchange" + "-composition calculations.", TRUE); + print1 = FALSE; + } + if (print == TRUE) { + sprintf(token, "Exchange %d.\t%.350s", + exchange[n].n_user, + exchange[n].description); + dup_print(token, FALSE); + } + use.exchange_ptr = &(exchange[n]); + use.solution_ptr = solution_bsearch(exchange[n].n_solution, &i, TRUE); + if (use.solution_ptr == NULL) { + error_msg("Solution not found for initial exchange calculation", STOP); + } +#ifdef PHREEQC_XML +{ + // int n; + //SAX_StartSystem(); + //SAX_AddSolution(use.solution_ptr); + //SAX_EndSystem(); + //SAX_UnpackSolutions(SAX_GetXMLStr(), SAX_GetXMLLength()); + //SAX_cleanup(); + } +#endif + prep(); + k_temp(use.solution_ptr->tc); + set(TRUE); + converge = model(); + converge1 = check_residuals(); + sum_species(); + species_list_sort(); + print_exchange(); + xexchange_save(n_user); + punch_all(); + /* free_model_allocs(); */ + if (converge == ERROR || converge1 == ERROR) { + error_msg("Model failed to converge for initial exchange calculation.", STOP); + } + } + for (i = n_user + 1; i <= last; i++) { + exchange_duplicate(n_user, i); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_gas_phases(int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through list of gas_phases, make initial calculations + * for any marked "new" that are defined to be in equilibrium with a + * solution. + */ + int i, converge, converge1; + int n, last, n_user, print1; + char token[2*MAX_LENGTH]; + struct gas_comp *gas_comp_ptr; + struct phase *phase_ptr; + struct rxn_token *rxn_ptr; + LDBLE lp; + + state = INITIAL_GAS_PHASE; + set_use(); + print1 = TRUE; + diffuse_layer_x = FALSE; + for (n=0; n < count_gas_phase; n++) { + if (gas_phase[n].new_def != TRUE) continue; + n_user = gas_phase[n].n_user; + last = gas_phase[n].n_user_end; + gas_phase[n].n_user_end = n_user; + if (gas_phase[n].solution_equilibria == TRUE) { + if (print1 == TRUE && print == TRUE) { + dup_print("Beginning of initial gas_phase" + "-composition calculations.", TRUE); + print1 = FALSE; + } + if (print == TRUE) { + sprintf(token, "Gas_Phase %d.\t%.350s", + gas_phase[n].n_user, + gas_phase[n].description); + dup_print(token, FALSE); + } + use.solution_ptr = solution_bsearch(gas_phase[n].n_solution, &i, TRUE); + prep(); + k_temp(use.solution_ptr->tc); + set(TRUE); + converge = model(); + converge1 = check_residuals(); + if (converge == ERROR || converge1 == ERROR) { + /* free_model_allocs(); */ + error_msg("Model failed to converge for initial gas phase calculation.", STOP); + } + use.gas_phase_ptr = &(gas_phase[n]); + use.gas_phase_ptr->total_p = 0; + use.gas_phase_ptr->total_moles = 0; + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + gas_comp_ptr = &(use.gas_phase_ptr->comps[i]); + phase_ptr = gas_comp_ptr->phase; + if (phase_ptr->in == TRUE) { + lp=-phase_ptr->lk; + for (rxn_ptr=phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + lp += rxn_ptr->s->la * rxn_ptr->coef; + } + gas_comp_ptr->phase->p_soln_x = exp(lp * LOG_10); + use.gas_phase_ptr->total_p += gas_comp_ptr->phase->p_soln_x; + gas_comp_ptr->phase->moles_x = gas_comp_ptr->phase->p_soln_x * + use.gas_phase_ptr->volume / (R_LITER_ATM * tk_x); + gas_comp_ptr->moles = gas_comp_ptr->phase->moles_x; + use.gas_phase_ptr->total_moles += gas_comp_ptr->moles; + } else { + gas_comp_ptr->phase->moles_x = 0; + } + } + print_gas_phase(); + xgas_save(n_user); + punch_all(); + /* free_model_allocs(); */ + } + for (i = n_user + 1; i <= last; i++) { + gas_phase_duplicate(n_user, i); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_surfaces(int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through list of surfaces, make initial calculations + * for any marked "new" that are defined to be in equilibrium with a + * solution. + */ + int i; + int n, last, n_user, print1; + char token[2*MAX_LENGTH]; + + state = INITIAL_SURFACE; + set_use(); + print1 = TRUE; + for (n=0; n < count_surface; n++) { + if (surface[n].new_def != TRUE) continue; + n_user = surface[n].n_user; + last = surface[n].n_user_end; + surface[n].n_user_end = n_user; + if (surface[n].solution_equilibria == TRUE) { + if (print1 == TRUE && print == TRUE) { + dup_print("Beginning of initial surface-composition calculations.", TRUE); + print1 = FALSE; + } + if (print == TRUE) { + sprintf(token, "Surface %d.\t%.350s", + surface[n].n_user, + surface[n].description); + dup_print(token, FALSE); + } + use.surface_ptr = &(surface[n]); + diffuse_layer_x = use.surface_ptr->diffuse_layer; + use.solution_ptr = solution_bsearch(surface[n].n_solution, &i, TRUE); + if (use.solution_ptr == NULL) { + error_msg("Solution not found for initial surface calculation", STOP); + } +#ifdef SKIP + if (diffuse_layer_x == TRUE) { + converge = surface_model(); + } else { + prep(); + k_temp(use.solution_ptr->tc); + set(TRUE); + converge = model(); + } + converge1 = check_residuals(); + sum_species(); +#endif + set_and_run_wrapper(-1, FALSE, FALSE, -1, 0.0); + species_list_sort(); + print_surface(); + punch_all(); +#ifdef SKIP + if (converge == ERROR || converge1 == ERROR) { + /* free_model_allocs(); */ + error_msg("Model failed to converge for initial surface calculation.", STOP); + } +#endif + xsurface_save(n_user); + /* free_model_allocs(); */ + } + for (i = n_user + 1; i <= last; i++) { + surface_duplicate(n_user, i); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int reactions(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make all reaction calculation which could include: + * equilibrium with a pure-phase assemblage, + * equilibrium with an exchanger, + * equilibrium with an surface, + * equilibrium with a gas phase, + * equilibrium with a solid solution assemblage, + * kinetics, + * change of temperature, + * mixture, + * or irreversible reaction. + */ + int count_steps, use_mix, m; + char token[2*MAX_LENGTH]; + struct save save_data; + LDBLE kin_time; + struct kinetics *kinetics_ptr; + + state = REACTION; + /* last_model.force_prep = TRUE; */ + if (set_use() == FALSE) return(OK); +/* + * Find maximum number of steps + */ + dup_print ("Beginning of batch-reaction calculations.", TRUE); + count_steps = 1; + if (use.irrev_in == TRUE && use.irrev_ptr != NULL) { + if (abs(use.irrev_ptr->count_steps) > count_steps) + count_steps = abs(use.irrev_ptr->count_steps); + } + if (use.kinetics_in == TRUE && use.kinetics_ptr != NULL) { + if (abs(use.kinetics_ptr->count_steps) > count_steps) + count_steps = abs(use.kinetics_ptr->count_steps); + } + if (use.temperature_in == TRUE && use.temperature_ptr != NULL) { + if (abs(use.temperature_ptr->count_t) > count_steps) + count_steps = abs(use.temperature_ptr->count_t); + } + count_total_steps = count_steps; +/* + * save data for saving solutions + */ + memcpy(&save_data, &save, sizeof(struct save)); + /* + *Copy everything to -2 + */ + copy_use(-2); + rate_sim_time_start = 0; + rate_sim_time = 0; + for (reaction_step=1; reaction_step <= count_steps; reaction_step++) { + sprintf(token,"Reaction step %d.", reaction_step); + if (reaction_step > 1 && incremental_reactions == FALSE) { + copy_use(-2); + } + set_initial_moles(-2); + dup_print(token, FALSE); +/* + * Determine time step for kinetics + */ + kin_time = 0.0; + if ( use.kinetics_in == TRUE) { + kinetics_ptr = kinetics_bsearch(-2, &m); + if (incremental_reactions == FALSE) { + if (kinetics_ptr->count_steps > 0) { + if (reaction_step > kinetics_ptr->count_steps) { + kin_time = kinetics_ptr->steps[kinetics_ptr->count_steps - 1]; + } else { + kin_time = kinetics_ptr->steps[reaction_step - 1]; + } + } else if (kinetics_ptr->count_steps < 0) { + if (reaction_step > -kinetics_ptr->count_steps) { + kin_time = kinetics_ptr->steps[0]; + } else { + kin_time = reaction_step * kinetics_ptr->steps[0] / ( (LDBLE) (-kinetics_ptr->count_steps)); + } + } + } else { + /* incremental reactions */ + if (kinetics_ptr->count_steps > 0) { + if (reaction_step > kinetics_ptr->count_steps) { + kin_time = kinetics_ptr->steps[kinetics_ptr->count_steps - 1]; + } else { + kin_time = kinetics_ptr->steps[reaction_step - 1]; + } + } else if (kinetics_ptr->count_steps < 0) { + if (reaction_step > -kinetics_ptr->count_steps) { + kin_time = 0; + } else { + kin_time = kinetics_ptr->steps[0] / ( (LDBLE) (-kinetics_ptr->count_steps)); + } + } + } + } + if (incremental_reactions == FALSE || + (incremental_reactions == TRUE && reaction_step == 1)) { + use_mix = TRUE; + } else { + use_mix = FALSE; + } +/* + * Run reaction step + */ + run_reactions(-2, kin_time, use_mix, 1.0); + if (incremental_reactions == TRUE) { + rate_sim_time_start += kin_time; + rate_sim_time = rate_sim_time_start; + } else { + rate_sim_time = kin_time; + } + if (state != ADVECTION) { + punch_all(); + print_all(); + } + /* saves back into -2 */ + if (reaction_step < count_steps) { + saver(); + } + } +/* + * save end of reaction + */ + memcpy(&save, &save_data, sizeof(struct save)); + if (use.kinetics_in == TRUE) { + kinetics_duplicate(-2, use.n_kinetics_user); + } + saver(); + + /* free_model_allocs(); */ + /* last_model.force_prep = TRUE; */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int saver(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save results of calcuations (data in variables with _x, + * in unknown structure x, in master, or s) into structure + * arrays. Structure "save" has info on whether to save + * data for each entity (solution, ex, surf, pp, gas, or s_s). + * Initial calculation may be saved into multiple "n_user" + * slots. + */ + int i, n; + char token[MAX_LENGTH]; + + if (save.solution == TRUE) { + sprintf(token, "Solution after simulation %d.", simulation); + description_x = (char *) free_check_null(description_x); + description_x = string_duplicate(token); + n = save.n_solution_user; + xsolution_save(n); + for(i = save.n_solution_user + 1; i <= save.n_solution_user_end; i++) { + solution_duplicate(n, i); + } + } + if (save.pp_assemblage == TRUE) { + n = save.n_pp_assemblage_user; + xpp_assemblage_save(n); + for(i = save.n_pp_assemblage_user + 1; i <= save.n_pp_assemblage_user_end; i++) { + pp_assemblage_duplicate(n, i); + } + } + if (save.exchange == TRUE) { + n = save.n_exchange_user; + xexchange_save(n); + for(i = save.n_exchange_user + 1; i <= save.n_exchange_user_end; i++) { + exchange_duplicate(n, i); + } + } + if (save.surface == TRUE) { + n = save.n_surface_user; + xsurface_save(n); + for(i = save.n_surface_user + 1; i <= save.n_surface_user_end; i++) { + surface_duplicate(n, i); + } + } + if (save.gas_phase == TRUE) { + n = save.n_gas_phase_user; + xgas_save(n); + for(i = save.n_gas_phase_user + 1; i <= save.n_gas_phase_user_end; i++) { + gas_phase_duplicate(n, i); + } + } + if (save.s_s_assemblage == TRUE) { + n = save.n_s_s_assemblage_user; + xs_s_assemblage_save(n); + for(i = save.n_s_s_assemblage_user + 1; i <= save.n_s_s_assemblage_user_end; i++) { + s_s_assemblage_duplicate(n, i); + } + } + if (save.kinetics == TRUE && use.kinetics_in == TRUE && use.kinetics_ptr != NULL) { + n = use.kinetics_ptr->n_user; + for(i = save.n_kinetics_user; i <= save.n_kinetics_user_end; i++) { + kinetics_duplicate(n, i); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int xexchange_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save exchanger assemblage into structure exchange with user + * number n_user. + */ + int i, j, n; + char token[MAX_LENGTH]; + int count_comps; + struct exchange temp_exchange, *exchange_ptr; + LDBLE charge; + if (use.exchange_ptr == NULL) return(OK); +/* + * Store data for structure exchange + */ + memcpy(&temp_exchange, use.exchange_ptr, sizeof(struct exchange)); + temp_exchange.n_user = n_user; + temp_exchange.n_user_end = n_user; + temp_exchange.new_def = FALSE; + sprintf(token, "Exchange assemblage after simulation %d.", simulation); + temp_exchange.description = string_duplicate(token); + temp_exchange.solution_equilibria = FALSE; + temp_exchange.n_solution = -2; + temp_exchange.count_comps = 0; +/* + * Count exchange components and allocate space + */ + count_comps = 0; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == EXCH) count_comps++; + } + temp_exchange.comps = (struct exch_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct exch_comp)); + if (temp_exchange.comps == NULL) malloc_error(); + temp_exchange.count_comps = count_comps; +/* + * Write exch_comp structure for each exchange component + */ + count_comps = 0; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == EXCH) { + memcpy(&temp_exchange.comps[count_comps], x[i]->exch_comp, sizeof(struct exch_comp)); + temp_exchange.comps[count_comps].master = x[i]->master[0]; + temp_exchange.comps[count_comps].la = x[i]->master[0]->s->la; + temp_exchange.comps[count_comps].formula_totals = elt_list_dup(x[i]->exch_comp->formula_totals); + temp_exchange.comps[count_comps].moles = 0.; +/* + * Save element concentrations on exchanger + */ + count_elts = 0; + paren_count = 0; + charge = 0.0; + for (j=0; j < count_species_list; j++) { + if (species_list[j].master_s == x[i]->master[0]->s) { + add_elt_list(species_list[j].s->next_elt, species_list[j].s->moles); + charge += species_list[j].s->moles * species_list[j].s->z; + } + } +/* + * Keep exchanger related to phase even if none currently in solution + */ + if (x[i]->exch_comp->phase_name != NULL && count_elts == 0) { + add_elt_list(x[i]->master[0]->s->next_elt, 1e-20); + } +/* + * Store list + */ + temp_exchange.comps[count_comps].charge_balance = charge; + temp_exchange.comps[count_comps].totals = elt_list_save(); +/* debug + output_msg(OUTPUT_MESSAGE, "Exchange charge_balance: %e\n", charge); + */ + /* update unknown pointer */ + x[i]->exch_comp = &(temp_exchange.comps[count_comps]); + count_comps++; + } + } +/* + * Finish up + */ + exchange_ptr = exchange_bsearch(n_user, &n); + if (exchange_ptr == NULL) { + n = count_exchange++; + space ((void **) ((void *) &exchange), count_exchange, &max_exchange, sizeof(struct exchange)); + } else { + exchange_free(&exchange[n]); + } + memcpy(&exchange[n], &temp_exchange, sizeof(struct exchange)); + /* sort only if necessary */ + if (n == count_exchange - 1 && count_exchange > 1) { + if (exchange[n].n_user < exchange[n-1].n_user) { + qsort (exchange, + (size_t) count_exchange, + (size_t) sizeof (struct exchange), + exchange_compare); + } + } + use.exchange_ptr = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int xgas_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save gas composition into structure gas_phase with user + * number n_user. + */ + int count_comps, n, i; + struct gas_phase temp_gas_phase, *gas_phase_ptr; + char token[MAX_LENGTH]; + + if (use.gas_phase_ptr == NULL) return(OK); +/* + * Count gases + */ + count_comps = use.gas_phase_ptr->count_comps; +/* + * Malloc space and copy + */ + temp_gas_phase.comps = (struct gas_comp *) PHRQ_malloc( (size_t) count_comps * sizeof(struct gas_comp)); + if (temp_gas_phase.comps == NULL) malloc_error(); + memcpy( (void *) temp_gas_phase.comps, (void *) use.gas_phase_ptr->comps, (size_t) count_comps * sizeof(struct gas_comp) ); +/* + * Store in gas_phase + */ + + temp_gas_phase.n_user = n_user; + temp_gas_phase.n_user_end = n_user; + sprintf(token, "Gas phase after simulation %d.", simulation); + temp_gas_phase.description = string_duplicate(token); + temp_gas_phase.new_def = FALSE; + temp_gas_phase.solution_equilibria = FALSE; + temp_gas_phase.n_solution = -99; + temp_gas_phase.type = use.gas_phase_ptr->type; + temp_gas_phase.total_p = use.gas_phase_ptr->total_p; + temp_gas_phase.total_moles = use.gas_phase_ptr->total_moles; + temp_gas_phase.volume = use.gas_phase_ptr->volume; + temp_gas_phase.temperature = use.gas_phase_ptr->temperature; + temp_gas_phase.count_comps = count_comps; +/* + * Update amounts + */ + for (i = 0; i < count_comps; i++) { + temp_gas_phase.comps[i].moles = use.gas_phase_ptr->comps[i].phase->moles_x; + } +/* + * Finish up + */ + gas_phase_ptr = gas_phase_bsearch(n_user, &n); + if (gas_phase_ptr == NULL) { + n = count_gas_phase++; + space ((void **) ((void *) &gas_phase), count_gas_phase, &max_gas_phase, sizeof(struct gas_phase)); + } else { + gas_phase_free(&gas_phase[n]); + } + memcpy(&gas_phase[n], &temp_gas_phase, sizeof(struct gas_phase)); + + /* update unknown pointer */ + if (gas_unknown != NULL) { + gas_unknown->gas_phase = &(gas_phase[n]); + } + /* sort only if necessary */ + if (n == count_gas_phase - 1 && count_gas_phase > 1) { + if (gas_phase[n].n_user < gas_phase[n-1].n_user) { + qsort (gas_phase, + (size_t) count_gas_phase, + (size_t) sizeof (struct gas_phase), + gas_phase_compare); + } + } + use.gas_phase_ptr = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int xs_s_assemblage_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save s_s_assemblage composition into structure s_s_assemblage with user + * number n_user. + */ + int i, j, n; + int count_comps, count_s_s; + struct s_s_assemblage temp_s_s_assemblage, *s_s_assemblage_ptr; + char token[MAX_LENGTH]; + + if (use.s_s_assemblage_ptr == NULL) return(OK); +/* + * Set s_s_assemblage + */ + temp_s_s_assemblage.n_user = n_user; + temp_s_s_assemblage.n_user_end = n_user; + sprintf(token, "Solid solution assemblage after simulation %d.", simulation); + temp_s_s_assemblage.description = string_duplicate(token); + temp_s_s_assemblage.new_def = FALSE; +#ifdef SKIP + temp_s_s_assemblage.type = use.s_s_assemblage_ptr->type; + temp_s_s_assemblage.solution_equilibria = FALSE; + temp_s_s_assemblage.n_solution = -99; +#endif + count_s_s = use.s_s_assemblage_ptr->count_s_s; + temp_s_s_assemblage.count_s_s = count_s_s; +/* + * Malloc space for solid solutions + */ + /* s_s_assemblage->s_s */ + temp_s_s_assemblage.s_s = (struct s_s *) PHRQ_malloc( (size_t) count_s_s * sizeof(struct s_s)); + if (temp_s_s_assemblage.s_s == NULL) malloc_error(); + for (i = 0; i < count_s_s; i++) { + memcpy(&(temp_s_s_assemblage.s_s[i]), &(use.s_s_assemblage_ptr->s_s[i]), sizeof(struct s_s)); + /* + * Malloc space for solid soution components + */ + count_comps = use.s_s_assemblage_ptr->s_s[i].count_comps; + temp_s_s_assemblage.s_s[i].comps = (struct s_s_comp *) PHRQ_malloc( (size_t) count_comps * sizeof(struct s_s_comp)); + if (temp_s_s_assemblage.s_s[i].comps == NULL) malloc_error(); + memcpy( (void *) temp_s_s_assemblage.s_s[i].comps, (void *) use.s_s_assemblage_ptr->s_s[i].comps, (size_t) count_comps * sizeof(struct s_s_comp) ); + + /* set initial moles for quick setup*/ + for (j = 0; j < count_comps; j++) { + temp_s_s_assemblage.s_s[i].comps[j].initial_moles = temp_s_s_assemblage.s_s[i].comps[j].moles; + } + } +/* + * Finish up + */ + s_s_assemblage_ptr = s_s_assemblage_bsearch(n_user, &n); + if (s_s_assemblage_ptr == NULL) { + space ((void **) ((void *) &s_s_assemblage), count_s_s_assemblage, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + n = count_s_s_assemblage++; + } else { + s_s_assemblage_free(&s_s_assemblage[n]); + } + memcpy(&s_s_assemblage[n], &temp_s_s_assemblage, sizeof(struct s_s_assemblage)); + /* sort only if necessary */ + if (n == count_s_s_assemblage - 1 && count_s_s_assemblage > 1) { + if (s_s_assemblage[n].n_user < s_s_assemblage[n-1].n_user) { + qsort (s_s_assemblage, + (size_t) count_s_s_assemblage, + (size_t) sizeof (struct s_s_assemblage), + s_s_assemblage_compare); + } + } + use.s_s_assemblage_ptr = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int xpp_assemblage_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save pure_phase assemblage into structure pp_assemblage with user + * number n_user. + */ + int count_comps, n, j, i; + struct pp_assemblage temp_pp_assemblage, *pp_assemblage_ptr; + char token[MAX_LENGTH]; + + if (use.pp_assemblage_ptr == NULL) return(OK); +/* + * Count pure phases + */ + count_comps = use.pp_assemblage_ptr->count_comps; + + temp_pp_assemblage.n_user = n_user; + temp_pp_assemblage.n_user_end = n_user; + sprintf(token, "Pure-phase assemblage after simulation %d.", simulation); + temp_pp_assemblage.description = string_duplicate(token); + temp_pp_assemblage.new_def = FALSE; + temp_pp_assemblage.count_comps = count_comps; + temp_pp_assemblage.next_elt = elt_list_dup(use.pp_assemblage_ptr->next_elt); +/* + * Malloc space and copy pure phase data + */ + temp_pp_assemblage.pure_phases = (struct pure_phase *) PHRQ_malloc( (size_t) count_comps * sizeof(struct pure_phase)); + if (temp_pp_assemblage.pure_phases == NULL) malloc_error(); + memcpy( (void *) temp_pp_assemblage.pure_phases, (void *) use.pp_assemblage_ptr->pure_phases, (size_t) count_comps * sizeof(struct pure_phase) ); +/* + * Update amounts + */ + i = 0; + for (j=0; j < count_unknowns; j++) { + if (x[j]->type != PP) continue; + temp_pp_assemblage.pure_phases[i].moles = x[j]->moles; + temp_pp_assemblage.pure_phases[i].delta = 0.0; + + /* update unknown ptr, old may be freed later */ + x[j]->pure_phase = &(temp_pp_assemblage.pure_phases[i]); + i++; + } +/* + * Finish up + */ + pp_assemblage_ptr = pp_assemblage_bsearch(n_user, &n); + if (pp_assemblage_ptr == NULL) { + space ((void **) ((void *) &pp_assemblage), count_pp_assemblage, &max_pp_assemblage, sizeof(struct pp_assemblage)); + n = count_pp_assemblage++; + } else { + pp_assemblage_free(&pp_assemblage[n]); + } + memcpy(&pp_assemblage[n], &temp_pp_assemblage, sizeof(struct pp_assemblage)); + /* sort only if necessary */ + if (n == count_pp_assemblage - 1 && count_pp_assemblage > 1) { + if (pp_assemblage[n].n_user < pp_assemblage[n-1].n_user) { + qsort (pp_assemblage, + (size_t) count_pp_assemblage, + (size_t) sizeof (struct pp_assemblage), + pp_assemblage_compare); + } + } + use.pp_assemblage_ptr = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int xsolution_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save solution composition into structure solution with user number + * n_user. + * + * input: n_user is user solution number of target + */ + int i, j, n; + int count_mass_balance, count_master_activity; + int max_mass_balance, max_master_activity; + struct solution *solution_ptr; + struct master *master_i_ptr, *master_ptr; +/* + * Malloc space for solution data + */ + solution_ptr = solution_alloc(); + + max_mass_balance=MAX_MASS_BALANCE; + max_master_activity=MAX_MASS_BALANCE; + + solution_ptr->n_user = n_user; + solution_ptr->n_user_end = n_user; + solution_ptr->new_def = FALSE; + solution_ptr->description = string_duplicate(description_x); + solution_ptr->tc = tc_x; + solution_ptr->ph = ph_x; + solution_ptr->solution_pe = solution_pe_x; + solution_ptr->mu = mu_x; + solution_ptr->ah2o = ah2o_x; + solution_ptr->density = density_x; + solution_ptr->total_h = total_h_x; + solution_ptr->total_o = total_o_x; + solution_ptr->cb = cb_x; /* cb_x does not include surface charge sfter sum_species */ + /* does include surface charge after step */ + + solution_ptr->mass_water = mass_water_aq_x; + solution_ptr->total_alkalinity = total_alkalinity; + /*solution_ptr->total_co2 = total_co2;*/ + solution_ptr->units = moles_per_kilogram_string; +/* + * Copy pe data + */ + + pe_data_free(solution_ptr->pe); + /*solution_ptr->pe = pe_data_dup(pe_x); */ + solution_ptr->pe = pe_data_alloc(); + solution_ptr->default_pe = 0; + /* + * Add in minor isotopes if initial solution calculation + */ + if (initial_solution_isotopes == TRUE) { + for (i = 0; i < count_master_isotope; i++) { + if (master_isotope[i]->moles > 0) { + master_i_ptr = master_bsearch(master_isotope[i]->name); + master_ptr = master_isotope[i]->elt->master; + if (master_isotope[i]->minor_isotope == TRUE) { + master_i_ptr->total = master_isotope[i]->moles; + if (master_ptr->total > 0) { + master_i_ptr->s->la = master_ptr->s->la + log10(master_i_ptr->total / master_ptr->total); + } else { + master_i_ptr->s->la = master_ptr->s->la; + } + } else if (master_isotope[i]->minor_isotope == FALSE && master_ptr->s != s_hplus && master_ptr->s != s_h2o) { + if (master_ptr->s->secondary != NULL) { + master_ptr->s->secondary->total = master_isotope[i]->moles; + } else { + master_ptr->s->primary->total = master_isotope[i]->moles; + } + } + } + } + } +/* + * Copy totals data + */ + count_mass_balance = 0; + count_master_activity = 0; + for (i=0; i < count_master; i++) { + if (master[i]->s->type == EX || + master[i]->s->type == SURF || + master[i]->s->type == SURF_PSI) continue; + if (strcmp(master[i]->elt->name,"H") == 0 || + strcmp(master[i]->elt->name,"H(1)") == 0 || + strcmp(master[i]->elt->name,"O") == 0 || + strcmp(master[i]->elt->name,"O(-2)") == 0) continue; +/* + * Save list of log activities + */ + if (master[i]->in != FALSE) { + count_master_activity++; + } + } + solution_ptr->master_activity = (struct master_activity *) PHRQ_realloc(solution_ptr->master_activity, (size_t) (count_master_activity + 1)*sizeof(struct master_activity)); + solution_ptr->count_master_activity = count_master_activity; + count_master_activity = 0; + for (i=0; i < count_master; i++) { + if (master[i]->s->type == EX || + master[i]->s->type == SURF || + master[i]->s->type == SURF_PSI) continue; + if (strcmp(master[i]->elt->name,"H") == 0 || + strcmp(master[i]->elt->name,"H(1)") == 0 || + strcmp(master[i]->elt->name,"O") == 0 || + strcmp(master[i]->elt->name,"O(-2)") == 0) continue; +/* + * Save list of log activities + */ + if (master[i]->in != FALSE) { + solution_ptr->master_activity[count_master_activity].description = master[i]->elt->name; + solution_ptr->master_activity[count_master_activity++].la = master[i]->s->la; + /* + if (count_master_activity + 2 >= max_master_activity) { + space ((void *) &(solution_ptr->master_activity), count_master_activity + 2, + &max_master_activity, sizeof (struct master_activity)); + } + */ + } + if (master[i]->total <= MIN_TOTAL) { + master[i]->total = 0.0; + master[i]->total_primary = 0.0; + continue; + } +/* if (master[i]->total <= 0.0) continue; */ +/* + * Save list of concentrations + */ + solution_ptr->totals[count_mass_balance].description = master[i]->elt->name; + solution_ptr->totals[count_mass_balance].input_conc = master[i]->total; + solution_ptr->totals[count_mass_balance].moles = master[i]->total; + solution_ptr->totals[count_mass_balance].units = solution_ptr->units; + solution_ptr->totals[count_mass_balance].equation_name = NULL; + solution_ptr->totals[count_mass_balance].n_pe = 0; + solution_ptr->totals[count_mass_balance].phase = NULL; + solution_ptr->totals[count_mass_balance].phase_si = 0.0; + solution_ptr->totals[count_mass_balance].as = NULL; + solution_ptr->totals[count_mass_balance].gfw = 0.0; + count_mass_balance++; +/* + * Make space + */ + if (count_mass_balance + 2 >= max_mass_balance) { + space ((void **) &(solution_ptr->totals), count_mass_balance + 2, + &max_mass_balance, sizeof (struct conc)); + } + } + if (pitzer_model == TRUE) { + i = 0; + for (j = 0; j < count_s; j++) { + if (s[j]->lg != 0.0) i++; + } + solution_ptr->species_gamma = (struct master_activity *) PHRQ_realloc(solution_ptr->species_gamma, (size_t) (i * sizeof(struct master_activity))); + i = 0; + for (j= 0; j < count_s; j++) { + if (s[j]->lg != 0.0) { + solution_ptr->species_gamma[i].la = s[j]->lg; + solution_ptr->species_gamma[i].description = s[j]->name; + i++; + } + } + solution_ptr->count_species_gamma = i; + } else { + solution_ptr->species_gamma = NULL; + solution_ptr->count_species_gamma = 0; + } +/* + * Mark end of totals + */ + solution_ptr->totals[count_mass_balance].description = NULL; + count_mass_balance++; + solution_ptr->master_activity[count_master_activity].description = NULL; + count_master_activity++; + solution_ptr->totals = (struct conc *) PHRQ_realloc(solution_ptr->totals, (size_t) count_mass_balance * sizeof(struct conc)); + if (solution_ptr->totals == NULL) malloc_error(); + solution_ptr->master_activity = (struct master_activity *) PHRQ_realloc(solution_ptr->master_activity, (size_t) count_master_activity * sizeof(struct master_activity)); + if (solution_ptr->master_activity == NULL) malloc_error(); + solution_ptr->count_master_activity = count_master_activity; +/* + * Save isotope data + */ + if (count_isotopes_x > 0 ) { + solution_ptr->count_isotopes = count_isotopes_x; + solution_ptr->isotopes = (struct isotope *) PHRQ_realloc(solution_ptr->isotopes, (size_t) count_isotopes_x * sizeof(struct isotope)); + if (solution_ptr->isotopes == NULL) malloc_error(); + memcpy(solution_ptr->isotopes, isotopes_x, (size_t) count_isotopes_x * sizeof(struct isotope)); + for (i = 0; i < count_isotopes_x; i++) { + solution_ptr->isotopes[i].total = solution_ptr->isotopes[i].master->total; + if (solution_ptr->isotopes[i].master == s_hplus->secondary) { + solution_ptr->isotopes[i].total = 2 * mass_water_aq_x / gfw_water; + } + if (solution_ptr->isotopes[i].master == s_h2o->secondary) { + solution_ptr->isotopes[i].total = mass_water_aq_x / gfw_water; + } + } + } else { + solution_ptr->count_isotopes = 0; + solution_ptr->isotopes = (struct isotope *) free_check_null(solution_ptr->isotopes); + solution_ptr->isotopes = NULL; + } +/* + * Save solution in solution + */ + if (solution_bsearch (n_user, &n, FALSE) != NULL) { + solution_free(solution[n]); + } else { + n = count_solution++; + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, sizeof (struct solution *) ); + } + } + solution[n] = solution_ptr; + /* sort only if necessary */ + if (count_solution > 1 && (solution[count_solution -1]->n_user < solution[count_solution - 2]->n_user)) { + solution_sort(); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int xsurface_save(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save surface data into structure surface with user + * number n_user. + */ + int i, j, n, last_charge; + int count_comps, count_charge; + char token[MAX_LENGTH]; + struct surface temp_surface, *surface_ptr; + LDBLE charge; + + if (use.surface_ptr == NULL) return(OK); +/* + * Store data for structure surface + */ + memcpy(&temp_surface, use.surface_ptr, sizeof(struct surface)); + temp_surface.n_user = n_user; + temp_surface.n_user_end = n_user; + temp_surface.new_def = FALSE; + temp_surface.diffuse_layer = diffuse_layer_x; + sprintf(token, "Surface assemblage after simulation %d.", simulation); + temp_surface.description = string_duplicate(token); + temp_surface.solution_equilibria = FALSE; + temp_surface.n_solution = -10; +/* + * Allocate space to pointer comps + */ + + count_comps = use.surface_ptr->count_comps; + count_charge = use.surface_ptr->count_charge; + temp_surface.count_comps = count_comps; + temp_surface.comps = (struct surface_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct surface_comp)); + if (temp_surface.comps == NULL) malloc_error(); + if (temp_surface.edl == FALSE) { + temp_surface.charge = NULL; + temp_surface.count_charge = 0; + } else { + temp_surface.count_charge = count_charge; + temp_surface.charge = (struct surface_charge *) PHRQ_malloc((size_t) (count_charge) * sizeof (struct surface_charge)); + if (temp_surface.charge == NULL) malloc_error(); + } +/* + * Write surface_comp structure for each surf component into comps_ptr + */ + count_comps = 0; + count_charge = 0; + /* + * Initial entry of surface sites is random + * Charge balance numbering follows the initial entry + * Surface sites are then sorted alphabetically + * Now when we save, the site order differs from the charge order + * last_charge sets up logic to renumber charge balance equations. + */ + last_charge = -1; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == SURFACE) { + memcpy(&temp_surface.comps[count_comps], x[i]->surface_comp, sizeof(struct surface_comp)); + + temp_surface.comps[count_comps].master = x[i]->master[0]; + temp_surface.comps[count_comps].la = x[i]->master[0]->s->la; + /* temp_surface.comps[count_comps].formula = NULL; */ + temp_surface.comps[count_comps].moles = 0.; + if (x[i]->surface_comp->charge == last_charge) { + temp_surface.comps[count_comps].charge = count_charge - 1; + } else { + temp_surface.comps[count_comps].charge = count_charge; + } + last_charge = x[i]->surface_comp->charge; +/* + * Save element concentrations on surface + */ + count_elts = 0; + paren_count = 0; + charge = 0.0; + for (j=0; j < count_species_list; j++) { + if (species_list[j].master_s == x[i]->master[0]->s) { + add_elt_list(species_list[j].s->next_elt, species_list[j].s->moles); + charge += species_list[j].s->moles * + species_list[j].s->z; + } + } + temp_surface.comps[count_comps].totals = elt_list_save(); + temp_surface.comps[count_comps].cb = charge; + + /* update unknown pointer */ + x[i]->surface_comp = &(temp_surface.comps[count_comps]); + count_comps++; + } else if (x[i]->type == SURFACE_CB) { + memcpy(&temp_surface.charge[count_charge], x[i]->surface_charge, sizeof(struct surface_charge)); + temp_surface.charge[count_charge].charge_balance = x[i]->f; + temp_surface.charge[count_charge].mass_water = x[i]->surface_charge->mass_water; + temp_surface.charge[count_charge].diffuse_layer_totals = NULL; + temp_surface.charge[count_charge].count_g = 0; + temp_surface.charge[count_charge].g = NULL; +/* + * Added code to save g + */ +/* + if (x[i]->surface_charge->count_g > 0) { + temp_surface.charge[count_charge].count_g = x[i]->surface_charge->count_g; + temp_surface.charge[count_charge].g = (struct surface_diff_layer *) PHRQ_malloc((size_t) x[i]->surface_charge->count_g * sizeof(struct surface_diff_layer)); + if (temp_surface.charge[count_charge].g == NULL) malloc_error(); + memcpy(temp_surface.charge[count_charge].g, x[i]->surface_charge->g, (size_t) x[i]->surface_charge->count_g * sizeof(struct surface_diff_layer)); + } +*/ + temp_surface.charge[count_charge].psi_master = x[i]->master[0]; + temp_surface.charge[count_charge].la_psi = x[i]->master[0]->s->la; +/* + * Store moles from diffuse_layer + */ + if (diffuse_layer_x == TRUE) { + sum_diffuse_layer(x[i]->surface_charge); + temp_surface.charge[count_charge].diffuse_layer_totals = elt_list_save(); + } + + /* update unknown pointer */ + x[i]->surface_charge = &(temp_surface.charge[count_charge]); + x[i]->surface_comp = x[i - 1]->surface_comp; + + count_charge++; + } + } +/* + * Finish up + */ + surface_ptr = surface_bsearch(n_user, &n); + if (surface_ptr == NULL) { + n = count_surface++; + space ((void **) ((void *) &surface), count_surface, &max_surface, sizeof(struct surface)); + } else { + surface_free(&surface[n]); + } + memcpy(&surface[n], &temp_surface, sizeof(struct surface)); + if (n == count_surface - 1 && count_surface > 1) { + if (surface[n].n_user < surface[n-1].n_user) { + qsort (surface, + (size_t) count_surface, + (size_t) sizeof (struct surface), + surface_compare); + } + } + use.surface_ptr = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +FILE *file_open (char *query, char *default_name, const char *status, int batch) +/* ---------------------------------------------------------------------- */ +{ + char name[MAX_LENGTH], answer[MAX_LENGTH]; + FILE *new_file; + int l; + + for (;;) { +/* + * Get file name + */ + strcpy(name, default_name); + if (batch == FALSE) { + output_msg(OUTPUT_SCREEN,"%s\n", query); + if (default_name[0] != '\0') { + output_msg(OUTPUT_SCREEN,"Default: %s\n", default_name); + } + fgets(name, MAX_LENGTH, stdin); + l = strlen(name); + name[l-1]='\0'; + if (name[0] == '\0') { + strcpy(name, default_name); + } + } +/* + * Open existing file to read + */ + if (status[0] == 'r') { + if ((new_file = fopen(name, "r")) == NULL) { + sprintf(error_string, "Can't open file, %s.", name); + output_msg(OUTPUT_SCREEN,"\nERROR: %s\n", error_string); + output_fflush(OUTPUT_SCREEN); + batch = FALSE; + continue; + } + break; +/* + * Open file to write, no check + */ + } else if (status[0] == 'w') { + if ((new_file = fopen(name, "w")) == NULL) { + sprintf(error_string, "Error opening file, %s.", name); + output_msg(OUTPUT_SCREEN,"\nERROR: %s\n", error_string); + output_fflush(OUTPUT_SCREEN); + batch = FALSE; + continue; + } + break; +/* + * Open file to write, check for existence + */ + } else if (status[0] == 'c') { + for (;;) { + if ((new_file = fopen(name, "r")) != NULL) { + fclose(new_file); + output_msg(OUTPUT_SCREEN,"Warning: File already exists, %s.\n" + "Enter new file name or to overwrite:", name); + fgets(answer, MAX_LENGTH, stdin); + l = strlen(answer); + answer[l-1]='\0'; + if (answer != '\0') { + strcpy(name, answer); + continue; + } + } + break; + } + if ((new_file = fopen(name, "w")) == NULL) { + sprintf(error_string, "Error opening file, %s.", name) ; + output_msg(OUTPUT_SCREEN,"\nERROR: %s\n", error_string); + output_fflush(OUTPUT_SCREEN); + batch = FALSE; + continue; + } + break; + } + } + strncpy(default_name, name, MAX_LENGTH); + return(new_file); +} +/* ---------------------------------------------------------------------- */ +int copy_use (int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Find mixture + */ + if (use.mix_in == TRUE) { + mix_duplicate(use.n_mix_user, i); + } +/* + * Find solution + */ + if (use.solution_in == TRUE) { + solution_duplicate(use.n_solution_user, i); + } +/* + * Always save solution to i, mixing or not + */ + save.solution = TRUE; + save.n_solution_user = i; + save.n_solution_user_end = i; +/* + * Find pure phase assemblage + */ + if (use.pp_assemblage_in == TRUE) { + pp_assemblage_duplicate(use.n_pp_assemblage_user, i); + save.pp_assemblage = TRUE; + save.n_pp_assemblage_user = i; + save.n_pp_assemblage_user_end = i; + } else { + save.pp_assemblage = FALSE; + } +/* + * Find irrev reaction + */ + if (use.irrev_in == TRUE) { + irrev_duplicate(use.n_irrev_user, i); + save.irrev = TRUE; + save.n_irrev_user = i; + save.n_irrev_user_end = i; + } else { + save.irrev = FALSE; + } +/* + * Find exchange + */ + if (use.exchange_in == TRUE) { + exchange_duplicate(use.n_exchange_user, i); + save.exchange = TRUE; + save.n_exchange_user = i; + save.n_exchange_user_end = i; + } else { + save.exchange = FALSE; + } +/* + * Find kinetics + */ + if (use.kinetics_in == TRUE) { + kinetics_duplicate(use.n_kinetics_user, i); + save.kinetics = TRUE; + save.n_kinetics_user = i; + save.n_kinetics_user_end = i; + } else { + save.kinetics = FALSE; + } +/* + * Find surface + */ + diffuse_layer_x = FALSE; + if (use.surface_in == TRUE) { + surface_duplicate(use.n_surface_user, i); + save.surface = TRUE; + save.n_surface_user = i; + save.n_surface_user_end = i; + } else { + save.surface = FALSE; + } +/* + * Find temperature + */ + if (use.temperature_in == TRUE) { + temperature_duplicate(use.n_temperature_user, i); + } +/* + * Find gas + */ + if (use.gas_phase_in == TRUE) { + gas_phase_duplicate(use.n_gas_phase_user, i); + save.gas_phase = TRUE; + save.n_gas_phase_user = i; + save.n_gas_phase_user_end = i; + } else { + save.gas_phase = FALSE; + } +/* + * Find solid solution + */ + if (use.s_s_assemblage_in == TRUE) { + s_s_assemblage_duplicate(use.n_s_s_assemblage_user, i); + save.s_s_assemblage = TRUE; + save.n_s_s_assemblage_user = i; + save.n_s_s_assemblage_user_end = i; + } else { + save.s_s_assemblage = FALSE; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int step_save_exch(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save solution composition into structure solution with user number + * n_user. + * + * input: n_user is user solution number of target + */ + int i, j, k, n; + int found; + struct exchange *exchange_ptr; +/* + * Malloc space for solution data + */ + if (use.exchange_ptr == NULL) return(OK); + exchange_duplicate(use.exchange_ptr->n_user, n_user); + exchange_ptr = exchange_bsearch(n_user, &n); + for (i=0; i < count_master; i++) { + if (master[i]->s->type != EX) continue; + found = FALSE; + for (j = 0; j < exchange_ptr->count_comps; j++) { + for (k = 0; exchange_ptr->comps[j].totals[k].elt != NULL; k++ ) { + if(exchange_ptr->comps[j].totals[k].elt == master[i]->elt) { + if (found == FALSE) { + found = TRUE; + if (master[i]->total <= MIN_TOTAL) { + exchange_ptr->comps[j].totals[k].coef = MIN_TOTAL; + } else { + exchange_ptr->comps[j].totals[k].coef = master[i]->total; + } + break; + } else { + exchange_ptr->comps[j].totals[k].coef = 0; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int step_save_surf(int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save surface for intermediate calculation + * Amt of surface may have changed due to reaction or surface related + * to kinetic reactant. + * + * input: n_user is user solution number of target + */ + int i, j, k, n, m; + struct surface *surface_ptr; +/* + * Malloc space for solution data + */ + if (use.surface_ptr == NULL) return(OK); + surface_duplicate(use.surface_ptr->n_user, n_user); + surface_ptr = surface_bsearch(n_user, &n); + for (i=0; i < count_master; i++) { + if (master[i]->s->type != SURF) continue; + for (j = 0; j < surface_ptr->count_comps; j++) { + for (k = 0; surface_ptr->comps[j].totals[k].elt != NULL; k++ ) { + if(surface_ptr->comps[j].totals[k].elt == master[i]->elt) { + if (master[i]->total <= MIN_TOTAL) { + surface_ptr->comps[j].totals[k].coef = MIN_TOTAL; + } else { + surface_ptr->comps[j].totals[k].coef = master[i]->total; + } + break; + } + } + } + } + /* + * Update grams + */ + if (surface_ptr->edl == TRUE && surface_ptr->related_rate == TRUE && use.kinetics_ptr != NULL) { + for (j = 0; j < surface_ptr->count_comps; j++) { + if (surface_ptr->comps[j].rate_name != NULL) { + for (m = 0; m < use.kinetics_ptr->count_comps; m++) { + if (strcmp_nocase(use.kinetics_ptr->comps[m].rate_name, surface_ptr->comps[j].rate_name) != 0) continue; + surface_ptr->charge[surface_ptr->comps[j].charge].grams = use.kinetics_ptr->comps[m].m; + break; + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int copy_entities(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, n, return_value; + return_value = OK; + if (copy_solution.count > 0) { + for (j = 0; j < copy_solution.count; j++) { + if (solution_bsearch(copy_solution.n_user[j], &n, FALSE) != NULL) { + for (i = copy_solution.start[j]; i <= copy_solution.end[j]; i++) { + if (i == copy_solution.n_user[j]) continue; + solution_duplicate(copy_solution.n_user[j], i); + } + } else { + warning_msg("SOLUTION to copy not found."); + return_value = ERROR; + } + } + } + if (copy_pp_assemblage.count > 0) { + for (j = 0; j < copy_pp_assemblage.count; j++) { + if (pp_assemblage_bsearch(copy_pp_assemblage.n_user[j], &n) != NULL) { + for (i = copy_pp_assemblage.start[j]; i <= copy_pp_assemblage.end[j]; i++) { + if (i == copy_pp_assemblage.n_user[j]) continue; + pp_assemblage_duplicate(copy_pp_assemblage.n_user[j], i); + } + } else { + warning_msg("EQUILIBRIUM_PHASES to copy not found."); + return_value = ERROR; + } + } + } + if (copy_irrev.count > 0) { + for (j = 0; j < copy_irrev.count; j++) { + if (irrev_bsearch(copy_irrev.n_user[j], &n) != NULL) { + for (i = copy_irrev.start[j]; i <= copy_irrev.end[j]; i++) { + if (i == copy_irrev.n_user[j]) continue; + irrev_duplicate(copy_irrev.n_user[j], i); + } + } else { + warning_msg("REACTION to copy not found."); + return_value = ERROR; + } + } + } + if (copy_mix.count > 0) { + for (j = 0; j < copy_mix.count; j++) { + if (mix_bsearch(copy_mix.n_user[j], &n) != NULL) { + for (i = copy_mix.start[j]; i <= copy_mix.end[j]; i++) { + if (i == copy_mix.n_user[j]) continue; + mix_duplicate(copy_mix.n_user[j], i); + } + } else { + warning_msg("MIX to copy not found."); + return_value = ERROR; + } + } + } + if (copy_exchange.count > 0) { + for (j = 0; j < copy_exchange.count; j++) { + if (exchange_bsearch(copy_exchange.n_user[j], &n) != NULL) { + for (i = copy_exchange.start[j]; i <= copy_exchange.end[j]; i++) { + if (i == copy_exchange.n_user[j]) continue; + exchange_duplicate(copy_exchange.n_user[j], i); + } + } else { + warning_msg("EXCHANGE to copy not found."); + return_value = ERROR; + } + } + } + if (copy_surface.count > 0) { + for (j = 0; j < copy_surface.count; j++) { + if (surface_bsearch(copy_surface.n_user[j], &n) != NULL) { + for (i = copy_surface.start[j]; i <= copy_surface.end[j]; i++) { + if (i == copy_surface.n_user[j]) continue; + surface_duplicate(copy_surface.n_user[j], i); + } + } else { + warning_msg("SURFACE to copy not found."); + return_value = ERROR; + } + } + } + if (copy_temperature.count > 0) { + for (j = 0; j < copy_temperature.count; j++) { + if (temperature_bsearch(copy_temperature.n_user[j], &n) != NULL) { + for (i = copy_temperature.start[j]; i <= copy_temperature.end[j]; i++) { + if (i == copy_temperature.n_user[j]) continue; + temperature_duplicate(copy_temperature.n_user[j], i); + } + } else { + warning_msg("TEMPERATURE to copy not found."); + return_value = ERROR; + } + } + } + if (copy_gas_phase.count > 0) { + for (j = 0; j < copy_gas_phase.count; j++) { + if (gas_phase_bsearch(copy_gas_phase.n_user[j], &n) != NULL) { + for (i = copy_gas_phase.start[j]; i <= copy_gas_phase.end[j]; i++) { + if (i == copy_gas_phase.n_user[j]) continue; + gas_phase_duplicate(copy_gas_phase.n_user[j], i); + } + } else { + warning_msg("GAS_PHASE to copy not found."); + return_value = ERROR; + } + } + } + if (copy_kinetics.count > 0) { + for (j = 0; j < copy_kinetics.count; j++) { + if (kinetics_bsearch(copy_kinetics.n_user[j], &n) != NULL) { + for (i = copy_kinetics.start[j]; i <= copy_kinetics.end[j]; i++) { + if (i == copy_kinetics.n_user[j]) continue; + kinetics_duplicate(copy_kinetics.n_user[j], i); + } + } else { + warning_msg("KINETICS to copy not found."); + return_value = ERROR; + } + } + } + if (copy_s_s_assemblage.count > 0) { + for (j = 0; j < copy_s_s_assemblage.count; j++) { + if (s_s_assemblage_bsearch(copy_s_s_assemblage.n_user[j], &n) != NULL) { + for (i = copy_s_s_assemblage.start[j]; i <= copy_s_s_assemblage.end[j]; i++) { + if (i == copy_s_s_assemblage.n_user[j]) continue; + s_s_assemblage_duplicate(copy_s_s_assemblage.n_user[j], i); + } + } else { + warning_msg("SOLID_SOLUTIONS to copy not found."); + return_value = ERROR; + } + } + } + copy_solution.count = 0; + copy_pp_assemblage.count = 0; + copy_exchange.count = 0; + copy_surface.count = 0; + copy_s_s_assemblage.count = 0; + copy_gas_phase.count = 0; + copy_kinetics.count = 0; + copy_mix.count = 0; + copy_irrev.count = 0; + copy_temperature.count = 0; + new_copy = FALSE; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_database(PFN_READ_CALLBACK pfn, void *cookie) +/* ---------------------------------------------------------------------- */ +{ + int errors; + simulation = 0; + +/* + * Prepare error handling + */ + errors = setjmp(mark); + if (errors != 0) { + return errors; + } + + set_read_callback(pfn, cookie, TRUE); + dup_print("Reading data base.", TRUE); + read_input(); + tidy_model(); + status(0, NULL); + return 0; +} +/* ---------------------------------------------------------------------- */ +int run_simulations(PFN_READ_CALLBACK pfn, void *cookie) +/* ---------------------------------------------------------------------- */ +{ + int errors; + char token[MAX_LENGTH]; + +/* + * Prepare error handling + */ + errors = setjmp(mark); + if (errors != 0) { + return errors; + } + + set_read_callback(pfn, cookie, FALSE); + +/* + * Read input data for simulation + */ + for (simulation = 1; ; simulation++) { + +#ifdef PHREEQ98 + AddSeries = !connect_simulations; +#endif + sprintf(token, "Reading input data for simulation %d.", simulation); + + output_msg(OUTPUT_GUI_ERROR, "\nSimulation %d\n", simulation); + + dup_print(token, TRUE); + if (read_input() == EOF) break; + + if (title_x != NULL) { + sprintf(token, "TITLE"); + dup_print(token, TRUE); + if (pr.headings == TRUE) output_msg(OUTPUT_MESSAGE,"%s\n\n", title_x); + } + tidy_model(); + test_classes(); + +#ifdef PHREEQ98 + if (!phreeq98_debug) { +#endif + +/* + * Calculate distribution of species for initial solutions + */ + if (new_solution) initial_solutions(TRUE); +/* + * Calculate distribution for exchangers + */ + if (new_exchange) initial_exchangers(TRUE); +/* + * Calculate distribution for surfaces + */ + if (new_surface) initial_surfaces(TRUE); +/* + * Calculate initial gas composition + */ + if (new_gas_phase) initial_gas_phases(TRUE); +/* + * Calculate reactions + */ + reactions(); +/* + * Calculate inverse models + */ + inverse_models(); +/* + * Calculate advection + */ + if (use.advect_in == TRUE) { + dup_print ("Beginning of advection calculations.", TRUE); + advection(); + } +/* + * Calculate transport + */ + if (use.trans_in == TRUE) { + dup_print ("Beginning of transport calculations.", TRUE); + transport(); + } +/* + * Copy + */ + if (new_copy) copy_entities(); +/* + * End of simulation + */ + dup_print( "End of simulation.", TRUE); +#ifdef PHREEQ98 + } /* if (!phreeq98_debug) */ +#endif + #ifdef SKIP + +{ + int n; + SAX_StartSystem(); + for (n = 0; n < count_solution; ++n) + { + SAX_AddSolution(solution[n]); + } + SAX_EndSystem(); + SAX_UnpackSolutions(SAX_GetXMLStr(), SAX_GetXMLLength()); + } + #endif + + } + + + return 0; +} +/* ---------------------------------------------------------------------- */ +int do_initialize(void) +/* ---------------------------------------------------------------------- */ +{ + int errors; +/* + * Prepare error handling + */ + errors = setjmp(mark); + if (errors != 0) { + return errors; + } + + state = INITIALIZE; + initialize(); + + return 0; +} +/* ---------------------------------------------------------------------- */ +int do_status(void) +/* ---------------------------------------------------------------------- */ +{ + int errors; +/* + * Prepare error handling + */ + errors = setjmp(mark); + if (errors != 0) { + return errors; + } + + if (pr.status == TRUE) { +#if defined(PHREEQCI_GUI) + state = -1; + status(0, "\r\nDone."); +#else + status(0, "\nDone."); +#endif + output_msg(OUTPUT_SCREEN,"\n"); + output_msg(OUTPUT_SEND_MESSAGE,"\r\n"); + } + dup_print ("End of run.", TRUE); + output_msg(OUTPUT_SCREEN,"\nEnd of Run.\n"); + output_msg(OUTPUT_SEND_MESSAGE,"\r\nEnd of Run.\r\n"); + + return 0; +} diff --git a/model.cpp b/model.cpp new file mode 100644 index 00000000..6c0d19b4 --- /dev/null +++ b/model.cpp @@ -0,0 +1,3102 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: model.c 632 2005-11-08 17:59:00Z dlpark $"; + +static LDBLE s_s_root(LDBLE a0, LDBLE a1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq); +static LDBLE s_s_halve(LDBLE a0, LDBLE a1, LDBLE x0, LDBLE x1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq); +static LDBLE s_s_f(LDBLE xb, LDBLE a0, LDBLE a1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq); + +#ifdef SKIP +static int adjust_step_size(void); +#endif + +/*#define SLNQ*/ + +#ifdef SLNQ +static int add_trivial_eqns(int rows, int cols, LDBLE *matrix); +extern int slnq (int n, LDBLE *a, LDBLE *delta, int ncols, int print); +#endif + +static int calc_gas_pressures(void); +static int calc_s_s_fractions(void); +static int gammas (LDBLE mu); +static int initial_guesses(void); +static int revise_guesses(void); +static int s_s_binary(struct s_s *s_s_ptr); +static int s_s_ideal(struct s_s *s_s_ptr); + +static int remove_unstable_phases; +static int gas_in; + +LDBLE min_value = 1e-10; + + +/* ---------------------------------------------------------------------- */ +int model(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * model is called after the equations have been set up by prep + * and initial guesses have been made in set. + * + * Here is the outline of the calculation sequence: + * residuals--residuals are calculated, if small we are done + * sum_jacobian--jacobian is calculated + * ineq--inequality solver is called + * reset--estimates of unknowns revised, if changes are small solution + * has been found, usually convergence is found in residuals. + * gammas--new activity coefficients + * molalities--calculate molalities + * mb_sums--calculate mass-balance sums + * mb_gases--decide if gas_phase exists + * mb_s_s--decide if solid_solutions exists + * switch_bases--check to see if new basis species is needed + * reprep--rewrite equations with new basis species if needed + * revise_guesses--revise unknowns to get initial mole balance + * check_residuals--check convergence one last time + * sum_species--calculate sums of elements from species concentrations + * + * An additional pass through may be needed if unstable phases still exist + * in the phase assemblage. + */ + int kode, return_kode; + int r; + int count_infeasible, count_basis_change; + int debug_model_save; + int mass_water_switch_save; + if (svnid == NULL) fprintf(stderr," "); + +/* debug_model = TRUE; */ +/* debug_prep = TRUE; */ +/* debug_set = TRUE; */ + /* mass_water_switch == TRUE, mass of water is constant */ + if (pitzer_model == TRUE) return model_pz(); + mass_water_switch_save = mass_water_switch; + if (mass_water_switch_save == FALSE && delay_mass_water == TRUE) { + mass_water_switch = TRUE; + } + debug_model_save = debug_model; + pe_step_size_now = pe_step_size; + step_size_now = step_size; + status(0, NULL); + iterations=0; + count_basis_change = count_infeasible = 0; + stop_program = FALSE; + remove_unstable_phases = FALSE; + for (; ; ) { + mb_gases(); + mb_s_s(); + kode = 1; + while ( ( r = residuals() ) != CONVERGED || remove_unstable_phases == TRUE) { +#if defined(PHREEQCI_GUI) + if (WaitForSingleObject(g_hKill /*g_eventKill*/, 0) == WAIT_OBJECT_0) + { + error_msg("Execution canceled by user.", CONTINUE); + RaiseException(USER_CANCELED_RUN, 0, 0, NULL); + } +#endif + iterations++; + if (iterations > itmax - 1 && debug_model == FALSE && pr.logfile == TRUE) { + set_forward_output_to_log(TRUE); + debug_model = TRUE; + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nIteration %d\tStep_size = %f\n", + iterations, (double) step_size_now); + output_msg(OUTPUT_MESSAGE,"\t\tPe_step_size = %f\n\n", (double) pe_step_size_now); + } +/* + * Iterations exceeded + */ + if (iterations > itmax ) { + sprintf(error_string,"Maximum iterations exceeded, %d\n",itmax); + warning_msg(error_string); + stop_program = TRUE; + break; + } +/* + * Calculate jacobian + */ + jacobian_sums(); +/* + * Full matrix with pure phases + */ + if ( r == OK || remove_unstable_phases == TRUE) { + return_kode = ineq(kode); + if ( return_kode != OK ) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "Ineq had infeasible solution, " + "kode %d, iteration %d\n", + return_kode, iterations); + } + output_msg(OUTPUT_LOG, "Ineq had infeasible solution, " + "kode %d, iteration %d\n", return_kode, iterations); + count_infeasible++; + } + if ( return_kode == 2 ) { + ineq(0); + } + reset(); + } + gammas(mu_x); + if (molalities(FALSE) == ERROR) { + revise_guesses(); +/* adjust_step_size(); */ + } + if(use.surface_ptr != NULL && + use.surface_ptr->diffuse_layer == TRUE && + use.surface_ptr->related_phases == TRUE) + initial_surface_water(); + mb_sums(); + mb_gases(); + mb_s_s(); +/* + * Switch bases if necessary + */ + + if (switch_bases() == TRUE ) { + count_basis_change++; + reprep(); + gammas(mu_x); + molalities(TRUE); + if(use.surface_ptr != NULL && + use.surface_ptr->diffuse_layer == TRUE && + use.surface_ptr->related_phases == TRUE) + initial_surface_water(); + revise_guesses(); + mb_sums(); + mb_gases(); + mb_s_s(); + } +/* debug + species_list_sort(); + sum_species(); + print_species(); + print_exchange(); + print_surface(); + */ + if (stop_program == TRUE) { + break; + } + } +/* + * Check for stop_program + */ + + if (stop_program == TRUE) { + break; + } + if (check_residuals() == ERROR) { + stop_program = TRUE; + break; + } + if (remove_unstable_phases == FALSE && mass_water_switch_save == FALSE && + mass_water_switch == TRUE) { + output_msg(OUTPUT_LOG,"\nChanging water switch to FALSE. Iteration %d.\n", iterations); + mass_water_switch = FALSE; + continue; + } + if (remove_unstable_phases == FALSE) break; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nRemoving unstable phases. Iteration %d.\n", iterations); + } + output_msg(OUTPUT_LOG,"\nRemoving unstable phases. Iteration %d.\n", iterations); + } + output_msg(OUTPUT_LOG,"\nNumber of infeasible solutions: %d\n",count_infeasible); + output_msg(OUTPUT_LOG,"Number of basis changes: %d\n\n",count_basis_change); + output_msg(OUTPUT_LOG,"Number of iterations: %d\n\n", iterations); + debug_model = debug_model_save; + set_forward_output_to_log(FALSE); + if (stop_program == TRUE) { + return(ERROR); + } + return(OK); +} +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +int adjust_step_size(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Step sizes are cut down if overflow occurs in molalities + */ + pe_step_size_now -= (pe_step_size_now - 1.0) / 2.0; + step_size_now -= (step_size_now - 1.) / 2.0; + if (pe_step_size_now < 1.5) pe_step_size_now = 1.5; + if (step_size_now < 1.5) step_size_now = 1.5; + output_msg(OUTPUT_LOG,"\tNew step sizes: %f\t%f\t%d\n", + step_size_now, pe_step_size_now, iterations); + return(OK); +} +#endif +/* ---------------------------------------------------------------------- */ +int check_residuals(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks for convergence of all equations, prints any nonconvergence + * Sets variable remove_unstable_phases if a phase is present, + * but undersaturated (i.e. aragonite in calcite-saturated solution). + */ + int i, return_value; + LDBLE epsilon; +#ifdef SKIP + if (punch.high_precision == FALSE) + epsilon = 1e-8; + else + epsilon = 1.e-12; +#endif + epsilon = convergence_tolerance; + + return_value = OK; + if (stop_program == TRUE) { + warning_msg("The program has failed to converge to a numerical solution.\n\nThe following equations were not satisfied:"); + /*error_msg("The program has failed to converge to a numerical solution.\n\nThe following equations were not satisfied:", CONTINUE);*/ + } + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == MB || x[i]->type == ALK) { + if ( fabs(residual[i]) >= epsilon*x[i]->moles && x[i]->moles > MIN_TOTAL /* || stop_program == TRUE */) { +#ifdef SKIP + if ( fabs(residual[i]) >= epsilon*x[i]->moles /* || stop_program == TRUE */) { +#endif + sprintf(error_string,"%20s has not converged. Total: %e\tCalculated: " + "%e\tResidual: %e\n", x[i]->description, (double) x[i]->moles, + (double) x[i]->f, (double) residual[i]); + error_msg(error_string, CONTINUE); + if (x[i]->type == ALK) { + error_msg("Is non-carbonate alkalinity " + "greater than total alkalinity?\n", CONTINUE); + } + return_value = ERROR; + } + } else if (x[i]->type == SOLUTION_PHASE_BOUNDARY) { + if (fabs (residual[i]) >= epsilon /* || stop_program == TRUE */) { + sprintf(error_string,"%20s solution phase boundary has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == CB) { + if (fabs (residual[i]) >= epsilon * mu_x *mass_water_aq_x /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Charge balance has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == MU && pitzer_model == FALSE) { + if (fabs (residual[i]) >= epsilon * mu_x * mass_water_aq_x /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Ionic strength has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == AH2O && pitzer_model == FALSE) { + if (fabs (residual[i]) >= epsilon /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Activity of water has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == MH && pitzer_model == FALSE) { +#define COMBINE + /*#define COMBINE_CHARGE*/ +#ifdef COMBINE +#ifndef COMBINE_CHARGE + if (fabs(residual[i]) > epsilon * (x[i]->moles + 2 * mass_oxygen_unknown->moles)) +#else + if (fabs(residual[i]) > epsilon * (x[i]->moles + 2 * mass_oxygen_unknown->moles + charge_balance_unknown->moles)) +#endif +#else + if (fabs (residual[i]) >= epsilon * x[i]->moles /* || stop_program == TRUE */) +#endif + { + sprintf(error_string,"%20s Mass of hydrogen has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == MH2O) { + if (mass_water_switch == TRUE) continue; + if (fabs (residual[i]) >= 0.01 * epsilon * x[i]->moles /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Mass of oxygen has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == PP) { + if (x[i]->pure_phase->add_formula == NULL) { + if (x[i]->dissolve_only == TRUE) { + if ((residual[i] > epsilon && x[i]->moles > 0.0) || ((residual[i] < -epsilon && (x[i]->pure_phase->initial_moles - x[i]->moles) > 0))) { + output_msg(OUTPUT_LOG,"%20s Dissolve_only pure phase has not converged. \tResidual: %e\n", x[i]->description, (double) residual[i]); + } + } else { + if ((residual[i] >= epsilon && x[i]->moles > 0.0) /* || stop_program == TRUE */) { + remove_unstable_phases = TRUE; + output_msg(OUTPUT_LOG,"%20s Pure phase has not converged. \tResidual: %e\n", x[i]->description, (double) residual[i]); + } else if (residual[i] <= -epsilon ) { + sprintf(error_string,"%20s Pure phase has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } + } else { + if ((fabs(residual[i]) >= epsilon && x[i]->moles > 0.0) /* || stop_program == TRUE */) { + output_msg(OUTPUT_LOG,"%s, Pure phase has not converged. \tResidual: %e\n", x[i]->description, (double) residual[i]); + sprintf(error_string,"%s, Pure phase with add formula has not converged.\n\t SI may be a local minimum." + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + warning_msg(error_string); + } + } + } else if (x[i]->type == EXCH) { + if (/* stop_program == TRUE || */ + (x[i]->moles <= MIN_RELATED_SURFACE && fabs(residual[i]) > epsilon) || + (x[i]->moles > MIN_RELATED_SURFACE && (fabs(residual[i]) > epsilon * x[i]->moles))) { + sprintf(error_string,"%20s Exchanger mass balance has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == SURFACE) { + if (/* stop_program == TRUE || */ + (x[i]->moles <= MIN_RELATED_SURFACE && fabs(residual[i]) > epsilon) || + (x[i]->moles > MIN_RELATED_SURFACE && (fabs(residual[i]) > epsilon * x[i]->moles))) { + sprintf(error_string,"%20s Surface mass balance has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == SURFACE_CB) { + if ((x[i]->surface_charge->grams > MIN_RELATED_SURFACE && fabs(residual[i]) > epsilon) /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Surface charge/potential has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == GAS_MOLES) { + if (gas_in == FALSE) continue; + if (residual[i] >= epsilon || residual[i] <= -epsilon /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Total moles in gas phase has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } else if (x[i]->type == PITZER_GAMMA) { + if (fabs(residual[i]) > epsilon ) { + sprintf(error_string,"%20s log gamma not converged.\tResidual: %e\n", x[i]->description, (double) residual[i]); + } + } else if (x[i]->type == S_S_MOLES) { + if (x[i]->s_s_in == FALSE) continue; + if (residual[i] >= epsilon || residual[i] <= -epsilon /* || stop_program == TRUE */) { + sprintf(error_string,"%20s Total moles in solid solution has not converged. " + "\tResidual: %e\n", x[i]->description, (double) residual[i]); + error_msg(error_string, CONTINUE); + } + } + } + if (remove_unstable_phases == TRUE) { + output_msg(OUTPUT_LOG, "%20sRemoving unstable phases, iteration %d."," ", iterations); + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int gammas (LDBLE mu) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates gammas and [moles * d(ln gamma)/d mu] for all aqueous + * species. + */ + int i, j; + int ifirst, ilast; + LDBLE f, a_llnl, b_llnl, bdot_llnl, log_g_co2, dln_g_co2, c2_llnl; + LDBLE s1, s2, s3; + LDBLE c1, c2, a, b; + LDBLE muhalf; + /* Initialize */ + if (pitzer_model == TRUE) return gammas_pz(); + a_llnl = b_llnl = bdot_llnl = log_g_co2 = dln_g_co2 = c2_llnl = 0; +/* + * compute temperature dependence of a and b for debye-huckel + */ + s1=374.11-tc_x; + s2=pow(s1,1.0/3.0); + s3=1.0+0.1342489*s2-3.946263e-03*s1; + s3=s3/(3.1975-0.3151548*s2-1.203374e-03*s1+7.48908e-13*(s1*s1*s1*s1)); + s3=sqrt(s3); + if (tk_x >= 373.15) { + c1=5321.0/tk_x+233.76-tk_x*(tk_x*(8.292e-07*tk_x-1.417e-03)+0.9297); + } else { + /* replaced by wateq4f expression + c1=87.74-tc_x*(tc_x*(1.41e-06*tc_x-9.398e-04)+0.4008); + */ + c1 = 2727.586+0.6224107*tk_x-466.9151*log(tk_x)-52000.87/tk_x; + } + c1=sqrt(c1*tk_x); + /* replaced by wateq4f expressions + a=1824600.0*s3/(c1 * c1 * c1); + b=50.29*s3/c1; + */ + a = 1824827.7 * s3 / (c1 * c1 * c1); + b = 50.2905 * s3 / c1; + /* + * LLNL temperature dependence + */ + if (llnl_count_temp > 0) { + ifirst = 0; + ilast = llnl_count_temp; + if (tc_x < llnl_temp[0] || tc_x > llnl_temp[llnl_count_temp - 1]) { + error_msg("Temperature out of range of LLNL_AQUEOUS_MODEL parameters", STOP); + } + for (i = 0; i < llnl_count_temp; i++) { + if (tc_x >= llnl_temp[i]) ifirst = i; + if (tc_x <= llnl_temp[i]) { + ilast = i; + break; + } + } + if (ilast == ifirst) { + f = 1; + } else { + f = (tc_x - llnl_temp[ifirst])/(llnl_temp[ilast] - llnl_temp[ifirst]); + } + a_llnl = (1 - f)*llnl_adh[ifirst] + f*llnl_adh[ilast]; + b_llnl = (1 - f)*llnl_bdh[ifirst] + f*llnl_bdh[ilast]; + bdot_llnl = (1 - f)*llnl_bdot[ifirst] + f*llnl_bdot[ilast]; + /* + * CO2 activity coefficient + */ + log_g_co2 = (llnl_co2_coefs[0] + llnl_co2_coefs[1]*tk_x + llnl_co2_coefs[2]/tk_x)*mu - + (llnl_co2_coefs[3] + llnl_co2_coefs[4]*tk_x)*(mu/(mu+1)); + log_g_co2 /= LOG_10; + dln_g_co2 = (llnl_co2_coefs[0] + llnl_co2_coefs[1]*tk_x + llnl_co2_coefs[2]/tk_x) - + (llnl_co2_coefs[3] + llnl_co2_coefs[4]*tk_x)*(1/((mu+1)*(mu+1))); + } + +/* + * constants for equations + */ + muhalf = sqrt(mu); + c1=(-a)*LOG_10*(1.0/(2*muhalf*(muhalf+1.0)*(muhalf+1.0))-0.3); + c2=-a/(2*muhalf); + if (llnl_count_temp > 0) { + c2_llnl = -a_llnl/(2*muhalf); + } + +/* + * Calculate activity coefficients + */ + for (i=0; i < count_s_x; i++) { + switch (s_x[i]->gflag) { + case 0: /* uncharged */ + s_x[i]->lg = s_x[i]->dhb * mu; + s_x[i]->dg = s_x[i]->dhb * LOG_10 * s_x[i]->moles; + break; + case 1: /* Davies */ + s_x[i]->lg = - s_x[i]->z * s_x[i]->z * a * + ( muhalf / (1.0 + muhalf) - 0.3 * mu); + s_x[i]->dg = c1 * s_x[i]->z * s_x[i]->z * s_x[i]->moles; + break; + case 2: /* Extended D-H, WATEQ D-H */ + s_x[i]->lg = -a * muhalf * s_x[i]->z * s_x[i]->z / + (1.0 + s_x[i]->dha * b * muhalf) + s_x[i]->dhb * mu; + s_x[i]->dg = (c2 * s_x[i]->z * s_x[i]->z / + ((1.0 + s_x[i]->dha * b * muhalf)*(1.0 + s_x[i]->dha * b * muhalf)) + s_x[i]->dhb) * LOG_10 * s_x[i]->moles; +/* if (mu_x < 1e-6) s_x[i]->dg = 0.0; */ + break; + case 3: /* Always 1.0 */ + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + break; + case 4: /* Exchange */ +/* + * Find CEC + * z contains valence of cation for exchange species, alk contains cec + */ +/* !!!!! */ + for (j=1; s_x[i]->rxn_x->token[j].s != NULL; j++) { + if (s_x[i]->rxn_x->token[j].s->type == EX) { + s_x[i]->alk = s_x[i]->rxn_x->token[j].s->primary->unknown->moles; + break; + } + } + if (s_x[i]->exch_gflag == 1 && s_x[i]->alk > 0) { + /* Davies */ + s_x[i]->lg = - s_x[i]->equiv * s_x[i]->equiv * a * + ( muhalf / (1.0 + muhalf) - 0.3 * mu) + + log10(fabs(s_x[i]->equiv)/s_x[i]->alk); + s_x[i]->dg = c1 * s_x[i]->equiv * s_x[i]->equiv * s_x[i]->moles; + } else if (s_x[i]->exch_gflag == 2 && s_x[i]->alk > 0) { + /* Extended D-H, WATEQ D-H */ + s_x[i]->lg = -a * muhalf * s_x[i]->equiv * s_x[i]->equiv / + (1.0 + s_x[i]->dha * b * muhalf) + s_x[i]->dhb * mu + + log10(fabs(s_x[i]->equiv)/s_x[i]->alk); + s_x[i]->dg = (c2 * s_x[i]->equiv * s_x[i]->equiv / + ((1.0 + s_x[i]->dha * b * muhalf)*(1.0 + s_x[i]->dha * b * muhalf)) + s_x[i]->dhb) * LOG_10 * s_x[i]->moles; + } else if (s_x[i]->exch_gflag == 7 && s_x[i]->alk > 0) { + if (llnl_count_temp >0 ) { + s_x[i]->lg = -a_llnl * muhalf * s_x[i]->equiv * s_x[i]->equiv / (1.0 + s_x[i]->dha * b_llnl * muhalf) + bdot_llnl * mu + log10(fabs(s_x[i]->equiv)/s_x[i]->alk); + s_x[i]->dg = (c2_llnl * s_x[i]->equiv * s_x[i]->equiv / ((1.0 + s_x[i]->dha * b_llnl * muhalf)*(1.0 + s_x[i]->dha * b_llnl * muhalf)) + bdot_llnl) * LOG_10 * s_x[i]->moles; + } else { + error_msg("LLNL_AQUEOUS_MODEL_PARAMETERS not defined.", STOP); + } + } else { +/* + * Master species is a dummy variable with meaningless activity and mass + */ + if (s_x[i]->primary != NULL) { + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + } else { + if (s_x[i]->alk <= 0) { + s_x[i]->lg = 0.0; + } else { + s_x[i]->lg = log10(fabs(s_x[i]->equiv)/s_x[i]->alk); + } + s_x[i]->dg = 0.0; + } + } + break; + case 5: /* Always 1.0 */ + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + break; + case 6: /* Surface */ +/* + * Find moles of sites. + * s_x[i]->equiv is stoichiometric coefficient of sites in species + */ + for (j=1; s_x[i]->rxn_x->token[j].s != NULL; j++) { + if (s_x[i]->rxn_x->token[j].s->type == SURF) { + s_x[i]->alk = s_x[i]->rxn_x->token[j].s->primary->unknown->moles; + break; + } + } + if (s_x[i]->alk > 0) { + s_x[i]->lg = log10(s_x[i]->equiv / s_x[i]->alk); + s_x[i]->dg = 0.0; + } else { + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + } + break; + case 7: /* LLNL */ + if (llnl_count_temp >0 ) { + if (s_x[i]->z == 0) { + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + } else { + s_x[i]->lg = -a_llnl * muhalf * s_x[i]->z * s_x[i]->z / + (1.0 + s_x[i]->dha * b_llnl * muhalf) + bdot_llnl * mu; + s_x[i]->dg = (c2_llnl * s_x[i]->z * s_x[i]->z / ((1.0 + s_x[i]->dha * b_llnl * muhalf)*(1.0 + s_x[i]->dha * b_llnl * muhalf)) + bdot_llnl) * LOG_10 * s_x[i]->moles; + break; + } + } else { + error_msg("LLNL_AQUEOUS_MODEL_PARAMETERS not defined.", STOP); + } + break; + case 8: /* LLNL CO2*/ + if (llnl_count_temp > 0) { + s_x[i]->lg = log_g_co2; + s_x[i]->dg = dln_g_co2 * s_x[i]->moles; + } else { + error_msg("LLNL_AQUEOUS_MODEL_PARAMETERS not defined.", STOP); + } + break; + case 9: /* activity water */ + s_x[i]->lg = log10(exp( s_h2o->la * LOG_10) * gfw_water); + s_x[i]->dg = 0.0; + break; + } +/* + if (mu_unknown != NULL) { + if (fabs(residual[mu_unknown->number]) > 0.1 && + fabs(residual[mu_unknown->number])/mu_x > 0.5) { + s_x[i]->dg = 0.0; + } + } + */ + } + return(OK); +} +/* ------------------------------------------------------------------------------- */ +int ineq(int in_kode) +/* ------------------------------------------------------------------------------- */ +{ +/* + * Sets up equations and inequalities for Cl1. + * Scales columns if necessary. + * Eliminates equations that are not necessary because + * gas_phase, s_s, or phase equation is not needed + * Mallocs space + * Calls Cl1 + * Rescales results if necessary + */ + int i, j; + int return_code; + int *back; + int count_rows; + int count_optimize, count_equal; + extern int max_row_count, max_column_count; + int k, l, m, n; + int klmd, nklmd, n2d; + int iter; + LDBLE error; + LDBLE *ineq_array, *res, *cu; + LDBLE *zero, *delta1; + int *iu, *is; + LDBLE *normal; + LDBLE max; + int kode; +#ifdef SKIP + LDBLE *save_row; +#endif + LDBLE min; +#ifdef SLNQ + LDBLE *slnq_array; + LDBLE *slnq_delta1; +#endif +/* Debug + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "\narray:\n\n"); + array_print(array, count_unknowns, count_unknowns + 1, count_unknowns + 1); + } + */ +/* + * Special case for removing unstable phases + */ + if ( remove_unstable_phases == TRUE ) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nSolution vector for removing unstable phases:\n"); + } + for (i=0; i< count_unknowns; i++) { + if (x[i]->type == PP && residual[i] > 0e-8 && x[i]->moles > 0 && + x[i]->pure_phase->add_formula == NULL && x[i]->dissolve_only == FALSE) { +/* + * Set mass transfer to all of phase + */ + delta[i] = x[i]->moles; + } else { + delta[i] = 0.0; + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e\n",i, + x[i]->description, (double) delta[i]); + } + } + remove_unstable_phases = FALSE; + return(OK); + } +/* + * Pitzer model does not have activity of water or mu + */ + if (pitzer_model == TRUE) { + for (i=0; i < count_unknowns; i++) { + if ( (x[i]->type == AH2O && full_pitzer == FALSE) || + x[i]->type == MH || + x[i]->type == MU || + (x[i]->type == PITZER_GAMMA && full_pitzer == FALSE)) { + for (j=0; jtype == MB || x[i]->type == ALK || x[i]->type == EXCH || x[i]->type == SURFACE || x[i]->type == SURFACE_CB) { +/* !!!! */ if ( x[i]->moles <= MIN_RELATED_SURFACE && (x[i]->type == EXCH || x[i]->type == SURFACE)) continue; + for (j = 0; j < count_unknowns; j++) { + if (x[i]->type == SURFACE && x[j]->type == SURFACE_CB ) continue; + + if (fabs(array[j *(count_unknowns + 1) + i]) > max) { + max = fabs(array[j * (count_unknowns + 1) + i]); + if (max > min_value) break; + } + } + if (diagonal_scale == TRUE) { + if (fabs(array[i *(count_unknowns + 1) + i]) < min_value) { + max = fabs(array[i * (count_unknowns + 1) + i]); + } + } + + if (max == 0) { + array[i *(count_unknowns + 1) + i] = 1e-5*x[i]->moles; + max = fabs(1e-5*x[i]->moles); + } + } + + if (x[i]->type == MH && pitzer_model == FALSE) { + /* make absolute value of diagonal at least 1e-12 */ + + min = 1e-12; + min = MIN_TOTAL; + array[x[i]->number * (count_unknowns + 1) + x[i]->number] += min; + if (fabs(array[x[i]->number * (count_unknowns + 1) + x[i]->number]) < min) + array[x[i]->number * (count_unknowns + 1) + x[i]->number] = min; + max = 0.0; + + for (j=0; jtype != MB && + x[j]->type != SURFACE && + x[j]->type != SURFACE_CB && + x[j]->type != EXCH && + x[j]->type != MH && + x[j]->type != MH2O) continue; + if (fabs(array[j * (count_unknowns + 1) + i]) > max) { + max = fabs(array[j * (count_unknowns + 1) + i]); + if (max > min_value) break; + } + } + } + + if (max > 0.0 && max < min_value) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "Scaling column for %s, max= %e\n", + x[i]->description, (double) max); + } + for (j=0; j < count_unknowns; j++) { + array[j * (count_unknowns + 1) + i] *= min_value / max ; + } + normal[i] = min_value / max; + } + } + +/* + * Allocate arrays for inequality solver + */ + max_row_count = 2*count_unknowns + 2; + max_column_count = count_unknowns + 2; + ineq_array = (LDBLE *) PHRQ_malloc((size_t) max_row_count * max_column_count * + sizeof(LDBLE)); + if (ineq_array == NULL) malloc_error(); + + back = (int *) PHRQ_malloc((size_t) max_row_count * sizeof(int)); + if (back == NULL) malloc_error(); + + zero = (LDBLE *) PHRQ_malloc((size_t) max_row_count*sizeof(LDBLE)); + if (zero == NULL) malloc_error(); + for (i=0; itype == PP ) { + /* not in model, ignore */ + if (x[i]->pure_phase->phase->in == FALSE) continue; + /* Undersaturated and no mass, ignore */ + if (x[i]->f > 0e-8 && x[i]->moles <= 0 && x[i]->pure_phase->add_formula == NULL) { + continue; + } else if (x[i]->f < 0e-8 && x[i]->dissolve_only == TRUE && (x[i]->moles - x[i]->pure_phase->initial_moles >= 0)) { + continue; + } else { + /* Copy in saturation index equation (has mass or supersaturated) */ + memcpy((void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + if (x[i]->pure_phase->add_formula == NULL && x[i]->dissolve_only == FALSE) { + res[count_rows] = 1.0; + } +/* + * If infeasible solution on first attempt, remove constraints on IAP + */ +#ifdef SKIP +#endif + if (pp_scale != 1){ + for (j = 0; j < count_unknowns +1; j++) { + ineq_array[count_rows * max_column_count + j] *= pp_scale; + } + } + + + if (in_kode != 1) { + res[count_rows] = 0.0; + } + count_rows++; + } + } else if (x[i]->type == ALK || + x[i]->type == SOLUTION_PHASE_BOUNDARY ) { +/* + * Alkalinity and solution phase boundary + */ + memcpy((void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + count_rows++; +/* + * Gas phase + */ + } else if (x[i]->type == GAS_MOLES && gas_in == TRUE) { + memcpy((void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + + res[count_rows] = 1.0; + if (in_kode != 1) { + res[count_rows] = 0.0; + } + count_rows++; +/* + * Solid solution + */ + } else if (x[i]->type == S_S_MOLES && x[i]->s_s_in == TRUE) { + memcpy((void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + res[count_rows] = 1.0; + if (in_kode != 1) { + res[count_rows] = 0.0; + } + count_rows++; + } + } + count_optimize = count_rows; +/* + * Copy equality equations into ineq_array + */ + for (i=0; i< count_unknowns; i++) { + if (x[i]->type != SOLUTION_PHASE_BOUNDARY && + x[i]->type != ALK && + x[i]->type != GAS_MOLES && + x[i]->type != S_S_MOLES && + x[i]->type != PP ) { + if(x[i]->type == MH && pitzer_model == TRUE) continue; + if(mass_water_switch == TRUE && x[i] == mass_oxygen_unknown) continue; +/* + * Mass balance, CB, MU, AH2O, MH, MH2O, others + */ + if (x[i]->type == EXCH && x[i]->moles <= MIN_RELATED_SURFACE) continue; + if (x[i]->type == SURFACE && + x[i]->phase_unknown == NULL && + x[i]->moles <= MIN_RELATED_SURFACE) continue; + if (x[i]->type == SURFACE_CB && + /* x[i-1]->phase_unknown == NULL && */ + /* x[i-1]->moles <= MIN_RELATED_SURFACE) continue; */ + x[i]->surface_charge->grams <= MIN_RELATED_SURFACE) continue; + if (x[i]->type == SURFACE && + x[i]->phase_unknown != NULL && +/* x[i]->phase_unknown->f > 0e-8 && */ + x[i]->phase_unknown->moles <= MIN_RELATED_SURFACE && + x[i]->phase_unknown->pure_phase->add_formula == NULL) continue; + if (x[i]->type == SURFACE_CB && + x[i-1]->phase_unknown != NULL && +/* x[i-1]->phase_unknown->f > 0e-8 && */ +/* x[i-1]->phase_unknown->moles <= MIN_RELATED_SURFACE && */ + x[i]->surface_charge->grams <= MIN_RELATED_SURFACE && + x[i-1]->phase_unknown->pure_phase->add_formula == NULL) continue; + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + if(mass_water_switch == TRUE && x[i] == mass_hydrogen_unknown) { + k = mass_oxygen_unknown->number; + for (j = 0; j < count_unknowns; j++) { + ineq_array[count_rows * max_column_count + j] -= 2*array[k * (count_unknowns + 1) + j]; + } + } + count_rows++; + } else if (x[i]->type == PITZER_GAMMA) { + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + } + } + count_equal = count_rows - count_optimize; +/* + * Copy inequality constraints into ineq + */ + if (pure_phase_unknown != NULL) { + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == PP) { + /* not in model, ignore */ + if (x[i]->pure_phase->phase->in == FALSE) continue; + /* No moles and undersaturated, ignore */ + if (x[i]->moles <= 0.0 && x[i]->f > 0e-8 && + x[i]->pure_phase->add_formula == NULL) { + continue; + /* No moles of pure phase present, must precipitate */ + } else if (x[i]->moles <= 0.0 ) { + delta1[i] = -1.0; + } else if (x[i]->f < 0e-8 && x[i]->dissolve_only == TRUE && (x[i]->moles - x[i]->pure_phase->initial_moles >= 0)) { + continue; + } else { + + /* Pure phase is present, force Mass transfer to be <= amount of mineral remaining */ + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(zero[ 0 ]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + ineq_array[count_rows*max_column_count + i] = 1.0; + ineq_array[count_rows*max_column_count + count_unknowns ] = x[i]->moles; + back[count_rows] = i; + count_rows++; + } + /* Pure phase is present and dissolve_only, force ppt to be <= amount of dissolved so far */ + if (x[i]->dissolve_only == TRUE) { + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), (void *) &(zero[ 0 ]), (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + ineq_array[count_rows*max_column_count + i] = -1.0; + ineq_array[count_rows*max_column_count + count_unknowns ] = x[i]->pure_phase->initial_moles - x[i]->moles; + back[count_rows] = i; + count_rows++; + } + } + } + } +/* + * Add inequality for mass of oxygen greater than zero + */ +#ifdef SKIP +#endif + if (pitzer_model) { + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == MH2O) { + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type < PP) { + ineq_array[count_rows*max_column_count + j] = 0.0; + } else { + /*ineq_array[count_rows*max_column_count + j] = -ineq_array[count_rows*max_column_count + j]; */ + } + } + ineq_array[count_rows*max_column_count + count_unknowns] = 0.5*x[i]->moles; + count_rows++; + } + } + } + + +/* + * Hydrogen mass balance is good + */ +/* + * No moles and undersaturated, mass transfer must be zero + */ + if (pure_phase_unknown != NULL) { + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == PP) { + if ((x[i]->moles <= 0.0 && x[i]->f > 0e-8 && + x[i]->pure_phase->add_formula == NULL) || x[i]->pure_phase->phase->in == FALSE) { + for (j=0; jdissolve_only == TRUE) { + if (x[i]->f < 0e-8 && (x[i]->moles - x[i]->pure_phase->initial_moles >= 0)) { + for (j=0; jrelated_phases == TRUE || use.exchange_ptr->related_rate == TRUE )) { + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == EXCH && x[i]->moles <= 0) { + for (j=0; jrelated_phases == TRUE || use.surface_ptr->related_rate == TRUE ) ) { + for (i=0; i < count_unknowns; i++) { + if ((x[i]->type == SURFACE && + x[i]->phase_unknown != NULL && +/* x[i]->phase_unknown->f > 0e-8 && */ + x[i]->phase_unknown->moles <= MIN_RELATED_SURFACE && + x[i]->phase_unknown->pure_phase->add_formula == NULL) || + (x[i]->type == SURFACE_CB && + x[i-1]->phase_unknown != NULL && +/* x[i-1]->phase_unknown->f > 0e-8 && */ + x[i]->surface_charge->grams <= MIN_RELATED_SURFACE && + x[i-1]->phase_unknown->pure_phase->add_formula == NULL)) { + for (j=0; jtype == SURFACE && + x[i]->phase_unknown == NULL && + x[i]->moles <= MIN_RELATED_SURFACE) || + (x[i]->type == SURFACE_CB && + x[i-1]->phase_unknown == NULL && + x[i]->surface_charge->grams <= MIN_RELATED_SURFACE)) { + for (j=0; j= zero + */ + if (gas_in == TRUE) { + i = gas_unknown->number; + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(zero[ 0 ]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + ineq_array[count_rows*max_column_count + i] = -1.0; + ineq_array[count_rows*max_column_count + count_unknowns ] = x[i]->moles; + back[count_rows] = i; + count_rows++; + } else if (use.gas_phase_ptr != NULL && gas_in == FALSE) { +/* + * Moles of gas small and sum p < ptotal + */ + i = gas_unknown->number; + for (j=0; j= zero + */ + + if (s_s_unknown != NULL) { + for (i = s_s_unknown->number; i < count_unknowns; i++) { + if (x[i]->type != S_S_MOLES) break; + if (x[i]->phase->in == TRUE && x[i]->s_s_in == TRUE) { + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(zero[ 0 ]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + ineq_array[count_rows*max_column_count + i] = 1.0; + ineq_array[count_rows*max_column_count + count_unknowns ] = 0.99*x[i]->moles - MIN_TOTAL; + back[count_rows] = i; + count_rows++; + } else { + for (j=0; jtype == MB && x[i]->moles < 0.0 ) { + memcpy( (void *) &(ineq_array[count_rows*max_column_count]), + (void *) &(array[i*(count_unknowns + 1)]), + (size_t) (count_unknowns + 1) * sizeof(LDBLE)); + back[count_rows] = i; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type < PP) { + ineq_array[count_rows*max_column_count + j] = 0.0; + } + } + count_rows++; + } + } + } +/* + * Zero column for mass of water + */ + if(mass_oxygen_unknown != NULL && mass_water_switch == TRUE) { + k = mass_oxygen_unknown->number; + for (j = 0; j < count_rows + 1; j++) { + ineq_array[j * max_column_count + k] = 0; + } + } +/* + * Scale column for pure phases + */ + for (i=0; i < count_unknowns; i++) { + if ( (x[i]->type == PP || x[i]->type == S_S_MOLES) && pp_column_scale != 1.0) { + for (j = 0; j < count_rows; j++) { + ineq_array[j* max_column_count + i] *= pp_column_scale; + } + normal[i] = pp_column_scale; + } + + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "\nA and B arrays:\n\n"); + array_print(ineq_array, count_rows, count_unknowns + 1, max_column_count); + } +/* + * Calculate dimensions + */ + k = count_optimize; /* rows in A */ + l = count_equal; /* rows in C */ + m = count_rows - l - k; /* rows in E */ + if (m < 0) m = 0; + + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "k, l, m\t%d\t%d\t%d\n",k, l, m); + } + + n = count_unknowns; /* columns in A, C, E */ + klmd = max_row_count - 2; + nklmd = n+klmd; + n2d = n + 2; +/* + * Retain constraints on mineral mass transfers, even if infeasible on + * first attempt. + */ + kode = 1; + + if (in_kode == 2) { + kode = 1; + } + iter = 200; +/* + * Allocate space for arrays + */ + cu = (LDBLE *) PHRQ_malloc((size_t) 2*nklmd*sizeof(LDBLE)); + if (cu == NULL) malloc_error(); + iu = (int *) PHRQ_malloc((size_t) 2*nklmd*sizeof(int)); + if (iu == NULL) malloc_error(); + is = (int *) PHRQ_malloc((size_t) klmd*sizeof(int)); + if (is == NULL) malloc_error(); +#ifdef SLNQ + slnq_array = (LDBLE *) PHRQ_malloc((size_t) count_unknowns*(count_unknowns+1)*sizeof(LDBLE)); + if (slnq_array == NULL) malloc_error(); + for (i = 0; i < k+l; i++) { + for (j = 0; j <= count_unknowns; j++) { + slnq_array[i*(count_unknowns + 1) + j] = ineq_array[i*max_column_count + j]; + } + } + slnq_delta1 = (LDBLE *) PHRQ_malloc( (size_t) max_column_count * sizeof(LDBLE)); + if (slnq_delta1 == NULL) malloc_error(); + memcpy( (void *) &(slnq_delta1[0]), (void *) &(zero[0]), (size_t) max_column_count * sizeof(LDBLE)); +#endif +/* + * Call CL1 + */ + cl1(k, l, m, n, + nklmd, n2d, ineq_array, + &kode, ineq_tol, &iter, + delta1, res, &error, cu, iu, is, FALSE); + +/* Set return_kode */ + if ( kode == 1) { + return_code = ERROR; + } else if (kode == 2) { + return_code = 2; + } else { + return_code = OK; + } +#ifdef SLNQ +/* if (kode > 0 && ((k + l) == count_unknowns)) { */ + if (kode > 0 && ((k + l) <= count_unknowns)) { + if (add_trivial_eqns(k+l, count_unknowns, slnq_array) == TRUE) { + if (debug_model == TRUE) output_msg(OUTPUT_MESSAGE, "Calling SLNQ, iteration %d\n", iterations); + output_msg(OUTPUT_LOG, "Calling SLNQ, iteration %d\n", iterations); + if (slnq(count_unknowns, slnq_array, slnq_delta1, count_unknowns+1, debug_model) == OK) { + memcpy( (void *) &(delta1[0]), (void *) &(slnq_delta1[0]), + (size_t) count_unknowns * sizeof(LDBLE)); + if (debug_model == TRUE) output_msg(OUTPUT_MESSAGE, "Using SLNQ results.\n"); + output_msg(OUTPUT_LOG, "Using SLNQ results.\n"); + return_code = OK; + } else { + if (debug_model == TRUE) output_msg(OUTPUT_MESSAGE, "Could not use SLNQ results.\n"); + output_msg(OUTPUT_LOG, "Could not use SLNQ results.\n"); + } + } else { + output_msg(OUTPUT_LOG, "Could not call SLNQ, row %d, unknowns %d, iteration %d\n", k+l, count_unknowns, iterations); + } + } else if (kode > 0) { + output_msg(OUTPUT_LOG, "Could not call SLNQ, row %d, unknowns %d\n", k+l, count_unknowns); + } +#endif +/* Copy delta1 into delta and scale */ + + memcpy( (void *) &(delta[0]), (void *) &(delta1[0]), + (size_t) count_unknowns * sizeof(LDBLE)); + for (i = 0; i < count_unknowns; i++) delta[i] *= normal[i]; +/* + * Rescale columns of array + */ + for (i = 0; i < count_unknowns; i++) { + if (normal[i] != 1.0) { + for (j=0; j < count_unknowns; j++) { + array[j * (count_unknowns + 1) + i] /= normal[i]; + } + } + } + +/* + * Debug, write results of ineq + */ + + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "kode: %d\titer: %d\terror: %e\n", kode, iter, (double) error); + output_msg(OUTPUT_MESSAGE, "\nsolution vector:\n"); + for (i=0; i < count_unknowns; i++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e",i, x[i]->description, (double) delta[i]); + if (x[i]->type == PP) { + output_msg(OUTPUT_MESSAGE, " -SI %10.2e Moles %10.2e", (double) x[i]->f, (double) x[i]->moles); + if (x[i]->f < 0e-8 || x[i]->moles > 0.0) { + output_msg(OUTPUT_MESSAGE, " **"); + } + } + output_msg(OUTPUT_MESSAGE, "\n"); + } + + output_msg(OUTPUT_MESSAGE, "\nresidual vector:\n"); + for (i=0; i < count_rows; i++) { + output_msg(OUTPUT_MESSAGE, "%6d %-12.12s %10.2e\n",i, x[back[i]]->description, (double) res[i]); + } + } + normal = (LDBLE *) free_check_null(normal); + ineq_array = (LDBLE *) free_check_null(ineq_array); + back = (int *) free_check_null(back); + zero = (LDBLE *) free_check_null(zero); + res = (LDBLE *) free_check_null(res); + delta1 = (LDBLE *) free_check_null(delta1); + cu = (LDBLE *) free_check_null(cu); + iu = (int *) free_check_null(iu); + is = (int *) free_check_null(is); +#ifdef SLNQ + slnq_array = free_check_null(slnq_array); + slnq_delta1 = free_check_null(slnq_delta1); +#endif + return(return_code); +} +/* ---------------------------------------------------------------------- */ +int jacobian_sums (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fills in jacobian array, uses arrays sum_jacob0, sum_jacob1, and + * sum_jacob2. + */ + int i, j, k; + LDBLE sinh_constant; +/* + * Clear array, note residuals are in array[i, count_unknowns+1] + */ + for (i=0; i < count_unknowns; i++) { + array[i]=0.0; + } + for (i=1; i < count_unknowns; i++) { + memcpy ( (void *) &(array[i*(count_unknowns + 1)]), (void *) &(array[0]), + (size_t) count_unknowns * sizeof(LDBLE)); + } +/* + * Add constant terms + */ + for (k=0; k < count_sum_jacob0; k++) { + *sum_jacob0[k].target += sum_jacob0[k].coef; + } +/* + * Add terms with coefficients of 1.0 + */ + for (k=0; k < count_sum_jacob1; k++) { + *sum_jacob1[k].target += *sum_jacob1[k].source; + } +/* + * Add terms with coefficients != 1.0 + */ + for (k=0; k < count_sum_jacob2; k++) { + *sum_jacob2[k].target += *sum_jacob2[k].source * sum_jacob2[k].coef; + } +/* + * Make final adustments to jacobian array + */ +/* + * Ionic strength + */ + if (mu_unknown != NULL) { + for (i=0; inumber*(count_unknowns+1)+i] *= 0.5; + } + array[mu_unknown->number*(count_unknowns+1)+mu_unknown->number] -= mass_water_aq_x; + } +/* + * Mass of oxygen + */ + if (mass_oxygen_unknown != NULL && mu_unknown != NULL) { + array[mu_unknown->number*(count_unknowns+1)+mass_oxygen_unknown->number] -= mu_x * mass_water_aq_x; + } +/* + * Activity of water + */ + if (ah2o_unknown != NULL) { + for (i=0; inumber*(count_unknowns+1)+i] *= -0.017; + } + array[ah2o_unknown->number*(count_unknowns+1)+ah2o_unknown->number] -= mass_water_aq_x*exp(s_h2o->la * LOG_10); + } + if (mass_oxygen_unknown != NULL && ah2o_unknown != NULL) { + array[ah2o_unknown->number*(count_unknowns+1)+mass_oxygen_unknown->number] -= + (exp(s_h2o->la * LOG_10) - 1) * mass_water_aq_x; + } +/* + * Surface charge balance + */ + if (surface_unknown != NULL && diffuse_layer_x == FALSE) { + sinh_constant = sqrt(8*EPSILON*EPSILON_ZERO*(R_KJ_DEG_MOL*1000)*tk_x*1000); + for (i=0; itype == SURFACE_CB && x[i]->surface_charge->grams > 0 ) { + for (j=0; j < count_unknowns; j++) { + array[x[i]->number * (count_unknowns + 1) + j] *= + F_C_MOL / (x[i]->surface_charge->specific_area * x[i]->surface_charge->grams); + } + array[x[i]->number * (count_unknowns + 1) + x[i]->number] -= + sinh_constant * sqrt(mu_x) * cosh(x[i]->master[0]->s->la * LOG_10); + if (mu_unknown != NULL) { + array[x[i]->number * (count_unknowns + 1) + mu_unknown->number] -= + 0.5 * sinh_constant / sqrt(mu_x) * sinh(x[i]->master[0]->s->la * LOG_10); + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_sums (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates sums of species for calculation of mass balances, charge + * balance. Also calculates saturation indices for solution_phase_boundaries + * and pure_phases. After this routine total calcium calculated from all + * calcium species in solution is stored in x[i]->f. Also calculates + * x[i]->sum for some types of unknowns. Uses arrays sum_mb1 and + * sum_mb1, which are generated in prep and reprep. + */ + int k; +/* + * Clear functions in unknowns + */ + for (k=0; k < count_unknowns; k++) { + x[k]->f=0.0; + x[k]->sum=0.0; + } +/* + * Add terms with coefficients of 1.0 + */ + for (k=0; k < count_sum_mb1; k++) { + *sum_mb1[k].target += *sum_mb1[k].source; +/* { k += 1; k -= 1;} */ + } +/* + * Add terms with coefficients != 1.0 + */ + for (k=0; k < count_sum_mb2; k++) { + *sum_mb2[k].target += *sum_mb2[k].source * sum_mb2[k].coef; +/* { k += 1; k -= 1;} */ + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_gases(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Determines whether gas_phase equation is needed + */ + gas_in = FALSE; + if (gas_unknown == NULL || use.gas_phase_ptr == NULL) return(OK); + if (use.gas_phase_ptr->type == PRESSURE) { + if (gas_unknown->f > use.gas_phase_ptr->total_p + 1e-7 || + gas_unknown->moles > MIN_TOTAL) { + gas_in = TRUE; + } + } else { + gas_in = FALSE; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_s_s(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + LDBLE lp, log10_iap, total_moles; + LDBLE iapc, iapb, kc, kb, lc, lb, xcaq, xbaq, xb, xc; + LDBLE sigmapi_aq, sigmapi_solid; + LDBLE total_p; + struct s_s *s_s_ptr; + struct rxn_token *rxn_ptr; + struct phase *phase_ptr; +/* + * Determines whether solid solution equation is needed + */ + if (s_s_unknown == NULL || use.s_s_assemblage_ptr == NULL) return(OK); + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + s_s_ptr = &(use.s_s_assemblage_ptr->s_s[i]); + total_moles = 0; + for (j = 0; j < s_s_ptr->count_comps; j++) { + total_moles += s_s_ptr->comps[j].moles; + } + if (total_moles > 1e-13) { + s_s_ptr->s_s_in = TRUE; + } else if (s_s_ptr->a0 != 0.0 || s_s_ptr->a1 != 0.0) { + /* + * Calculate IAPc and IAPb + */ + if (s_s_ptr->comps[0].phase->rxn_x != NULL) { + log10_iap = 0; + for (rxn_ptr = s_s_ptr->comps[0].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + log10_iap += rxn_ptr->s->la * rxn_ptr->coef; + } + iapc = exp(log10_iap * LOG_10); + } else { + iapc = 1e-99; + } + if (s_s_ptr->comps[1].phase->rxn_x != NULL) { + log10_iap = 0; + for (rxn_ptr = s_s_ptr->comps[1].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + log10_iap += rxn_ptr->s->la * rxn_ptr->coef; + } + iapb = exp(log10_iap * LOG_10); + } else { + iapb = 1e-99; + } + /* + * Calculate sigma pi, aq + */ + sigmapi_aq = iapc + iapb; + /* + * Calculate xc,aq and xb, aq + */ + xcaq = iapc/(iapb + iapc); + xbaq = iapb/(iapb + iapc); + /* + * Get Kc and Kb + */ + kc = exp(s_s_ptr->comps[0].phase->lk*LOG_10); + kb = exp(s_s_ptr->comps[1].phase->lk*LOG_10); + /* + * Solve for xb + */ + xb = s_s_root(s_s_ptr->a0, s_s_ptr->a1, kc, kb, xcaq, xbaq); + /* + * Calculate lambdac and lambdab + */ + xc = 1 - xb; + lc = exp((s_s_ptr->a0 - s_s_ptr->a1*(-4*xb + 3))*xb*xb); + lb = exp((s_s_ptr->a0 + s_s_ptr->a1*(4*xb - 3))*xc*xc); + /* + * Calculate sigma pi, solid + */ + sigmapi_solid = xb*lb*kb + xc*lc*kc; + /* + * If Sigma pi, solid < sigma pi, aq, then use eqns + */ + if (sigmapi_solid < sigmapi_aq) { + s_s_ptr->s_s_in = TRUE; + } else { + s_s_ptr->s_s_in = FALSE; + } + } else { + /* + * Calculate total mole fraction from solution activities + */ + total_p = 0; + for (j = 0; j < s_s_ptr->count_comps; j++) { + phase_ptr = s_s_ptr->comps[j].phase; + if (phase_ptr->in == TRUE) { + lp=-phase_ptr->lk; + for (rxn_ptr = s_s_ptr->comps[j].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + lp += rxn_ptr->s->la * rxn_ptr->coef; + } + total_p += exp(lp * LOG_10); + } + } + if (total_p > 1.0) { + s_s_ptr->s_s_in = TRUE; + } else { + s_s_ptr->s_s_in= FALSE; + } + } + } + for (i = s_s_unknown->number; i < count_unknowns; i++) { + if (x[i]->type != S_S_MOLES) break; + x[i]->s_s_in = x[i]->s_s->s_s_in; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int molalities (int allow_overflow) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates la for master species + * Calculates lm and moles from lk, lg, and la's of master species + * Adjusts lm of h2 and o2. + */ + int i, j, count_g; + LDBLE total_g; + struct rxn_token *rxn_ptr; +/* + * la for master species + */ + for (i=0; i < count_master; i++) { + if (master[i]->in == REWRITE) { + master[i]->s->la = master[i]->s->lm + master[i]->s->lg; + } + } + if (diffuse_layer_x == TRUE) { + s_h2o->tot_g_moles = s_h2o->moles; + s_h2o->tot_dh2o_moles = 0.0; + } + for (i=0; i < count_s_x; i++) { + if (s_x[i]->type > HPLUS && s_x[i]->type != EX && s_x[i]->type != SURF) continue; +/* + * lm and moles for all aqueous species + */ + s_x[i]->lm=s_x[i]->lk - s_x[i]->lg; + for (rxn_ptr = s_x[i]->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + s_x[i]->lm += rxn_ptr->s->la * rxn_ptr->coef; + } + if (s_x[i]->type == EX ) { + s_x[i]->moles = exp(s_x[i]->lm * LOG_10); + } else if (s_x[i]->type == SURF ) { + s_x[i]->moles = exp(s_x[i]->lm * LOG_10); /* formerly * mass water */ + + } else { + s_x[i]->moles = under (s_x[i]->lm) * mass_water_aq_x; + if (s_x[i]->moles/mass_water_aq_x > 30) { + output_msg(OUTPUT_LOG,"Overflow: %s\t%e\t%e\t%d\n", s_x[i]->name, (double) (s_x[i]->moles/mass_water_aq_x), (double) s_x[i]->lm, iterations); + + if (iterations >= 0 && allow_overflow == FALSE) { + return(ERROR); + } + } + + } +/* + * other terms for diffuse layer model + */ + if (use.surface_ptr != NULL && diffuse_layer_x == TRUE && s_x[i]->type <= HPLUS) { + total_g = 0.0; + s_x[i]->tot_dh2o_moles = 0.0; + for (j = 0; j < use.surface_ptr->count_charge; j++) { + count_g = s_x[i]->diff_layer[j].count_g; +#ifdef SKIP +/* + * original formulation incorrectly mixes concentrations of surface relative + * to moles_water_aq_x and concentrations of diffuse layer in terms + * of moles_water_bulk_x. Moles_water_bulk_x is wrong anyway because + * an individual surface sees only moles_water_aq_x + moles_water_surface + * (not sum of all surfaces) + */ + s_x[i]->diff_layer[j].g_moles = s_x[i]->moles * + (s_x[i]->diff_layer[j].charge->g[count_g].g * + mass_water_bulk_x / mass_water_aq_x + + s_x[i]->diff_layer[j].charge->mass_water / + mass_water_aq_x); + + /* g.dg is dg/dx(-2y**2) or dg/d(ln y) */ + s_x[i]->diff_layer[j].dx_moles = s_x[i]->moles * + s_x[i]->diff_layer[j].charge->g[count_g].dg * + mass_water_bulk_x / mass_water_aq_x; + + total_g += s_x[i]->diff_layer[j].charge->g[count_g].g * + mass_water_bulk_x / mass_water_aq_x + + s_x[i]->diff_layer[j].charge->mass_water / mass_water_aq_x; + + s_x[i]->diff_layer[j].dh2o_moles = - s_x[i]->moles * + (s_x[i]->diff_layer[j].charge->g[count_g].g + 1) * + s_x[i]->diff_layer[j].charge->mass_water / mass_water_aq_x; + + s_x[i]->tot_dh2o_moles += s_x[i]->diff_layer[j].dh2o_moles; + + /* surface related to phase */ + + s_x[i]->diff_layer[j].drelated_moles = s_x[i]->moles * (s_x[i]->diff_layer[j].charge->g[count_g].g + 1) * use.surface_ptr->charge[j].specific_area * use.surface_ptr->thickness / mass_water_aq_x; +#endif +/* + * partially corrected formulation assumes mass of water in diffuse layer + * is insignificant. Excess is calculated on the basis of moles_water_aq_x + * instead of moles_water_bulk. + */ + /* revised eq. 61 */ + s_x[i]->diff_layer[j].g_moles = s_x[i]->moles * + (s_x[i]->diff_layer[j].charge->g[count_g].g + + s_x[i]->diff_layer[j].charge->mass_water / + mass_water_aq_x); + if (s_x[i]->moles > 1e-30) { + s_x[i]->diff_layer[j].dg_g_moles = s_x[i]->dg * s_x[i]->diff_layer[j].g_moles / s_x[i]->moles; + } + + /* + * first term of 63 is summed for all surfaces in + * s_x[i]->tot_g_moles. This sum is then used in + * the jacobian for species i + */ + total_g += s_x[i]->diff_layer[j].charge->g[count_g].g + s_x[i]->diff_layer[j].charge->mass_water / mass_water_aq_x; + + /* revised eq. 63, second term */ + /* g.dg is dg/dx(-2y**2) or dg/d(ln y) */ + s_x[i]->diff_layer[j].dx_moles = s_x[i]->moles * s_x[i]->diff_layer[j].charge->g[count_g].dg; + + /* revised eq. 63, third term */ + s_x[i]->diff_layer[j].dh2o_moles = - s_x[i]->moles * s_x[i]->diff_layer[j].charge->mass_water / mass_water_aq_x; + s_x[i]->tot_dh2o_moles += s_x[i]->diff_layer[j].dh2o_moles; + + /* surface related to phase */ + s_x[i]->diff_layer[j].drelated_moles = s_x[i]->moles * + use.surface_ptr->charge[j].specific_area * + use.surface_ptr->thickness / mass_water_aq_x; + } + s_x[i]->tot_g_moles = s_x[i]->moles * (1 + total_g); + + /* note that dg is for cb, act water, mu eqns */ + /* dg_total_g for mole balance eqns */ + /* dg_g_moles for surface cb */ + + if (s_x[i]->moles > 1e-30) { + s_x[i]->dg_total_g = s_x[i]->dg * s_x[i]->tot_g_moles / s_x[i]->moles; + } else { + s_x[i]->dg_total_g = 0.0; + } +#ifdef SKIP +#endif + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "%s\t%e\t%e\n", s_x[i]->name, (double) s_x[i]->moles, (double) s_x[i]->tot_g_moles); + output_msg(OUTPUT_MESSAGE, "\tg\n"); + for (j=0; j < use.surface_ptr->count_charge; j++) { + count_g = s_x[i]->diff_layer[j].count_g; + output_msg(OUTPUT_MESSAGE, "\t%e", (double) s_x[i]->diff_layer[j].charge->g[count_g].g); + } + output_msg(OUTPUT_MESSAGE, "\n\tg_moles\n"); + for (j=0; j < use.surface_ptr->count_charge; j++) { + output_msg(OUTPUT_MESSAGE, "\t%e", (double) s_x[i]->diff_layer[j].g_moles); + } + output_msg(OUTPUT_MESSAGE, "\n\tdg\n"); + for (j=0; j < use.surface_ptr->count_charge; j++) { + count_g = s_x[i]->diff_layer[j].count_g; + output_msg(OUTPUT_MESSAGE, "\t%e", (double) s_x[i]->diff_layer[j].charge->g[count_g].dg); + } + output_msg(OUTPUT_MESSAGE, "\n\tdx_moles\n"); + for (j=0; j < use.surface_ptr->count_charge; j++) { + output_msg(OUTPUT_MESSAGE, "\t%e", (double) s_x[i]->diff_layer[j].dx_moles); + } + output_msg(OUTPUT_MESSAGE, "\n\tdh2o_moles\t%e\n", (double) s_x[i]->tot_dh2o_moles); + for (j=0; j < use.surface_ptr->count_charge; j++) { + output_msg(OUTPUT_MESSAGE, "\t%e", (double) s_x[i]->diff_layer[j].dh2o_moles); + } + output_msg(OUTPUT_MESSAGE, "\n"); + } + } + } + if (use.gas_phase_ptr != NULL) calc_gas_pressures(); + if (use.s_s_assemblage_ptr != NULL) calc_s_s_fractions(); + + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int calc_gas_pressures(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE lp; + struct rxn_token *rxn_ptr; + struct gas_comp *gas_comp_ptr; + struct phase *phase_ptr; +/* + * moles and partial pressures for gases + */ + if (use.gas_phase_ptr == NULL) return(OK); + if (use.gas_phase_ptr->type == VOLUME) { + use.gas_phase_ptr->total_p = 0; + use.gas_phase_ptr->total_moles = 0; + } + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + gas_comp_ptr = &(use.gas_phase_ptr->comps[i]); + phase_ptr = use.gas_phase_ptr->comps[i].phase; + if (phase_ptr->in == TRUE) { + lp=-phase_ptr->lk; + for (rxn_ptr=phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + lp += rxn_ptr->s->la * rxn_ptr->coef; + } + gas_comp_ptr->phase->p_soln_x = exp(lp * LOG_10); + if (use.gas_phase_ptr->type == PRESSURE) { + gas_comp_ptr->phase->moles_x = gas_comp_ptr->phase->p_soln_x * + gas_unknown->moles / gas_unknown->gas_phase->total_p; + gas_comp_ptr->phase->fraction_x = gas_comp_ptr->phase->moles_x / gas_unknown->moles; + } else { + gas_comp_ptr->phase->moles_x = gas_comp_ptr->phase->p_soln_x * + use.gas_phase_ptr->volume / (R_LITER_ATM * tk_x); + use.gas_phase_ptr->total_p += gas_comp_ptr->phase->p_soln_x; + use.gas_phase_ptr->total_moles += gas_comp_ptr->phase->moles_x; + } + } else { + gas_comp_ptr->phase->moles_x = 0; + gas_comp_ptr->phase->fraction_x = 0; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int calc_s_s_fractions(void) +/* ---------------------------------------------------------------------- */ +{ + int i, k; + LDBLE moles, n_tot; + struct s_s *s_s_ptr; + +/* + * moles and lambdas for solid solutions + */ + if (s_s_unknown == NULL) return(OK); +/* + * Calculate mole fractions and log lambda and derivative factors + */ + if (use.s_s_assemblage_ptr == NULL) return(OK); + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + s_s_ptr = &(use.s_s_assemblage_ptr->s_s[i]); + n_tot = 0; + for (k = 0; k < s_s_ptr->count_comps; k++) { + moles = s_s_ptr->comps[k].moles; + if (s_s_ptr->comps[k].moles < 0) { + moles = MIN_TOTAL; + s_s_ptr->comps[k].initial_moles = moles; + } + n_tot += moles; + } + s_s_ptr->total_moles = n_tot; + for (k = 0; k < s_s_ptr->count_comps; k++) { + moles = s_s_ptr->comps[k].moles; + if (s_s_ptr->comps[k].moles < 0) { + moles = MIN_TOTAL; + } + s_s_ptr->comps[k].fraction_x = moles / n_tot; + s_s_ptr->comps[k].log10_fraction_x = log10(moles / n_tot); + + /* all mb and jacobian items must be in x or phase to be static between models */ + s_s_ptr->comps[k].phase->log10_fraction_x = s_s_ptr->comps[k].log10_fraction_x; + } + if (s_s_ptr->a0 != 0.0 || s_s_ptr->a1 != 0) { + s_s_binary(s_s_ptr); + } else { + s_s_ideal(s_s_ptr); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_binary(struct s_s *s_s_ptr) +/* ---------------------------------------------------------------------- */ +{ + LDBLE nb, nc, n_tot, xb, xc, dnb, dnc, a0, a1; + LDBLE xb2, xb3, xb4, xc2, xc3; + LDBLE xb1, xc1; +/* + * component 0 is major component + * component 1 is minor component + * xb is the mole fraction of second component (formerly trace) + * xc is the mole fraction of first component (formerly major) +*/ +/* + * Calculate mole fractions and log lambda and derivative factors + */ + n_tot = s_s_ptr->total_moles; + + nc = s_s_ptr->comps[0].moles; + xc = nc/n_tot; + nb = s_s_ptr->comps[1].moles; + xb = nb/n_tot; +/* + * In miscibility gap + */ + a0 = s_s_ptr->a0; + a1 = s_s_ptr->a1; + if (s_s_ptr->miscibility == TRUE && xb > s_s_ptr->xb1 && xb < s_s_ptr->xb2) { + xb1 = s_s_ptr->xb1; + xc1 = 1.0 - xb1; + s_s_ptr->comps[0].fraction_x = xc1; + s_s_ptr->comps[0].log10_fraction_x = log10(xc1); + s_s_ptr->comps[0].phase->log10_fraction_x = s_s_ptr->comps[0].log10_fraction_x; + + s_s_ptr->comps[1].fraction_x = xb1; + s_s_ptr->comps[1].log10_fraction_x = log10(xb1); + s_s_ptr->comps[1].phase->log10_fraction_x = s_s_ptr->comps[1].log10_fraction_x; + + s_s_ptr->comps[0].log10_lambda = xb1*xb1*(a0 - a1*(3 -4*xb1))/LOG_10; + s_s_ptr->comps[0].phase->log10_lambda = s_s_ptr->comps[0].log10_lambda; + + s_s_ptr->comps[1].log10_lambda = xc1*xc1*(a0 + a1*(4*xb1 - 1))/LOG_10; + s_s_ptr->comps[1].phase->log10_lambda = s_s_ptr->comps[1].log10_lambda; + + s_s_ptr->comps[0].dnb = 0; + s_s_ptr->comps[0].dnc = 0; + s_s_ptr->comps[1].dnb = 0; + s_s_ptr->comps[1].dnc = 0; + s_s_ptr->comps[0].phase->dnb = 0; + s_s_ptr->comps[0].phase->dnc = 0; + s_s_ptr->comps[1].phase->dnb = 0; + s_s_ptr->comps[1].phase->dnc = 0; + } else { +/* + * Not in miscibility gap + */ + s_s_ptr->comps[0].fraction_x = xc; + s_s_ptr->comps[0].log10_fraction_x = log10(xc); + s_s_ptr->comps[0].phase->log10_fraction_x = s_s_ptr->comps[0].log10_fraction_x; + + s_s_ptr->comps[1].fraction_x = xb; + s_s_ptr->comps[1].log10_fraction_x = log10(xb); + s_s_ptr->comps[1].phase->log10_fraction_x = s_s_ptr->comps[1].log10_fraction_x; + + s_s_ptr->comps[0].log10_lambda = xb*xb*(a0 - a1*(3 -4*xb))/LOG_10; + s_s_ptr->comps[0].phase->log10_lambda = s_s_ptr->comps[0].log10_lambda; + + s_s_ptr->comps[1].log10_lambda = xc*xc*(a0 + a1*(4*xb - 1))/LOG_10; + s_s_ptr->comps[1].phase->log10_lambda = s_s_ptr->comps[1].log10_lambda; + + xc2 = xc*xc; + xc3 = xc2*xc; + xb2 = xb*xb; + xb3 = xb2*xb; + xb4 = xb3*xb; +#ifdef SKIP + /* first component */ + dnb = -2*a0*xb*xc2 - 8*a1*xb2*xc2 + 6*a1*xb*xc2 - 4*a1*xc*xb4 - 8*a1*xb3*xc2 - + 4*a1*xb2*xc3 - 2*a0*xc*xb2 - 8*a1*xc*xb3 + 6*a1*xc*xb2 + 1; + s_s_ptr->comps[0].phase->dnb = dnb/n_tot; + dnc = 2*a0*xb3 + 2*a0*xc*xb2 + 8*a1*xb4 + 8*a1*xc*xb3 - 2*a1*xb3 - 6*a1*xc*xb2; + s_s_ptr->comps[0].phase->dnc = - xb/nc + dnc/n_tot; + + /* second component */ + dnb = 2*a0*xb*xc2 + 2*a0*xc3 + 8*a1*xb2*xc2 + 8*a1*xb*xc3 - 2*a1*xb*xc2 -6*a1*xc3; + s_s_ptr->comps[1].phase->dnb = -xc/nb + dnb/n_tot; + dnc = -2*a0*xc*xb2 - 8*a1*xc*xb3 + 2*a1*xc*xb2 - 2*a0*xb*xc2 - 8*a1*xb2*xc2 + 6*a1*xb*xc2 + 1; + s_s_ptr->comps[1].phase->dnc = dnc/n_tot; +#endif + /* used derivation that did not substitute x2 = 1-x1 */ + + /* first component, df1/dn1*/ + dnc = 2*a0*xb2 + 12*a1*xc*xb2 + 6*a1*xb2; + s_s_ptr->comps[0].phase->dnc = - xb/nc + dnc/n_tot; + + + /* first component, df1/dn2*/ + dnb = 1 - 2*a0*xb + 2*a0*xb2 + 8*a1*xc*xb - 12*a1*xc*xb2 - 2*a1*xb + 2*a1*xb2; + s_s_ptr->comps[0].phase->dnb = dnb/n_tot; + + /* second component, df2/dn1 */ + dnc = 1 -2*a0*xc +2*a0*xc2 - 8*a1*xb*xc + 12*a1*xb*xc2 + 2*a1*xc - 2*a1*xc2; + s_s_ptr->comps[1].phase->dnc = dnc/n_tot; + + /* second component, df2/dn2 */ + dnb = 2*a0*xc2 + 12*a1*xb*xc2 - 6*a1*xc2; + s_s_ptr->comps[1].phase->dnb = -xc/nb + dnb/n_tot; + + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_ideal(struct s_s *s_s_ptr) +/* ---------------------------------------------------------------------- */ +{ + int k, j; + LDBLE n_tot, n_tot1; + +/* + * component 0 is major component + * component 1 is minor component + * xb is the mole fraction of second component (formerly trace) + * xc is the mole fraction of first component (formerly major) +*/ +/* + * Calculate mole fractions and log lambda and derivative factors + */ + n_tot = s_s_ptr->total_moles; + +/* + * Ideal solid solution + */ + s_s_ptr->dn = 1.0 / n_tot; + for (k = 0; k < s_s_ptr->count_comps; k++) { + n_tot1 = 0; + for (j = 0; j < s_s_ptr->count_comps; j++) { + if (j != k) { + n_tot1 += s_s_ptr->comps[j].moles; + } + } + s_s_ptr->comps[k].log10_lambda = 0; + s_s_ptr->comps[k].phase->log10_lambda = 0; + + s_s_ptr->comps[k].dnb = -(n_tot1)/(s_s_ptr->comps[k].moles*n_tot); + s_s_ptr->comps[k].phase->dnb = s_s_ptr->comps[k].dnb; + + s_s_ptr->comps[k].dn = s_s_ptr->dn; + s_s_ptr->comps[k].phase->dn = s_s_ptr->dn; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int reset(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks deltas (changes to unknowns) to make sure they are reasonable + * Scales deltas if necessary + * Updates unknowns with deltas + */ + + int i, j; + int converge; + LDBLE up, down; + LDBLE d; + LDBLE factor, f0; + LDBLE sum_deltas; + LDBLE step_up; +#ifdef SKIP + LDBLE epsilon; +#endif + LDBLE mu_calc; + LDBLE old_moles; +/*appt char name[MAX_LENGTH]; LDBLE surf_chrg_eq; + */ +/* + * Calculate interphase mass transfers + */ +#ifdef SKIP + if (punch.high_precision == FALSE) + epsilon = 1e-9; + else + epsilon = 1.e-12; +#endif + step_up = log(step_size_now); + factor = 1.; + + if ( pure_phase_unknown != NULL || s_s_unknown != NULL) { +/* + * Don't take out more mineral than is present + */ + for (i=0; itype == PP || x[i]->type == S_S_MOLES) { + if (/* delta[i] > 0.0 && */ x[i]->moles > 0.0 && delta[i] > x[i]->moles ) { + f0 = delta[i] / x[i]->moles; + if (f0 > factor) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s, Removing more than total mineral.\t%f\n", + x[i]->description, (double) f0); + } + factor=f0; + } + } else if ( delta[i] > 0.0 && x[i]->moles <= 0.0 ) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "%-10.10s\tDelta: %e\tMass: %e " + "Dissolving mineral with 0.0 mass.\n ", + x[i]->description, (double) delta[i], (double) x[i]->moles); + } + delta[i] = 0.0 ; + } else if (delta[i] < 0.0 && x[i]->moles > 0.0 && delta[i] < -100.0 ) { + f0 = -delta[i] / 100.0 ; + if (f0 > factor) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s, Precipitating too much mineral.\t%f\n", x[i]->description, (double) f0); + } + factor=f0; + } + } + } + } + } +/* + * Calculate change in element concentrations due to pure phases and gases + */ + if (pure_phase_unknown != NULL || gas_unknown != NULL || s_s_unknown != NULL) { + for(i=0; i < count_unknowns; i++) { + x[i]->delta = 0.0; + } + + for (i=0; i < count_sum_delta; i++) { + *sum_delta[i].target += *sum_delta[i].source * sum_delta[i].coef; + } + +/* + * Apply factor from minerals to deltas + */ + + + for(i=0; i < count_unknowns; i++) { + x[i]->delta /= factor; + if (x[i]->type == PP || x[i]->type == S_S_MOLES) delta[i] /= factor; + } + + } + + +/* + * Calc factor for mass balance equations for aqueous unknowns + */ + factor=1.0; + sum_deltas=0.0; + for (i=0; i < count_unknowns; i++) { + sum_deltas += fabs(delta[i]); + up = step_up; + down = up; + if (x[i]->type <= SOLUTION_PHASE_BOUNDARY) { + up = step_up; + down = 1.3 * up; + } else if (x[i]->type == MU) { + up = 100 * mu_x; +#ifdef SKIP + if (up > 0.1) { + up = 2 * mu_x; + up = 0.1; + } +#endif +#ifdef SKIP + down = 0.7 * mu_x; + if (down < 0.1) down = 0.1; +#endif + down = mu_x; + } else if (x[i]->type == AH2O) { + down = up; + } else if (x[i]->type == MH) { + up = log(pe_step_size_now); + down = 1.3*up; + } else if (x[i]->type == MH2O) { + /* ln gH2O + delta; ln(gH2O*delta); */ + /* + up = log(10.); + down = log(4.); + */ + up = log(1.3); + down = log(1.2); + + } else if (x[i]->type == PP) { + continue; + } else if (x[i]->type == GAS_MOLES) { + up = 1000. * x[i]->moles; + if (up <= 0.0) up = 1e-1; + if (up >= 1.0) up = 1.; + down = x[i]->moles; + } else if (x[i]->type == S_S_MOLES) { + continue; + } else if (x[i]->type == EXCH) { + up = step_up; + down = 1.3 * up; + } else if (x[i]->type == SURFACE) { + up = step_up; + down = 1.3 * up; + } else if (x[i]->type == SURFACE_CB) { + up = step_up; + down = 1.3 * up; + } + + if (delta[i] > 0.0) { + f0=delta[i]/up; + if (f0 > factor) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s\t%f\n",x[i]->description, (double) f0); + } + factor=f0; + } + } else { + f0=delta[i]/(-down); + if (f0 > factor) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s\t%f\n",x[i]->description, (double) f0); + } + factor=f0; + } + } + } + + /*converge=TRUE;*/ + + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nSum of deltas: %12.6f\n", (double) sum_deltas); + output_msg(OUTPUT_MESSAGE,"Factor: %12.4e\n", (double) factor); + } + factor = 1.0/factor; + + for (i=0; itype != PP && x[i]->type != S_S_MOLES) delta[i] *= factor; + } +/* + * Solution mass balances: MB, ALK, CB, SOLUTION_PHASE_BOUNDARY + */ + for (i=0; i < count_unknowns ; i++) { + if (x[i]->type == MB || x[i]->type == ALK || x[i]->type == EXCH || x[i]->type == SURFACE) { + /*if ( fabs(delta[i]) >= epsilon ) converge = FALSE;*/ + d = delta[i] / LOG_10; + /* surface */ + if (x[i]->type == SURFACE) { + old_moles = x[i]->moles; + if (x[i]->phase_unknown != NULL) { + x[i]->moles = x[i]->surface_comp->phase_proportion * + (x[i]->phase_unknown->moles - + delta[x[i]->phase_unknown->number]); + if (x[i]->phase_unknown->moles - delta[x[i]->phase_unknown->number] <= MIN_RELATED_SURFACE) { + x[i]->moles = 0.0; + if (fabs(x[i]->f) > MIN_RELATED_SURFACE) { + x[i]->master[0]->s->la -= 5.; + } + } + if (old_moles <= 0 && x[i]->moles > 0) { + x[i]->master[0]->s->la = log10(x[i]->moles) - 5.; + } + } + } + /* exch */ + if (x[i]->type == EXCH && x[i]->moles <= MIN_RELATED_SURFACE) { + x[i]->moles = 0.0; + if (fabs(x[i]->f) > MIN_RELATED_SURFACE) { + x[i]->master[0]->s->la -= 5.; + } + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e " + "%-8s%10.2e\n", x[i]->description, + "old la", (double) x[i]->master[0]->s->la, + "new la", (double) x[i]->master[0]->s->la + (double) d, + "delta", (double) delta[i], "delta/c", (double) d); + } + x[i]->master[0]->s->la += d; + if (x[i]->master[0]->s->la < (double) (DBL_MIN_10_EXP+10)) x[i]->master[0]->s->la = (double) (DBL_MIN_10_EXP+10); + +/* + * Surface charge balance + */ + + } else if ( x[i]->type == SURFACE_CB ) { + d = delta[i] / LOG_10; + if (x[i]->phase_unknown != NULL) { + x[i]->surface_charge->grams = /* !!!! x[i]->surface_comp->phase_proportion * */ + (x[i]->phase_unknown->moles - + delta[x[i]->phase_unknown->number]); + if (x[i]->surface_charge->grams <= MIN_RELATED_SURFACE) { + x[i]->surface_charge->grams = 0.0; + } + } + if (x[i]->surface_charge->grams <= MIN_RELATED_SURFACE) { + x[i]->surface_charge->grams = 0.0; + } +#ifdef SKIP + else if (fabs(delta[i]) > epsilon) { + converge=FALSE; + } +#endif + x[i]->related_moles = x[i]->surface_charge->grams; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e\n", + x[i]->description, "old f*psi", (double) x[i]->master[0]->s->la, "new f*psi", (double) x[i]->master[0]->s->la + (double) d,"delta", (double) d); + } + + x[i]->master[0]->s->la += d; + + /* recalculte g's for component */ + if (diffuse_layer_x == TRUE) { + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "\ncharge, old g, new g, dg*delta," + " dg, delta\n"); + } + for (j = 0; j < x[i]->surface_charge->count_g; j++) { + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE, "%12f\t%12.4e\t%12.4e\t%12.4e\t%12.4e\t%12.4e\n", + (double) x[i]->surface_charge->g[j].charge, + (double) x[i]->surface_charge->g[j].g, + (double) x[i]->surface_charge->g[j].g + + (double) (x[i]->surface_charge->g[j].dg * delta[i]), + (double) (x[i]->surface_charge->g[j].dg * delta[i]), + (double) x[i]->surface_charge->g[j].dg, + (double) delta[i]); + } +/*appt*/ if (use.surface_ptr->donnan != TRUE) { + x[i]->surface_charge->g[j].g += x[i]->surface_charge->g[j].dg * delta[i]; + } + } +/*appt*/ if (use.surface_ptr->donnan == TRUE) { + calc_all_donnan(); + } + } + +/* Solution phase boundary */ + } else if ( x[i]->type == SOLUTION_PHASE_BOUNDARY ) { + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + d = delta[i] / LOG_10; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old la", (double) x[i]->master[0]->s->la, "new la", (double) (x[i]->master[0]->s->la + d), "delta", (double) delta[i], "delta/c", (double) d); + } + x[i]->master[0]->s->la += d; +/* Charge balance */ + } else if ( x[i]->type == CB ) { + /*if (fabs(delta[i]) > epsilon * mu_x * mass_water_aq_x ) converge=FALSE;*/ + d = delta[i] / LOG_10; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old la", (double) x[i]->master[0]->s->la, "new la", (double) (x[i]->master[0]->s->la + d), "delta", (double) delta[i], "delta/c", (double) d); + } + x[i]->master[0]->s->la += d; +/* Ionic strength */ + } else if (x[i]->type == MU) { + + /*if (fabs(delta[i]) > epsilon * mu_x ) converge=FALSE;*/ + mu_calc = 0.5*mu_unknown->f/mass_water_aq_x; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"Calculated mu: %e\n", (double) mu_calc); + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e\n", + x[i]->description, "old mu", (double) mu_x, "new mu", + (double) (mu_x + delta[i]), + "delta", (double) delta[i]); + } + d = mu_x + delta[i]; + if (d < 1e-7) { + delta[i] = sqrt(mu_calc * mu_x) - mu_x; + mu_x = sqrt(mu_calc * mu_x); + } else { + mu_x += delta[i]; + } + if (mu_x <= 1e-8) { + mu_x = 1e-8; + } +/* Activity of water */ + } else if (x[i]->type == AH2O) { + /*if (pitzer_model == TRUE && full_pitzer == FALSE) continue;*/ + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + d = delta[i] / LOG_10; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old la", (double) x[i]->master[0]->s->la, "new la", (double) (x[i]->master[0]->s->la + d), "delta", (double) delta[i], "delta/c", (double) d); + } + s_h2o->la += d; + if (pitzer_model == FALSE) { + if (s_h2o->la < -1.0) { + d = -1.0 - s_h2o->la; + delta[i] = d * LOG_10; + s_h2o->la = -1.0; + } + } +/* pe */ + } else if (x[i]->type == MH) { + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + d = delta[i] / LOG_10; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old pe", (double) x[i]->master[0]->s->la, "new pe", (double) (x[i]->master[0]->s->la + d), "delta", (double) delta[i], "delta/c", (double) d); + } + s_eminus->la += d; +/* Mass of water */ + } else if (x[i]->type == MH2O) { + if (mass_water_switch == TRUE) continue; + /*if (fabs(delta[i]) > epsilon * mass_water_aq_x) converge=FALSE;*/ + /* ln(gh2o) + delta, log(gh2o) + d, gh2o * 10**d */ + d = exp(delta[i]); + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.2e %-9s%10.2e %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old MH2O", (double) mass_water_aq_x, "new MH2O", (double) (mass_water_aq_x * d), "delta", (double) delta[i], "10**d/c", (double) d); + } + mass_water_aq_x *= d; + mass_water_bulk_x = mass_water_aq_x + mass_water_surfaces_x; + if (debug_model == TRUE && diffuse_layer_x == TRUE) { + output_msg(OUTPUT_MESSAGE,"mass_water bulk: %e\taq: %e\tsurfaces: %e\n", + (double) mass_water_bulk_x, (double) mass_water_aq_x, (double) mass_water_surfaces_x); + } + x[i]->master[0]->s->moles = mass_water_aq_x/gfw_water; + + if (mass_water_aq_x < 1e-10) { + sprintf(error_string, "Mass of water is less than 1e-10 kilogram.\n" + "The aqueous phase may not be stable relative to given masses of minerals."); + warning_msg(error_string); + stop_program = TRUE; + return(TRUE); + } +/* Pure phases */ + } else if (x[i]->type == PP) { + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.2e %-9s%10.2e %-6s%10.2e\n", + x[i]->description, "old mass", (double) x[i]->moles, + "new mass", (double) (x[i]->moles - delta[i]), "delta", (double) delta[i]); + } + x[i]->moles -= delta[i]; +/* if (fabs(x[i]->moles) < MIN_RELATED_SURFACE) x[i]->moles = 0.0; */ + } else if (x[i]->type == GAS_MOLES) { + + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + /*if (gas_in == TRUE && fabs(residual[i]) > epsilon) converge=FALSE;*/ + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.2e %-9s%10.2e %-6s%10.2e\n", + x[i]->description, "old mol", (double) x[i]->moles, + "new mol", (double) (x[i]->moles + delta[i]), + "delta", (double) delta[i]); + } + x[i]->moles += delta[i]; + if (x[i]->moles < MIN_TOTAL) x[i]->moles = MIN_TOTAL; + } else if (x[i]->type == S_S_MOLES) { + + /*if (fabs(delta[i]) > epsilon) converge=FALSE;*/ + /*if (x[i]->s_s_in == TRUE && fabs(residual[i]) > epsilon) converge=FALSE;*/ + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.2e %-9s%10.2e %-6s%10.2e\n", + x[i]->description, "old mol", (double) x[i]->moles, + "new mol", (double) (x[i]->moles - delta[i]), + "delta", (double) delta[i]); + } + x[i]->moles -= delta[i]; + if (x[i]->moles < MIN_TOTAL) x[i]->moles = MIN_TOTAL; + x[i]->s_s_comp->moles = x[i]->moles; +/* Pitzer gamma */ + } else if ( x[i]->type == PITZER_GAMMA ) { + if (full_pitzer == FALSE) continue; + d = delta[i]; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.5f %-9s%10.5f %-6s%10.2e %-8s%10.2e\n", x[i]->description, "old lg", (double) x[i]->s->lg, "new lg", (double) (x[i]->s->lg + d), "delta", (double) delta[i], "delta", (double) d); + } + x[i]->s->lg += d; + } + } +/* + * Reset total molalities in mass balance equations + */ + if (pure_phase_unknown != NULL || gas_unknown != NULL || s_s_unknown != NULL) { + for (i=0; itype == MB || x[i]->type == MH || + x[i]->type == MH2O || + x[i]->type == CB || x[i]->type == EXCH || + x[i]->type == SURFACE ) { + /*if (fabs(x[i]->delta) > epsilon*x[i]->moles) converge = FALSE;*/ + if (x[i]->type == SURFACE) x[i]->delta = 0.0; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%-10.10s %-9s%10.2e %-9s%10.2e %-6s%10.2e\n", + x[i]->description, "old mole", (double) x[i]->moles, + "new mole", (double) (x[i]->moles + x[i]->delta), + "delta", (double) x[i]->delta); + } + x[i]->moles += x[i]->delta; + } + } + } + converge = FALSE; + return(converge); +} +/* ---------------------------------------------------------------------- */ +int residuals(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates residuals for all equations + */ + int i; + int converge; + + LDBLE toler; + LDBLE sum_residual; + LDBLE sinh_constant; + + sum_residual = 0.0; + +/* + * Calculate residuals + */ + converge = TRUE; +#ifdef SKIP + if (punch.high_precision == FALSE) + toler = 1e-8; + else + toler = 1.e-12; +#endif + toler = convergence_tolerance; + + for (i=0; i < count_unknowns; i++) { + if (x[i]->type == MB ) { + residual[i] = x[i]->moles - x[i]->f; + if (fabs(residual[i]) > toler * x[i]->moles && x[i]->moles > MIN_TOTAL ) { + /* + fprintf(stderr,"Residuals %d: %s %d %e\n", iterations, x[i]->description, i, residual[i]); + */ + converge = FALSE; + } + } else if (x[i]->type == ALK) { + residual[i] = x[i]->moles - x[i]->f; + if (fabs(residual[i]) > toler * x[i]->moles ) converge = FALSE; + } else if (x[i]->type == SOLUTION_PHASE_BOUNDARY) { + residual[i] = x[i]->f * LOG_10; + if (fabs(residual[i]) > toler ) converge = FALSE; + } else if (x[i]->type == CB) { + residual[i] = - x[i]->f; + if (ph_unknown == charge_balance_unknown) { + residual[i] += x[i]->moles; + } + if (fabs(residual[i]) >= toler * mu_x * mass_water_aq_x ) converge = FALSE; + } else if (x[i]->type == MU && pitzer_model == FALSE) { + residual[i] = mass_water_aq_x * mu_x - 0.5*x[i]->f; + if (fabs(residual[i]) > toler*mu_x * mass_water_aq_x ) converge = FALSE; + } else if (x[i]->type == AH2O /*&& pitzer_model == FALSE*/) { + /*if (pitzer_model == TRUE && full_pitzer == FALSE) continue;*/ + residual[i] = mass_water_aq_x*exp(s_h2o->la * LOG_10) - mass_water_aq_x + 0.017 * x[i]->f; + if (pitzer_model) { + residual[i] = pow(10.0,s_h2o->la) - AW; + if (full_pitzer == FALSE) { + residual[i] = 0.0; + } + } + if (fabs(residual[i]) > toler ) converge = FALSE; + } else if (x[i]->type == MH && pitzer_model == FALSE) { +#ifdef COMBINE + residual[i] = x[i]->moles - x[i]->f; +#else + residual[i] = (x[i]->moles - 2*s_h2o->moles) - x[i]->f; + x[i]->f += 2 * s_h2o->moles; +#endif + if (mass_water_switch == TRUE) { + residual[i] -= 2 * (mass_oxygen_unknown->moles - mass_oxygen_unknown->f); + } +#ifdef COMBINE +#ifndef COMBINE_CHARGE + if (fabs(residual[i]) > toler*(x[i]->moles + 2 * mass_oxygen_unknown->moles)) converge = FALSE; +#else + if (fabs(residual[i]) > toler*(x[i]->moles + 2 * mass_oxygen_unknown->moles + charge_balance_unknown->moles)) converge = FALSE; +#endif +#else + if (fabs(residual[i]) > toler*x[i]->moles ) converge = FALSE; +#endif + } else if (x[i]->type == MH2O) { + if (mass_water_switch == TRUE) continue; +#ifdef COMBINE + residual[i] = x[i]->moles - x[i]->f; +#else + residual[i] = (x[i]->moles - s_h2o->moles) - x[i]->f; + x[i]->f += s_h2o->moles; +#endif + if (fabs(residual[i]) > 0.01 * toler*x[i]->moles ) converge = FALSE; + } else if (x[i]->type == PP) { + residual[i] = x[i]->f * LOG_10; + if (x[i]->pure_phase->add_formula == NULL) { + if (x[i]->dissolve_only == TRUE) { + if ((residual[i] > toler && x[i]->moles > 0.0) || (residual[i] < -toler && (x[i]->pure_phase->initial_moles - x[i]->moles) > 0)) { + converge = FALSE; + } + } else { + if (residual[i] < -toler || iterations < 1) converge = FALSE; + } + } else { + /* if (x[i]->moles > 0.0 && fabs(residual[i]) > toler) converge = FALSE;*/ + if (residual[i] < -toler || iterations < 1) { + converge = FALSE; + } + } + } else if (x[i]->type == GAS_MOLES) { + residual[i] = x[i]->gas_phase->total_p - x[i]->f; + if (fabs(residual[i]) > toler && gas_in == TRUE) converge = FALSE; + } else if (x[i]->type == S_S_MOLES) { + residual[i] = x[i]->f * LOG_10; + if (fabs(residual[i]) > toler && x[i]->s_s_in == TRUE) converge = FALSE; + } else if (x[i]->type == EXCH) { + residual[i] = x[i]->moles - x[i]->f; + if (x[i]->moles <= MIN_RELATED_SURFACE) { + if (fabs(residual[i]) > toler) converge = FALSE; + } else if (fabs(residual[i]) > toler * x[i]->moles ) { + converge = FALSE; + } + } else if (x[i]->type == SURFACE) { + residual[i] = x[i]->moles - x[i]->f; + if (x[i]->moles <= MIN_RELATED_SURFACE) { + if ( fabs(residual[i]) > toler ) converge = FALSE; + } else if (fabs(residual[i]) > toler * x[i]->moles ) { + converge = FALSE; + } + } else if (x[i]->type == PITZER_GAMMA) { + if (full_pitzer == FALSE) continue; + residual[i] = x[i]->s->lg - x[i]->s->lg_pitzer; + if (fabs(residual[i]) > toler ) { + /* + fprintf(stderr,"Residuals %d: %s %d %e\n", iterations, x[i]->description, i, residual[i]); + */ + converge = FALSE; + } + } else if (x[i]->type == SURFACE_CB) { + /*sinh_constant = 0.1174;*/ + sinh_constant = sqrt(8*EPSILON*EPSILON_ZERO*(R_KJ_DEG_MOL*1000)*tk_x*1000); +/* if (x[i]->surface_charge->grams <= MIN_RELATED_SURFACE) { */ + if (x[i]->surface_charge->grams == 0) { + residual[i] = 0.0; + } else if (diffuse_layer_x == TRUE) { + residual[i] = - x[i]->f; + } else { +/* + * sinh_constant is (8 e e0 R T 1000)**1/2 + * = sqrt(8*EPSILON*EPSILON_ZERO*(R_KJ_DEG_MOL*1000)*t_x*1000) + * ~ 0.1174 at 25C + */ + residual[i] = sinh_constant * sqrt(mu_x) * + sinh(x[i]->master[0]->s->la * LOG_10) - + x[i]->f * F_C_MOL / + (x[i]->surface_charge->specific_area * x[i]->surface_charge->grams); + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"Charge/Potential\n"); + if (x[i]->surface_charge->grams > 0) { + output_msg(OUTPUT_MESSAGE,"\tSum of surface charge %e eq\n", + (double) (x[i]->f /* F_C_MOL / (x[i]->surface_charge->specific_area * x[i]->surface_charge->grams)*/)); + } else { + output_msg(OUTPUT_MESSAGE,"\tResidual %e\n", (double) x[i]->f ); + } + output_msg(OUTPUT_MESSAGE,"\t grams %g\n", (double) x[i]->surface_charge->grams); + output_msg(OUTPUT_MESSAGE,"\tCharge from potential %e eq\n", + (double) (x[i]->surface_charge->specific_area * x[i]->surface_charge->grams / F_C_MOL * + sinh_constant * sqrt(mu_x) * + sinh(x[i]->master[0]->s->la * LOG_10))); + output_msg(OUTPUT_MESSAGE,"\t FPsi/2RT %e\n", + (double) (x[i]->master[0]->s->la * LOG_10)); + output_msg(OUTPUT_MESSAGE,"\t Sinh(FPsi/2RT) %e\n", + sinh(x[i]->master[0]->s->la * LOG_10)); + output_msg(OUTPUT_MESSAGE,"\t Cosh(FPsi/2RT) %e\n", + cosh(x[i]->master[0]->s->la * LOG_10)); + output_msg(OUTPUT_MESSAGE,"\t Sqrt(mu_x) %e\n", + sqrt(mu_x)); + } + if (x[i]->surface_charge->grams > MIN_RELATED_SURFACE && fabs(residual[i]) > toler ) converge = FALSE; + } +/* + * Store residuals in array + */ + array[(i+1)*(count_unknowns+1)-1] = residual[i]; + sum_residual += fabs(residual[i]); + } +/* + * Return + */ + if (pitzer_model == TRUE && iterations < 1) return(OK); + if (converge == TRUE ) { + return (CONVERGED); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set(int initial) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sets initial guesses for unknowns if initial == TRUE + * Revises guesses whether initial is true or not + */ + int i; + struct solution *solution_ptr; +/* + * Set initial log concentrations to zero + */ + if (pitzer_model == TRUE) return(set_pz(initial)); + iterations = -1; + solution_ptr = use.solution_ptr; + for (i=0; i < count_s_x; i++) { + s_x[i]->lm = LOG_ZERO_MOLALITY; + s_x[i]->lg = 0.0; + } +/* + * Set master species activities + */ + + tc_x=solution_ptr->tc; + tk_x=tc_x+273.15; +/* + * H+, e-, H2O + */ + mass_water_aq_x = solution_ptr->mass_water; + mu_x = solution_ptr->mu; + s_h2o->moles = mass_water_aq_x/gfw_water; + s_h2o->la = log10(solution_ptr->ah2o); + s_hplus->la = - solution_ptr->ph; + s_hplus->lm = s_hplus->la; + s_hplus->moles = exp(s_hplus->lm * LOG_10)*mass_water_aq_x; + s_eminus->la= - solution_ptr->solution_pe; + if (initial == TRUE) initial_guesses(); + if (diffuse_layer_x == TRUE) initial_surface_water(); + revise_guesses(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_guesses(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make initial guesses for activities of master species and + * ionic strength + */ + int i; + struct solution *solution_ptr; + + solution_ptr = use.solution_ptr; + mu_x = s_hplus->moles + exp((solution_ptr->ph - 14.) * LOG_10) * mass_water_aq_x; + mu_x /= mass_water_aq_x; + s_h2o->la=0.0; + for ( i=0; i < count_unknowns; i++ ) { + if (x[i] == ph_unknown || x[i] == pe_unknown ) continue; + if (x[i]->type < CB) { + mu_x += x[i]->moles / mass_water_aq_x * 0.5 * x[i]->master[0]->s->z * + x[i]->master[0]->s->z; + x[i]->master[0]->s->la = log10(x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == CB) { + x[i]->master[0]->s->la = log10(0.001 * x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == SOLUTION_PHASE_BOUNDARY) { + x[i]->master[0]->s->la = log10(0.001 * x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == EXCH) { + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + x[i]->master[0]->s->la = log10(x[i]->moles); + } + } else if (x[i]->type == SURFACE) { + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + x[i]->master[0]->s->la = log10(0.1 * x[i]->moles); + } + } else if (x[i]->type == SURFACE_CB) { + x[i]->master[0]->s->la = 0.0; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int revise_guesses(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Revise la's of master species + */ + int i; + int iter, max_iter, repeat, fail; + LDBLE weight, f; +/*appt char name[MAX_LENGTH]; LDBLE surf_chrg_eq; + */ + max_iter = 10; + gammas(mu_x); + iter = 0; + repeat = TRUE; + fail = FALSE;; + while ( repeat == TRUE ) { + iter++; + if (debug_set == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nBeginning set iteration %d.\n", iter); + } + if (iter == max_iter + 1) { + output_msg(OUTPUT_LOG, "Did not converge in set, iteration %d.\n", iterations); + fail = TRUE; + } + if (iter > 2*max_iter) { + output_msg(OUTPUT_LOG, "Did not converge with relaxed criteria in set.\n"); + return(OK); + } + molalities(TRUE); + mb_sums(); + if (state < REACTION) { + sum_species(); + } else { + for (i = 0; i < count_unknowns; i++) { + x[i]->sum = x[i]->f; + } + } +/* debug + if (debug_set == TRUE) { + pr.species = TRUE; + pr.all = TRUE; + print_species(); + } + */ + repeat=FALSE; + for ( i=0; i < count_unknowns; i++ ) { + if (x[i] == ph_unknown || x[i] == pe_unknown) continue; + if (x[i]->type == MB || +/* x[i]->type == ALK || */ + x[i]->type == CB || + x[i]->type == SOLUTION_PHASE_BOUNDARY || + x[i]->type == EXCH || + x[i]->type == SURFACE ) { + + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\t%5s at beginning of set %d: %e\t%e\t%e\n", x[i]->description, iter, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + if (fabs(x[i]->moles) < 1e-30) x[i]->moles = 0; + f = fabs(x[i]->sum); + if (f == 0 && x[i]->moles == 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + continue; + } else if (f == 0) { + repeat = TRUE; + x[i]->master[0]->s->la += 5; +/*!!!!*/ if (x[i]->master[0]->s->la < -999.) x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else if (fail == TRUE && f < 1.5 * fabs(x[i]->moles)) { + continue; + } else if (f > 1.5 * fabs(x[i]->moles) || f < 1e-5 * fabs(x[i]->moles) ) { + weight = (f < 1e-5 * fabs(x[i]->moles)) ? 0.3 : 1.0; + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + repeat = TRUE; + x[i]->master[0]->s->la += weight * log10(fabs(x[i]->moles / x[i]->sum)); + } + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t%5s not converged in set %d: %e\t%e\t%e\n", x[i]->description, iter, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + } + } else if (x[i]->type == ALK) { + f = total_co2; + if (fail == TRUE && f < 1.5 * fabs(x[i]->moles)) { + continue; + } + if (f > 1.5 * fabs(x[i]->moles) || f < 1e-5 * fabs(x[i]->moles) ) { + repeat = TRUE; + weight = (f < 1e-5 * fabs(x[i]->moles)) ? 0.3 : 1.0; + x[i]->master[0]->s->la += weight * + log10(fabs(x[i]->moles / x[i]->sum)); + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"%s not converged in set. %e\t%e\t%e\n", x[i]->description, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + } + } + } + } + output_msg(OUTPUT_LOG,"Iterations in revise_guesses: %d\n", iter); + mu_x = mu_unknown->f * 0.5 / mass_water_aq_x; + if (mu_x <= 1e-8) { + mu_x = 1e-8; + } + gammas(mu_x); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int sum_species(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates total alk, total carbon, total co2, electrical balance, + * total hydrogen, and total oxygen. + * + * Sorts species for summing and printing based on valence state and + * concentrations. + * + * Sums total valence states and stores in master[i]->total. + */ + int i, j; + struct master *master_ptr; +/* + * Set global variables + */ + ph_x = -s_hplus->la; + solution_pe_x = -s_eminus->la; + ah2o_x = exp(s_h2o->la * LOG_10); + density_x = 1.0; + if (s_o2 != NULL) s_o2->moles = under(s_o2->lm) * mass_water_aq_x; + if (s_h2 != NULL) s_h2->moles = under(s_h2->lm) * mass_water_aq_x; + +/* + * Calculate sums + */ + total_alkalinity = 0.0; + total_carbon = 0.0; + total_co2 = 0.0; + cb_x = 0.0; + total_ions_x = 0.0; + total_o_x = 0.0; + total_h_x = 0.0; + for (i=0; i < count_s_x; i++) { + if (s_x[i]->type == EX ) continue; + if (s_x[i]->type == SURF ) continue; + cb_x += s_x[i]->z * s_x[i]->moles; + total_ions_x += fabs(s_x[i]->z * s_x[i]->moles); + total_alkalinity += s_x[i]->alk * s_x[i]->moles; + total_carbon += s_x[i]->carbon * s_x[i]->moles; + total_co2 += s_x[i]->co2 * s_x[i]->moles; + total_h_x += s_x[i]->h * s_x[i]->moles; + total_o_x += s_x[i]->o * s_x[i]->moles; + } +/* + * Sum valence states, put in master->total + */ + for (i=0; i < count_master; i++) { + master[i]->total=0.0; + master[i]->total_primary = 0.0; + } + for (i=0; i < count_species_list; i++) { + if (species_list[i].master_s->secondary != NULL) { + master_ptr = species_list[i].master_s->secondary; + } else { + master_ptr = species_list[i].master_s->primary; + } + master_ptr->total += species_list[i].s->moles * species_list[i].coef; + } +/* + * Calculate mass-balance sums + */ + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == MB || + x[i]->type == SOLUTION_PHASE_BOUNDARY || + x[i]->type == EXCH || + x[i]->type == SURFACE || + ( x[i]->type == CB && x[i] != ph_unknown && x[i] != pe_unknown ) ) { + x[i]->sum = 0.0; + for (j = 0; x[i]->master[j] != NULL; j++) { + x[i]->sum += x[i]->master[j]->total; + } + } else if (x[i]->type == ALK) { + x[i]->sum = total_co2; + } + } +/* + * Calculate total element concentrations + */ + for (i = 0; i < count_master; i++) { + master[i]->elt->primary->total_primary += + master[i]->total; + } + /* + * Calculate isotope ratios + */ + calculate_values(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_model(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Use extra iterative loop to converge on g_factors + */ + int i, g_iterations, debug_diffuse_layer_save, debug_model_save; + +/* + * Allocate space for g factors for diffuse layer in surface complexation + */ + debug_diffuse_layer_save = debug_diffuse_layer; + debug_model_save = debug_model; + if (last_model.force_prep == TRUE) { + same_model = FALSE; + } else { + same_model = check_same_model(); + } + if (diffuse_layer_x == TRUE && same_model == FALSE) { + for (i=0; i < count_s; i++) { + s[i]->diff_layer = (struct species_diff_layer *) free_check_null(s[i]->diff_layer); + s[i]->diff_layer = (struct species_diff_layer *) PHRQ_malloc((size_t) use.surface_ptr->count_charge * sizeof (struct species_diff_layer)); + if (s[i]->diff_layer == NULL) malloc_error(); + } + } + prep(); + k_temp(tc_x); + if (use.surface_ptr->donnan == TRUE) { + initial_surface_water(); + calc_init_donnan(); + } else { + calc_init_g(); + } + if (state >= REACTION && use.surface_ptr->new_def == FALSE) { + set(FALSE); + } else { + set(TRUE); + } + if (model() == ERROR) return(ERROR); + g_iterations = 0; + if (use.surface_ptr->donnan == TRUE) { + do { + g_iterations++; + k_temp(tc_x); + gammas(mu_x); + molalities(TRUE); + mb_sums(); + if (model() == ERROR) return(ERROR); + if (use.surface_ptr->related_phases != TRUE && use.surface_ptr->related_rate != TRUE) initial_surface_water(); + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "Surface_model (Donnan approximation): %d g_iterations, %d model iterations\n", + g_iterations, iterations); + } + } while (calc_all_donnan() == FALSE && g_iterations < itmax); + } else { + do { + g_iterations++; + if (g_iterations > itmax - 10) { + debug_model = TRUE; + debug_diffuse_layer = TRUE; + } + k_temp(tc_x); + gammas(mu_x); + molalities(TRUE); + mb_sums(); + if (model() == ERROR) return(ERROR); + if (use.surface_ptr->related_phases != TRUE && use.surface_ptr->related_rate != TRUE) initial_surface_water(); + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "Surface_model (full integration): %d g_iterations, %d iterations\n", + g_iterations, iterations); + } + } while (calc_all_g() == FALSE && g_iterations < itmax); + } + if (g_iterations >= itmax) { + error_msg("Did not converge on g (diffuse layer excess)", STOP); + } +/* + print_all(); + */ + debug_diffuse_layer = debug_diffuse_layer_save; + debug_model = debug_model_save; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int free_model_allocs(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * free space allocated in model + */ + int i; + if (x != NULL) { + for (i = 0; i < max_unknowns; i++) { + unknown_free(x[i]); + } + } + x = (struct unknown **) free_check_null(x); + max_unknowns = 0; + array = (LDBLE *) free_check_null(array); + delta = (LDBLE *) free_check_null(delta); + residual = (LDBLE *) free_check_null(residual); + s_x = (struct species **) free_check_null(s_x); + sum_mb1 = (struct list1*) free_check_null(sum_mb1); + sum_mb2 = (struct list2 *) free_check_null(sum_mb2); + sum_jacob0 = (struct list0 *) free_check_null(sum_jacob0); + sum_jacob1 = (struct list1 *) free_check_null(sum_jacob1); + sum_jacob2 = (struct list2 *) free_check_null(sum_jacob2); + sum_delta = (struct list2 *) free_check_null(sum_delta); + charge_group = (struct charge_group *) free_check_null(charge_group); + return(OK); +} +#ifdef SLNQ +/* ---------------------------------------------------------------------- */ +int add_trivial_eqns(int rows, int cols, LDBLE *matrix) +/* ---------------------------------------------------------------------- */ +{ + int r, i, j; + r = rows; + if (rows == cols) return(OK); + if (rows > cols) return(ERROR); + for (i = 0; i < cols; i++) { + for (j = 0; j < rows; j++) { + if (matrix[j*(cols+1) + i] != 0.0) break; + } + if (j < rows) continue; + for (j = 0; j < cols+1; j++) matrix[r*(cols+1) + j] = 0.0; + matrix[r*(cols+1) + i] = 1.0; + r++; + } + if (r == cols) return(OK); + return(ERROR); +} +#endif +#define ZERO_TOL 1.0e-30 +/* ---------------------------------------------------------------------- */ +LDBLE s_s_root(LDBLE a0, LDBLE a1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE x0, y0, x1, y1, xb, miny; + +/* + * Bracket answer + */ + x0 = 0.0; + x1 = 0.0; + y0 = s_s_f( x0, a0, a1, kc, kb, xcaq, xbaq); + miny = fabs(y0); + for (i = 1; i <= 10; i++) { + x1 = (LDBLE) i / 10; + y1 = s_s_f( x1, a0, a1, kc, kb, xcaq, xbaq); + if (fabs(y1) < miny) { + miny = fabs(y1); + } + if (y0*y1 < 0) { + break; + } else { + x0 = x1; + y0 = y1; + } + } +/* + * Interval halve + */ + if (i > 10) { + xb = 0.0; + } else { + xb = s_s_halve(a0, a1, x0, x1, kc, kb, xcaq, xbaq); + } + return(xb); +} +/* ---------------------------------------------------------------------- */ +LDBLE s_s_halve(LDBLE a0, LDBLE a1, LDBLE x0, LDBLE x1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE x, y0, dx, y; + + y0 = s_s_f( x0, a0, a1, kc, kb, xcaq, xbaq); + dx = (x1 - x0); +/* + * Loop for interval halving + */ + for (i = 0; i < 100; i++) { + dx *= 0.5; + x = x0 + dx; + y = s_s_f( x, a0, a1, kc, kb, xcaq, xbaq); + if (dx < 1e-8 || y == 0) { + break; + } +#ifdef SKIP + if (y0*y < 0) { + x1 = x; + } else { + x0 = x; + y0 = y; + } +#endif + if (y0*y >= 0) { + x0 = x; + y0 = y; + } + } + return(x0 + dx); +} +/* ---------------------------------------------------------------------- */ +LDBLE s_s_f(LDBLE xb, LDBLE a0, LDBLE a1, LDBLE kc, LDBLE kb, LDBLE xcaq, LDBLE xbaq) +/* ---------------------------------------------------------------------- */ +{ +/* + * Need root of this function to determine xb + */ + LDBLE lb, lc, f, xc, r; + xc = 1 - xb; + if (xb == 0) xb = 1e-20; + if (xc == 0) xc = 1e-20; + lc = exp((a0-a1*(-4*xb + 3))*xb*xb); + lb = exp((a0+a1*(4*xb - 3))*xc*xc); + r = lc*kc/(lb*kb); + f = xcaq*(xb/r + xc) + xbaq*(xb + r*xc) - 1; + return(f); +} + + + diff --git a/nvector.cpp b/nvector.cpp new file mode 100644 index 00000000..331479d8 --- /dev/null +++ b/nvector.cpp @@ -0,0 +1,193 @@ +/******************************************************************* + * * + * File : nvector.c * + * Programmers : Radu Serban, LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for a generic NVECTOR * + * package. It contains the implementation of the N_Vector * + * kernels listed in nvector.h. * + * * + *******************************************************************/ + +#include "nvector.h" /* generic M_Env and N_Vector */ +#include "output.h" +static char const svnid[] = "$Id: nvector.c 78 2005-02-01 22:47:12Z dlpark $"; + +N_Vector N_VNew(integertype n, M_Env machEnv) +{ + N_Vector v_new; + v_new = machEnv->ops->nvnew(n, machEnv); + return(v_new); +} + +N_Vector_S N_VNew_S(integertype ns, integertype n, M_Env machEnv) +{ + N_Vector_S vs_new; + vs_new = machEnv->ops->nvnewS(ns, n, machEnv); + return(vs_new); +} + +void N_VFree(N_Vector v) +{ + v->menv->ops->nvfree(v); +} + +void N_VFree_S(integertype ns, N_Vector_S vs) +{ + (*vs)->menv->ops->nvfreeS(ns, vs); +} + +N_Vector N_VMake(integertype n, realtype *v_data, M_Env machEnv) +{ + N_Vector v_new; + v_new = machEnv->ops->nvmake(n, v_data, machEnv); + return(v_new); +} + +void N_VDispose(N_Vector v) +{ + v->menv->ops->nvdispose(v); +} + +realtype *N_VGetData(N_Vector v) +{ + realtype *data; + data = v->menv->ops->nvgetdata(v); + return(data); +} + +void N_VSetData(realtype *v_data, N_Vector v) +{ + v->menv->ops->nvsetdata(v_data, v); +} + +void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z) +{ + z->menv->ops->nvlinearsum(a, x, b, y, z); +} + +void N_VConst(realtype c, N_Vector z) +{ + z->menv->ops->nvconst(c, z); +} + +void N_VProd(N_Vector x, N_Vector y, N_Vector z) +{ + z->menv->ops->nvprod(x, y, z); +} + +void N_VDiv(N_Vector x, N_Vector y, N_Vector z) +{ + z->menv->ops->nvdiv(x, y, z); +} + +void N_VScale(realtype c, N_Vector x, N_Vector z) +{ + z->menv->ops->nvscale(c, x, z); +} + +void N_VAbs(N_Vector x, N_Vector z) +{ + z->menv->ops->nvabs(x, z); +} + +void N_VInv(N_Vector x, N_Vector z) +{ + z->menv->ops->nvinv(x, z); +} + +void N_VAddConst(N_Vector x, realtype b, N_Vector z) +{ + z->menv->ops->nvaddconst(x, b, z); +} + +realtype N_VDotProd(N_Vector x, N_Vector y) +{ + realtype prod; + prod = y->menv->ops->nvdotprod(x, y); + return(prod); +} + +realtype N_VMaxNorm(N_Vector x) +{ + realtype norm; + norm = x->menv->ops->nvmaxnorm(x); + return(norm); +} + +realtype N_VWrmsNorm(N_Vector x, N_Vector w) +{ + realtype norm; + norm = x->menv->ops->nvwrmsnorm(x, w); + return(norm); +} + +realtype N_VMin(N_Vector x) +{ + realtype minval; + minval = x->menv->ops->nvmin(x); + return(minval); +} + +realtype N_VWL2Norm(N_Vector x, N_Vector w) +{ + realtype norm; + norm = x->menv->ops->nvwl2norm(x, w); + return(norm); +} + +realtype N_VL1Norm(N_Vector x) +{ + realtype norm; + norm = x->menv->ops->nvl1norm(x); + return(norm); +} + +void N_VOneMask(N_Vector x) +{ + x->menv->ops->nvonemask(x); +} + +void N_VCompare(realtype c, N_Vector x, N_Vector z) +{ + z->menv->ops->nvcompare(c, x, z); +} + +booleantype N_VInvTest(N_Vector x, N_Vector z) +{ + booleantype flag; + flag = z->menv->ops->nvinvtest(x, z); + return(flag); +} + +booleantype N_VConstrProdPos(N_Vector c, N_Vector x) +{ + booleantype flag; + flag = x->menv->ops->nvconstrprodpos(c, x); + return(flag); +} + +booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m) +{ + booleantype flag; + flag = x->menv->ops->nvconstrmask(c, x, m); + return(flag); +} + +realtype N_VMinQuotient(N_Vector num, N_Vector denom) +{ + realtype quotient; + quotient = num->menv->ops->nvminquotient(num, denom); + return(quotient); +} + +void N_VPrint(N_Vector x) +{ + x->menv->ops->nvprint(x); +} diff --git a/nvector.h b/nvector.h new file mode 100644 index 00000000..9be6345d --- /dev/null +++ b/nvector.h @@ -0,0 +1,441 @@ +/******************************************************************* + * * + * File : nvector.h * + * Programmers : Radu Serban, LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the header file for a generic NVECTOR package. * + * It defines the N_Vector and M_Env structures: * + * M_Env has an implementation-dependent 'content' field * + * which contains the data needed to generate a new * + * nvector in that implementation and an 'ops' filed * + * which is a structure listing operations acting on * + * such nvectors. * + * N_Vector has an implementation-dependent 'content' field * + * which contains the description and actual data of * + * the nvector and a 'menv' field which points to the * + * M_Env structure used in creating the nvector. * + * * + * Part I of this file contains type declarations for the * + * the following structures: _generic_M_Env, _generic_N_Vector, * + * and _generic_N_Vector_Ops, as well as references to pointers * + * to such structures (M_Env and N_Vector). * + * * + * Part II of this file contains the prototypes for the vector * + * kernels which operate on N_Vector. * + * * + * A particular implementation of an NVECTOR package must then * + * specify the 'content' fields of M_Env and N_Vector, define * + * the propotypes for kernel operations on those N_Vectors * + * (NOTE: kernel routine names must be unique to that * + * implementation), and finally provide an initialization * + * routine (which generates an M_Env with that particular * + * 'content' field and links the defined vector kernel routines * + * into the 'ops' field). * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidnvector[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef included_nvector_h +#define included_nvector_h + +#include "sundialstypes.h" /* definition of types */ + +/**************************************************************** + * Generic definitions of machine environment and N_Vector * + ****************************************************************/ + +/* Forward reference for pointer to N_Vector_Ops object */ +typedef struct _generic_N_Vector_Ops *N_Vector_Ops; + +/* Forward reference for pointer to M_Env object */ +typedef struct _generic_M_Env *M_Env; + +/* Forward reference for pointer to N_Vector object */ +typedef struct _generic_N_Vector *N_Vector; + +/* Define array of N_Vectors */ +typedef N_Vector *N_Vector_S; + +/* Structure containing function pointers to vector operations */ +struct _generic_N_Vector_Ops { + N_Vector (*nvnew)(integertype, M_Env); + N_Vector_S (*nvnewS)(integertype, integertype, M_Env); + void (*nvfree)(N_Vector); + void (*nvfreeS)(integertype, N_Vector_S); + N_Vector (*nvmake)(integertype, realtype *, M_Env); + void (*nvdispose)(N_Vector); + realtype* (*nvgetdata)(N_Vector); + void (*nvsetdata)(realtype *, N_Vector); + void (*nvlinearsum)(realtype, N_Vector, realtype, N_Vector, N_Vector); + void (*nvconst)(realtype, N_Vector); + void (*nvprod)(N_Vector, N_Vector, N_Vector); + void (*nvdiv)(N_Vector, N_Vector, N_Vector); + void (*nvscale)(realtype, N_Vector, N_Vector); + void (*nvabs)(N_Vector, N_Vector); + void (*nvinv)(N_Vector, N_Vector); + void (*nvaddconst)(N_Vector, realtype, N_Vector); + realtype (*nvdotprod)(N_Vector, N_Vector); + realtype (*nvmaxnorm)(N_Vector); + realtype (*nvwrmsnorm)(N_Vector, N_Vector); + realtype (*nvmin)(N_Vector); + realtype (*nvwl2norm)(N_Vector, N_Vector); + realtype (*nvl1norm)(N_Vector); + void (*nvonemask)(N_Vector); + void (*nvcompare)(realtype, N_Vector, N_Vector); + booleantype (*nvinvtest)(N_Vector, N_Vector); + booleantype (*nvconstrprodpos)(N_Vector, N_Vector); + booleantype (*nvconstrmask)(N_Vector, N_Vector, N_Vector); + realtype (*nvminquotient)(N_Vector, N_Vector); + void (*nvprint)(N_Vector); +}; + +/* A machine environment is a structure with an implementation + dependent 'content' representation (used to generate a new vector + in that implementation), a set of operations defined in the above + structure, and an ID tag */ +struct _generic_M_Env { + void *content; + struct _generic_N_Vector_Ops *ops; + char tag[8]; +}; + +/* A vector is a structure with an implementation dependent content + representation and a pointer to the machine environment + corresponding to that implementation */ +struct _generic_N_Vector { + void *content; + struct _generic_M_Env *menv; +}; + +/**************************************************************** + * Functions exported by nvector * + ****************************************************************/ + +/*--------------------------------------------------------------* + * Function : N_VNew * + * Usage : v = N_VNew(n, machEnv); * + *--------------------------------------------------------------* + * Returns a new N_Vector of length n. The parameter machEnv * + * is a pointer to machine environment-specific information. * + * If there is not enough memory for a new N_Vector, then * + * N_VNew returns NULL. * + *--------------------------------------------------------------*/ + +N_Vector N_VNew(integertype n, M_Env machEnv); + +/*--------------------------------------------------------------* + * Function : N_VNew_S * + * Usage : v = N_VNew_S(ns, n, machEnv); * + *--------------------------------------------------------------* + * Returns an array of ns new N_Vectors of length n. The * + * parameter machEnv is a pointer to machine environment * + * specific information. * + * If there is not enough memory for a new array of N_Vectors * + * or for one of the components, then N_VNew_S returns NULL. * + *--------------------------------------------------------------*/ + +N_Vector_S N_VNew_S(integertype ns, integertype n, M_Env machEnv); + +/*--------------------------------------------------------------* + * Function : N_VFree * + * Usage : N_VFree(v); * + *--------------------------------------------------------------* + * Frees the N_Vector v. It is illegal to use v after the call * + * N_VFree(v). * + *--------------------------------------------------------------*/ + +void N_VFree(N_Vector v); + +/*--------------------------------------------------------------* + * Function : N_VFree_S * + * Usage : N_VFree_S(ns, vs); * + *--------------------------------------------------------------* + * Frees the array of ns N_Vectors vs. * + * It is illegal to use vs after the call N_VFree_S(Ns,vs). * + *--------------------------------------------------------------*/ + +void N_VFree_S(integertype ns, N_Vector_S vs); + +/*--------------------------------------------------------------* + * Function : N_VMake * + * Usage : v = N_VMake(n, v_data, machEnv); * + *--------------------------------------------------------------* + * Creates an N_Vector with component array data allocated by * + * the user. * + *--------------------------------------------------------------*/ + +N_Vector N_VMake(integertype n, realtype *v_data, M_Env machEnv); + +/*--------------------------------------------------------------* + * Function : N_VDispose * + * Usage : N_VDispose(v); * + *--------------------------------------------------------------* + * Destroys an N_Vector with component array data allocated by * + * the user. * + *--------------------------------------------------------------*/ + +void N_VDispose(N_Vector v); + +/*--------------------------------------------------------------* + * Function : N_VGetData * + * Usage : v_data = N_VGetData(v); * + *--------------------------------------------------------------* + * Extracts the data component array from the N_Vector v. * + * Note: this routine is used in the solver-specific interfaces * + * to the dense and banded linear solvers, as well as the * + * interfaces to the banded preconditioners provided with * + * SUNDIALS. It needs not be implemented by a user * + * defined NVECTOR module, if these linear solvers are not* + * used. * + *--------------------------------------------------------------*/ + +realtype *N_VGetData(N_Vector v); + +/*--------------------------------------------------------------* + * Function : N_VSetData * + * Usage : N_VSetData(v_data, v); * + *--------------------------------------------------------------* + * Attaches the data component array v_data to the N_Vector v. * + * Note: this routine is used in the solver-specific interfaces * + * to the dense and banded linear solvers, as well as the * + * interfaces to the banded preconditioners provided with * + * SUNDIALS. It needs not be implemented by a user * + * defined NVECTOR module, if these linear solvers are not* + * used. * + *--------------------------------------------------------------*/ + +void N_VSetData(realtype *v_data, N_Vector v); + +/*--------------------------------------------------------------* + * Function : N_VLinearSum * + * Operation : z = a x + b y * + *--------------------------------------------------------------*/ + +void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, + N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VConst * + * Operation : z[i] = c for i=0, 1, ..., N-1 * + *--------------------------------------------------------------*/ + +void N_VConst(realtype c, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VProd * + * Operation : z[i] = x[i] * y[i] for i=0, 1, ..., N-1 * + *--------------------------------------------------------------*/ + +void N_VProd(N_Vector x, N_Vector y, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VDiv * + * Operation : z[i] = x[i] / y[i] for i=0, 1, ..., N-1 * + *--------------------------------------------------------------*/ + +void N_VDiv(N_Vector x, N_Vector y, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VScale * + * Operation : z = c x * + *--------------------------------------------------------------*/ + +void N_VScale(realtype c, N_Vector x, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VAbs * + * Operation : z[i] = |x[i]|, for i=0, 1, ..., N-1 * + *--------------------------------------------------------------*/ + +void N_VAbs(N_Vector x, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VInv * + * Operation : z[i] = 1.0 / x[i] for i = 0, 1, ..., N-1 * + *--------------------------------------------------------------* + * This routine does not check for division by 0. It should be * + * called only with an N_Vector x which is guaranteed to have * + * all non-zero components. * + *--------------------------------------------------------------*/ + +void N_VInv(N_Vector x, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VAddConst * + * Operation : z[i] = x[i] + b for i = 0, 1, ..., N-1 * + *--------------------------------------------------------------*/ + +void N_VAddConst(N_Vector x, realtype b, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VDotProd * + * Usage : dotprod = N_VDotProd(x, y); * + *--------------------------------------------------------------* + * Returns the value of the ordinary dot product of x and y: * + * -> sum (i=0 to N-1) {x[i] * y[i]} * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VDotProd(N_Vector x, N_Vector y); + +/*--------------------------------------------------------------* + * Function : N_VMaxNorm * + * Usage : maxnorm = N_VMaxNorm(x); * + *--------------------------------------------------------------* + * Returns the maximum norm of x: * + * -> max (i=0 to N-1) |x[i]| * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VMaxNorm(N_Vector x); + +/*--------------------------------------------------------------* + * Function : N_VWrmsNorm * + * Usage : wrmsnorm = N_VWrmsNorm(x, w); * + *--------------------------------------------------------------* + * Returns the weighted root mean square norm of x with * + * weight vector w: * + * -> sqrt [(sum (i=0 to N-1) {(x[i] * w[i])^2}) / N] * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VWrmsNorm(N_Vector x, N_Vector w); + +/*--------------------------------------------------------------* + * Function : N_VMin * + * Usage : min = N_VMin(x); * + *--------------------------------------------------------------* + * Returns the smallest element of x: * + * -> min (i=0 to N-1) x[i] * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VMin(N_Vector x); + +/*--------------------------------------------------------------* + * Function : N_VWL2Norm * + * Usage : wl2norm = N_VWL2Norm(x, w); * + *--------------------------------------------------------------* + * Returns the weighted Euclidean L2 norm of x with * + * weight vector w: * + * -> sqrt [(sum (i=0 to N-1) {(x[i] * w[i])^2}) ] * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VWL2Norm(N_Vector x, N_Vector w); + +/*--------------------------------------------------------------* + * Function : N_VL1Norm * + * Usage : l1norm = N_VL1Norm(x); * + *--------------------------------------------------------------* + * Returns the L1 norm of x: * + * -> sum (i=0 to N-1) {ABS(x[i])} * + * Returns 0.0 if N <= 0. * + *--------------------------------------------------------------*/ + +realtype N_VL1Norm(N_Vector x); + +/*--------------------------------------------------------------* + * Function : N_VOneMask * + * Operation : x[i] = 1.0 if |x[i]| != 0. i = 0, 1, ..., N-1 * + * 0.0 otherwise * + *--------------------------------------------------------------*/ + +void N_VOneMask(N_Vector x); + +/*--------------------------------------------------------------* + * Function : N_VCompare * + * Operation : z[i] = 1.0 if |x[i]| >= c i = 0, 1, ..., N-1 * + * 0.0 otherwise * + *--------------------------------------------------------------*/ + +void N_VCompare(realtype c, N_Vector x, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VInvTest * + * Operation : z[i] = 1.0 / x[i] with a test for x[i]==0.0 * + * before inverting x[i]. * + *--------------------------------------------------------------* + * This routine returns TRUE if all components of x are * + * non-zero (successful inversion) and returns FALSE * + * otherwise. * + *--------------------------------------------------------------*/ + +booleantype N_VInvTest(N_Vector x, N_Vector z); + +/*--------------------------------------------------------------* + * Function : N_VConstrProdPos * + * Usage : booltest = N_VConstrProdPos(c,x); * + *--------------------------------------------------------------* + * Returns a boolean equal to * + * FALSE if some c[i] != 0.0 and x[i]*c[i] <= 0.0, or * + * TRUE otherwise. * + * * + * This routine is used for constraint checking. * + *--------------------------------------------------------------*/ + +booleantype N_VConstrProdPos(N_Vector c, N_Vector x); + +/*--------------------------------------------------------------* + * Function : N_VConstrMask * + * Operation : m[i] = 1.0 if constraint test fails for x[i] * + * m[i] = 0.0 if constraint test passes for x[i] * + * where the constraint tests are as follows: * + * If c[i] = 2.0, then x[i] must be > 0.0. * + * If c[i] = 1.0, then x[i] must be >= 0.0. * + * If c[i] = -1.0, then x[i] must be <= 0.0. * + * If c[i] = -2.0, then x[i] must be < 0.0. * + *--------------------------------------------------------------* + * This routine returns a boolean FALSE if any element failed * + * the constraint test, TRUE if all passed. It also sets a * + * mask vector m, with elements equal to 1.0 where the * + * corresponding constraint test failed, and equal to 0.0 * + * where the constraint test passed. * + * This routine is specialized in that it is used only for * + * constraint checking. * + *--------------------------------------------------------------*/ + +booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m); + +/*--------------------------------------------------------------* + * Function : N_VMinQuotient * + * Operation : minq = min ( num[i]/denom[i]) over all i such * + * that denom[i] != 0. * + *--------------------------------------------------------------* + * This routine returns the minimum of the quotients obtained * + * by term-wise dividing num[i] by denom[i]. A zero element * + * in denom will be skipped. If no such quotients are found, * + * then the large value 1.e99 is returned. * + *--------------------------------------------------------------*/ + +realtype N_VMinQuotient(N_Vector num, N_Vector denom); + +/*--------------------------------------------------------------* + * Function : N_VPrint * + * Usage : N_VPrint(x); * + *--------------------------------------------------------------* + * Prints the N_Vector x to stdout. * + * This routine is provided as an aid in debugging code which * + * uses this vector package. * + *--------------------------------------------------------------*/ + +void N_VPrint(N_Vector x); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/nvector_serial.cpp b/nvector_serial.cpp new file mode 100644 index 00000000..cef66fd6 --- /dev/null +++ b/nvector_serial.cpp @@ -0,0 +1,869 @@ +/******************************************************************* + * * + * File : nvector_serial.c * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, * + * Radu Serban, and Allan G. Taylor, LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for a serial implementation * + * of the NVECTOR package. It contains the implementation of * + * the serial machine environment intialization and free * + * routines (and of the Fortran callable interfaces to them) * + * and of the N_Vector kernels listed in nvector_serial.h. * + * * + *******************************************************************/ + +#include +#include +#include +#include "nvector_serial.h" +#include "sundialstypes.h" +#include "sundialsmath.h" +#include "output.h" +#include "phqalloc.h" +/* WARNING don't include any headers below here */ +#define malloc PHRQ_malloc +static char const svnid[] = "$Id: nvector_serial.c 663 2005-11-16 00:46:04Z dlpark $"; + +#define ZERO RCONST(0.0) +#define HALF RCONST(0.5) +#define ONE RCONST(1.0) +#define ONEPT5 RCONST(1.5) + + +/* Private Helper Prototypes */ +/* z=x */ +static void VCopy_Serial(N_Vector x, N_Vector z); +/* z=x+y */ +static void VSum_Serial(N_Vector x, N_Vector y, N_Vector z); +/* z=x-y */ +static void VDiff_Serial(N_Vector x, N_Vector y, N_Vector z); +/* z=-x */ +static void VNeg_Serial(N_Vector x, N_Vector z); +/* z=c(x+y) */ +static void VScaleSum_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z); +/* z=c(x-y) */ +static void VScaleDiff_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z); +/* z=ax+y */ +static void VLin1_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z); +/* z=ax-y */ +static void VLin2_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z); +/* y <- ax+y */ +static void Vaxpy_Serial(realtype a, N_Vector x, N_Vector y); +/* x <- ax */ +static void VScaleBy_Serial(realtype a, N_Vector x); + +/********************* Exported Functions ************************/ + +/* Serial implementation of the machine environment + initialization routine */ + +M_Env M_EnvInit_Serial(integertype vec_length) +{ + M_Env me; + + if (svnid == NULL) fprintf(stderr," "); + /* Create machine environment structure */ + me = (M_Env) malloc(sizeof *me); + if (me == NULL) return(NULL); + + /* Create serial content of machine environment structure */ + me->content = (M_EnvSerialContent) malloc(sizeof(struct _M_EnvSerialContent)); + if (me->content == NULL) { + free(me); + return(NULL); + } + + /* Load serial content of machine environment structure */ + ME_CONTENT_S(me)->length = vec_length; + + /* Attach vector operations */ + me->ops = (N_Vector_Ops) malloc(sizeof(struct _generic_N_Vector_Ops)); + if (me->ops == NULL) { + free(me->content); + free(me); + return(NULL); + } + + me->ops->nvnew = N_VNew_Serial; + me->ops->nvnewS = N_VNew_S_Serial; + me->ops->nvfree = N_VFree_Serial; + me->ops->nvfreeS = N_VFree_S_Serial; + me->ops->nvmake = N_VMake_Serial; + me->ops->nvdispose = N_VDispose_Serial; + me->ops->nvgetdata = N_VGetData_Serial; + me->ops->nvsetdata = N_VSetData_Serial; + me->ops->nvlinearsum = N_VLinearSum_Serial; + me->ops->nvconst = N_VConst_Serial; + me->ops->nvprod = N_VProd_Serial; + me->ops->nvdiv = N_VDiv_Serial; + me->ops->nvscale = N_VScale_Serial; + me->ops->nvabs = N_VAbs_Serial; + me->ops->nvinv = N_VInv_Serial; + me->ops->nvaddconst = N_VAddConst_Serial; + me->ops->nvdotprod = N_VDotProd_Serial; + me->ops->nvmaxnorm = N_VMaxNorm_Serial; + me->ops->nvwrmsnorm = N_VWrmsNorm_Serial; + me->ops->nvmin = N_VMin_Serial; + me->ops->nvwl2norm = N_VWL2Norm_Serial; + me->ops->nvl1norm = N_VL1Norm_Serial; + me->ops->nvonemask = N_VOneMask_Serial; + me->ops->nvcompare = N_VCompare_Serial; + me->ops->nvinvtest = N_VInvTest_Serial; + me->ops->nvconstrprodpos = N_VConstrProdPos_Serial; + me->ops->nvconstrmask = N_VConstrMask_Serial; + me->ops->nvminquotient = N_VMinQuotient_Serial; + me->ops->nvprint = N_VPrint_Serial; + + /* Attach ID tag */ + strcpy(me->tag, ID_TAG_S); + + return(me); + +} + +/* Serial implementation of the machine environment + free routine */ + +void M_EnvFree_Serial(M_Env machEnv) +{ + if (machEnv == NULL) return; + + free(machEnv->content); + free(machEnv->ops); + free(machEnv); +} + +/***************************************************************************/ + +/* BEGIN implementation of vector operations */ + +N_Vector N_VNew_Serial(integertype n, M_Env machEnv) +{ + N_Vector v; + integertype length; + + if (n <= 0) return(NULL); + + if (machEnv == NULL) return(NULL); + + v = (N_Vector) malloc(sizeof *v); + if (v == NULL) return(NULL); + + v->content = (N_VectorSerialContent) malloc(sizeof(struct _N_VectorSerialContent)); + if (v->content == NULL) { + free(v); + return(NULL); + } + + length = ME_CONTENT_S(machEnv)->length; + + NV_CONTENT_S(v)->data = (realtype *) malloc(length * sizeof(realtype)); + if(NV_CONTENT_S(v)->data == NULL) { + free(v->content); + free(v); + return(NULL); + } + + NV_CONTENT_S(v)->length = length; + + v->menv = machEnv; + + return(v); +} + + +N_Vector_S N_VNew_S_Serial(integertype ns, integertype n, M_Env machEnv) +{ + N_Vector_S vs; + integertype is, j; + + + if (ns <= 0 || n <= 0) return(NULL); + + if (machEnv == NULL) return(NULL); + + vs = (N_Vector_S) malloc(ns * sizeof(N_Vector *)); + if (vs == NULL) return(NULL); + + for (is=0; iscontent = (N_VectorSerialContent) malloc(sizeof(struct _N_VectorSerialContent)); + if (v->content == NULL) { + free(v); + return(NULL); + } + + length = ME_CONTENT_S(machEnv)->length; + + NV_CONTENT_S(v)->data = v_data; + + NV_CONTENT_S(v)->length = length; + + v->menv = machEnv; + + return(v); +} + +void N_VDispose_Serial(N_Vector v) +{ + free(NV_CONTENT_S(v)); + free(v); +} + +realtype *N_VGetData_Serial(N_Vector v) +{ + realtype *v_data; + v_data = NV_CONTENT_S(v)->data; + return(v_data); +} + +void N_VSetData_Serial(realtype *v_data, N_Vector v) +{ + NV_CONTENT_S(v)->data = v_data; +} + +void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z) +{ + integertype i, N; + realtype c, *xd, *yd, *zd; + N_Vector v1, v2; + booleantype test; + + if ((b == ONE) && (z == y)) { /* BLAS usage: axpy y <- ax+y */ + Vaxpy_Serial(a,x,y); + return; + } + + if ((a == ONE) && (z == x)) { /* BLAS usage: axpy x <- by+x */ + Vaxpy_Serial(b,y,x); + return; + } + + /* Case: a == b == 1.0 */ + + if ((a == ONE) && (b == ONE)) { + VSum_Serial(x, y, z); + return; + } + + /* Cases: (1) a == 1.0, b = -1.0, (2) a == -1.0, b == 1.0 */ + + /*if ((test = ((a == ONE) && (b == -ONE))) || ((a == -ONE) && (b == ONE))) {*/ + test = ((a == ONE) && (b == -ONE)); + if (test || ((a == -ONE) && (b == ONE))) { + v1 = test ? y : x; + v2 = test ? x : y; + VDiff_Serial(v2, v1, z); + return; + } + + /* Cases: (1) a == 1.0, b == other or 0.0, (2) a == other or 0.0, b == 1.0 */ + /* if a or b is 0.0, then user should have called N_VScale */ + + /*if ((test = (a == ONE)) || (b == ONE)) {*/ + test = (a == ONE); + if (test || (b == ONE)) { + c = test ? b : a; + v1 = test ? y : x; + v2 = test ? x : y; + VLin1_Serial(c, v1, v2, z); + return; + } + + /* Cases: (1) a == -1.0, b != 1.0, (2) a != 1.0, b == -1.0 */ + + /*if ((test = (a == -ONE)) || (b == -ONE)) {*/ + test = (a == -ONE); + if (test || (b == -ONE)) { + c = test ? b : a; + v1 = test ? y : x; + v2 = test ? x : y; + VLin2_Serial(c, v1, v2, z); + return; + } + + /* Case: a == b */ + /* catches case both a and b are 0.0 - user should have called N_VConst */ + + if (a == b) { + VScaleSum_Serial(a, x, y, z); + return; + } + + /* Case: a == -b */ + + if (a == -b) { + VScaleDiff_Serial(a, x, y, z); + return; + } + + /* Do all cases not handled above: + (1) a == other, b == 0.0 - user should have called N_VScale + (2) a == 0.0, b == other - user should have called N_VScale + (3) a,b == other, a !=b, a != -b */ + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + yd = NV_DATA_S(y); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = a * (*xd++) + b * (*yd++); +} + + +void N_VConst_Serial(realtype c, N_Vector z) +{ + integertype i, N; + realtype *zd; + + N = NV_LENGTH_S(z); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = c; +} + + +void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z) +{ + integertype i, N; + realtype *xd, *yd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + yd = NV_DATA_S(y); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = (*xd++) * (*yd++); +} + + +void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z) +{ + integertype i, N; + realtype *xd, *yd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + yd = NV_DATA_S(y); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = (*xd++) / (*yd++); +} + + +void N_VScale_Serial(realtype c, N_Vector x, N_Vector z) +{ + integertype i, N; + realtype *xd, *zd; + + if (z == x) { /* BLAS usage: scale x <- cx */ + VScaleBy_Serial(c, x); + return; + } + + if (c == ONE) { + VCopy_Serial(x, z); + } else if (c == -ONE) { + VNeg_Serial(x, z); + } else { + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + zd = NV_DATA_S(z); + for (i=0; i < N; i++) + *zd++ = c * (*xd++); + } +} + + +void N_VAbs_Serial(N_Vector x, N_Vector z) +{ + integertype i, N; + realtype *xd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++, xd++, zd++) + *zd = ABS(*xd); +} + + +void N_VInv_Serial(N_Vector x, N_Vector z) +{ + integertype i, N; + realtype *xd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = ONE / (*xd++); +} + + +void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z) +{ + integertype i, N; + realtype *xd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) + *zd++ = (*xd++) + b; +} + + +realtype N_VDotProd_Serial(N_Vector x, N_Vector y) +{ + integertype i, N; + realtype sum = ZERO, *xd, *yd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + yd = NV_DATA_S(y); + + for (i=0; i < N; i++) + sum += (*xd++) * (*yd++); + + return(sum); +} + + +realtype N_VMaxNorm_Serial(N_Vector x) +{ + integertype i, N; + realtype max = ZERO, *xd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + + for (i=0; i < N; i++, xd++) { + if (ABS(*xd) > max) max = ABS(*xd); + } + + return(max); +} + + +realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w) +{ + integertype i, N; + realtype sum = ZERO, prodi, *xd, *wd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + wd = NV_DATA_S(w); + + for (i=0; i < N; i++) { + prodi = (*xd++) * (*wd++); + sum += prodi * prodi; + } + + return(RSqrt(sum / N)); +} + + +realtype N_VMin_Serial(N_Vector x) +{ + integertype i, N; + realtype min, *xd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + + min = xd[0]; + + xd++; + for (i=1; i < N; i++, xd++) { + if ((*xd) < min) min = *xd; + } + + return(min); +} + + +realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w) +{ + integertype i, N; + realtype sum = ZERO, prodi, *xd, *wd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + wd = NV_DATA_S(w); + + for (i=0; i < N; i++) { + prodi = (*xd++) * (*wd++); + sum += prodi * prodi; + } + + return(RSqrt(sum)); +} + + +realtype N_VL1Norm_Serial(N_Vector x) +{ + integertype i, N; + realtype sum = ZERO, *xd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + + for (i=0; i= c) ? ONE : ZERO; + } +} + + +booleantype N_VInvTest_Serial(N_Vector x, N_Vector z) +{ + integertype i, N; + realtype *xd, *zd; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + zd = NV_DATA_S(z); + + for (i=0; i < N; i++) { + if (*xd == ZERO) return(FALSE); + *zd++ = ONE / (*xd++); + } + + return(TRUE); +} + + +booleantype N_VConstrProdPos_Serial(N_Vector c, N_Vector x) +{ + integertype i, N; + realtype *xd, *cd; + booleantype test; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + cd = NV_DATA_S(c); + + test = TRUE; + + for (i=0; i < N; i++, xd++,cd++) { + if (*cd != ZERO) { + if ((*xd)*(*cd) <= ZERO) { + test = FALSE; + break; + } + } + } + return(test); +} + + +booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m) +{ + integertype i, N; + booleantype test; + realtype *cd, *xd, *md; + + N = NV_LENGTH_S(x); + xd = NV_DATA_S(x); + cd = NV_DATA_S(c); + md = NV_DATA_S(m); + + test = TRUE; + + for (i=0; i ONEPT5 || (*cd) < -ONEPT5) { + if ( (*xd)*(*cd) <= ZERO) {test = FALSE; *md = ONE; } + continue; + } + if ( (*cd) > HALF || (*cd) < -HALF) { + if ( (*xd)*(*cd) < ZERO ) {test = FALSE; *md = ONE; } + } + } + return(test); +} + + +realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom) +{ + booleantype notEvenOnce; + integertype i, N; + realtype *nd, *dd, min; + + N = NV_LENGTH_S(num); + nd = NV_DATA_S(num); + dd = NV_DATA_S(denom); + min = 0; + + notEvenOnce = TRUE; + + for (i=0; i since these macros expand to calls to * + * malloc and free. * + * * + * When looping over the components of an N_Vector v, it is * + * more efficient to first obtain the component array via * + * v_data=NV_DATA_S(v) and then access v_data[i] within the * + * loop than it is to use NV_Ith_S(v,i) within the loop. * + * * + * NV_MAKE_S and NV_DISPOSE_S are similar to N_VNew_Serial and * + * N_VFree_Serial, while NVS_MAKE_S and NVS_DISPOSE_S are * + * similar to N_VNew_S_Serial and N_VFree_S_Serial. The * + * difference is one of responsibility for component memory * + * allocation and deallocation. N_VNew_Serial allocates memory * + * for the N_Vector components and N_VFree_Serial frees the * + * component memory allocated by N_VNew_Serial. For NV_MAKE_S * + * and NV_DISPOSE_S, the component memory is allocated and * + * freed by the user of this package. Similar remarks hold for * + * NVS_MAKE_S, NVS_DISPOSE_S and N_VNew_S_Serial, * + * N_VFree_S_Serial. * + * * + ****************************************************************/ + +#define NV_MAKE_S(v, v_data, machenv) \ + v = (N_Vector) malloc(sizeof(*v)); \ + v->content = (N_VectorSerialContent) malloc(sizeof(struct _N_VectorSerialContent)); \ + v->content->data = v_data; \ + v->content->length = machenv->content->v_len; \ + v->menv = machenv + +#define NV_DISPOSE_S(v) \ + free((N_VectorSerialContent)(v->content)); \ + free(v) + +#define NVS_MAKE_S(vs, vs_data, s_len, machenv) \ + vs = (N_Vector_S) malloc(s_len*sizeof(N_Vector *)); \ + for ((int)is=0; iscontent) ) + +#define NV_CONTENT_S(v) ( (N_VectorSerialContent)(v->content) ) + +#define NV_LENGTH_S(v) ( NV_CONTENT_S(v)->length ) + +#define NV_DATA_S(v) ( NV_CONTENT_S(v)->data ) + +#define NV_Ith_S(v,i) ( NV_DATA_S(v)[i] ) + + +/**************************************************************** + * PART III: * + * Functions exported by nvector_serial * + ****************************************************************/ + +/*--------------------------------------------------------------* + * Routine : M_EnvInit_Serial * + *--------------------------------------------------------------* + * This function sets the content field of the machine * + * environment for the serial implementation to a structure of * + * type _MEnvSerialContent and attaches the vector operations * + * defined for this implementation. * + * * + * If successful, M_EnvInit_Serial returns a pointer of type * + * M_Env. This pointer should in turn be passed in any user * + * calls to N_VNew, or uses of the macros NV_MAKE_S and * + * NVS_MAKE_S. * + * * + *--------------------------------------------------------------* + * * + * vec_length is the length of the vector. * + * * + *--------------------------------------------------------------*/ + +M_Env M_EnvInit_Serial(integertype vec_length); + +/*--------------------------------------------------------------* + * Function M_EnvFree_Serial * + *--------------------------------------------------------------* + * Function to free the block of machine-dependent environment * + * information created by M_EnvInit_Serial. * + * Its only argument is the pointer machenv returned by * + * M_EnvInit_Serial. * + * * + *--------------------------------------------------------------*/ + +void M_EnvFree_Serial(M_Env machenv); + +/*--------------------------------------------------------------* + * Serial implementations of the vector operations * + * * + * For a complete description of each of the following routines * + * see the header file nvector.h * + *--------------------------------------------------------------*/ + +N_Vector N_VNew_Serial(integertype n, M_Env machEnv); +N_Vector_S N_VNew_S_Serial(integertype ns, integertype n, M_Env machEnv); +void N_VFree_Serial(N_Vector v); +void N_VFree_S_Serial(integertype ns, N_Vector_S vs); +N_Vector N_VMake_Serial(integertype n, realtype *v_data, M_Env machEnv); +void N_VDispose_Serial(N_Vector v); +realtype *N_VGetData_Serial(N_Vector v); +void N_VSetData_Serial(realtype *v_data, N_Vector v); +void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z); +void N_VConst_Serial(realtype c, N_Vector z); +void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z); +void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z); +void N_VScale_Serial(realtype c, N_Vector x, N_Vector z); +void N_VAbs_Serial(N_Vector x, N_Vector z); +void N_VInv_Serial(N_Vector x, N_Vector z); +void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z); +realtype N_VDotProd_Serial(N_Vector x, N_Vector y); +realtype N_VMaxNorm_Serial(N_Vector x); +realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w); +realtype N_VMin_Serial(N_Vector x); +realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w); +realtype N_VL1Norm_Serial(N_Vector x); +void N_VOneMask_Serial(N_Vector x); +void N_VCompare_Serial(realtype c, N_Vector x, N_Vector z); +booleantype N_VInvTest_Serial(N_Vector x, N_Vector z); +booleantype N_VConstrProdPos_Serial(N_Vector c, N_Vector x); +booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m); +realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom); +void N_VPrint_Serial(N_Vector x); + + + +#endif +#ifdef __cplusplus +} +#endif diff --git a/output.cpp b/output.cpp new file mode 100644 index 00000000..51ecd413 --- /dev/null +++ b/output.cpp @@ -0,0 +1,182 @@ +#define EXTERNAL extern +#include +#include "global.h" +#include "output.h" +#include "phrqproto.h" +#include "phqalloc.h" +static char const svnid[] = "$Id: output.c 663 2005-11-16 00:46:04Z dlpark $"; + +#define MAX_CALLBACKS 10 +static struct output_callback output_callbacks[MAX_CALLBACKS]; +static size_t count_output_callback = 0; +static int forward_output_to_log = 0; + +/* ---------------------------------------------------------------------- */ +int add_output_callback(PFN_OUTPUT_CALLBACK pfn, void *cookie) +/* ---------------------------------------------------------------------- */ +{ + if (svnid == NULL) fprintf(stderr," "); + if (pfn) { + if (count_output_callback >= MAX_CALLBACKS - 1) { + sprintf(error_string, "Too many callbacks.\nSee %s\n", __FILE__); + fprintf(stderr, "%s", error_string); + error_msg(error_string, STOP); + return ERROR; + } + output_callbacks[count_output_callback].callback = pfn; + output_callbacks[count_output_callback].cookie = cookie; + ++count_output_callback; + } + return OK; +} + +/* ---------------------------------------------------------------------- */ +int output_message(const int type, const char *err_str, const int stop, const char *format, va_list args) +/* ---------------------------------------------------------------------- */ +{ + extern jmp_buf mark; + size_t i; + + for (i = 0; i < count_output_callback; ++i) { + (output_callbacks[i].callback)(ACTION_OUTPUT, type, err_str, stop, output_callbacks[i].cookie, format, args); + } + + if (stop == STOP) { + longjmp(mark, input_error); + } + return OK; +} + +/* ---------------------------------------------------------------------- */ +int clean_up_output_callbacks(void) +/* ---------------------------------------------------------------------- */ +{ + count_output_callback = 0; + return OK; +} + +/* ---------------------------------------------------------------------- */ +int error_msg (const char *err_str, const int stop, ...) +/* ---------------------------------------------------------------------- */ +{ + va_list args; + int return_value; + + if (input_error <= 0) input_error = 1; + va_start(args, stop); + return_value = output_message(OUTPUT_ERROR, err_str, stop, "", args); + va_end(args); + return(return_value); +} + +/* ---------------------------------------------------------------------- */ +int warning_msg (const char *err_str, ...) +/* ---------------------------------------------------------------------- */ +{ + va_list args; + int return_value; + + va_start(args, err_str); + return_value = output_message(OUTPUT_WARNING, err_str, CONTINUE, "", args); + count_warnings++; + va_end(args); + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int output_msg (const int type, const char* format, ...) +/* ---------------------------------------------------------------------- */ +{ + int return_value; + va_list args; + + va_start(args, format); + return_value = output_message(type, NULL, CONTINUE, format, args); + va_end(args); + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +void set_forward_output_to_log(int value) +/* ---------------------------------------------------------------------- */ +{ + forward_output_to_log = value; +} +/* ---------------------------------------------------------------------- */ +int get_forward_output_to_log(void) +/* ---------------------------------------------------------------------- */ +{ + return forward_output_to_log; +} +/* ---------------------------------------------------------------------- */ +int output_fflush(const int type, ...) +/* ---------------------------------------------------------------------- */ +{ + size_t i; + int check; + va_list args; + + check = OK; + va_start(args, type); + for (i = 0; i < count_output_callback; ++i) { + check = (output_callbacks[i].callback)(ACTION_FLUSH, type, NULL, CONTINUE, output_callbacks[i].cookie, NULL, args); + if (check != OK) break; + } + va_end(args); + if (check != OK) return(ERROR); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int output_rewind(const int type, ...) +/* ---------------------------------------------------------------------- */ +{ + size_t i; + int check; + va_list args; + + check = OK; + va_start(args, type); + for (i = 0; i < count_output_callback; ++i) { + check = (output_callbacks[i].callback)(ACTION_REWIND, type, NULL, CONTINUE, output_callbacks[i].cookie, NULL, args); + if (check != OK) break; + } + va_end(args); + if (check != OK) return(ERROR); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int output_close(const int type, ...) +/* ---------------------------------------------------------------------- */ +{ + size_t i; + int check; + va_list args; + + check = OK; + va_start(args, type); + for (i = 0; i < count_output_callback; ++i) { + check = (output_callbacks[i].callback)(ACTION_CLOSE, type, NULL, CONTINUE, output_callbacks[i].cookie, NULL, args); + if (check != OK) break; + } + va_end(args); + if (check != OK) return(ERROR); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int output_open(const int type, const char *file_name, ...) +/* ---------------------------------------------------------------------- */ +{ + size_t i; + int check; + va_list args; + assert(file_name && strlen(file_name)); + + check = OK; + va_start(args, file_name); + for (i = 0; i < count_output_callback; ++i) { + check = (output_callbacks[i].callback)(ACTION_OPEN, type, file_name, CONTINUE, output_callbacks[i].cookie, NULL, args); + if (check != OK) break; + } + va_end(args); + if (check != OK) return(ERROR); + return(OK); +} diff --git a/output.h b/output.h new file mode 100644 index 00000000..4ad59e67 --- /dev/null +++ b/output.h @@ -0,0 +1,57 @@ +#ifndef _INC_MESSAGE_H +#define _INC_MESSAGE_H + +#include +#ifdef PHREEQC_IDENT +static char const svnidoutput[] = "$Id$"; +#endif + +typedef int (*PFN_OUTPUT_CALLBACK)(const int action, const int type, const char *err_str, const int stop, void *cookie, const char *, va_list args); + +struct output_callback { + PFN_OUTPUT_CALLBACK callback; + void *cookie; +}; + +int add_output_callback(PFN_OUTPUT_CALLBACK pfn, void *cookie); +int clean_up_output_callbacks(void); +int output_msg (const int type, const char* format, ...); +int warning_msg (const char *err_str, ...); +int error_msg (const char *err_str, const int stop, ...); +int phreeqc_handler(const int action, const int type, const char *err_str, const int stop, void *cookie, const char *, va_list args); +void set_forward_output_to_log(int value); +int get_forward_output_to_log(void); + +/* + * Functions for output callbacks + */ +int output_open(const int type, const char *file_name, ...); +int output_fflush(const int type, ...); +int output_rewind(const int type, ...); +int output_close(const int type, ...); + +typedef enum { + OUTPUT_ERROR, + OUTPUT_WARNING, + OUTPUT_MESSAGE, + OUTPUT_PUNCH, + OUTPUT_SCREEN, + OUTPUT_LOG, + OUTPUT_CHECKLINE, + OUTPUT_GUI_ERROR, + OUTPUT_BASIC, + OUTPUT_CVODE, + OUTPUT_DUMP, + OUTPUT_STDERR, + OUTPUT_SEND_MESSAGE +} output_type; + +typedef enum { + ACTION_OPEN, + ACTION_OUTPUT, + ACTION_CLOSE, + ACTION_REWIND, + ACTION_FLUSH +} action_type; + +#endif /* _INC_MESSAGE_H */ diff --git a/p2c.h b/p2c.h new file mode 100644 index 00000000..725328dd --- /dev/null +++ b/p2c.h @@ -0,0 +1,543 @@ +#ifndef P2C_H +#define P2C_H + +#ifdef PHREEQC_IDENT +static char const svnidp2c[] = "$Id$"; +#endif + +/* Header file for code generated by "p2c", the Pascal-to-C translator */ + +/* "p2c" Copyright (C) 1989, 1990, 1991 Free Software Foundation. + * By Dave Gillespie, daveg@csvax.cs.caltech.edu. Version 1.20. + * This file may be copied, modified, etc. in any way. It is not restricted + * by the licence agreement accompanying p2c itself. + */ + + +#include + + + +/* If the following heuristic fails, compile -DBSD=0 for non-BSD systems, + or -DBSD=1 for BSD systems. */ + +#ifdef M_XENIX +# define BSD 0 +#endif + +#ifdef vms +# define BSD 0 +# ifndef __STDC__ +# define __STDC__ 1 +# endif +#endif + +#ifdef __TURBOC__ +# define MSDOS 1 +#endif + +#ifdef MSDOS +# define BSD 0 +#endif + +#ifdef FILE /* a #define in BSD, a typedef in SYSV (hp-ux, at least) */ +# ifndef BSD /* (a convenient, but horrible kludge!) */ +# define BSD 1 +# endif +#endif + +#ifdef BSD +# if !BSD +# undef BSD +# endif +#endif + + +#if (defined(__STDC__) && !defined(M_XENIX)) || defined(__TURBOC__) +# include +# include +# define HAS_STDLIB +# if defined(vms) || defined(__TURBOC__) +# define __ID__(a)a +# endif +#else +# ifndef BSD +# ifndef __TURBOC__ +# include +# endif +# endif +# ifdef hpux +# ifdef _INCLUDE__STDC__ +# include +# include +# endif +# endif +# include +# if !defined(MSDOS) || defined(__TURBOC__) +# define __ID__(a)a +# endif +#endif + +#ifdef __ID__ +# define __CAT__(a,b)__ID__(a)b +#else +# define __CAT__(a,b)a##b +#endif + + +#ifdef BSD +# include +# define memcpy(a,b,n) (bcopy(b,a,n),a) +# define memcmp(a,b,n) bcmp(a,b,n) +# define strchr(s,c) index(s,c) +# define strrchr(s,c) rindex(s,c) +#else +# include +#endif + +#include +#include +#include +#include + + +#ifndef NO_LACK +#ifdef vms + +#define LACK_LABS +#define LACK_MEMMOVE +#define LACK_MEMCPY + +#else + +#define LACK_LABS /* Undefine these if your library has these */ +#ifdef SKIP +#define LACK_MEMMOVE +#endif + +#endif +#endif + + +typedef struct __p2c_jmp_buf { + struct __p2c_jmp_buf *next; + jmp_buf jbuf; +} __p2c_jmp_buf; + + +/* Warning: The following will not work if setjmp is used simultaneously. + This also violates the ANSI restriction about using vars after longjmp, + but a typical implementation of longjmp will get it right anyway. */ + +#ifndef FAKE_TRY +# define TRY(x) do { __p2c_jmp_buf __try_jb; \ + __try_jb.next = __top_jb; \ + if (!setjmp((__top_jb = &__try_jb)->jbuf)) { +# define RECOVER(x) __top_jb = __try_jb.next; } else { +#ifdef SKIP +# define RECOVER2(x,L) __top_jb = __try_jb.next; } else { \ + if (0) { L: __top_jb = __try_jb.next; } +#endif +# define RECOVER2(x,L) __top_jb = __try_jb.next; } else { \ + { L: __top_jb = __try_jb.next; } +# define ENDTRY(x) } } while (0) +#else +# define TRY(x) if (1) { +# define RECOVER(x) } else do { +# define RECOVER2(x,L) } else do { L: ; +# define ENDTRY(x) } while (0) +#endif + + + +#ifdef M_XENIX /* avoid compiler bug */ +# define INT_MAX (32767) +# define INT_MIN (-32768) +#endif + + +/* The following definitions work only on twos-complement machines */ +#ifndef INT_MAX +# define INT_MAX ((int)(((unsigned int) -1) >> 1)) +# define INT_MIN (~INT_MAX) +#endif + +#ifndef INT_MAX +# define INT_MAX ((int)(((unsigned int) -1) >> 1)) +# define INT_MIN (~INT_MAX) +#endif + +#ifndef LONG_MAX +# define LONG_MAX ((long)(((unsigned long) -1) >> 1)) +# define LONG_MIN (~LONG_MAX) +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif + +#ifndef EXIT_SUCCESS +# ifdef vms +# define EXIT_SUCCESS 1 +# define EXIT_FAILURE (02000000000L) +# else +# define EXIT_SUCCESS 0 +# define EXIT_FAILURE 1 +# endif +#endif + + +#define SETBITS 32 + +#ifdef SKIP +#if defined(__STDC__) || defined(__TURBOC__) +# if !defined(vms) && !defined(M_LINT) +# define Signed signed +# else +# define Signed +# endif +# define Void void /* Void f() = procedure */ +# ifndef Const +# define Const const +# endif +# ifndef Volatile +# define Volatile volatile +# endif +# ifdef M_LINT +# define P2PP(x) () +# define PV() () +typedef char *Anyptr; +# else +# define P2PP(x) x /* function prototype */ +# define PV() (void) /* null function prototype */ +typedef void *Anyptr; +# endif +#else +# define Signed +# define Void void +# ifndef Const +# define Const +# endif +# ifndef Volatile +# define Volatile +# endif +# define P2PP(x) () +# define PV() () +typedef char *Anyptr; +#endif +#endif + + +#define Signed +#define Void void +#ifndef Const +# define Const +#endif +#ifndef Volatile +# define Volatile +#endif +#define P2PP(x) () +#define PV() () +typedef char *Anyptr; + + +#ifdef __GNUC__ +# define Inline inline +#else +# define Inline +#endif + +#define Register register /* Register variables */ +#define Char char /* Characters (not bytes) */ + +#ifndef Static +# define Static static /* Private global funcs and vars */ +#endif + +#ifndef Local +# define Local static /* Nested functions */ +#endif + +typedef Signed char schar; +/*typedef unsigned char uchar;*/ +typedef unsigned char boolean; + +#ifndef true +# define true 1 +# define false 0 +#endif + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + + +typedef struct { + Anyptr proc, link; +} _PROCEDURE; + +#ifndef _FNSIZE +# define _FNSIZE 120 +#endif + + +/*extern Void PASCAL_MAIN P2PP( (int, Char **) );*/ +extern Void PASCAL_MAIN (int, Char **) ; +/* +extern Char **P_argv; +extern int P_argc; +*/ +extern int P_escapecode; +extern int P_ioresult; +extern __p2c_jmp_buf *__top_jb; + + +#ifdef P2C_H_PROTO /* if you have Ansi C but non-prototyped header files */ +extern Char *strcat P2PP( (Char *, Const Char *) ); +extern Char *strchr P2PP( (Const Char *, int) ); +extern int strcmp P2PP( (Const Char *, Const Char *) ); +extern Char *strcpy P2PP( (Char *, Const Char *) ); +extern size_t strlen P2PP( (Const Char *) ); +extern Char *strncat P2PP( (Char *, Const Char *, size_t) ); +extern int strncmp P2PP( (Const Char *, Const Char *, size_t) ); +extern Char *strncpy P2PP( (Char *, Const Char *, size_t) ); +extern Char *strrchr P2PP( (Const Char *, int) ); + +extern Anyptr memchr P2PP( (Const Anyptr, int, size_t) ); +extern Anyptr memmove P2PP( (Anyptr, Const Anyptr, size_t) ); +extern Anyptr memset P2PP( (Anyptr, int, size_t) ); +#ifndef memcpy +extern Anyptr memcpy P2PP( (Anyptr, Const Anyptr, size_t) ); +extern int memcmp P2PP( (Const Anyptr, Const Anyptr, size_t) ); +#endif + +extern int atoi P2PP( (Const Char *) ); +extern LDBLE atof P2PP( (Const Char *) ); +extern long atol P2PP( (Const Char *) ); +extern LDBLE strtod P2PP( (Const Char *, Char **) ); +extern long strtol P2PP( (Const Char *, Char **, int) ); +#endif /*P2C_H_PROTO*/ + +/* force stdlib for DEC */ +#define HAS_STDLIB +#ifndef HAS_STDLIB +extern Anyptr malloc P2PP( (size_t) ); +extern Void free P2PP( (Anyptr) ); +#endif + +extern int _OutMem PV(); +extern int _CaseCheck PV(); +extern int _NilCheck PV(); +/*extern int _Escape P2PP( (int) );*/ +extern int _Escape(int); +/*extern int _EscIO P2PP( (int) );*/ +extern int _EscIO (int); +extern long ipow P2PP( (long, long) ); +extern Char *strsub P2PP( (Char *, Char *, int, int) ); +extern Char *strltrim P2PP( (Char *) ); +extern Char *strrtrim P2PP( (Char *) ); +extern Char *strrpt P2PP( (Char *, Char *, int) ); +extern Char *strpad P2PP( (Char *, Char *, int, int) ); +extern int strpos2 P2PP( (Char *, Char *, int) ); +extern long memavail PV(); +extern int P_peek P2PP( (FILE *) ); +extern int P_eof P2PP( (FILE *) ); +extern int P_eoln P2PP( (FILE *) ); +extern Void P_readpaoc P2PP( (FILE *, Char *, int) ); +extern Void P_readlnpaoc P2PP( (FILE *, Char *, int) ); +extern long P_maxpos P2PP( (FILE *) ); +extern Char *P_trimname P2PP( (Char *, int) ); +extern long *P_setunion P2PP( (long *, long *, long *) ); +extern long *P_setint P2PP( (long *, long *, long *) ); +extern long *P_setdiff P2PP( (long *, long *, long *) ); +extern long *P_setxor P2PP( (long *, long *, long *) ); +extern int P_inset P2PP( (unsigned, long *) ); +extern int P_setequal P2PP( (long *, long *) ); +extern int P_subset P2PP( (long *, long *) ); +extern long *P_addset P2PP( (long *, unsigned) ); +extern long *P_addsetr P2PP( (long *, unsigned, unsigned) ); +extern long *P_remset P2PP( (long *, unsigned) ); +extern long *P_setcpy P2PP( (long *, long *) ); +extern long *P_expset P2PP( (long *, long) ); +extern long P_packset P2PP( (long *) ); +extern int P_getcmdline P2PP( (int, int, Char *) ); +extern Void TimeStamp P2PP( (int *, int *, int *, + int *, int *, int *) ); +extern Void P_sun_argv P2PP( (char *, int, int) ); + + +/* I/O error handling */ +#define _CHKIO(cond,ior,val,def) ((cond) ? P_ioresult=0,(val) \ + : P_ioresult=(ior),(def)) +#define _SETIO(cond,ior) (P_ioresult = (cond) ? 0 : (ior)) + +/* Following defines are suitable for the HP Pascal operating system */ +#define FileNotFound 10 +#define FileNotOpen 13 +#define FileWriteError 38 +#define BadInputFormat 14 +#define EndOfFile 30 + +#define FILENOTFOUND 10 +#define FILENOTOPEN 13 +#define FILEWRITEERROR 38 +#define BADINPUTFORMAT 14 +#define ENDOFFILE 30 + +/* Creating temporary files */ +#if (defined(BSD) || defined(NO_TMPFILE)) && !defined(HAVE_TMPFILE) +# define tmpfile() (fopen(tmpnam(NULL), "w+")) +#endif + +/* File buffers */ +#define FILEBUF(f,sc,type) sc int __CAT__(f,_BFLAGS); \ + sc type __CAT__(f,_BUFFER) +#define FILEBUFNC(f,type) int __CAT__(f,_BFLAGS); \ + type __CAT__(f,_BUFFER) + +#define RESETBUF(f,type) (__CAT__(f,_BFLAGS) = 1) +#define SETUPBUF(f,type) (__CAT__(f,_BFLAGS) = 0) + +#define GETFBUF(f,type) (*((__CAT__(f,_BFLAGS) == 1 && \ + ((__CAT__(f,_BFLAGS) = 2), \ + fread(&__CAT__(f,_BUFFER), \ + sizeof(type),1,(f)))),\ + &__CAT__(f,_BUFFER))) +#define AGETFBUF(f,type) ((__CAT__(f,_BFLAGS) == 1 && \ + ((__CAT__(f,_BFLAGS) = 2), \ + fread(__CAT__(f,_BUFFER), \ + sizeof(type),1,(f)))),\ + __CAT__(f,_BUFFER)) + +#define PUTFBUF(f,type,v) (GETFBUF(f,type) = (v)) +#define CPUTFBUF(f,v) (PUTFBUF(f,char,v)) +#define APUTFBUF(f,type,v) (memcpy(AGETFBUF(f,type), (v), \ + sizeof(__CAT__(f,_BUFFER)))) + +#define GET(f,type) (__CAT__(f,_BFLAGS) == 1 ? \ + fread(&__CAT__(f,_BUFFER),sizeof(type),1,(f)) : \ + (__CAT__(f,_BFLAGS) = 1)) + +#define PUT(f,type) (fwrite(&__CAT__(f,_BUFFER),sizeof(type),1,(f)), \ + (__CAT__(f,_BFLAGS) = 0)) +#define CPUT(f) (PUT(f,char)) + +#define BUFEOF(f) (__CAT__(f,_BFLAGS) != 2 && P_eof(f)) +#define BUFFPOS(f) (ftell(f) - (__CAT__(f,_BFLAGS) == 2)) + +#ifdef SKIP +typedef struct { + FILE *f; + FILEBUFNC(f,Char); + Char name[_FNSIZE]; +} _TEXT; +#endif + +/* Memory allocation */ +#ifdef __GCC__ +# define Malloc(n) (PHRQ_malloc(n) ?: (Anyptr)_OutMem()) +#else +extern Anyptr __MallocTemp__; +# define Malloc(n) ((__MallocTemp__ = PHRQ_malloc(n)) ? __MallocTemp__ : (Anyptr)_OutMem()) +#endif +#define FreeR(p) (free((Anyptr)(p))) /* used if arg is an rvalue */ +#define Free(p) (free((Anyptr)(p)), (p)=NULL) + +/* sign extension */ +#define SEXT(x,n) ((x) | -(((x) & (1L<<((n)-1))) << 1)) + +/* packed arrays */ /* BEWARE: these are untested! */ +#define P_getbits_UB(a,i,n,L) ((int)((a)[(i)>>(L)-(n)] >> \ + (((~(i))&((1<<(L)-(n))-1)) << (n)) & \ + (1<<(1<<(n)))-1)) + +#define P_getbits_SB(a,i,n,L) ((int)((a)[(i)>>(L)-(n)] << \ + (16 - ((((~(i))&((1<<(L)-(n))-1))+1) <<\ + (n)) >> (16-(1<<(n)))))) + +#define P_putbits_UB(a,i,x,n,L) ((a)[(i)>>(L)-(n)] |= \ + (x) << (((~(i))&((1<<(L)-(n))-1)) << (n))) + +#define P_putbits_SB(a,i,x,n,L) ((a)[(i)>>(L)-(n)] |= \ + ((x) & (1<<(1<<(n)))-1) << \ + (((~(i))&((1<<(L)-(n))-1)) << (n))) + +#define P_clrbits_B(a,i,n,L) ((a)[(i)>>(L)-(n)] &= \ + ~( ((1<<(1<<(n)))-1) << \ + (((~(i))&((1<<(L)-(n))-1)) << (n))) ) + +/* small packed arrays */ +#define P_getbits_US(v,i,n) ((int)((v) >> ((i)<<(n)) & (1<<(1<<(n)))-1)) +#define P_getbits_SS(v,i,n) ((int)((long)(v) << (SETBITS - (((i)+1) << (n))) >> (SETBITS-(1<<(n))))) +#define P_putbits_US(v,i,x,n) ((v) |= (x) << ((i) << (n))) +#define P_putbits_SS(v,i,x,n) ((v) |= ((x) & (1<<(1<<(n)))-1) << ((i)<<(n))) +#define P_clrbits_S(v,i,n) ((v) &= ~( ((1<<(1<<(n)))-1) << ((i)<<(n)) )) + +#define P_max(a,b) ((a) > (b) ? (a) : (b)) +#define P_min(a,b) ((a) < (b) ? (a) : (b)) + + +/* Fix ANSI-isms */ + +#ifdef LACK_LABS +# ifndef labs +# define labs my_labs + extern long my_labs P2PP( (long) ); +# endif +#endif + +#ifdef LACK_MEMMOVE +# ifndef memmove +# define memmove my_memmove + extern Anyptr my_memmove P2PP( (Anyptr, Const Anyptr, size_t) ); +# endif +#endif + +#ifdef LACK_MEMCPY +# ifndef memcpy +# define memcpy my_memcpy + extern Anyptr my_memcpy P2PP( (Anyptr, Const Anyptr, size_t) ); +# endif +# ifndef memcmp +# define memcmp my_memcmp + extern int my_memcmp P2PP( (Const Anyptr, Const Anyptr, size_t) ); +# endif +# ifndef memset +# define memset my_memset + extern Anyptr my_memset P2PP( (Anyptr, int, size_t) ); +# endif +#endif + +/* Fix toupper/tolower on Suns and other stupid BSD systems */ +#ifdef toupper +# undef toupper +# undef tolower +# define toupper(c) my_toupper(c) +# define tolower(c) my_tolower(c) +#endif + +#ifndef _toupper +# if 'A' == 65 && 'a' == 97 +# define _toupper(c) ((c)-'a'+'A') +# define _tolower(c) ((c)-'A'+'a') +# else +# ifdef toupper +# undef toupper /* hope these are shadowing real functions, */ +# undef tolower /* because my_toupper calls _toupper! */ +# endif +# define _toupper(c) toupper(c) +# define _tolower(c) tolower(c) +# endif +#endif + + +#endif /* P2C_H */ + + + +/* End. */ + + diff --git a/p2clib.cpp b/p2clib.cpp new file mode 100644 index 00000000..88b662b8 --- /dev/null +++ b/p2clib.cpp @@ -0,0 +1,936 @@ + +/* Run-time library for use with "p2c", the Pascal to C translator */ + +/* "p2c" Copyright (C) 1989, 1990, 1991 Free Software Foundation. + * By Dave Gillespie, daveg@csvax.cs.caltech.edu. Version --VERSION--. + * This file may be copied, modified, etc. in any way. It is not restricted + * by the licence agreement accompanying p2c itself. + */ + +static char const svnid[] = "$Id: p2clib.c 663 2005-11-16 00:46:04Z dlpark $"; + +#include "p2c.h" +#include "output.h" +#define STOP 1 +#define CONTINUE 0 + +#define NO_TIME +#ifndef NO_TIME +# include +#endif +#include + +#define Isspace(c) isspace(c) /* or "((c) == ' ')" if preferred */ + + + + +static int P_argc; +static char **P_argv; +static char *_ShowEscape(char *buf, int code, int ior, char *prefix); + +int P_escapecode; +int P_ioresult; + +long EXCP_LINE; /* Used by Pascal workstation system */ + +Anyptr __MallocTemp__; + +__p2c_jmp_buf *__top_jb; + +void PASCAL_MAIN(int argc, char **argv) +{ + if (svnid == NULL) fprintf(stderr," "); + P_argc = argc; + P_argv = argv; + __top_jb = NULL; + P_escapecode = 0; + P_ioresult = 0; +#ifdef LOCAL_INIT + LOCAL_INIT(); +#endif +} + + + + + +/* In case your system lacks these... */ + +long my_labs(long x) +{ + return((x > 0) ? x : -x); +} + + +/* #define __STDC__ */ /* PHREEQ98 */ + +Anyptr my_memmove(Anyptr d, Const Anyptr s, size_t n) +{ + register char *dd = (char *)d, *ss = (char *)s; + if (dd < ss || (unsigned int) (dd - ss) >= n) { + memcpy(dd, ss, n); + } else if (n > 0) { + dd += n; + ss += n; + while (n-- > 0) + *--dd = *--ss; + } + return d; +} + + +Anyptr my_memcpy(Anyptr d, Const Anyptr s, size_t n) + +{ + register char *ss = (char *)s, *dd = (char *)d; + while (n-- > 0) + *dd++ = *ss++; + return d; +} + +int my_memcmp(Const Anyptr s1, Const Anyptr s2, size_t n) +{ + register char *a = (char *)s1, *b = (char *)s2; + register int i; + while (n-- > 0) + if ((i = (*a++) - (*b++)) != 0) + return i; + return 0; +} + +Anyptr my_memset(Anyptr d, int c, size_t n) +{ + register char *dd = (char *)d; + while (n-- > 0) + *dd++ = (char) c; + return d; +} + +int my_toupper(int c) +{ + if (islower(c)) + return _toupper(c); + else + return c; +} + + +int my_tolower(int c) + +{ + if (isupper(c)) + return _tolower(c); + else + return c; +} + + + + +long ipow(long a, long b) +{ + long v; + + if (a == 0 || a == 1) + return a; + if (a == -1) + return (b & 1) ? -1 : 1; + if (b < 0) + return 0; + if (a == 2) + return 1L << b; + v = (b & 1) ? a : 1; + while ((b >>= 1) > 0) { + a *= a; + if (b & 1) + v *= a; + } + return v; +} + + + + +/* Common string functions: */ + +/* Store in "ret" the substring of length "len" starting from "pos" (1-based). + Store a shorter or null string if out-of-range. Return "ret". */ +char *strsub(register char *ret, register char *s, register int pos, register int len) +{ + register char *s2; + + if (--pos < 0 || len <= 0) { + *ret = 0; + return ret; + } + while (pos > 0) { + if (!*s++) { + *ret = 0; + return ret; + } + pos--; + } + s2 = ret; + while (--len >= 0) { + if (!(*s2++ = *s++)) + return ret; + } + *s2 = 0; + return ret; +} + + +/* Return the index of the first occurrence of "pat" as a substring of "s", + starting at index "pos" (1-based). Result is 1-based, 0 if not found. */ + +int strpos2(char *s, register char *pat, register int pos) +{ + register char *cp, ch; + register int slen; + + if (--pos < 0) + return 0; + slen = strlen(s) - pos; + cp = s + pos; + if (!(ch = *pat++)) + return 0; + pos = strlen(pat); + slen -= pos; + while (--slen >= 0) { + if (*cp++ == ch && !strncmp(cp, pat, pos)) + return cp - s; + } + return 0; +} + + +/* Case-insensitive version of strcmp. */ +int strcicmp(register char *s1, register char *s2) +{ + register unsigned char c1, c2; + + while (*s1) { + if (*s1++ != *s2++) { + if (!s2[-1]) + return 1; + c1 = (unsigned char) toupper(s1[-1]); + c2 = (unsigned char) toupper(s2[-1]); + if (c1 != c2) + return c1 - c2; + } + } + if (*s2) + return -1; + return 0; +} + + + + +/* HP and Turbo Pascal string functions: */ + +/* Trim blanks at left end of string. */ +char *strltrim(register char *s) +{ + while (Isspace((int) *s++)) ; + return s - 1; +} + + +/* Trim blanks at right end of string. */ +char *strrtrim(register char *s) +{ + register char *s2 = s; + + if (!*s) + return s; + while (*++s2) ; + while (s2 > s && Isspace((int) *--s2)) + *s2 = 0; + return s; +} + + +/* Store in "ret" "num" copies of string "s". Return "ret". */ +#ifdef SKIP +char *strrpt(ret, s, num) +char *ret; +register char *s; +register int num; +{ + register char *s2 = ret; + register char *s1; + + while (--num >= 0) { + s1 = s; + while ((*s2++ = *s1++)) ; + s2--; + } + return ret; +} +#endif + +/* Store in "ret" string "s" with enough pad chars added to reach "size". */ + +#ifdef SKIP +char *strpad +(ret, s, padchar, num) +char *ret; +register char *s; +register int padchar, num; +{ + register char *d = ret; + + if (s == d) { + while (*d++) ; + } else { + while ((*d++ = *s++)) ; + } + num -= (--d - ret); + while (--num >= 0) + *d++ = (char) padchar; + *d = 0; + return ret; +} +#endif + +/* Copy the substring of length "len" from index "spos" of "s" (1-based) + to index "dpos" of "d", lengthening "d" if necessary. Length and + indices must be in-range. */ +void strmove(register int len, register char *s, register int spos, register char *d, register int dpos) +{ + s += spos - 1; + d += dpos - 1; + while (*d && --len >= 0) + *d++ = *s++; + if (len > 0) { + while (--len >= 0) + *d++ = *s++; + *d = 0; + } +} + + +/* Delete the substring of length "len" at index "pos" from "s". + Delete less if out-of-range. */ +#ifdef SKIP +void strdelete(s, pos, len) +register char *s; +register int pos, len; +{ + register int slen; + + if (--pos < 0) + return; + slen = strlen(s) - pos; + if (slen <= 0) + return; + s += pos; + if (slen <= len) { + *s = 0; + return; + } + while ((*s = s[len])) s++; +} +#endif + +/* Insert string "src" at index "pos" of "dst". */ +void strinsert(register char *src, register char *dst, register int pos) +{ + register int slen, dlen; + + if (--pos < 0) + return; + dlen = strlen(dst); + dst += dlen; + dlen -= pos; + if (dlen <= 0) { + strcpy(dst, src); + return; + } + slen = strlen(src); + do { + dst[slen] = *dst; + --dst; + } while (--dlen >= 0); + dst++; + while (--slen >= 0) + *dst++ = *src++; +} + + + + +/* File functions */ + +/* Peek at next character of input stream; return EOF at end-of-file. */ +int P_peek(FILE *f) +{ + int ch; + + ch = getc(f); + if (ch == EOF) + return EOF; + ungetc(ch, f); + return (ch == '\n') ? ' ' : ch; +} + + +/* Check if at end of file, using Pascal "eof" semantics. End-of-file for + stdin is broken; remove the special case for it to be broken in a + different way. */ +/*int P_eof(FILE *f)*/ +int P_eof(void) +{ +#ifdef SKIP + register int ch; + if (feof(f)) + return 1; + if (f == stdin) + return 0; /* not safe to look-ahead on the keyboard! */ + ch = getc(f); + if (ch == EOF) + return 1; + ungetc(ch, f); +#endif + return 0; +} + + +/* Check if at end of line (or end of entire file). */ +int P_eoln(FILE *f) +{ + register int ch; + + ch = getc(f); + if (ch == EOF) + return 1; + ungetc(ch, f); + return (ch == '\n'); +} + + +/* Read a packed array of characters from a file. */ +Void P_readpaoc(FILE *f, char *s, int len) +{ + int ch; + + for (;;) { + if (len <= 0) + return; + ch = getc(f); + if (ch == EOF || ch == '\n') + break; + *s++ = (char) ch; + --len; + } + while (--len >= 0) + *s++ = ' '; + if (ch != EOF) + ungetc(ch, f); +} +Void P_readlnpaoc(FILE *f, char *s, int len) +{ + int ch; + + for (;;) { + ch = getc(f); + if (ch == EOF || ch == '\n') + break; + if (len > 0) { + *s++ = (char) ch; + --len; + } + } + while (--len >= 0) + *s++ = ' '; +} + + +/* Compute maximum legal "seek" index in file (0-based). */ +long P_maxpos(FILE *f) +{ + long savepos = ftell(f); + long val; + + if (fseek(f, 0L, SEEK_END)) + return -1; + val = ftell(f); + if (fseek(f, savepos, SEEK_SET)) + return -1; + return val; +} + + +/* Use packed array of char for a file name. */ +Char *P_trimname(register Char *fn, register int len) +{ + static Char fnbuf[256]; + register Char *cp = fnbuf; + + while (--len >= 0 && *fn && !isspace((int) *fn)) + *cp++ = *fn++; + *cp = 0; + return fnbuf; +} + + + + +/* Pascal's "memavail" doesn't make much sense in Unix with virtual memory. + We fix memory size as 10Meg as a reasonable compromise. */ + +long memavail(void) +{ + return 10000000; /* worry about this later! */ +} + +long maxavail(void) +{ + return memavail(); +} + + + + +/* Sets are stored as an array of longs. S[0] is the size of the set; + S[N] is the N'th 32-bit chunk of the set. S[0] equals the maximum + I such that S[I] is nonzero. S[0] is zero for an empty set. Within + each long, bits are packed from lsb to msb. The first bit of the + set is the element with ordinal value 0. (Thus, for a "set of 5..99", + the lowest five bits of the first long are unused and always zero.) */ + +/* (Sets with 32 or fewer elements are normally stored as plain longs.) */ +long *P_setunion(register long *d, register long *s1, register long *s2) /* d := s1 + s2 */ +{ + long *dbase = d++; + register int sz1 = *s1++, sz2 = *s2++; + while (sz1 > 0 && sz2 > 0) { + *d++ = *s1++ | *s2++; + sz1--, sz2--; + } + while (--sz1 >= 0) + *d++ = *s1++; + while (--sz2 >= 0) + *d++ = *s2++; + *dbase = d - dbase - 1; + return dbase; +} + +long *P_setint(register long *d, register long *s1, register long *s2) /* d := s1 * s2 */ +{ + long *dbase = d++; + register int sz1 = *s1++, sz2 = *s2++; + while (--sz1 >= 0 && --sz2 >= 0) + *d++ = *s1++ & *s2++; + while (--d > dbase && !*d) ; + *dbase = d - dbase; + return dbase; +} + +long *P_setdiff(register long *d, register long *s1, register long *s2) /* d := s1 - s2 */ +{ + long *dbase = d++; + register int sz1 = *s1++, sz2 = *s2++; + while (--sz1 >= 0 && --sz2 >= 0) + *d++ = *s1++ & ~*s2++; + if (sz1 >= 0) { + while (sz1-- >= 0) + *d++ = *s1++; + } + while (--d > dbase && !*d) ; + *dbase = d - dbase; + return dbase; +} + +long *P_setxor(register long *d, register long *s1, register long *s2) /* d := s1 / s2 */ +{ + long *dbase = d++; + register int sz1 = *s1++, sz2 = *s2++; + while (sz1 > 0 && sz2 > 0) { + *d++ = *s1++ ^ *s2++; + sz1--, sz2--; + } + while (--sz1 >= 0) + *d++ = *s1++; + while (--sz2 >= 0) + *d++ = *s2++; + while (--d > dbase && !*d) ; + *dbase = d - dbase; + return dbase; +} + +int P_inset(register unsigned val, register long *s) /* val IN s */ +{ + register int bit; + bit = val % SETBITS; + val /= SETBITS; + if ((long) val < (*s++ && ((1L< size) { + s += size; + while ((long) val > size) + *++s = 0, size++; + *sbase = size; + } else + s += val; + *s |= 1L< (int)v2) + return sbase; + b1 = v1 % SETBITS; + v1 /= SETBITS; + b2 = v2 % SETBITS; + v2 /= SETBITS; + size = *s; + v1++; + if ((int) ++v2 > size) { + while ((int) v2 > size) + s[++size] = 0; + s[v2] = 0; + *s = v2; + } + s += v1; + if (v1 == v2) { + *s |= (~((-2L)<<(b2-b1))) << b1; + } else { + *s++ |= (-1L) << b1; + while (++v1 < v2) + *s++ = -1; + *s |= ~((-2L) << b2); + } + return sbase; +} + +long *P_remset(register long *s, register unsigned val) /* s := s - [val] */ +{ + register int bit; + bit = val % SETBITS; + val /= SETBITS; + if ((long) ++val <= *s) { + if (!(s[val] &= ~(1L<= 0) { + if (*s1++ != *s2++) + return 0; + } + return 1; +} + +int P_subset(register long *s1, register long *s2) /* s1 <= s2 */ +{ + register int sz1 = *s1++, sz2 = *s2++; + if (sz1 > sz2) + return 0; + while (--sz1 >= 0) { + if (*s1++ & ~*s2++) + return 0; + } + return 1; +} + +long *P_setcpy(register long *d, register long *s) /* d := s */ +{ + register long *save_d = d; + +#ifdef SETCPY_MEMCPY + memcpy(d, s, (*s + 1) * sizeof(long)); +#else + register int i = *s + 1; + while (--i >= 0) + *d++ = *s++; +#endif + return save_d; +} + + +/* s is a "smallset", i.e., a 32-bit or less set stored + directly in a long. */ +long *P_expset(register long *d, register long s) /* d := s */ +{ + if (s) { + d[1] = s; + *d = 1; + } else + *d = 0; + return d; +} + +long P_packset(register long *s) /* convert s to a small-set */ +{ + if (*s++) + return *s; + else + return 0; +} + + + + + +/* Oregon Software Pascal extensions, courtesy of William Bader */ +int P_getcmdline(int l, int h, Char *line) +{ + int i, len; + char *s; + + h = h - l + 1; + len = 0; + for(i = 1; i < P_argc; i++) { + s = P_argv[i]; + while (*s) { + if (len >= h) return len; + line[len++] = *s++; + } + if (len >= h) return len; + line[len++] = ' '; + } + return len; +} + +#ifndef NO_TIME +Void TimeStamp(Day, Month, Year, Hour, Min, Sec) +int *Day, *Month, *Year, *Hour, *Min, *Sec; +{ + struct tm *tm; + long clock; + + time(&clock); + tm = localtime(&clock); + *Day = tm->tm_mday; + *Month = tm->tm_mon + 1; /* Jan = 0 */ + *Year = tm->tm_year; + if (*Year < 1900) + *Year += 1900; /* year since 1900 */ + *Hour = tm->tm_hour; + *Min = tm->tm_min; + *Sec = tm->tm_sec; +} + +Void VAXdate(s) +char *s; +{ + long clock; + char *c; + int i; + static int where[] = {8, 9, 0, 4, 5, 6, 0, 20, 21, 22, 23}; + + time(&clock); + c = ctime(&clock); + for (i = 0; i < 11; i++) + s[i] = my_toupper(c[where[i]]); + s[2] = '-'; + s[6] = '-'; +} + +Void VAXtime(s) +char *s; +{ + long clock; + char *c; + int i; + + time(&clock); + c = ctime(&clock); + for (i = 0; i < 8; i++) + s[i] = c[i+11]; + s[8] = '.'; + s[9] = '0'; + s[10] = '0'; +} +#endif + + + + +/* SUN Berkeley Pascal extensions */ +Void P_sun_argv(register char *s, register int len, register int n) +{ + register char *cp; + + if (n < P_argc) + cp = P_argv[n]; + else + cp = ""; + while (*cp && --len >= 0) + *s++ = *cp++; + while (--len >= 0) + *s++ = ' '; +} + + + + +int _OutMem(void) +{ + return _Escape(-2); +} + +int _CaseCheck(void) +{ + return _Escape(-9); +} + +int _NilCheck(void) +{ + return _Escape(-3); +} + + + + + +/* The following is suitable for the HP Pascal operating system. + It might want to be revised when emulating another system. */ + +#ifdef SKIP +static char *_ShowEscape(buf, code, ior, prefix) +char *buf, *prefix; +int code, ior; +#endif +static char *_ShowEscape(char *buf, int code, int ior, char *prefix) +{ + char *bufp; + + if (prefix && *prefix) { + strcpy(buf, prefix); + strcat(buf, ": "); + bufp = buf + strlen(buf); + } else { + bufp = buf; + } + if (code == -10) { + sprintf(bufp, "Pascal system I/O error %d", ior); + switch (ior) { + case 3: + strcat(buf, " (illegal I/O request)"); + break; + case 7: + strcat(buf, " (bad file name)"); + break; + case FileNotFound: /*10*/ + strcat(buf, " (file not found)"); + break; + case FileNotOpen: /*13*/ + strcat(buf, " (file not open)"); + break; + case BadInputFormat: /*14*/ + strcat(buf, " (bad input format)"); + break; + case 24: + strcat(buf, " (not open for reading)"); + break; + case 25: + strcat(buf, " (not open for writing)"); + break; + case 26: + strcat(buf, " (not open for direct access)"); + break; + case 28: + strcat(buf, " (string subscript out of range)"); + break; + case EndOfFile: /*30*/ + strcat(buf, " (end-of-file)"); + break; + case FileWriteError: /*38*/ + strcat(buf, " (file write error)"); + break; + } + } else { + sprintf(bufp, "Pascal system error %d", code); + switch (code) { + case -2: + strcat(buf, " (out of memory)"); + break; + case -3: + strcat(buf, " (reference to NIL pointer)"); + break; + case -4: + strcat(buf, " (integer overflow)"); + break; + case -5: + strcat(buf, " (divide by zero)"); + break; + case -6: + strcat(buf, " (real math overflow)"); + break; + case -8: + strcat(buf, " (value range error)"); + break; + case -9: + strcat(buf, " (CASE value range error)"); + break; + case -12: + strcat(buf, " (bus error)"); + break; + case -20: + strcat(buf, " (stopped by user)"); + break; + } + } + return buf; +} +int _Escape(int code) +{ + char buf[100]; + char token[200]; + + P_escapecode = code; + if (__top_jb) { + __p2c_jmp_buf *jb = __top_jb; + __top_jb = jb->next; + longjmp(jb->jbuf, 1); + } + if (code == 0) + /* exit(EXIT_SUCCESS); */ + error_msg("Exit success in Basic", STOP); + if (code == -1) { + error_msg("Fatal error in Basic interpreter.", CONTINUE); + sprintf(token, "%s", _ShowEscape(buf, P_escapecode, P_ioresult, "")); + error_msg(token, STOP); + exit(EXIT_FAILURE); + } + /* fprintf(stderr, "%s\n", _ShowEscape(buf, P_escapecode, P_ioresult, "")); */ + /* exit(EXIT_FAILURE); */ + error_msg("Fatal error in Basic interpreter.", CONTINUE); + sprintf(token, "%s", _ShowEscape(buf, P_escapecode, P_ioresult, "")); + error_msg(token, STOP); + return(1); +} +int _EscIO(int code) +{ + P_ioresult = code; + return _Escape(-10); +} + + + + +/* End. */ diff --git a/parse.cpp b/parse.cpp new file mode 100644 index 00000000..27d39c58 --- /dev/null +++ b/parse.cpp @@ -0,0 +1,904 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: parse.c 392 2005-07-19 16:05:07Z dlpark $"; + +static int get_coef(LDBLE *coef, char **eqnaddr); +static int get_secondary (char **t_ptr, char *element, int *i); +static int get_species (char **ptr); + +/* ---------------------------------------------------------------------- */ +int parse_eq(char *eqn, struct elt_list **elt_ptr, int association) +/* ---------------------------------------------------------------------- */ +/* + * function to break equation up into component species + * returns species name, coefficient, and charge in global variable "rxn_list". + * Also returns pointer to elt_list structure array with list of elements + * and coefficients in species. + * rxn_list global variable, output with contiguous rxn_list structures, + * which is the reaction. Target species is first in + * list, coefficient is -1.0. + * + * Argurments: + * *eqn input, pointer to equation to be parsed. + * **elt_ptr output, pointer to contiguous elt_list structures, + * which is list of elements and coefficients in the + * target species. + * association input, TRUE or FALSE if reaction is an association reaction + */ +{ + int i; + LDBLE coef, z; + char c; + char *ptr, *char_ptr; + if (svnid == NULL) fprintf(stderr," "); + + paren_count = 0; +/* + * Remove white space + */ + squeeze_white(eqn); +/* + * Check for illegal characters + */ + for (i = 0; (c=eqn[i]) != '\0'; i++) { + if( islegit(c) == FALSE ){ + sprintf(error_string,"Character is not allowed,\ + %c (octal: %o).",c,c); + error_msg(error_string, CONTINUE); + return(ERROR); + } + } + +/* + * Find coefficients, name, and charge for each species for lhs + */ + count_trxn=0; + ptr=eqn; + c = ptr[0]; + for (;;) { + if (c == '=') break; + if (c == '\0'){ + sprintf(error_string,"Equation has no equal sign.\n\t%s",eqn); + error_msg(error_string, CONTINUE); + return(ERROR); + } + if ( get_species (&ptr) == ERROR ){ + return(ERROR); + } + c = ptr[0]; + if ( association == FALSE ) { + trxn.token[count_trxn].coef *= -1.0; + } + count_trxn++; + } +/* + * Get coefficient, name, and charge of species for dissociation reaction + */ + ptr++; + if ( association == TRUE ) { + if ( get_species (&ptr) == ERROR ){ + return(ERROR); + } + trxn.token[count_trxn].coef *= -1.0; + /* Swap species into first structure position */ + char_ptr=trxn.token[0].name; + coef=trxn.token[0].coef; + z=trxn.token[0].z; + trxn.token[0].name=trxn.token[count_trxn].name; + trxn.token[0].coef=trxn.token[count_trxn].coef; + trxn.token[0].z=trxn.token[count_trxn].z; + trxn.token[count_trxn].name=char_ptr; + trxn.token[count_trxn].coef=coef; + trxn.token[count_trxn].z=z; + count_trxn++; + } +/* + * Get reaction species from rhs of equation + */ + c = ptr[0]; + for (;;) { + if (c == '\0') break; + if ( get_species (&ptr) == ERROR ){ + return(ERROR); + } + c = ptr[0]; + if ( association == TRUE ) { + trxn.token[count_trxn].coef *= -1.0; + } + count_trxn++; + } +/* + * Sort list of reaction species + */ + trxn_sort(); +/* + * Get elements in species or mineral formula + */ + count_elts=0; + char_ptr=trxn.token[0].name; + if ( get_elts_in_species( &char_ptr , trxn.token[0].coef ) == ERROR ) { + return(ERROR); + } +/* + * Sort elements in reaction and combine + */ + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + if (elt_list_combine () == ERROR) return(ERROR); +/* + * Malloc space and store element data for return + */ + *elt_ptr=(struct elt_list *) PHRQ_malloc((size_t) (count_elts + 1)*sizeof(struct elt_list)); + if (*elt_ptr == NULL ) malloc_error(); + for ( i=0; i < count_elts; i++ ) { + (*elt_ptr)[i].elt=elt_list[i].elt; + (*elt_ptr)[i].coef=-elt_list[i].coef; + } + (*elt_ptr)[count_elts].elt=NULL; +/* + * Debugging print of parsed equation + trxn_print(); + */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int check_eqn ( int association ) +/* ---------------------------------------------------------------------- */ +/* + * Check that equation is balanced reaction. Uses array "trxn.token" and + * assumes "count_trxn" is set to number of species in reaction. + * Charge and elements are checked. + * + * Arguments: + * + * association input, TRUE or FALSE if reaction is an association reaction. + */ +{ + int i; + int oops=0; + char *t_ptr; + LDBLE sumcharge; + + paren_count=0; + count_elts=0; +/* + * Check that coefficient of first species is -1.0 + */ + if ( equal(trxn.token[0].coef,-1.0,TOL) == FALSE ) { + if (association == TRUE) { + sprintf(error_string, "Coefficient of first species on rhs is not equal to 1.0."); + error_msg(error_string, CONTINUE); + } else { + sprintf(error_string, "Coefficient of mineral (first on lhs) is not equal to 1.0."); + error_msg(error_string, CONTINUE); + } + return(ERROR); + } +/* + * Go through all species in the reaction; sum the charge and store elements + */ + sumcharge=0.0; + for (i=0; i < count_trxn; i++) { + sumcharge += ( trxn.token[i].coef)*(trxn.token[i].z); + t_ptr=trxn.token[i].name; + if ( get_elts_in_species(&t_ptr, trxn.token[i].coef ) == ERROR ) { + return(ERROR); + } + } +/* + * Sort elements in reaction and combine + */ + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + if (elt_list_combine() == ERROR) return(ERROR); +/* + * Check charge + */ + if ( equal(sumcharge, 0.0, TOL) == FALSE) { + sprintf(error_string, "Equation is not charge balanced."); + error_msg(error_string, CONTINUE); + oops++; + } +/* + * Check mass balance + */ + for ( i=0; i < count_elts; i++) { + if ( (equal(elt_list[i].coef,0.0,TOL) == FALSE) && + strncmp( (elt_list[i].elt)->name , "e" , MAX_LENGTH) != 0) { + sprintf(error_string, "Equation does not balance for element, %s.", (elt_list[i].elt)->name); + error_msg(error_string, CONTINUE); + oops++; + } + } + if (oops == 0) { + return(OK); + } else { + return(ERROR); + } +} +/* ---------------------------------------------------------------------- */ +int get_charge(char *charge, LDBLE *z) +/* ---------------------------------------------------------------------- */ +/* + * Function takes character string and calculates the charge on + * the species. Charge can be in two forms: (1) string of "+" or "-" + * or (2) + or - followed by an integer. Charge is reduced to form (2) + * and stored in the pointer location *charge. + * + * Arguments: + * *charge input, string containing charge + * output, string containing charge of the form + or - + * followed by an integer, if integer greater than 1. + * *z output, value of charge. + * + * Returns: + * ERROR, + * OK. + */ +{ + int i; + char *ptr; + char c,c1; +/* + * Charge is zero + */ + if((c=charge[0]) == '\0'){ + *z=0.0; + return(OK); + } +/* + * Error check for + or - at start of string + */ + if(c != '+' && c != '-'){ + sprintf(error_string,"Character string for charge does not start with + or -,\t%s.", charge); + error_msg(error_string, CONTINUE); + return(ERROR); + } +/* + * Count string of +'s or -'s + */ + i=0; + while (c == (c1=charge[i++]) ); + i--; + if (c1 == '\0') { + if (c == '-') i=-i; + } else { +/* + * + or - followed by a number + */ + errno=0; + i=strtol(charge,&ptr,0); +#ifdef SKIP + if (errno == ERANGE) { + sprintf(error_string, "Error in character string for charge, %s.", charge); + error_msg(error_string, CONTINUE); + return(ERROR); + } +#endif +/* + * Truncate fractional part of charge if all zeros + */ + if (*ptr != '\0') { + if ( *ptr == '.') { + while (*(++ptr) != '\0') { + if (*ptr != '0') { + *z = strtod(charge, &ptr); + return(OK); +#ifdef SKIP + sprintf(error_string, "Charge must be an integer, %s.", charge); + error_msg(error_string, CONTINUE); + return(ERROR); +#endif + } + } +/* + * Non-numeric characters + */ + } else { + sprintf(error_string, "Error in character string for charge, %s.", charge); + error_msg(error_string, CONTINUE); + return(ERROR); + } + } + } +/* + * Charge is zero, must have had +0 or -0 in eqn + */ + if (i == 0) { + charge[0]='\0'; + } +/* + * Charge is +1 or -1, single + or - + */ + if (abs(i) == 1) { + charge[0]=c; + charge[1]='\0'; + } +/* + * Abs(z)>1, set charge to + or - plus integer + */ + if (abs(i)>1) { + if (sprintf(charge,"%-+d",i) == EOF){ + sprintf(error_string, "Error converting charge to character string, %s.", charge); + error_msg(error_string, CONTINUE); + return(ERROR); + } + } + *z=i; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_coef(LDBLE *coef, char **eqnaddr) +/* ---------------------------------------------------------------------- */ +/* + * Function reads through eqn and determines the coefficient of the next + * species. + * + * Arguments: + * *coef output, coefficient of next species. + * + * **eqnaddr input, pointer to a position in eqn to start parsing + * output, pointer to next position after coefficient + * + * Returns: + * ERROR, + * OK. + */ +{ + int i; + char c,c1; + char *ptr, *ptr1, *rest; + char token[MAX_LENGTH];; + + rest=*eqnaddr; + ptr=*eqnaddr; /* address of a position in eqn */ + c=*ptr; /* character in eqn */ + *coef=0.0; +/* + * No leading sign or number + */ + if (isalpha((int) c) || + (c == '(') || + (c == ')') || + (c == '[') || + (c == ']') + ) { + *coef=1.0; + return(OK); + } +/* + * Leading +, no digits + */ + c1=*(ptr+1); + if (c == '+' && + ( isalpha((int) c1) || + (c1 == '(') || + (c1 == ')') || + (c1 == '[') || + (c1 == ']') ) ) { + *eqnaddr=++ptr; + *coef=1.0; + return(OK); + } +/* + * Leading -, no digits + */ + if (c == '-' && + ( isalpha((int) c1) || + (c1 == '(') || + (c1 == ')') || + (c1 == '[') || + (c1 == ']') + ) ) { + *eqnaddr=++ptr; + *coef=-1.0; + return(OK); + } + i=0; +/* + * Has number coefficient + */ + if (isdigit((int) c) || c == '+' || c == '-' || c =='.') { + while (isdigit((int) c) || c == '+' || c == '-' || c =='.') { + token[i++]=c; + if (i >= MAX_LENGTH) { + sprintf(error_string, "Coefficient has more than MAX_LENGTH characters."); + error_msg(error_string, CONTINUE); + return(ERROR); + } + c=*(++ptr); + } + token[i]='\0'; + *eqnaddr=ptr; + errno = 0; + *coef=strtod(token,&ptr1); + if ((errno == ERANGE) || + (*ptr1 != '\0') ) { + sprintf(error_string, "Error converting coefficient in get_coef, %s.", token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + return(OK); + } +/* + * None of the above, unknown construct + */ + sprintf(error_string, "Illegal equation construct detected in get_coef.\n\t%s.", rest); + error_msg(error_string, CONTINUE); + return(ERROR); +} +/* ---------------------------------------------------------------------- */ +int get_elt (char **t_ptr, char *element, int *i) +/* ---------------------------------------------------------------------- */ +/* + * Function reads an element name out of the equation string. + * An element name is composed of a capital letter followed by any number + * of lower case characters. + * + * Arguments: + * **t_ptr input, points to position in the equation to begin + * output, points to next character of equation after + * element name. + * *element input pointer to place to return element character string + */ +{ + char c; + + c=*(*t_ptr)++; + if (c == '\0') { + sprintf(error_string, "Empty string in get_elt. Expected an element name."); + error_msg(error_string, CONTINUE); + return(ERROR); + } +/* + * Load name into char array element + */ + element[0]=c; + *i=1; + if (c == '[') { + while ((c=(**t_ptr)) != ']') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + if ((c=(**t_ptr)) == ']') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + break; + } else if (**t_ptr == '\0') { + error_msg("No ending bracket (]) for element name", CONTINUE); + input_error++; + break; + } + } + while (islower((int) (c=(**t_ptr))) || c == '_') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } + } else { + while (islower((int) (c=(**t_ptr))) || c == '_') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } + } + element[*i]='\0'; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_elts_in_species (char **t_ptr, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Makes a list of elements with their coefficients, stores elements + * in elt_list at position count_elts. Global variable count_elts is + * updated with each stored element. Also uses static global variable + * paren_count. + * + * Arguments: + * **t_ptr input, point in token string to start looking + * output, is next position to start looking + * coef input, coefficient to multiply subscripts by + */ + int i, count, l; + char c, c1; + LDBLE d; + char element[MAX_LENGTH]; + + while ( ( (c=**t_ptr) != '+') && + (c != '-') && (c != '\0') ) { + /* close parenthesis */ + if (c == ')') { + paren_count--; + if (paren_count < 0) { + sprintf(error_string,"Too many right parentheses."); + error_msg(error_string, CONTINUE); + return(ERROR); + } + (*t_ptr)++; + return(OK); + } + c1=*((*t_ptr)+1); + /* beginning of element name */ + if (isupper((int) c) || + (c == 'e' && c1 == '-') + || (c == '[') + ) { +/* + * Get new element and subscript + */ + if ( get_elt( t_ptr, element, &l) == ERROR) { + return(ERROR); + } + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + elt_list[count_elts].elt = element_store ( element ); + if ( get_num( t_ptr , &d ) == ERROR) { + return(ERROR); + } + elt_list[count_elts].coef = d*coef; + count_elts++; +/* + * Expand working space for elements if necessary + */ + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + continue; + } +/* + * Open parentheses + */ + if (c=='(') { + count=count_elts; + if (c1 == ')') { + sprintf(error_string, "Empty parentheses."); + warning_msg(error_string); + } + paren_count++; + (*t_ptr)++; + if ( get_elts_in_species(t_ptr, coef ) == ERROR ) { + return(ERROR); + } + if (get_num (t_ptr, &d) == ERROR ) { + return(ERROR); + } + for (i=count; i < count_elts; i++) { + elt_list[i].coef *= d; + } + continue; + } +/* + * Colon + */ + if (c==':') { + count=count_elts; + (*t_ptr)++; + if (get_num (t_ptr, &d) == ERROR ) { + return(ERROR); + } + if ( get_elts_in_species(t_ptr, coef ) == ERROR ) { + return(ERROR); + } + for (i=count; i < count_elts; i++) { + elt_list[i].coef *= d; + } + continue; + } +/* + * Not beginning of element and not opening paren + */ + sprintf(error_string, "Parsing error in get_elts_in_species, unexpected character, %c.", c); + error_msg(error_string, CONTINUE); + input_error++; + return (ERROR); + } + if (paren_count != 0) { + sprintf(error_string,"Unbalanced parentheses."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +static int get_secondary (char **t_ptr, char *element, int *i) +/* ---------------------------------------------------------------------- */ +/* + * Function reads an element name out of the equation string. + * An element name is composed of a capital letter followed by any number + * of lower case characters. + * + * Arguments: + * **t_ptr input, points to position in the equation to begin + * output, points to next character of equation after + * element name. + * *element input pointer to place to return element character string + */ +{ + int j; + char c; + char *ptr; + + c=*(*t_ptr)++; + if (c == '\0') { + sprintf(error_string, "Empty string in get_elt. Expected an element name."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Load name into char array element + */ + element[0]=c; + *i=1; + if (c == '[') { + while ((c=(**t_ptr)) != ']') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + if ((c=(**t_ptr)) == ']') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + c=(**t_ptr); + break; + } else if ((c=(**t_ptr)) == '\0') { + error_msg("Did not find ending bracket (])", CONTINUE); + input_error++; + return(ERROR); + } + } + while (islower((int) (c=(**t_ptr))) || c == '_') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } + } else { + while (islower((int) (c=(**t_ptr))) || c == '_') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } + } +/* + * Check if secondary master species element + */ + j = *i; + ptr = *t_ptr; + if (c == '(') { + /* copy parenthesis */ + element[*i]=c; + (*i)++; + (*t_ptr)++; + /* copy number */ + for (;;) { + c = **t_ptr; + if (isdigit((int) c) || c == '-' || c == '.') { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } else if (c == '+') { + (*t_ptr)++; + } else { + break; + } + } + /* go back to before parenthesis */ + if (c != ')' ) { + *i = j; + *t_ptr = ptr; + /* put in closing parenthesis */ + } else { + element[*i]=c; + (*i)++; + (*t_ptr)++; + } + } + element[*i]='\0'; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_secondary_in_species (char **t_ptr, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Makes a list of elements with their coefficients, stores elements + * in elt_list at position count_elts. Global variable count_elts is + * updated with each stored element. Also uses static global variable + * paren_count. + * + * Arguments: + * **t_ptr input, point in token string to start looking + * output, is next position to start looking + * coef input, coefficient to multiply subscripts by + */ + int i, count, l; + char c, c1; + LDBLE d; + char element[MAX_LENGTH]; + + while ( ( (c=**t_ptr) != '+') && + (c != '-') && (c != '\0') ) { + /* close parenthesis */ + if (c == ')') { + paren_count--; + if (paren_count < 0) { + sprintf(error_string,"Too many right parentheses."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } + (*t_ptr)++; + return(OK); + } + c1=*((*t_ptr)+1); + /* beginning of element name */ + if (isupper((int) c) || + c == '[' || + (c == 'e' && c1 == '-') ) { +/* + * Get new element and subscript + */ + if ( get_secondary( t_ptr, element, &l) == ERROR) { + return(ERROR); + } + elt_list[count_elts].elt = element_store ( element ); + if ( get_num( t_ptr , &d ) == ERROR) { + return(ERROR); + } + elt_list[count_elts].coef = d*coef; + count_elts++; +/* + * Expand working space for elements if necessary + */ + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + continue; + } +/* + * Open parentheses + */ + if (c=='(') { + count=count_elts; + if (c1 == ')') { + sprintf(error_string, "Empty parentheses."); + warning_msg(error_string); + } + paren_count++; + (*t_ptr)++; + if ( get_secondary_in_species(t_ptr, coef ) == ERROR ) { + return(ERROR); + } + if (get_num (t_ptr, &d) == ERROR ) { + return(ERROR); + } + for (i=count; i < count_elts; i++) { + elt_list[i].coef *= d; + } + continue; + } +/* + * Colon + */ + if (c==':') { + count=count_elts; + (*t_ptr)++; + if (get_num (t_ptr, &d) == ERROR ) { + return(ERROR); + } + if ( get_secondary_in_species(t_ptr, coef ) == ERROR ) { + return(ERROR); + } + for (i=count; i < count_elts; i++) { + elt_list[i].coef *= d; + } + continue; + } +/* + * Not beginning of element and not opening paren + */ + sprintf(error_string, "Parsing error in get_secondary_in_species, unexpected character, %c.", c); + error_msg(error_string, CONTINUE); + return (ERROR); + } + if (paren_count != 0) { + sprintf(error_string,"Unbalanced parentheses."); + error_msg(error_string, CONTINUE); + return(ERROR); + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int get_num (char **t_ptr, LDBLE *num) +/* ---------------------------------------------------------------------- */ +/* + * Function reads through a string looking for leading numeric field + * if no numeric field is found, the number is set to 1.0. + * + * Arguments: + * + * **t_ptr input, points to a position in a character string from which + * a number is to be extracted. + * output, points to next position to be parsed. + * *num address where the number is to be stored. + * + * Returns: + * ERROR, + * OK. + */ +{ + int i, decimal; + char c; + char *ptr1; + char token[MAX_LENGTH]; + + *num=1.0; + i=0; + c=**t_ptr; + decimal=0; + if (isdigit((int) c) || (c == '.') ){ + while (isdigit((int) c) || (c == '.') ) { + if (c == '.') decimal++; + if (decimal > 1) break; + token[i++]=c; + /* check number length */ + if (i >= MAX_LENGTH ) { + sprintf(error_string, "Number was greater than MAX_LENGTH characters."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } + c=*(++(*t_ptr)); + } + token[i]='\0'; + errno=0; + *num=strtod(token,&ptr1); + if ( errno == ERANGE ) { + sprintf(error_string,"Converting number in get_num, %s.", token); + input_error++; + error_msg(error_string, CONTINUE); + return(ERROR); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_species (char **ptr) +/* ---------------------------------------------------------------------- */ +{ +/* Function reads next species out of the equation, including optional + * preceding coefficient and optional trailing charge. Data are + * store in trxn.token[count]. + * + * Arguments: + * **ptr input, points to the position in the equation to pick up the species. + * output, points to the next character after the species charge. + * + */ + char string[MAX_LENGTH]; + int l; + + if (count_trxn + 1 >= max_trxn) { + space ((void **) &(trxn.token), count_trxn+1, &max_trxn, + sizeof(struct rxn_token_temp)); + } + /* coefficient */ + if ( get_coef(&(trxn.token[count_trxn].coef), ptr) == ERROR ) { + return(ERROR); + } + /* name and charge */ + if ( get_token( ptr, string, &trxn.token[count_trxn].z, &l) == ERROR ) { + return(ERROR); + } + trxn.token[count_trxn].name = string_hsave ( string ); + return(OK); +} diff --git a/phast.xsd b/phast.xsd new file mode 100644 index 00000000..e2b59f7d --- /dev/null +++ b/phast.xsd @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phqalloc.cpp b/phqalloc.cpp new file mode 100644 index 00000000..30b6b0f2 --- /dev/null +++ b/phqalloc.cpp @@ -0,0 +1,246 @@ +#define EXTERNAL extern +#include "global.h" +#include "output.h" +/*#include */ +#include +#include +#include +static char const svnid[] = "$Id: phqalloc.c 78 2005-02-01 22:47:12Z dlpark $"; + +#if defined(PHREEQCI_GUI) +#define _CRTDBG_MAP_ALLOC +#include +#endif + +typedef struct PHRQMemHeader { + struct PHRQMemHeader *pNext; /* memory allocated just after this one */ + struct PHRQMemHeader *pPrev; /* memory allocated just prior to this one */ +#if !defined(NDEBUG) + size_t size; /* memory request + sizeof(PHRQMemHeader) */ + char *szFileName; /* file name */ + int nLine; /* line number */ + int dummy; /* alignment */ +#endif +} PHRQMemHeader; + +/* + * This pointer points to the last allocated block + * Note: s_pTail->pNext should always be NULL + */ +static PHRQMemHeader *s_pTail = NULL; + + +/* ---------------------------------------------------------------------- */ +#if !defined(NDEBUG) +void *PHRQ_malloc( size_t size, const char *szFileName, int nLine) +#else +void *PHRQ_malloc( size_t size) +#endif +/* ---------------------------------------------------------------------- */ +{ + PHRQMemHeader *p; + if (svnid == NULL) fprintf(stderr," "); + + assert((s_pTail == NULL) || (s_pTail->pNext == NULL)); + + p = (PHRQMemHeader*)malloc(sizeof(PHRQMemHeader) + size); + + if (p == NULL) return NULL; + +#if !defined(NDEBUG) + memset(p, 0, sizeof(PHRQMemHeader) + size); +#endif + p->pNext = NULL; + + if ( (p->pPrev = s_pTail) != NULL ) { + s_pTail->pNext = p; + } + +#if !defined(NDEBUG) + p->size = sizeof(PHRQMemHeader) + size; + p->szFileName = (char *) malloc(strlen(szFileName) + 1); + if (p->szFileName) strcpy(p->szFileName, szFileName); + p->nLine = nLine; +#endif + + s_pTail = p; + p++; + return ((void *)(p)); +} + +/* ---------------------------------------------------------------------- */ +void PHRQ_free( void *ptr ) +/* ---------------------------------------------------------------------- */ +{ + PHRQMemHeader *p; + + assert((s_pTail == NULL) || (s_pTail->pNext == NULL)); + + if (ptr == NULL) return; + + p = (PHRQMemHeader *)ptr - 1; + + if (p->pNext != NULL) { + p->pNext->pPrev = p->pPrev; + } else { + /* Handle special case when (p == s_pTail) */ + assert(s_pTail != NULL); + assert(p == s_pTail); + s_pTail = p->pPrev; + } + + if (p->pPrev) { + p->pPrev->pNext = p->pNext; + } + +#if !defined(NDEBUG) + free(p->szFileName); +#endif + + free(p); +} + +/* ---------------------------------------------------------------------- */ +void PHRQ_free_all( void ) +/* ---------------------------------------------------------------------- */ +{ + assert((s_pTail == NULL) || (s_pTail->pNext == NULL)); + + if (s_pTail == NULL) { +#if !defined(NDEBUG) + output_msg(OUTPUT_MESSAGE, "No memory leaks\n"); +#endif + return; + } + while (s_pTail->pPrev != NULL) + { + s_pTail = s_pTail->pPrev; +#if !defined(NDEBUG) + output_msg(OUTPUT_MESSAGE, "%s(%d) %p: freed in PHRQ_free_all\n", + s_pTail->pNext->szFileName, s_pTail->pNext->nLine, (void *) (s_pTail->pNext + 1)); + free(s_pTail->pNext->szFileName); +#endif + free(s_pTail->pNext); + } + +#if !defined(NDEBUG) + output_msg(OUTPUT_MESSAGE, "%s(%d) %p: freed in PHRQ_free_all\n", + s_pTail->szFileName, s_pTail->nLine, (void *) (s_pTail+1)); + if (phast == TRUE) { + output_msg(OUTPUT_STDERR, "%s(%d) %p: freed in PHRQ_free_all, %d\n", + s_pTail->szFileName, s_pTail->nLine, (void *) (s_pTail+1), phreeqc_mpi_myself); + } + free(s_pTail->szFileName); +#endif + free(s_pTail); + s_pTail = NULL; +} + +/* ---------------------------------------------------------------------- */ +void *PHRQ_calloc( size_t num, + size_t size +#if !defined(NDEBUG) + , + const char *szFileName, + int nLine +#endif + ) +/* ---------------------------------------------------------------------- */ +{ + PHRQMemHeader *p; + + assert((s_pTail == NULL) || (s_pTail->pNext == NULL)); + + p = (PHRQMemHeader*)malloc(sizeof(PHRQMemHeader) + size * num); + + if (p == NULL) return NULL; + + p->pNext = NULL; + + if ( (p->pPrev = s_pTail) != NULL ) { + s_pTail->pNext = p; + } + +#if !defined(NDEBUG) + p->size = sizeof(PHRQMemHeader) + size * num; + p->szFileName = (char *) malloc(strlen(szFileName) + 1); + if (p->szFileName) strcpy(p->szFileName, szFileName); + p->nLine = nLine; +#endif + + s_pTail = p; + p++; + return memset(p, 0, size * num); +} + +/* ---------------------------------------------------------------------- */ +void *PHRQ_realloc( void *ptr, + size_t size +#if !defined(NDEBUG) + , + const char *szFileName, + int nLine +#endif + ) +/* ---------------------------------------------------------------------- */ +{ + PHRQMemHeader *p; + size_t new_size; + +#if !defined(NDEBUG) + size_t old_size; +#endif + + if (ptr == NULL) + { + return PHRQ_malloc(size +#if !defined(NDEBUG) + , + szFileName, + nLine +#endif + ); + } + + assert((s_pTail == NULL) || (s_pTail->pNext == NULL)); + + p = (PHRQMemHeader*)ptr - 1; + + new_size = sizeof(PHRQMemHeader) + size; + +#if defined(NDEBUG) + p = (PHRQMemHeader*)realloc(p, new_size); +#else + old_size = p->size; + p = (PHRQMemHeader*)realloc(p, new_size); + if (p != NULL) { + p->size = new_size; + if (new_size > old_size) { + memset((char*)p + old_size, 0, new_size - old_size); + } + } +#endif + + if (p == NULL) return NULL; + + if (p->pPrev != NULL) { + p->pPrev->pNext = p; + } + + if (p->pNext != NULL) { + p->pNext->pPrev = p; + } else { + s_pTail = p; + } + +#if !defined(NDEBUG) + free(p->szFileName); + p->szFileName = (char *) malloc(strlen(szFileName) + 1); + if (p->szFileName) strcpy(p->szFileName, szFileName); + p->nLine = nLine; +#endif + + p++; + return ((void *)(p)); +} + diff --git a/phqalloc.h b/phqalloc.h new file mode 100644 index 00000000..6d06a4b2 --- /dev/null +++ b/phqalloc.h @@ -0,0 +1,46 @@ +#if !defined (INCLUDE_PHRQALLOC_H) +#define INCLUDE_PHRQALLOC_H + +#if !defined(WIN32_MEMORY_DEBUG) +#define USE_PHRQ_ALLOC +#endif + +#if defined (USE_PHRQ_ALLOC) + +#ifdef PHREEQC_IDENT +static char const svnidphqalloc[] = "$Id$"; +#endif + +#if !defined(NDEBUG) +extern void *PHRQ_malloc(size_t, const char *, int); +extern void *PHRQ_calloc(size_t, size_t, const char *, int); +extern void *PHRQ_realloc(void *, size_t, const char *, int); +#else +extern void *PHRQ_malloc(size_t); +extern void *PHRQ_calloc(size_t, size_t); +extern void *PHRQ_realloc(void *, size_t); +#endif + +extern void PHRQ_free(void *); +extern void PHRQ_free_all(void); + +#if !defined(NDEBUG) +#define PHRQ_malloc(s) PHRQ_malloc(s, __FILE__, __LINE__) +#define PHRQ_calloc(c, s) PHRQ_calloc(c, s, __FILE__, __LINE__) +#define PHRQ_realloc(p, s) PHRQ_realloc(p, s, __FILE__, __LINE__) +#endif + +#define free(p) PHRQ_free(p) + +#else /* defined (USE_PHRQ_ALLOC) */ + +#define PHRQ_malloc malloc +#define PHRQ_realloc realloc +#define PHRQ_calloc calloc +#define PHRQ_free free + +#define PHRQ_free_all() do{}while(0) /* NO-OP */ + +#endif /* defined (USE_PHRQ_ALLOC) */ + +#endif /* !defined (INCLUDE_PHRQALLOC_H) */ diff --git a/phreeqc.dat b/phreeqc.dat new file mode 100644 index 00000000..befd93da --- /dev/null +++ b/phreeqc.dat @@ -0,0 +1,1556 @@ +SOLUTION_MASTER_SPECIES +# +#element species alk gfw_formula element_gfw +# +H H+ -1. H 1.008 +H(0) H2 0.0 H +H(1) H+ -1. 0.0 +E e- 0.0 0.0 0.0 +O H2O 0.0 O 16.00 +O(0) O2 0.0 O +O(-2) H2O 0.0 0.0 +Ca Ca+2 0.0 Ca 40.08 +Mg Mg+2 0.0 Mg 24.312 +Na Na+ 0.0 Na 22.9898 +K K+ 0.0 K 39.102 +Fe Fe+2 0.0 Fe 55.847 +Fe(+2) Fe+2 0.0 Fe +Fe(+3) Fe+3 -2.0 Fe +Mn Mn+2 0.0 Mn 54.938 +Mn(+2) Mn+2 0.0 Mn +Mn(+3) Mn+3 0.0 Mn +Al Al+3 0.0 Al 26.9815 +Ba Ba+2 0.0 Ba 137.34 +Sr Sr+2 0.0 Sr 87.62 +Si H4SiO4 0.0 SiO2 28.0843 +Cl Cl- 0.0 Cl 35.453 +C CO3-2 2.0 HCO3 12.0111 +C(+4) CO3-2 2.0 HCO3 +C(-4) CH4 0.0 CH4 +Alkalinity CO3-2 1.0 Ca0.5(CO3)0.5 50.05 +S SO4-2 0.0 SO4 32.064 +S(6) SO4-2 0.0 SO4 +S(-2) HS- 1.0 S +N NO3- 0.0 N 14.0067 +N(+5) NO3- 0.0 N +N(+3) NO2- 0.0 N +N(0) N2 0.0 N +N(-3) NH4+ 0.0 N +B H3BO3 0.0 B 10.81 +P PO4-3 2.0 P 30.9738 +F F- 0.0 F 18.9984 +Li Li+ 0.0 Li 6.939 +Br Br- 0.0 Br 79.904 +Zn Zn+2 0.0 Zn 65.37 +Cd Cd+2 0.0 Cd 112.4 +Pb Pb+2 0.0 Pb 207.19 +Cu Cu+2 0.0 Cu 63.546 +Cu(+2) Cu+2 0.0 Cu +Cu(+1) Cu+1 0.0 Cu + +SOLUTION_SPECIES + +H+ = H+ + log_k 0.000 + -gamma 9.0000 0.0000 + +e- = e- + log_k 0.000 + +H2O = H2O + log_k 0.000 + +Ca+2 = Ca+2 + log_k 0.000 + -gamma 5.0000 0.1650 + +Mg+2 = Mg+2 + log_k 0.000 + -gamma 5.5000 0.2000 + +Na+ = Na+ + log_k 0.000 + -gamma 4.0000 0.0750 + +K+ = K+ + log_k 0.000 + -gamma 3.5000 0.0150 + +Fe+2 = Fe+2 + log_k 0.000 + -gamma 6.0000 0.0000 + +Mn+2 = Mn+2 + log_k 0.000 + -gamma 6.0000 0.0000 + +Al+3 = Al+3 + log_k 0.000 + -gamma 9.0000 0.0000 + +Ba+2 = Ba+2 + log_k 0.000 + -gamma 5.0000 0.0000 + +Sr+2 = Sr+2 + log_k 0.000 + -gamma 5.2600 0.1210 + +H4SiO4 = H4SiO4 + log_k 0.000 + +Cl- = Cl- + log_k 0.000 + -gamma 3.5000 0.0150 + +CO3-2 = CO3-2 + log_k 0.000 + -gamma 5.4000 0.0000 + +SO4-2 = SO4-2 + log_k 0.000 + -gamma 5.0000 -0.0400 + +NO3- = NO3- + log_k 0.000 + -gamma 3.0000 0.0000 + +H3BO3 = H3BO3 + log_k 0.000 + +PO4-3 = PO4-3 + log_k 0.000 + -gamma 4.0000 0.0000 + +F- = F- + log_k 0.000 + -gamma 3.5000 0.0000 + +Li+ = Li+ + log_k 0.000 + -gamma 6.0000 0.0000 + +Br- = Br- + log_k 0.000 + -gamma 3.0000 0.0000 + +Zn+2 = Zn+2 + log_k 0.000 + -gamma 5.0000 0.0000 + +Cd+2 = Cd+2 + log_k 0.000 + +Pb+2 = Pb+2 + log_k 0.000 + +Cu+2 = Cu+2 + log_k 0.000 + -gamma 6.0000 0.0000 + +H2O = OH- + H+ + log_k -14.000 + delta_h 13.362 kcal + -analytic -283.971 -0.05069842 13323.0 102.24447 -1119669.0 + -gamma 3.5000 0.0000 + +2 H2O = O2 + 4 H+ + 4 e- + log_k -86.08 + delta_h 134.79 kcal + +2 H+ + 2 e- = H2 + log_k -3.15 + delta_h -1.759 kcal + +CO3-2 + H+ = HCO3- + log_k 10.329 + delta_h -3.561 kcal + -analytic 107.8871 0.03252849 -5151.79 -38.92561 563713.9 + -gamma 5.4000 0.0000 + +CO3-2 + 2 H+ = CO2 + H2O + log_k 16.681 + delta_h -5.738 kcal + -analytic 464.1965 0.09344813 -26986.16 -165.75951 2248628.9 + +CO3-2 + 10 H+ + 8 e- = CH4 + 3 H2O + log_k 41.071 + delta_h -61.039 kcal + +SO4-2 + H+ = HSO4- + log_k 1.988 + delta_h 3.85 kcal + -analytic -56.889 0.006473 2307.9 19.8858 0.0 + +HS- = S-2 + H+ + log_k -12.918 + delta_h 12.1 kcal + -gamma 5.0000 0.0000 + +SO4-2 + 9 H+ + 8 e- = HS- + 4 H2O + log_k 33.65 + delta_h -60.140 kcal + -gamma 3.5000 0.0000 + +HS- + H+ = H2S + log_k 6.994 + delta_h -5.300 kcal + -analytical -11.17 0.02386 3279.0 + + +NO3- + 2 H+ + 2 e- = NO2- + H2O + log_k 28.570 + delta_h -43.760 kcal + -gamma 3.0000 0.0000 + +2 NO3- + 12 H+ + 10 e- = N2 + 6 H2O + log_k 207.080 + delta_h -312.130 kcal + +NH4+ = NH3 + H+ + log_k -9.252 + delta_h 12.48 kcal + -analytic 0.6322 -0.001225 -2835.76 + +NO3- + 10 H+ + 8 e- = NH4+ + 3 H2O + log_k 119.077 + delta_h -187.055 kcal + -gamma 2.5000 0.0000 + +NH4+ + SO4-2 = NH4SO4- + log_k 1.11 + +H3BO3 = H2BO3- + H+ + log_k -9.240 + delta_h 3.224 kcal +# -analytical 24.3919 0.012078 -1343.9 -13.2258 + +H3BO3 + F- = BF(OH)3- + log_k -0.400 + delta_h 1.850 kcal + +H3BO3 + 2 F- + H+ = BF2(OH)2- + H2O + log_k 7.63 + delta_h 1.618 kcal + +H3BO3 + 2 H+ + 3 F- = BF3OH- + 2 H2O + log_k 13.67 + delta_h -1.614 kcal + +H3BO3 + 3 H+ + 4 F- = BF4- + 3 H2O + log_k 20.28 + delta_h -1.846 kcal + +PO4-3 + H+ = HPO4-2 + log_k 12.346 + delta_h -3.530 kcal + -gamma 4.0000 0.0000 + +PO4-3 + 2 H+ = H2PO4- + log_k 19.553 + delta_h -4.520 kcal + -gamma 4.5000 0.0000 + +H+ + F- = HF + log_k 3.18 + delta_h 3.18 kcal + -analytic -2.033 0.012645 429.01 + +H+ + 2 F- = HF2- + log_k 3.760 + delta_h 4.550 kcal + +Ca+2 + H2O = CaOH+ + H+ + log_k -12.780 + +Ca+2 + CO3-2 = CaCO3 + log_k 3.224 + delta_h 3.545 kcal + -analytic -1228.732 -0.299440 35512.75 485.818 + +Ca+2 + CO3-2 + H+ = CaHCO3+ + log_k 11.435 + delta_h -0.871 kcal + -analytic 1317.0071 0.34546894 -39916.84 -517.70761 563713.9 + -gamma 5.4000 0.0000 + +Ca+2 + SO4-2 = CaSO4 + log_k 2.300 + delta_h 1.650 kcal + +Ca+2 + HSO4- = CaHSO4+ + log_k 1.08 + +Ca+2 + PO4-3 = CaPO4- + log_k 6.459 + delta_h 3.100 kcal + +Ca+2 + HPO4-2 = CaHPO4 + log_k 2.739 + delta_h 3.3 kcal + +Ca+2 + H2PO4- = CaH2PO4+ + log_k 1.408 + delta_h 3.4 kcal + +Ca+2 + F- = CaF+ + log_k 0.940 + delta_h 4.120 kcal + +Mg+2 + H2O = MgOH+ + H+ + log_k -11.440 + delta_h 15.952 kcal + +Mg+2 + CO3-2 = MgCO3 + log_k 2.98 + delta_h 2.713 kcal + -analytic 0.9910 0.00667 + +Mg+2 + H+ + CO3-2 = MgHCO3+ + log_k 11.399 + delta_h -2.771 kcal + -analytic 48.6721 0.03252849 -2614.335 -18.00263 563713.9 + +Mg+2 + SO4-2 = MgSO4 + log_k 2.370 + delta_h 4.550 kcal + +Mg+2 + PO4-3 = MgPO4- + log_k 6.589 + delta_h 3.100 kcal + +Mg+2 + HPO4-2 = MgHPO4 + log_k 2.87 + delta_h 3.3 kcal + +Mg+2 + H2PO4- = MgH2PO4+ + log_k 1.513 + delta_h 3.4 kcal + +Mg+2 + F- = MgF+ + log_k 1.820 + delta_h 3.200 kcal + +Na+ + H2O = NaOH + H+ + log_k -14.180 + +Na+ + CO3-2 = NaCO3- + log_k 1.270 + delta_h 8.910 kcal + +Na+ + HCO3- = NaHCO3 + log_k -0.25 + +Na+ + SO4-2 = NaSO4- + log_k 0.700 + delta_h 1.120 kcal + +Na+ + HPO4-2 = NaHPO4- + log_k 0.29 + +Na+ + F- = NaF + log_k -0.240 + +K+ + H2O = KOH + H+ + log_k -14.460 + +K+ + SO4-2 = KSO4- + log_k 0.850 + delta_h 2.250 kcal + -analytical 3.106 0.0 -673.6 + + +K+ + HPO4-2 = KHPO4- + log_k 0.29 + +Fe+2 + H2O = FeOH+ + H+ + log_k -9.500 + delta_h 13.200 kcal + +Fe+2 + Cl- = FeCl+ + log_k 0.140 + +Fe+2 + CO3-2 = FeCO3 + log_k 4.380 + +Fe+2 + HCO3- = FeHCO3+ + log_k 2.0 + +Fe+2 + SO4-2 = FeSO4 + log_k 2.250 + delta_h 3.230 kcal + +Fe+2 + HSO4- = FeHSO4+ + log_k 1.08 + +Fe+2 + 2HS- = Fe(HS)2 + log_k 8.95 + +Fe+2 + 3HS- = Fe(HS)3- + log_k 10.987 + +Fe+2 + HPO4-2 = FeHPO4 + log_k 3.6 + +Fe+2 + H2PO4- = FeH2PO4+ + log_k 2.7 + +Fe+2 + F- = FeF+ + log_k 1.000 + +Fe+2 = Fe+3 + e- + log_k -13.020 + delta_h 9.680 kcal + -gamma 9.0000 0.0000 + +Fe+3 + H2O = FeOH+2 + H+ + log_k -2.19 + delta_h 10.4 kcal + +Fe+3 + 2 H2O = Fe(OH)2+ + 2 H+ + log_k -5.67 + delta_h 17.1 kcal + +Fe+3 + 3 H2O = Fe(OH)3 + 3 H+ + log_k -12.56 + delta_h 24.8 kcal + +Fe+3 + 4 H2O = Fe(OH)4- + 4 H+ + log_k -21.6 + delta_h 31.9 kcal + +2 Fe+3 + 2 H2O = Fe2(OH)2+4 + 2 H+ + log_k -2.95 + delta_h 13.5 kcal + +3 Fe+3 + 4 H2O = Fe3(OH)4+5 + 4 H+ + log_k -6.3 + delta_h 14.3 kcal + +Fe+3 + Cl- = FeCl+2 + log_k 1.48 + delta_h 5.6 kcal + +Fe+3 + 2 Cl- = FeCl2+ + log_k 2.13 + +Fe+3 + 3 Cl- = FeCl3 + log_k 1.13 + +Fe+3 + SO4-2 = FeSO4+ + log_k 4.04 + delta_h 3.91 kcal + +Fe+3 + HSO4- = FeHSO4+2 + log_k 2.48 + +Fe+3 + 2 SO4-2 = Fe(SO4)2- + log_k 5.38 + delta_h 4.60 kcal + +Fe+3 + HPO4-2 = FeHPO4+ + log_k 5.43 + delta_h 5.76 kcal + +Fe+3 + H2PO4- = FeH2PO4+2 + log_k 5.43 + +Fe+3 + F- = FeF+2 + log_k 6.2 + delta_h 2.7 kcal + +Fe+3 + 2 F- = FeF2+ + log_k 10.8 + delta_h 4.8 kcal + +Fe+3 + 3 F- = FeF3 + log_k 14.0 + delta_h 5.4 kcal + +Mn+2 + H2O = MnOH+ + H+ + log_k -10.590 + delta_h 14.400 kcal + +Mn+2 + Cl- = MnCl+ + log_k 0.610 + +Mn+2 + 2 Cl- = MnCl2 + log_k 0.250 + +Mn+2 + 3 Cl- = MnCl3- + log_k -0.310 + +Mn+2 + CO3-2 = MnCO3 + log_k 4.900 + +Mn+2 + HCO3- = MnHCO3+ + log_k 1.95 + +Mn+2 + SO4-2 = MnSO4 + log_k 2.250 + delta_h 3.370 kcal + +Mn+2 + 2 NO3- = Mn(NO3)2 + log_k 0.600 + delta_h -0.396 kcal + +Mn+2 + F- = MnF+ + log_k 0.840 + +Mn+2 = Mn+3 + e- + log_k -25.510 + delta_h 25.800 kcal + +Al+3 + H2O = AlOH+2 + H+ + log_k -5.00 + delta_h 11.49 kcal + -analytic -38.253 0.0 -656.27 14.327 + +Al+3 + 2 H2O = Al(OH)2+ + 2 H+ + log_k -10.1 + delta_h 26.90 kcal + -analytic 88.500 0.0 -9391.6 -27.121 + +Al+3 + 3 H2O = Al(OH)3 + 3 H+ + log_k -16.9 + delta_h 39.89 kcal + -analytic 226.374 0.0 -18247.8 -73.597 + +Al+3 + 4 H2O = Al(OH)4- + 4 H+ + log_k -22.7 + delta_h 42.30 kcal + -analytic 51.578 0.0 -11168.9 -14.865 + +Al+3 + SO4-2 = AlSO4+ + log_k 3.5 + delta_h 2.29 kcal + +Al+3 + 2SO4-2 = Al(SO4)2- + log_k 5.0 + delta_h 3.11 kcal + +Al+3 + HSO4- = AlHSO4+2 + log_k 0.46 + +Al+3 + F- = AlF+2 + log_k 7.000 + delta_h 1.060 kcal + +Al+3 + 2 F- = AlF2+ + log_k 12.700 + delta_h 1.980 kcal + +Al+3 + 3 F- = AlF3 + log_k 16.800 + delta_h 2.160 kcal + +Al+3 + 4 F- = AlF4- + log_k 19.400 + delta_h 2.200 kcal + +Al+3 + 5 F- = AlF5-2 + log_k 20.600 + delta_h 1.840 kcal + +Al+3 + 6 F- = AlF6-3 + log_k 20.600 + delta_h -1.670 kcal + +H4SiO4 = H3SiO4- + H+ + log_k -9.83 + delta_h 6.12 kcal + -analytic -302.3724 -0.050698 15669.69 108.18466 -1119669.0 + +H4SiO4 = H2SiO4-2 + 2 H+ + log_k -23.0 + delta_h 17.6 kcal + -analytic -294.0184 -0.072650 11204.49 108.18466 -1119669.0 + +H4SiO4 + 4 H+ + 6 F- = SiF6-2 + 4 H2O + log_k 30.180 + delta_h -16.260 kcal + +Ba+2 + H2O = BaOH+ + H+ + log_k -13.470 + +Ba+2 + CO3-2 = BaCO3 + log_k 2.71 + delta_h 3.55 kcal + -analytic 0.113 0.008721 + +Ba+2 + HCO3- = BaHCO3+ + log_k 0.982 + delta_h 5.56 kcal + -analytical -3.0938 0.013669 0.0 0.0 0.0 + +Ba+2 + SO4-2 = BaSO4 + log_k 2.700 + +Sr+2 + H2O = SrOH+ + H+ + log_k -13.290 + -gamma 5.0000 0.0000 + +Sr+2 + CO3-2 + H+ = SrHCO3+ + log_k 11.509 + delta_h 2.489 kcal + -analytic 104.6391 0.04739549 -5151.79 -38.92561 563713.9 + -gamma 5.4000 0.0000 + +Sr+2 + CO3-2 = SrCO3 + log_k 2.81 + delta_h 5.22 kcal + -analytic -1.019 0.012826 + +Sr+2 + SO4-2 = SrSO4 + log_k 2.290 + delta_h 2.080 kcal + +Li+ + H2O = LiOH + H+ + log_k -13.640 + +Li+ + SO4-2 = LiSO4- + log_k 0.640 + +Cu+2 + e- = Cu+ + log_k 2.720 + delta_h 1.650 kcal + -gamma 2.5000 0.0000 + +Cu+2 + H2O = CuOH+ + H+ + log_k -8.000 + -gamma 4.0000 0.0000 + +Cu+2 + 2 H2O = Cu(OH)2 + 2 H+ + log_k -13.680 + +Cu+2 + 3 H2O = Cu(OH)3- + 3 H+ + log_k -26.900 + +Cu+2 + 4 H2O = Cu(OH)4-2 + 4 H+ + log_k -39.600 + +Cu+2 + SO4-2 = CuSO4 + log_k 2.310 + delta_h 1.220 kcal + +Zn+2 + H2O = ZnOH+ + H+ + log_k -8.96 + delta_h 13.4 kcal + +Zn+2 + 2 H2O = Zn(OH)2 + 2 H+ + log_k -16.900 + +Zn+2 + 3 H2O = Zn(OH)3- + 3 H+ + log_k -28.400 + +Zn+2 + 4 H2O = Zn(OH)4-2 + 4 H+ + log_k -41.200 + +Zn+2 + Cl- = ZnCl+ + log_k 0.43 + delta_h 7.79 kcal + +Zn+2 + 2 Cl- = ZnCl2 + log_k 0.45 + delta_h 8.5 kcal + +Zn+2 + 3Cl- = ZnCl3- + log_k 0.5 + delta_h 9.56 kcal + +Zn+2 + 4Cl- = ZnCl4-2 + log_k 0.2 + delta_h 10.96 kcal + +Zn+2 + CO3-2 = ZnCO3 + log_k 5.3 + +Zn+2 + 2CO3-2 = Zn(CO3)2-2 + log_k 9.63 + +Zn+2 + HCO3- = ZnHCO3+ + log_k 2.1 + +Zn+2 + SO4-2 = ZnSO4 + log_k 2.37 + delta_h 1.36 kcal + +Zn+2 + 2SO4-2 = Zn(SO4)2-2 + log_k 3.28 + +Cd+2 + H2O = CdOH+ + H+ + log_k -10.080 + delta_h 13.1 kcal + +Cd+2 + 2 H2O = Cd(OH)2 + 2 H+ + log_k -20.350 + +Cd+2 + 3 H2O = Cd(OH)3- + 3 H+ + log_k -33.300 + +Cd+2 + 4 H2O = Cd(OH)4-2 + 4 H+ + log_k -47.350 + +Cd+2 + Cl- = CdCl+ + log_k 1.980 + delta_h 0.59 kcal + +Cd+2 + 2 Cl- = CdCl2 + log_k 2.600 + delta_h 1.24 kcal + +Cd+2 + 3 Cl- = CdCl3- + log_k 2.400 + delta_h 3.9 kcal + +Cd+2 + CO3-2 = CdCO3 + log_k 2.9 + +Cd+2 + 2CO3-2 = Cd(CO3)2-2 + log_k 6.4 + +Cd+2 + HCO3- = CdHCO3+ + log_k 1.5 + +Cd+2 + SO4-2 = CdSO4 + log_k 2.460 + delta_h 1.08 kcal + +Cd+2 + 2SO4-2 = Cd(SO4)2-2 + log_k 3.5 + +Pb+2 + H2O = PbOH+ + H+ + log_k -7.710 + +Pb+2 + 2 H2O = Pb(OH)2 + 2 H+ + log_k -17.120 + +Pb+2 + 3 H2O = Pb(OH)3- + 3 H+ + log_k -28.060 + +Pb+2 + 4 H2O = Pb(OH)4-2 + 4 H+ + log_k -39.700 + +2 Pb+2 + H2O = Pb2OH+3 + H+ + log_k -6.360 + +Pb+2 + Cl- = PbCl+ + log_k 1.600 + delta_h 4.38 kcal + +Pb+2 + 2 Cl- = PbCl2 + log_k 1.800 + delta_h 1.08 kcal + +Pb+2 + 3 Cl- = PbCl3- + log_k 1.700 + delta_h 2.17 kcal + +Pb+2 + 4 Cl- = PbCl4-2 + log_k 1.380 + delta_h 3.53 kcal + +Pb+2 + CO3-2 = PbCO3 + log_k 7.240 + +Pb+2 + 2 CO3-2 = Pb(CO3)2-2 + log_k 10.640 + +Pb+2 + HCO3- = PbHCO3+ + log_k 2.9 + +Pb+2 + SO4-2 = PbSO4 + log_k 2.750 + +Pb+2 + 2 SO4-2 = Pb(SO4)2-2 + log_k 3.470 + +Pb+2 + NO3- = PbNO3+ + log_k 1.170 + +PHASES + +Calcite + CaCO3 = CO3-2 + Ca+2 + log_k -8.480 + delta_h -2.297 kcal + -analytic -171.9065 -0.077993 2839.319 71.595 + +Aragonite + CaCO3 = CO3-2 + Ca+2 + log_k -8.336 + delta_h -2.589 kcal + -analytic -171.9773 -0.077993 2903.293 71.595 + +Dolomite + CaMg(CO3)2 = Ca+2 + Mg+2 + 2 CO3-2 + log_k -17.090 + delta_h -9.436 kcal + +Siderite + FeCO3 = Fe+2 + CO3-2 + log_k -10.890 + delta_h -2.480 kcal + +Rhodochrosite + MnCO3 = Mn+2 + CO3-2 + log_k -11.130 + delta_h -1.430 kcal + +Strontianite + SrCO3 = Sr+2 + CO3-2 + log_k -9.271 + delta_h -0.400 kcal + -analytic 155.0305 0.0 -7239.594 -56.58638 + +Witherite + BaCO3 = Ba+2 + CO3-2 + log_k -8.562 + delta_h 0.703 kcal + -analytic 607.642 0.121098 -20011.25 -236.4948 + +Gypsum + CaSO4:2H2O = Ca+2 + SO4-2 + 2 H2O + log_k -4.580 + delta_h -0.109 kcal + -analytic 68.2401 0.0 -3221.51 -25.0627 + +Anhydrite + CaSO4 = Ca+2 + SO4-2 + log_k -4.360 + delta_h -1.710 kcal + -analytic 197.52 0.0 -8669.8 -69.835 + +Celestite + SrSO4 = Sr+2 + SO4-2 + log_k -6.630 + delta_h -1.037 kcal + -analytic -14805.9622 -2.4660924 756968.533 5436.3588 -40553604.0 + +Barite + BaSO4 = Ba+2 + SO4-2 + log_k -9.970 + delta_h 6.350 kcal + -analytic 136.035 0.0 -7680.41 -48.595 + +Hydroxyapatite + Ca5(PO4)3OH + 4 H+ = H2O + 3 HPO4-2 + 5 Ca+2 + log_k -3.421 + delta_h -36.155 kcal + +Fluorite + CaF2 = Ca+2 + 2 F- + log_k -10.600 + delta_h 4.690 kcal + -analytic 66.348 0.0 -4298.2 -25.271 + +SiO2(a) + SiO2 + 2 H2O = H4SiO4 + log_k -2.710 + delta_h 3.340 kcal + -analytic -0.26 0.0 -731.0 + +Chalcedony + SiO2 + 2 H2O = H4SiO4 + log_k -3.550 + delta_h 4.720 kcal + -analytic -0.09 0.0 -1032.0 + +Quartz + SiO2 + 2 H2O = H4SiO4 + log_k -3.980 + delta_h 5.990 kcal + -analytic 0.41 0.0 -1309.0 + +Gibbsite + Al(OH)3 + 3 H+ = Al+3 + 3 H2O + log_k 8.110 + delta_h -22.800 kcal + +Al(OH)3(a) + Al(OH)3 + 3 H+ = Al+3 + 3 H2O + log_k 10.800 + delta_h -26.500 kcal + +Kaolinite + Al2Si2O5(OH)4 + 6 H+ = H2O + 2 H4SiO4 + 2 Al+3 + log_k 7.435 + delta_h -35.300 kcal + +Albite + NaAlSi3O8 + 8 H2O = Na+ + Al(OH)4- + 3 H4SiO4 + log_k -18.002 + delta_h 25.896 kcal + +Anorthite + CaAl2Si2O8 + 8 H2O = Ca+2 + 2 Al(OH)4- + 2 H4SiO4 + log_k -19.714 + delta_h 11.580 kcal + +K-feldspar + KAlSi3O8 + 8 H2O = K+ + Al(OH)4- + 3 H4SiO4 + log_k -20.573 + delta_h 30.820 kcal + +K-mica + KAl3Si3O10(OH)2 + 10 H+ = K+ + 3 Al+3 + 3 H4SiO4 + log_k 12.703 + delta_h -59.376 kcal + +Chlorite(14A) + Mg5Al2Si3O10(OH)8 + 16H+ = 5Mg+2 + 2Al+3 + 3H4SiO4 + 6H2O + log_k 68.38 + delta_h -151.494 kcal + +Ca-Montmorillonite + Ca0.165Al2.33Si3.67O10(OH)2 + 12 H2O = 0.165Ca+2 + 2.33 Al(OH)4- + 3.67 H4SiO4 + 2 H+ + log_k -45.027 + delta_h 58.373 kcal + +Talc + Mg3Si4O10(OH)2 + 4 H2O + 6 H+ = 3 Mg+2 + 4 H4SiO4 + log_k 21.399 + delta_h -46.352 kcal + +Illite + K0.6Mg0.25Al2.3Si3.5O10(OH)2 + 11.2H2O = 0.6K+ + 0.25Mg+2 + 2.3Al(OH)4- + 3.5H4SiO4 + 1.2H+ + log_k -40.267 + delta_h 54.684 kcal + +Chrysotile + Mg3Si2O5(OH)4 + 6 H+ = H2O + 2 H4SiO4 + 3 Mg+2 + log_k 32.200 + delta_h -46.800 kcal + -analytic 13.248 0.0 10217.1 -6.1894 + +Sepiolite + Mg2Si3O7.5OH:3H2O + 4 H+ + 0.5H2O = 2 Mg+2 + 3 H4SiO4 + log_k 15.760 + delta_h -10.700 kcal + +Sepiolite(d) + Mg2Si3O7.5OH:3H2O + 4 H+ + 0.5H2O = 2 Mg+2 + 3 H4SiO4 + log_k 18.660 + +Hematite + Fe2O3 + 6 H+ = 2 Fe+3 + 3 H2O + log_k -4.008 + delta_h -30.845 kcal + +Goethite + FeOOH + 3 H+ = Fe+3 + 2 H2O + log_k -1.000 + delta_h -14.48 kcal + +Fe(OH)3(a) + Fe(OH)3 + 3 H+ = Fe+3 + 3 H2O + log_k 4.891 + +Pyrite + FeS2 + 2 H+ + 2 e- = Fe+2 + 2 HS- + log_k -18.479 + delta_h 11.300 kcal + +FeS(ppt) + FeS + H+ = Fe+2 + HS- + log_k -3.915 + +Mackinawite + FeS + H+ = Fe+2 + HS- + log_k -4.648 + +Sulfur + S + 2H+ + 2e- = H2S + log_k 4.882 + delta_h -9.5 kcal + +Vivianite + Fe3(PO4)2:8H2O = 3 Fe+2 + 2 PO4-3 + 8 H2O + log_k -36.000 + +Pyrolusite + MnO2 + 4 H+ + 2 e- = Mn+2 + 2 H2O + log_k 41.380 + delta_h -65.110 kcal + +Hausmannite + Mn3O4 + 8 H+ + 2 e- = 3 Mn+2 + 4 H2O + log_k 61.030 + delta_h -100.640 kcal + +Manganite + MnOOH + 3 H+ + e- = Mn+2 + 2 H2O + log_k 25.340 + +Pyrochroite + Mn(OH)2 + 2 H+ = Mn+2 + 2 H2O + log_k 15.200 + +Halite + NaCl = Na+ + Cl- + log_k 1.582 + delta_h 0.918 kcal + +CO2(g) + CO2 = CO2 + log_k -1.468 + delta_h -4.776 kcal + -analytic 108.3865 0.01985076 -6919.53 -40.45154 669365.0 + +O2(g) + O2 = O2 + log_k -2.960 + delta_h -1.844 kcal + +H2(g) + H2 = H2 + log_k -3.150 + delta_h -1.759 kcal + +H2O(g) + H2O = H2O + log_k 1.51 + delta_h -44.03 kJ +# Stumm and Morgan, from NBS and Robie, Hemmingway, and Fischer (1978) + +N2(g) + N2 = N2 + log_k -3.260 + delta_h -1.358 kcal + +H2S(g) + H2S = H2S + log_k -0.997 + delta_h -4.570 kcal + +CH4(g) + CH4 = CH4 + log_k -2.860 + delta_h -3.373 kcal + +NH3(g) + NH3 = NH3 + log_k 1.770 + delta_h -8.170 kcal + +Melanterite + FeSO4:7H2O = 7 H2O + Fe+2 + SO4-2 + log_k -2.209 + delta_h 4.910 kcal + -analytic 1.447 -0.004153 0.0 0.0 -214949.0 + +Alunite + KAl3(SO4)2(OH)6 + 6 H+ = K+ + 3 Al+3 + 2 SO4-2 + 6H2O + log_k -1.400 + delta_h -50.250 kcal + +Jarosite-K + KFe3(SO4)2(OH)6 + 6 H+ = 3 Fe+3 + 6 H2O + K+ + 2 SO4-2 + log_k -9.210 + delta_h -31.280 kcal + +Zn(OH)2(e) + Zn(OH)2 + 2 H+ = Zn+2 + 2 H2O + log_k 11.50 + +Smithsonite + ZnCO3 = Zn+2 + CO3-2 + log_k -10.000 + delta_h -4.36 kcal + +Sphalerite + ZnS + H+ = Zn+2 + HS- + log_k -11.618 + delta_h 8.250 kcal + +Willemite 289 + Zn2SiO4 + 4H+ = 2Zn+2 + H4SiO4 + log_k 15.33 + delta_h -33.37 kcal + +Cd(OH)2 + Cd(OH)2 + 2 H+ = Cd+2 + 2 H2O + log_k 13.650 + +Otavite 315 + CdCO3 = Cd+2 + CO3-2 + log_k -12.1 + delta_h -0.019 kcal + +CdSiO3 328 + CdSiO3 + H2O + 2H+ = Cd+2 + H4SiO4 + log_k 9.06 + delta_h -16.63 kcal + +CdSO4 329 + CdSO4 = Cd+2 + SO4-2 + log_k -0.1 + delta_h -14.74 kcal + +Cerrusite 365 + PbCO3 = Pb+2 + CO3-2 + log_k -13.13 + delta_h 4.86 kcal + +Anglesite 384 + PbSO4 = Pb+2 + SO4-2 + log_k -7.79 + delta_h 2.15 kcal + +Pb(OH)2 389 + Pb(OH)2 + 2H+ = Pb+2 + 2H2O + log_k 8.15 + delta_h -13.99 kcal + +EXCHANGE_MASTER_SPECIES + X X- +EXCHANGE_SPECIES + X- = X- + log_k 0.0 + + Na+ + X- = NaX + log_k 0.0 + -gamma 4.0 0.075 + + K+ + X- = KX + log_k 0.7 + -gamma 3.5 0.015 + delta_h -4.3 # Jardine & Sparks, 1984 + + Li+ + X- = LiX + log_k -0.08 + -gamma 6.0 0.0 + delta_h 1.4 # Merriam & Thomas, 1956 + + NH4+ + X- = NH4X + log_k 0.6 + -gamma 2.5 0.0 + delta_h -2.4 # Laudelout et al., 1968 + + Ca+2 + 2X- = CaX2 + log_k 0.8 + -gamma 5.0 0.165 + delta_h 7.2 # Van Bladel & Gheyl, 1980 + + Mg+2 + 2X- = MgX2 + log_k 0.6 + -gamma 5.5 0.2 + delta_h 7.4 # Laudelout et al., 1968 + + Sr+2 + 2X- = SrX2 + log_k 0.91 + -gamma 5.26 0.121 + delta_h 5.5 # Laudelout et al., 1968 + + Ba+2 + 2X- = BaX2 + log_k 0.91 + -gamma 5.0 0.0 + delta_h 4.5 # Laudelout et al., 1968 + + Mn+2 + 2X- = MnX2 + log_k 0.52 + -gamma 6.0 0.0 + + Fe+2 + 2X- = FeX2 + log_k 0.44 + -gamma 6.0 0.0 + + Cu+2 + 2X- = CuX2 + log_k 0.6 + -gamma 6.0 0.0 + + Zn+2 + 2X- = ZnX2 + log_k 0.8 + -gamma 5.0 0.0 + + Cd+2 + 2X- = CdX2 + log_k 0.8 + + Pb+2 + 2X- = PbX2 + log_k 1.05 + + Al+3 + 3X- = AlX3 + log_k 0.41 + -gamma 9.0 0.0 + + AlOH+2 + 2X- = AlOHX2 + log_k 0.89 + -gamma 0.0 0.0 +SURFACE_MASTER_SPECIES + Hfo_s Hfo_sOH + Hfo_w Hfo_wOH +SURFACE_SPECIES +# All surface data from +# Dzombak and Morel, 1990 +# +# +# Acid-base data from table 5.7 +# +# strong binding site--Hfo_s, + + Hfo_sOH = Hfo_sOH + log_k 0.0 + + Hfo_sOH + H+ = Hfo_sOH2+ + log_k 7.29 # = pKa1,int + + Hfo_sOH = Hfo_sO- + H+ + log_k -8.93 # = -pKa2,int + +# weak binding site--Hfo_w + + Hfo_wOH = Hfo_wOH + log_k 0.0 + + Hfo_wOH + H+ = Hfo_wOH2+ + log_k 7.29 # = pKa1,int + + Hfo_wOH = Hfo_wO- + H+ + log_k -8.93 # = -pKa2,int + +############################################### +# CATIONS # +############################################### +# +# Cations from table 10.1 or 10.5 +# +# Calcium + Hfo_sOH + Ca+2 = Hfo_sOHCa+2 + log_k 4.97 + + Hfo_wOH + Ca+2 = Hfo_wOCa+ + H+ + log_k -5.85 +# Strontium + Hfo_sOH + Sr+2 = Hfo_sOHSr+2 + log_k 5.01 + + Hfo_wOH + Sr+2 = Hfo_wOSr+ + H+ + log_k -6.58 + + Hfo_wOH + Sr+2 + H2O = Hfo_wOSrOH + 2H+ + log_k -17.60 +# Barium + Hfo_sOH + Ba+2 = Hfo_sOHBa+2 + log_k 5.46 + + Hfo_wOH + Ba+2 = Hfo_wOBa+ + H+ + log_k -7.2 # table 10.5 +# +# Cations from table 10.2 +# +# Cadmium + Hfo_sOH + Cd+2 = Hfo_sOCd+ + H+ + log_k 0.47 + + Hfo_wOH + Cd+2 = Hfo_wOCd+ + H+ + log_k -2.91 +# Zinc + Hfo_sOH + Zn+2 = Hfo_sOZn+ + H+ + log_k 0.99 + + Hfo_wOH + Zn+2 = Hfo_wOZn+ + H+ + log_k -1.99 +# Copper + Hfo_sOH + Cu+2 = Hfo_sOCu+ + H+ + log_k 2.89 + + Hfo_wOH + Cu+2 = Hfo_wOCu+ + H+ + log_k 0.6 # table 10.5 +# Lead + Hfo_sOH + Pb+2 = Hfo_sOPb+ + H+ + log_k 4.65 + + Hfo_wOH + Pb+2 = Hfo_wOPb+ + H+ + log_k 0.3 # table 10.5 +# +# Derived constants table 10.5 +# +# Magnesium + Hfo_wOH + Mg+2 = Hfo_wOMg+ + H+ + log_k -4.6 +# Manganese + Hfo_sOH + Mn+2 = Hfo_sOMn+ + H+ + log_k -0.4 # table 10.5 + + Hfo_wOH + Mn+2 = Hfo_wOMn+ + H+ + log_k -3.5 # table 10.5 +# Iron +# Hfo_sOH + Fe+2 = Hfo_sOFe+ + H+ +# log_k 0.7 # LFER using table 10.5 + +# Hfo_wOH + Fe+2 = Hfo_wOFe+ + H+ +# log_k -2.5 # LFER using table 10.5 + +# Iron, strong site: Appelo, Van der Weiden, Tournassat & Charlet, subm. + Hfo_sOH + Fe+2 = Hfo_sOFe+ + H+ + log_k -0.95 +# Iron, weak site: Liger et al., GCA 63, 2939, re-optimized for D&M + Hfo_wOH + Fe+2 = Hfo_wOFe+ + H+ + log_k -2.98 + + Hfo_wOH + Fe+2 + H2O = Hfo_wOFeOH + 2H+ + log_k -11.55 + +############################################### +# ANIONS # +############################################### +# +# Anions from table 10.6 +# +# Phosphate + Hfo_wOH + PO4-3 + 3H+ = Hfo_wH2PO4 + H2O + log_k 31.29 + + Hfo_wOH + PO4-3 + 2H+ = Hfo_wHPO4- + H2O + log_k 25.39 + + Hfo_wOH + PO4-3 + H+ = Hfo_wPO4-2 + H2O + log_k 17.72 +# +# Anions from table 10.7 +# +# Borate + Hfo_wOH + H3BO3 = Hfo_wH2BO3 + H2O + log_k 0.62 +# +# Anions from table 10.8 +# +# Sulfate + Hfo_wOH + SO4-2 + H+ = Hfo_wSO4- + H2O + log_k 7.78 + + Hfo_wOH + SO4-2 = Hfo_wOHSO4-2 + log_k 0.79 +# +# Derived constants table 10.10 +# + Hfo_wOH + F- + H+ = Hfo_wF + H2O + log_k 8.7 + + Hfo_wOH + F- = Hfo_wOHF- + log_k 1.6 +# +# Carbonate: Van Geen et al., 1994 reoptimized for HFO +# 0.15 g HFO/L has 0.344 mM sites == 2 g of Van Geen's Goethite/L +# +# Hfo_wOH + CO3-2 + H+ = Hfo_wCO3- + H2O +# log_k 12.56 +# +# Hfo_wOH + CO3-2 + 2H+= Hfo_wHCO3 + H2O +# log_k 20.62 + +# 9/19/96 +# Added analytical expression for H2S, NH3, KSO4. +# Added species CaHSO4+. +# Added delta H for Goethite. + +RATES + +########### +#K-feldspar +########### +# +# Sverdrup, H.U., 1990, The kinetics of base cation release due to +# chemical weathering: Lund University Press, Lund, 246 p. +# +# Example of KINETICS data block for K-feldspar rate: +# KINETICS 1 +# K-feldspar +# -m0 2.16 # 10% K-fsp, 0.1 mm cubes +# -m 1.94 +# -parms 1.36e4 0.1 + +K-feldspar + -start + 1 rem specific rate from Sverdrup, 1990, in kmol/m2/s + 2 rem parm(1) = 10 * (A/V, 1/dm) (recalc's sp. rate to mol/kgw) + 3 rem parm(2) = corrects for field rate relative to lab rate + 4 rem temp corr: from p. 162. E (kJ/mol) / R / 2.303 = H in H*(1/T-1/298) + + 10 dif_temp = 1/TK - 1/298 + 20 pk_H = 12.5 + 3134 * dif_temp + 30 pk_w = 15.3 + 1838 * dif_temp + 40 pk_OH = 14.2 + 3134 * dif_temp + 50 pk_CO2 = 14.6 + 1677 * dif_temp + #60 pk_org = 13.9 + 1254 * dif_temp # rate increase with DOC + 70 rate = 10^-pk_H * ACT("H+")^0.5 + 10^-pk_w + 10^-pk_OH * ACT("OH-")^0.3 + 71 rate = rate + 10^-pk_CO2 * (10^SI("CO2(g)"))^0.6 + #72 rate = rate + 10^-pk_org * TOT("Doc")^0.4 + 80 moles = parm(1) * parm(2) * rate * (1 - SR("K-feldspar")) * time + 81 rem decrease rate on precipitation + 90 if SR("K-feldspar") > 1 then moles = moles * 0.1 + 100 save moles + -end + +########### +#Albite +########### +# +# Sverdrup, H.U., 1990, The kinetics of base cation release due to +# chemical weathering: Lund University Press, Lund, 246 p. +# +# Example of KINETICS data block for Albite rate: +# KINETICS 1 +# Albite +# -m0 0.43 # 2% Albite, 0.1 mm cubes +# -parms 2.72e3 0.1 + +Albite + -start + 1 rem specific rate from Sverdrup, 1990, in kmol/m2/s + 2 rem parm(1) = 10 * (A/V, 1/dm) (recalc's sp. rate to mol/kgw) + 3 rem parm(2) = corrects for field rate relative to lab rate + 4 rem temp corr: from p. 162. E (kJ/mol) / R / 2.303 = H in H*(1/T-1/298) + + 10 dif_temp = 1/TK - 1/298 + 20 pk_H = 12.5 + 3359 * dif_temp + 30 pk_w = 14.8 + 2648 * dif_temp + 40 pk_OH = 13.7 + 3359 * dif_temp + #41 rem ^12.9 in Sverdrup, but larger than for oligoclase... + 50 pk_CO2 = 14.0 + 1677 * dif_temp + #60 pk_org = 12.5 + 1254 * dif_temp # ...rate increase for DOC + 70 rate = 10^-pk_H * ACT("H+")^0.5 + 10^-pk_w + 10^-pk_OH * ACT("OH-")^0.3 + 71 rate = rate + 10^-pk_CO2 * (10^SI("CO2(g)"))^0.6 + #72 rate = rate + 10^-pk_org * TOT("Doc")^0.4 + 80 moles = parm(1) * parm(2) * rate * (1 - SR("Albite")) * time + 81 rem decrease rate on precipitation + 90 if SR("Albite") > 1 then moles = moles * 0.1 + 100 save moles + -end + +######## +#Calcite +######## +# +# Plummer, L.N., Wigley, T.M.L., and Parkhurst, D.L., 1978, +# American Journal of Science, v. 278, p. 179-216. +# +# Example of KINETICS data block for calcite rate: +# +# KINETICS 1 +# Calcite +# -tol 1e-8 +# -m0 3.e-3 +# -m 3.e-3 +# -parms 5.0 0.6 +Calcite + -start + 1 REM Modified from Plummer and others, 1978 + 2 REM M = current moles of calcite + 3 REM M0 = initial moles of calcite + 4 REM parm(1) = Area/Volume, cm^2/L (or cm^2 per cell) + 5 REM parm(2) = exponent for M/M0 for surface area correction + 10 REM rate = 0 if no calcite and undersaturated + 20 si_cc = SI("Calcite") + 30 if (M <= 0 and si_cc < 0) then goto 300 + 40 k1 = 10^(0.198 - 444.0 / TK ) + 50 k2 = 10^(2.84 - 2177.0 / TK ) + 60 if TC <= 25 then k3 = 10^(-5.86 - 317.0 / TK ) + 70 if TC > 25 then k3 = 10^(-1.1 - 1737.0 / TK ) + 80 REM surface area calculation + 90 t = 1 + 100 if M0 > 0 then t = M/M0 + 110 if t = 0 then t = 1 + 120 area = PARM(1) * (t)^PARM(2) + 130 rf = k1 * ACT("H+") + k2 * ACT("CO2") + k3 * ACT("H2O") + 140 REM 1e-3 converts mmol to mol + 150 rate = area * 1e-3 * rf * (1 - 10^(2/3*si_cc)) + 160 moles = rate * TIME + 170 REM do not dissolve more calcite than present + 180 if (moles > M) then moles = M + 190 if (moles >= 0) then goto 300 + 200 REM do not precipitate more Ca or C(4) than present + 210 temp = TOT("Ca") + 220 mc = TOT("C(4)") + 230 if mc < temp then temp = mc + 240 if -moles > temp then moles = -temp + 300 SAVE moles + -end + +####### +#Pyrite +####### +# +# Williamson, M.A. and Rimstidt, J.D., 1994, +# Geochimica et Cosmochimica Acta, v. 58, p. 5443-5454. +# +# Example of KINETICS data block for pyrite rate: +# KINETICS 1 +# Pyrite +# -tol 1e-8 +# -m0 5.e-4 +# -m 5.e-4 +# -parms 2.0 0.67 .5 -0.11 +Pyrite + -start + 1 rem Williamson and Rimstidt, 1994 + 2 rem parm(1) = log10(A/V, 1/dm) parm(2) = exp for (m/m0) + 3 rem parm(3) = exp for O2 parm(4) = exp for H+ + + 10 if (m <= 0) then goto 200 + 20 if (si("Pyrite") >= 0) then goto 200 + 20 rate = -10.19 + parm(1) + parm(3)*lm("O2") + parm(4)*lm("H+") + parm(2)*log10(m/m0) + 30 moles = 10^rate * time + 40 if (moles > m) then moles = m + 200 save moles + -end + +########## +#Organic_C +########## +# +# Example of KINETICS data block for Organic_C rate: +# KINETICS 1 +# Organic_C +# -tol 1e-8 +# # m in mol/kgw +# -m0 5e-3 +# -m 5e-3 +Organic_C + -start + 1 rem Additive Monod kinetics + 2 rem Electron acceptors: O2, NO3, and SO4 + + 10 if (m <= 0) then goto 200 + 20 mO2 = mol("O2") + 30 mNO3 = tot("N(5)") + 40 mSO4 = tot("S(6)") + 50 rate = 1.57e-9*mO2/(2.94e-4 + mO2) + 1.67e-11*mNO3/(1.55e-4 + mNO3) + 60 rate = rate + 1.e-13*mSO4/(1.e-4 + mSO4) + 70 moles = rate * m * (m/m0) * time + 80 if (moles > m) then moles = m + 200 save moles + -end + +########### +#Pyrolusite +########### +# +# Postma, D. and Appelo, C.A.J., 2000, GCA 64, in press +# +# Example of KINETICS data block for Pyrolusite +# KINETICS 1-12 +# Pyrolusite +# -tol 1.e-7 +# -m0 0.1 +# -m 0.1 +Pyrolusite + -start + 5 if (m <= 0.0) then goto 200 + 7 sr_pl = sr("Pyrolusite") + 9 if abs(1 - sr_pl) < 0.1 then goto 200 + 10 if (sr_pl > 1.0) then goto 100 + #20 rem initially 1 mol Fe+2 = 0.5 mol pyrolusite. k*A/V = 1/time (3 cells) + #22 rem time (3 cells) = 1.432e4. 1/time = 6.98e-5 + 30 Fe_t = tot("Fe(2)") + 32 if Fe_t < 1.e-8 then goto 200 + 40 moles = 6.98e-5 * Fe_t * (m/m0)^0.67 * time * (1 - sr_pl) + 50 if moles > Fe_t / 2 then moles = Fe_t / 2 + 70 if moles > m then moles = m + 90 goto 200 + 100 Mn_t = tot("Mn") + 110 moles = 2e-3 * 6.98e-5 * (1-sr_pl) * time + 120 if moles <= -Mn_t then moles = -Mn_t + 200 save moles + -end +END diff --git a/phreeqc.rev b/phreeqc.rev new file mode 100644 index 00000000..8dc8253f --- /dev/null +++ b/phreeqc.rev @@ -0,0 +1,4579 @@ + +RCS file: RCS/README.TXT,v +Working file: README.TXT +head: 1.17 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 17 +============================================================================= + +RCS file: RCS/NOTICE.TXT,v +Working file: NOTICE.TXT +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: RCS/RELEASE.TXT,v +Working file: RELEASE.TXT +head: 1.16 +branch: +locks: strict + dlpark: 1.16 +access list: +symbolic names: +keyword substitution: kv +total revisions: 16 +============================================================================= + +RCS file: src/RCS/Makefile,v +Working file: src/Makefile +head: 1.35 +branch: +locks: strict +access list: +symbolic names: + C_260: 1.33 + C_259: 1.33 + C_258: 1.33 + C_257: 1.31 + C_256: 1.31 + C_255: 1.31 + C_254: 1.30 + C_253: 1.26 + C_252: 1.25 + C_251: 1.25 + C_250: 1.25 + C_249: 1.24 + C_248: 1.24 + C_247: 1.24 + C_246: 1.24 + C_245: 1.24 + C_244: 1.24 + C_243: 1.24 + C_242: 1.23 + C_241: 1.22 + C_240: 1.22 + C_239: 1.22 + C_238: 1.22 + C_237: 1.22 + C_236: 1.22 + C_235: 1.22 + C_234: 1.22 + C_233: 1.22 + C_232: 1.22 + C_231: 1.22 + C_230: 1.22 + C_229: 1.22 + C_227: 1.22 + C_226: 1.22 + C_225: 1.22 + C_224: 1.22 + C_222: 1.21 + C_221: 1.21 + C_220: 1.21 + C_219: 1.21 + C_218: 1.21 + RC1: 1.20 + C_216: 1.20 + C_215: 1.20 + C_214: 1.20 + C_213: 1.20 + C_212: 1.20 + C_206: 1.18 + C_205_3: 1.15 + C_205_2: 1.15 + C_205_1: 1.15 + C_205: 1.15 + C_204_2: 1.14 + C_204_1: 1.14 + C_204: 1.14 + C_202: 1.10 + C_201: 1.5 + C_200: 1.5 +keyword substitution: kv +total revisions: 35 +============================================================================= + +RCS file: src/RCS/advection.c,v +Working file: src/advection.c +head: 2.8 +branch: +locks: strict + dlpark: 2.8 +access list: +symbolic names: + C_260: 2.8 + C_259: 2.8 + C_258: 2.8 + C_257: 2.8 + C_256: 2.7 + C_255: 2.7 + C_254: 2.7 + C_253: 2.7 + C_252: 2.7 + C_251: 2.7 + C_250: 2.7 + C_249: 2.6 + C_248: 2.6 + C_247: 2.5 + C_246: 2.5 + C_245: 2.5 + C_244: 2.5 + C_243: 2.5 + C_242: 2.4 + C_241: 2.4 + C_240: 2.4 + C_239: 2.4 + C_238: 2.3 + C_237: 2.2 + C_236: 2.2 + C_235: 2.2 + C_234: 2.2 + C_233: 2.2 + C_232: 2.2 + C_231: 2.2 + C_230: 2.2 + C_229: 2.2 + C_227: 2.2 + C_226: 2.2 + C_225: 2.2 + C_224: 2.2 + C_222: 2.2 + C_221: 2.2 + C_220: 2.2 + C_219: 2.2 + C_218: 2.1 + RC1: 2.1 + C_216: 2.1 + C_215: 2.1 + C_214: 2.1 + C_213: 2.1 + C_212: 2.0 + C_206: 2.0 + C_205_3: 2.0 + C_205_2: 2.0 + C_205_1: 2.0 + C_205: 2.0 + C_204_2: 2.0 + C_204_1: 2.0 + C_204: 2.0 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: src/RCS/basic.c,v +Working file: src/basic.c +head: 2.44 +branch: +locks: strict + dlpark: 2.44 +access list: +symbolic names: + C_260: 2.44 + C_259: 2.44 + C_258: 2.44 + C_257: 2.44 + C_256: 2.43 + C_255: 2.43 + C_254: 2.43 + C_253: 2.42 + C_252: 2.42 + C_251: 2.42 + C_250: 2.42 + C_249: 2.41 + C_248: 2.41 + C_247: 2.41 + C_246: 2.41 + C_245: 2.41 + C_244: 2.41 + C_243: 2.41 + C_242: 2.39 + C_241: 2.39 + C_240: 2.39 + C_239: 2.39 + C_238: 2.38 + C_237: 2.37 + C_236: 2.37 + C_235: 2.37 + C_234: 2.37 + C_233: 2.36 + C_232: 2.34 + C_231: 2.33 + C_230: 2.30 + C_229: 2.30 + C_227: 2.30 + C_226: 2.30 + C_225: 2.30 + C_224: 2.30 + C_222: 2.30 + C_221: 2.20 + C_220: 2.20 + C_219: 2.19 + C_218: 2.19 + RC1: 2.19 + C_216: 2.19 + C_215: 2.18 + C_214: 2.17 + C_213: 2.17 + C_212: 2.16 + C_206: 2.16 + C_205_3: 2.14 + C_205_2: 2.14 + C_205_1: 2.13 + C_205: 2.11 + C_204_2: 2.11 + C_204_1: 2.11 + C_204: 2.11 + C_202_2: 2.10 + C_202_1: 2.10 + C_202: 2.6 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 45 +============================================================================= + +RCS file: src/RCS/basicsubs.c,v +Working file: src/basicsubs.c +head: 2.18 +branch: +locks: strict + dlpark: 2.18 +access list: +symbolic names: + C_260: 2.18 + C_259: 2.18 + C_258: 2.18 + C_257: 2.18 + C_256: 2.17 + C_255: 2.17 + C_254: 2.17 + C_253: 2.16 + C_252: 2.16 + C_251: 2.15 + C_250: 2.15 + C_249: 2.14 + C_248: 2.14 + C_247: 2.14 + C_246: 2.14 + C_245: 2.14 + C_244: 2.14 + C_243: 2.14 + C_242: 2.13 + C_241: 2.13 + C_240: 2.13 + C_239: 2.13 + C_238: 2.12 + C_237: 2.12 + C_236: 2.12 + C_235: 2.12 + C_234: 2.12 + C_233: 2.11 + C_232: 2.9 + C_231: 2.9 + C_230: 2.7 + C_229: 2.7 + C_227: 2.7 + C_226: 2.7 + C_225: 2.7 + C_224: 2.6 + C_222: 2.6 + C_221: 2.6 + C_220: 2.6 + C_219: 2.6 + C_218: 2.6 + RC1: 2.6 + C_216: 2.6 + C_215: 2.6 + C_214: 2.5 + C_213: 2.4 + C_212: 2.3 + C_206: 2.2 + C_205_3: 2.2 + C_205_2: 2.1 + C_205_1: 2.1 +keyword substitution: kv +total revisions: 18 +============================================================================= + +RCS file: src/RCS/cl1.c,v +Working file: src/cl1.c +head: 2.7 +branch: +locks: strict + dlpark: 2.7 +access list: +symbolic names: + C_260: 2.7 + C_259: 2.7 + C_258: 2.7 + C_257: 2.6 + C_256: 2.5 + C_255: 2.5 + C_254: 2.5 + C_253: 2.5 + C_252: 2.5 + C_251: 2.5 + C_250: 2.5 + C_249: 2.4 + C_248: 2.4 + C_247: 2.4 + C_246: 2.4 + C_245: 2.4 + C_244: 2.4 + C_243: 2.4 + C_242: 2.3 + C_241: 2.3 + C_240: 2.3 + C_239: 2.2 + C_238: 2.1 + C_237: 2.1 + C_236: 2.1 + C_235: 2.1 + C_234: 2.1 + C_233: 2.1 + C_232: 2.1 + C_231: 2.1 + C_230: 2.1 + C_229: 2.1 + C_227: 2.1 + C_226: 2.1 + C_225: 2.1 + C_224: 2.1 + C_222: 2.1 + C_221: 2.1 + C_220: 2.1 + C_219: 2.1 + C_218: 2.1 + RC1: 2.1 + C_216: 2.1 + C_215: 2.1 + C_214: 2.1 + C_213: 2.1 + C_212: 2.0 + C_206: 2.0 + C_205_3: 2.0 + C_205_2: 2.0 + C_205_1: 2.0 + C_205: 2.0 + C_204_2: 2.0 + C_204_1: 2.0 + C_204: 2.0 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 8 +============================================================================= + +RCS file: src/RCS/cvdense.c,v +Working file: src/cvdense.c +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_260: 1.4 + C_259: 1.4 + C_258: 1.4 + C_257: 1.4 + C_256: 1.3 + C_255: 1.3 + C_254: 1.3 + C_253: 1.3 + C_252: 1.3 + C_251: 1.3 + C_250: 1.3 + C_249: 1.3 + C_248: 1.3 + C_247: 1.3 + C_246: 1.3 + C_245: 1.3 + C_244: 1.3 + C_243: 1.3 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 + C_225: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: src/RCS/cvode.c,v +Working file: src/cvode.c +head: 1.10 +branch: +locks: strict +access list: +symbolic names: + C_260: 1.10 + C_259: 1.9 + C_258: 1.9 + C_257: 1.9 + C_256: 1.8 + C_255: 1.8 + C_254: 1.8 + C_253: 1.8 + C_252: 1.8 + C_251: 1.8 + C_250: 1.7 + C_249: 1.6 + C_248: 1.6 + C_247: 1.6 + C_246: 1.6 + C_245: 1.6 + C_244: 1.6 + C_243: 1.6 + C_242: 1.4 + C_241: 1.4 + C_240: 1.4 + C_239: 1.4 + C_238: 1.2 + C_237: 1.2 + C_236: 1.2 + C_235: 1.2 + C_234: 1.2 + C_233: 1.2 + C_232: 1.2 + C_231: 1.2 + C_230: 1.2 + C_229: 1.2 + C_227: 1.2 + C_226: 1.1 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: src/RCS/dense.c,v +Working file: src/dense.c +head: 1.3 +branch: +locks: strict + dlpark: 1.3 +access list: +symbolic names: + C_260: 1.3 + C_259: 1.3 + C_258: 1.3 + C_257: 1.3 + C_256: 1.2 + C_255: 1.2 + C_254: 1.2 + C_253: 1.2 + C_252: 1.2 + C_251: 1.2 + C_250: 1.2 + C_249: 1.2 + C_248: 1.2 + C_247: 1.2 + C_246: 1.2 + C_245: 1.2 + C_244: 1.2 + C_243: 1.2 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: src/RCS/input.c,v +Working file: src/input.c +head: 1.3 +branch: +locks: strict + dlpark: 1.3 +access list: +symbolic names: + C_260: 1.3 + C_259: 1.3 + C_258: 1.3 + C_257: 1.3 + C_256: 1.2 + C_255: 1.1 + C_254: 1.1 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: src/RCS/integrate.c,v +Working file: src/integrate.c +head: 2.8 +branch: +locks: strict + dlpark: 2.8 +access list: +symbolic names: + C_260: 2.8 + C_259: 2.8 + C_258: 2.8 + C_257: 2.8 + C_256: 2.7 + C_255: 2.7 + C_254: 2.7 + C_253: 2.7 + C_252: 2.7 + C_251: 2.7 + C_250: 2.7 + C_249: 2.6 + C_248: 2.6 + C_247: 2.6 + C_246: 2.6 + C_245: 2.6 + C_244: 2.6 + C_243: 2.6 + C_242: 2.5 + C_241: 2.5 + C_240: 2.5 + C_239: 2.5 + C_238: 2.4 + C_237: 2.4 + C_236: 2.4 + C_235: 2.4 + C_234: 2.4 + C_233: 2.4 + C_232: 2.4 + C_231: 2.4 + C_230: 2.4 + C_229: 2.4 + C_227: 2.4 + C_226: 2.4 + C_225: 2.4 + C_224: 2.3 + C_222: 2.3 + C_221: 2.3 + C_220: 2.3 + C_219: 2.3 + C_218: 2.3 + RC1: 2.3 + C_216: 2.3 + C_215: 2.3 + C_214: 2.3 + C_213: 2.3 + C_212: 2.2 + C_206: 2.2 + C_205_3: 2.2 + C_205_2: 2.2 + C_205_1: 2.2 + C_205: 2.2 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.1 + C_202_1: 2.1 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: src/RCS/inverse.c,v +Working file: src/inverse.c +head: 2.10 +branch: +locks: strict + dlpark: 2.10 +access list: +symbolic names: + C_260: 2.10 + C_259: 2.10 + C_258: 2.10 + C_257: 2.10 + C_256: 2.9 + C_255: 2.9 + C_254: 2.9 + C_253: 2.8 + C_252: 2.8 + C_251: 2.7 + C_250: 2.7 + C_249: 2.6 + C_248: 2.6 + C_247: 2.6 + C_246: 2.6 + C_245: 2.6 + C_244: 2.6 + C_243: 2.6 + C_242: 2.4 + C_241: 2.4 + C_240: 2.4 + C_239: 2.4 + C_238: 2.3 + C_237: 2.2 + C_236: 2.2 + C_235: 2.2 + C_234: 2.2 + C_233: 2.2 + C_232: 2.2 + C_231: 2.2 + C_230: 2.2 + C_229: 2.2 + C_227: 2.2 + C_226: 2.2 + C_225: 2.2 + C_224: 2.2 + C_222: 2.2 + C_221: 2.2 + C_220: 2.2 + C_219: 2.2 + C_218: 2.2 + RC1: 2.2 + C_216: 2.2 + C_215: 2.2 + C_214: 2.2 + C_213: 2.2 + C_212: 2.1 + C_206: 2.1 + C_205_3: 2.1 + C_205_2: 2.1 + C_205_1: 2.1 + C_205: 2.1 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.1 + C_202_1: 2.1 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: src/RCS/isotopes.c,v +Working file: src/isotopes.c +head: 2.12 +branch: +locks: strict + dlpark: 2.12 +access list: +symbolic names: + C_260: 2.12 + C_259: 2.12 + C_258: 2.12 + C_257: 2.12 + C_256: 2.11 + C_255: 2.11 + C_254: 2.11 + C_253: 2.11 + C_252: 2.11 + C_251: 2.11 + C_250: 2.10 + C_249: 2.9 + C_248: 2.9 + C_247: 2.9 + C_246: 2.9 + C_245: 2.9 + C_244: 2.9 + C_243: 2.9 + C_242: 2.8 + C_241: 2.8 + C_240: 2.8 + C_239: 2.8 + C_238: 2.7 + C_237: 2.7 + C_236: 2.7 + C_235: 2.7 + C_234: 2.7 + C_233: 2.7 + C_232: 2.7 + C_231: 2.7 + C_230: 2.7 + C_229: 2.7 + C_227: 2.7 + C_226: 2.7 + C_225: 2.7 + C_224: 2.7 + C_222: 2.7 + C_221: 2.7 + C_220: 2.7 + C_219: 2.7 + C_218: 2.7 + RC1: 2.7 + C_216: 2.7 + C_215: 2.7 + C_214: 2.7 + C_213: 2.7 + C_212: 2.4 + C_206: 2.4 + C_205_3: 2.2 + C_205_2: 2.1 + C_205_1: 2.1 +keyword substitution: kv +total revisions: 12 +============================================================================= + +RCS file: src/RCS/kinetics.c,v +Working file: src/kinetics.c +head: 2.36 +branch: +locks: strict + dlpark: 2.36 +access list: +symbolic names: + C_260: 2.36 + C_259: 2.36 + C_258: 2.36 + C_257: 2.33 + C_256: 2.32 + C_255: 2.31 + C_254: 2.31 + C_253: 2.30 + C_252: 2.30 + C_251: 2.29 + C_250: 2.29 + C_249: 2.28 + C_248: 2.28 + C_247: 2.26 + C_246: 2.26 + C_245: 2.26 + C_244: 2.26 + C_243: 2.26 + C_242: 2.24 + C_241: 2.24 + C_240: 2.24 + C_239: 2.23 + C_238: 2.22 + C_237: 2.22 + C_236: 2.22 + C_235: 2.22 + C_234: 2.21 + C_233: 2.21 + C_232: 2.21 + C_231: 2.21 + C_230: 2.21 + C_229: 2.21 + C_227: 2.21 + C_226: 2.20 + C_225: 2.19 + C_224: 2.19 + C_222: 2.19 + C_221: 2.19 + C_220: 2.19 + C_219: 2.18 + C_218: 2.17 + RC1: 2.17 + C_216: 2.17 + C_215: 2.17 + C_214: 2.17 + C_213: 2.17 + C_212: 2.16 + C_206: 2.16 + C_205_3: 2.16 + C_205_2: 2.16 + C_205_1: 2.15 + C_205: 2.11 + C_204_2: 2.7 + C_204_1: 2.7 + C_204: 2.7 + C_202_2: 2.6 + C_202_1: 2.6 + C_202: 2.4 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 37 +============================================================================= + +RCS file: src/RCS/main.c,v +Working file: src/main.c +head: 2.35 +branch: +locks: strict +access list: +symbolic names: + C_260: 2.35 + C_259: 2.34 + C_258: 2.34 + C_257: 2.34 + C_256: 2.33 + C_255: 2.33 + C_254: 2.32 + C_253: 2.31 + C_252: 2.30 + C_251: 2.30 + C_250: 2.30 + C_249: 2.29 + C_248: 2.29 + C_247: 2.29 + C_246: 2.29 + C_245: 2.29 + C_244: 2.28 + C_243: 2.28 + C_242: 2.26 + C_241: 2.25 + C_240: 2.25 + C_239: 2.25 + C_238: 2.25 + C_237: 2.24 + C_236: 2.24 + C_235: 2.24 + C_234: 2.23 + C_233: 2.23 + C_232: 2.23 + C_231: 2.23 + C_230: 2.23 + C_229: 2.23 + C_227: 2.23 + C_226: 2.23 + C_225: 2.23 + C_224: 2.23 + C_222: 2.22 + C_221: 2.22 + C_220: 2.22 + C_219: 2.22 + C_218: 2.20 + RC1: 2.19 + C_216: 2.19 + C_215: 2.18 + C_214: 2.18 + C_213: 2.18 + C_212: 2.14 + C_206: 2.14 + C_205_3: 2.13 + C_205_2: 2.13 + C_205_1: 2.13 + C_205: 2.13 + C_204_2: 2.12 + C_204_1: 2.11 + C_204: 2.11 + C_202_2: 2.9 + C_202_1: 2.6 + C_202: 2.4 + C_201: 2.2 + C_200: 2.1 +keyword substitution: kv +total revisions: 36 +============================================================================= + +RCS file: src/RCS/mainsubs.c,v +Working file: src/mainsubs.c +head: 2.38 +branch: +locks: strict + dlpark: 2.38 +access list: +symbolic names: + C_260: 2.38 + C_259: 2.38 + C_258: 2.38 + C_257: 2.36 + C_256: 2.35 + C_255: 2.35 + C_254: 2.34 + C_253: 2.33 + C_252: 2.33 + C_251: 2.32 + C_250: 2.32 + C_249: 2.31 + C_248: 2.31 + C_247: 2.30 + C_246: 2.30 + C_245: 2.30 + C_244: 2.30 + C_243: 2.30 + C_242: 2.28 + C_241: 2.28 + C_240: 2.28 + C_239: 2.27 + C_238: 2.25 + C_237: 2.24 + C_236: 2.24 + C_235: 2.24 + C_234: 2.23 + C_233: 2.23 + C_232: 2.23 + C_231: 2.23 + C_230: 2.23 + C_229: 2.23 + C_227: 2.22 + C_226: 2.22 + C_225: 2.22 + C_224: 2.22 + C_222: 2.22 + C_221: 2.22 + C_220: 2.22 + C_219: 2.22 + C_218: 2.21 + RC1: 2.21 + C_216: 2.21 + C_215: 2.21 + C_214: 2.20 + C_213: 2.20 + C_212: 2.17 + C_206: 2.15 + C_205_3: 2.14 + C_205_2: 2.13 + C_205_1: 2.12 + C_205: 2.11 + C_204_2: 2.10 + C_204_1: 2.10 + C_204: 2.10 + C_202_2: 2.6 + C_202_1: 2.4 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 39 +============================================================================= + +RCS file: src/RCS/model.c,v +Working file: src/model.c +head: 2.27 +branch: +locks: strict + dlpark: 2.27 +access list: +symbolic names: + C_260: 2.27 + C_259: 2.27 + C_258: 2.27 + C_257: 2.26 + C_256: 2.25 + C_255: 2.25 + C_254: 2.25 + C_253: 2.24 + C_252: 2.24 + C_251: 2.24 + C_250: 2.24 + C_249: 2.23 + C_248: 2.23 + C_247: 2.22 + C_246: 2.22 + C_245: 2.22 + C_244: 2.22 + C_243: 2.22 + C_242: 2.20 + C_241: 2.19 + C_240: 2.19 + C_239: 2.19 + C_238: 2.17 + C_237: 2.17 + C_236: 2.17 + C_235: 2.17 + C_234: 2.17 + C_233: 2.16 + C_232: 2.15 + C_231: 2.15 + C_230: 2.14 + C_229: 2.14 + C_227: 2.14 + C_226: 2.14 + C_225: 2.14 + C_224: 2.14 + C_222: 2.14 + C_221: 2.14 + C_220: 2.14 + C_219: 2.14 + C_218: 2.14 + RC1: 2.13 + C_216: 2.13 + C_215: 2.13 + C_214: 2.12 + C_213: 2.12 + C_212: 2.11 + C_206: 2.11 + C_205_3: 2.11 + C_205_2: 2.11 + C_205_1: 2.10 + C_205: 2.8 + C_204_2: 2.6 + C_204_1: 2.6 + C_204: 2.6 + C_202_2: 2.5 + C_202_1: 2.4 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 28 +============================================================================= + +RCS file: src/RCS/nvector.c,v +Working file: src/nvector.c +head: 1.3 +branch: +locks: strict + dlpark: 1.3 +access list: +symbolic names: + C_260: 1.3 + C_259: 1.3 + C_258: 1.3 + C_257: 1.3 + C_256: 1.2 + C_255: 1.2 + C_254: 1.2 + C_253: 1.2 + C_252: 1.2 + C_251: 1.2 + C_250: 1.2 + C_249: 1.2 + C_248: 1.2 + C_247: 1.2 + C_246: 1.2 + C_245: 1.2 + C_244: 1.2 + C_243: 1.2 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: src/RCS/nvector_serial.c,v +Working file: src/nvector_serial.c +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_260: 1.5 + C_259: 1.5 + C_258: 1.5 + C_257: 1.5 + C_256: 1.4 + C_255: 1.4 + C_254: 1.4 + C_253: 1.4 + C_252: 1.4 + C_251: 1.4 + C_250: 1.4 + C_249: 1.3 + C_248: 1.3 + C_247: 1.3 + C_246: 1.3 + C_245: 1.3 + C_244: 1.3 + C_243: 1.3 + C_242: 1.2 + C_241: 1.2 + C_240: 1.2 + C_239: 1.2 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: src/RCS/output.c,v +Working file: src/output.c +head: 1.2 +branch: +locks: strict + dlpark: 1.2 +access list: +symbolic names: + C_260: 1.2 + C_259: 1.2 + C_258: 1.2 + C_257: 1.1 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: src/RCS/p2clib.c,v +Working file: src/p2clib.c +head: 2.6 +branch: +locks: strict + dlpark: 2.6 +access list: +symbolic names: + C_260: 2.6 + C_259: 2.6 + C_258: 2.6 + C_257: 2.6 + C_256: 2.5 + C_255: 2.5 + C_254: 2.5 + C_253: 2.5 + C_252: 2.5 + C_251: 2.5 + C_250: 2.5 + C_249: 2.5 + C_248: 2.5 + C_247: 2.5 + C_246: 2.5 + C_245: 2.5 + C_244: 2.5 + C_243: 2.5 + C_242: 2.3 + C_241: 2.3 + C_240: 2.3 + C_239: 2.3 + C_238: 2.3 + C_237: 2.3 + C_236: 2.3 + C_235: 2.3 + C_234: 2.3 + C_233: 2.3 + C_232: 2.3 + C_231: 2.3 + C_230: 2.3 + C_229: 2.3 + C_227: 2.3 + C_226: 2.3 + C_225: 2.3 + C_224: 2.3 + C_222: 2.3 + C_221: 2.2 + C_220: 2.2 + C_219: 2.2 + C_218: 2.2 + RC1: 2.2 + C_216: 2.2 + C_215: 2.2 + C_214: 2.2 + C_213: 2.2 + C_212: 2.1 + C_206: 2.1 + C_205_3: 2.1 + C_205_2: 2.1 + C_205_1: 2.1 + C_205: 2.1 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.1 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 7 +============================================================================= + +RCS file: src/RCS/parse.c,v +Working file: src/parse.c +head: 2.8 +branch: +locks: strict + dlpark: 2.8 +access list: +symbolic names: + C_260: 2.8 + C_259: 2.8 + C_258: 2.8 + C_257: 2.8 + C_256: 2.7 + C_255: 2.7 + C_254: 2.7 + C_253: 2.7 + C_252: 2.7 + C_251: 2.7 + C_250: 2.7 + C_249: 2.6 + C_248: 2.6 + C_247: 2.6 + C_246: 2.6 + C_245: 2.6 + C_244: 2.6 + C_243: 2.6 + C_242: 2.5 + C_241: 2.5 + C_240: 2.5 + C_239: 2.5 + C_238: 2.4 + C_237: 2.4 + C_236: 2.4 + C_235: 2.4 + C_234: 2.4 + C_233: 2.4 + C_232: 2.4 + C_231: 2.4 + C_230: 2.4 + C_229: 2.4 + C_227: 2.4 + C_226: 2.4 + C_225: 2.4 + C_224: 2.4 + C_222: 2.4 + C_221: 2.4 + C_220: 2.4 + C_219: 2.4 + C_218: 2.4 + RC1: 2.4 + C_216: 2.4 + C_215: 2.4 + C_214: 2.4 + C_213: 2.4 + C_212: 2.3 + C_206: 2.3 + C_205_3: 2.3 + C_205_2: 2.2 + C_205_1: 2.2 + C_205: 2.2 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.1 + C_202_1: 2.1 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: src/RCS/phqalloc.c,v +Working file: src/phqalloc.c +head: 2.9 +branch: +locks: strict + dlpark: 2.9 +access list: +symbolic names: + C_260: 2.9 + C_259: 2.9 + C_258: 2.9 + C_257: 2.9 + C_256: 2.8 + C_255: 2.8 + C_254: 2.8 + C_253: 2.7 + C_252: 2.7 + C_251: 2.7 + C_250: 2.7 + C_249: 2.7 + C_248: 2.7 + C_247: 2.7 + C_246: 2.7 + C_245: 2.7 + C_244: 2.7 + C_243: 2.7 + C_242: 2.5 + C_241: 2.5 + C_240: 2.5 + C_239: 2.5 + C_238: 2.5 + C_237: 2.5 + C_236: 2.5 + C_235: 2.5 + C_234: 2.5 + C_233: 2.5 + C_232: 2.5 + C_231: 2.5 + C_230: 2.5 + C_229: 2.5 + C_227: 2.5 + C_226: 2.5 + C_225: 2.5 + C_224: 2.5 + C_222: 2.5 + C_221: 2.5 + C_220: 2.5 + C_219: 2.5 + C_218: 2.5 + RC1: 2.5 + C_216: 2.4 + C_215: 2.4 + C_214: 2.4 + C_213: 2.4 + C_212: 2.2 + C_206: 2.2 + C_205_3: 2.2 + C_205_2: 2.2 + C_205_1: 2.2 + C_205: 2.2 + C_204_2: 2.2 + C_204_1: 2.2 + C_204: 2.2 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: src/RCS/phreeqc_files.c,v +Working file: src/phreeqc_files.c +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_260: 1.4 + C_259: 1.4 + C_258: 1.3 + C_257: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: src/RCS/prep.c,v +Working file: src/prep.c +head: 2.15 +branch: +locks: strict + dlpark: 2.15 +access list: +symbolic names: + C_260: 2.15 + C_259: 2.15 + C_258: 2.15 + C_257: 2.15 + C_256: 2.14 + C_255: 2.14 + C_254: 2.14 + C_253: 2.14 + C_252: 2.14 + C_251: 2.14 + C_250: 2.14 + C_249: 2.13 + C_248: 2.13 + C_247: 2.13 + C_246: 2.13 + C_245: 2.13 + C_244: 2.13 + C_243: 2.13 + C_242: 2.11 + C_241: 2.11 + C_240: 2.11 + C_239: 2.11 + C_238: 2.10 + C_237: 2.9 + C_236: 2.9 + C_235: 2.9 + C_234: 2.9 + C_233: 2.9 + C_232: 2.8 + C_231: 2.8 + C_230: 2.8 + C_229: 2.8 + C_227: 2.7 + C_226: 2.7 + C_225: 2.7 + C_224: 2.6 + C_222: 2.6 + C_221: 2.6 + C_220: 2.6 + C_219: 2.5 + C_218: 2.5 + RC1: 2.5 + C_216: 2.5 + C_215: 2.5 + C_214: 2.5 + C_213: 2.5 + C_212: 2.4 + C_206: 2.4 + C_205_3: 2.4 + C_205_2: 2.4 + C_205_1: 2.3 + C_205: 2.3 + C_204_2: 2.3 + C_204_1: 2.3 + C_204: 2.3 + C_202_2: 2.3 + C_202_1: 2.3 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 16 +============================================================================= + +RCS file: src/RCS/print.c,v +Working file: src/print.c +head: 2.38 +branch: +locks: strict + dlpark: 2.38 +access list: +symbolic names: + C_260: 2.38 + C_259: 2.38 + C_258: 2.38 + C_257: 2.38 + C_256: 2.37 + C_255: 2.36 + C_254: 2.35 + C_253: 2.34 + C_252: 2.34 + C_251: 2.32 + C_250: 2.32 + C_249: 2.31 + C_248: 2.31 + C_247: 2.31 + C_246: 2.31 + C_245: 2.31 + C_244: 2.31 + C_243: 2.31 + C_242: 2.30 + C_241: 2.30 + C_240: 2.30 + C_239: 2.30 + C_238: 2.29 + C_237: 2.29 + C_236: 2.29 + C_235: 2.28 + C_234: 2.27 + C_233: 2.27 + C_232: 2.27 + C_231: 2.27 + C_230: 2.27 + C_229: 2.27 + C_227: 2.27 + C_226: 2.27 + C_225: 2.26 + C_224: 2.26 + C_222: 2.26 + C_221: 2.25 + C_220: 2.25 + C_219: 2.24 + C_218: 2.24 + RC1: 2.24 + C_216: 2.24 + C_215: 2.24 + C_214: 2.21 + C_213: 2.20 + C_212: 2.15 + C_206: 2.15 + C_205_3: 2.11 + C_205_2: 2.10 + C_205_1: 2.9 + C_205: 2.8 + C_204_2: 2.7 + C_204_1: 2.7 + C_204: 2.7 + C_202_2: 2.5 + C_202_1: 2.4 + C_202: 2.4 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 39 +============================================================================= + +RCS file: src/RCS/read.c,v +Working file: src/read.c +head: 2.43 +branch: +locks: strict + dlpark: 2.43 +access list: +symbolic names: + C_260: 2.43 + C_259: 2.43 + C_258: 2.43 + C_257: 2.43 + C_256: 2.42 + C_255: 2.41 + C_254: 2.41 + C_253: 2.39 + C_252: 2.39 + C_251: 2.39 + C_250: 2.39 + C_249: 2.38 + C_248: 2.38 + C_247: 2.38 + C_246: 2.38 + C_245: 2.38 + C_244: 2.38 + C_243: 2.38 + C_242: 2.36 + C_241: 2.36 + C_240: 2.36 + C_239: 2.36 + C_238: 2.35 + C_237: 2.33 + C_236: 2.33 + C_235: 2.32 + C_234: 2.31 + C_233: 2.31 + C_232: 2.31 + C_231: 2.31 + C_230: 2.31 + C_229: 2.31 + C_227: 2.30 + C_226: 2.29 + C_225: 2.29 + C_224: 2.29 + C_222: 2.29 + C_221: 2.29 + C_220: 2.29 + C_219: 2.29 + C_218: 2.29 + RC1: 2.29 + C_216: 2.29 + C_215: 2.28 + C_214: 2.27 + C_213: 2.27 + C_212: 2.23 + C_206: 2.21 + C_205_3: 2.20 + C_205_2: 2.19 + C_205_1: 2.18 + C_205: 2.17 + C_204_2: 2.12 + C_204_1: 2.11 + C_204: 2.11 + C_202_2: 2.8 + C_202_1: 2.6 + C_202: 2.2 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 44 +============================================================================= + +RCS file: src/RCS/readtr.c,v +Working file: src/readtr.c +head: 2.13 +branch: +locks: strict + dlpark: 2.13 +access list: +symbolic names: + C_260: 2.13 + C_259: 2.13 + C_258: 2.12 + C_257: 2.12 + C_256: 2.11 + C_255: 2.10 + C_254: 2.10 + C_253: 2.9 + C_252: 2.9 + C_251: 2.9 + C_250: 2.9 + C_249: 2.8 + C_248: 2.8 + C_247: 2.8 + C_246: 2.8 + C_245: 2.8 + C_244: 2.8 + C_243: 2.8 + C_242: 2.6 + C_241: 2.6 + C_240: 2.6 + C_239: 2.6 + C_238: 2.5 + C_237: 2.5 + C_236: 2.5 + C_235: 2.5 + C_234: 2.5 + C_233: 2.5 + C_232: 2.5 + C_231: 2.5 + C_230: 2.5 + C_229: 2.5 + C_227: 2.5 + C_226: 2.5 + C_225: 2.5 + C_224: 2.5 + C_222: 2.5 + C_221: 2.5 + C_220: 2.5 + C_219: 2.4 + C_218: 2.4 + RC1: 2.4 + C_216: 2.4 + C_215: 2.3 + C_214: 2.3 + C_213: 2.3 + C_212: 2.2 + C_206: 2.2 + C_205_3: 2.2 + C_205_2: 2.2 + C_205_1: 2.2 + C_205: 2.1 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.1 + C_202_1: 2.1 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 14 +============================================================================= + +RCS file: src/RCS/smalldense.c,v +Working file: src/smalldense.c +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_260: 1.4 + C_259: 1.4 + C_258: 1.4 + C_257: 1.4 + C_256: 1.3 + C_255: 1.3 + C_254: 1.3 + C_253: 1.3 + C_252: 1.3 + C_251: 1.3 + C_250: 1.3 + C_249: 1.3 + C_248: 1.3 + C_247: 1.3 + C_246: 1.3 + C_245: 1.3 + C_244: 1.3 + C_243: 1.3 + C_242: 1.2 + C_241: 1.2 + C_240: 1.2 + C_239: 1.2 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: src/RCS/spread.c,v +Working file: src/spread.c +head: 2.17 +branch: +locks: strict + dlpark: 2.17 +access list: +symbolic names: + C_260: 2.17 + C_259: 2.17 + C_258: 2.16 + C_257: 2.16 + C_256: 2.15 + C_255: 2.15 + C_254: 2.15 + C_253: 2.15 + C_252: 2.15 + C_251: 2.15 + C_250: 2.15 + C_249: 2.14 + C_248: 2.14 + C_247: 2.14 + C_246: 2.14 + C_245: 2.14 + C_244: 2.14 + C_243: 2.14 + C_242: 2.13 + C_241: 2.13 + C_240: 2.13 + C_239: 2.13 + C_238: 2.12 + C_237: 2.12 + C_236: 2.12 + C_235: 2.12 + C_234: 2.12 + C_233: 2.12 + C_232: 2.12 + C_231: 2.12 + C_230: 2.11 + C_229: 2.11 + C_227: 2.11 + C_226: 2.11 + C_225: 2.11 + C_224: 2.11 + C_222: 2.11 + C_221: 2.11 + C_220: 2.11 + C_219: 2.11 + C_218: 2.11 + RC1: 2.11 + C_216: 2.11 + C_215: 2.11 + C_214: 2.11 + C_213: 2.11 + C_212: 2.10 + C_206: 2.10 + C_205_3: 2.10 + C_205_2: 2.10 + C_205_1: 2.9 + C_205: 2.8 + C_204_2: 2.8 + C_204_1: 2.7 + C_204: 2.6 + C_202_2: 2.3 + C_202_1: 2.2 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 18 +============================================================================= + +RCS file: src/RCS/step.c,v +Working file: src/step.c +head: 2.13 +branch: +locks: strict + dlpark: 2.13 +access list: +symbolic names: + C_260: 2.13 + C_259: 2.13 + C_258: 2.13 + C_257: 2.13 + C_256: 2.12 + C_255: 2.12 + C_254: 2.12 + C_253: 2.12 + C_252: 2.12 + C_251: 2.12 + C_250: 2.12 + C_249: 2.11 + C_248: 2.11 + C_247: 2.11 + C_246: 2.11 + C_245: 2.11 + C_244: 2.11 + C_243: 2.11 + C_242: 2.10 + C_241: 2.10 + C_240: 2.10 + C_239: 2.10 + C_238: 2.9 + C_237: 2.7 + C_236: 2.7 + C_235: 2.7 + C_234: 2.7 + C_233: 2.7 + C_232: 2.7 + C_231: 2.7 + C_230: 2.7 + C_229: 2.7 + C_227: 2.7 + C_226: 2.6 + C_225: 2.5 + C_224: 2.5 + C_222: 2.5 + C_221: 2.5 + C_220: 2.5 + C_219: 2.4 + C_218: 2.4 + RC1: 2.4 + C_216: 2.4 + C_215: 2.4 + C_214: 2.4 + C_213: 2.3 + C_212: 2.2 + C_206: 2.2 + C_205_3: 2.2 + C_205_2: 2.2 + C_205_1: 2.2 + C_205: 2.2 + C_204_2: 2.0 + C_204_1: 2.0 + C_204: 2.0 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 14 +============================================================================= + +RCS file: src/RCS/structures.c,v +Working file: src/structures.c +head: 2.35 +branch: +locks: strict + dlpark: 2.35 +access list: +symbolic names: + C_260: 2.35 + C_259: 2.35 + C_258: 2.34 + C_257: 2.33 + C_256: 2.32 + C_255: 2.32 + C_254: 2.31 + C_253: 2.29 + C_252: 2.29 + C_251: 2.29 + C_250: 2.29 + C_249: 2.28 + C_248: 2.28 + C_247: 2.28 + C_246: 2.28 + C_245: 2.28 + C_244: 2.28 + C_243: 2.28 + C_242: 2.26 + C_241: 2.25 + C_240: 2.25 + C_239: 2.24 + C_238: 2.23 + C_237: 2.22 + C_236: 2.22 + C_235: 2.22 + C_234: 2.21 + C_233: 2.21 + C_232: 2.20 + C_231: 2.20 + C_230: 2.20 + C_229: 2.20 + C_227: 2.19 + C_226: 2.19 + C_225: 2.19 + C_224: 2.19 + C_222: 2.19 + C_221: 2.19 + C_220: 2.19 + C_219: 2.19 + C_218: 2.18 + RC1: 2.18 + C_216: 2.18 + C_215: 2.18 + C_214: 2.17 + C_213: 2.17 + C_212: 2.15 + C_206: 2.14 + C_205_3: 2.13 + C_205_2: 2.13 + C_205_1: 2.12 + C_205: 2.11 + C_204_2: 2.10 + C_204_1: 2.10 + C_204: 2.10 + C_202_2: 2.6 + C_202_1: 2.4 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 36 +============================================================================= + +RCS file: src/RCS/sundialsmath.c,v +Working file: src/sundialsmath.c +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_260: 1.4 + C_259: 1.4 + C_258: 1.4 + C_257: 1.4 + C_256: 1.3 + C_255: 1.3 + C_254: 1.3 + C_253: 1.3 + C_252: 1.3 + C_251: 1.3 + C_250: 1.3 + C_249: 1.3 + C_248: 1.3 + C_247: 1.3 + C_246: 1.3 + C_245: 1.3 + C_244: 1.3 + C_243: 1.3 + C_242: 1.2 + C_241: 1.2 + C_240: 1.2 + C_239: 1.2 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: src/RCS/tally.c,v +Working file: src/tally.c +head: 1.14 +branch: +locks: strict + dlpark: 1.14 +access list: +symbolic names: + C_260: 1.14 + C_259: 1.14 + C_258: 1.14 + C_257: 1.14 + C_256: 1.13 + C_255: 1.13 + C_254: 1.13 + C_253: 1.13 + C_252: 1.13 + C_251: 1.12 + C_250: 1.12 + C_249: 1.11 + C_248: 1.11 + C_247: 1.11 + C_246: 1.10 + C_245: 1.10 + C_244: 1.9 + C_243: 1.8 + C_242: 1.6 + C_241: 1.5 + C_240: 1.4 +keyword substitution: kv +total revisions: 14 +============================================================================= + +RCS file: src/RCS/tidy.c,v +Working file: src/tidy.c +head: 2.30 +branch: +locks: strict +access list: +symbolic names: + C_260: 2.30 + C_259: 2.29 + C_258: 2.29 + C_257: 2.29 + C_256: 2.28 + C_255: 2.28 + C_254: 2.28 + C_253: 2.27 + C_252: 2.27 + C_251: 2.27 + C_250: 2.27 + C_249: 2.26 + C_248: 2.26 + C_247: 2.26 + C_246: 2.26 + C_245: 2.26 + C_244: 2.26 + C_243: 2.26 + C_242: 2.24 + C_241: 2.23 + C_240: 2.23 + C_239: 2.22 + C_238: 2.21 + C_237: 2.19 + C_236: 2.19 + C_235: 2.19 + C_234: 2.19 + C_233: 2.19 + C_232: 2.17 + C_231: 2.17 + C_230: 2.17 + C_229: 2.16 + C_227: 2.16 + C_226: 2.16 + C_225: 2.16 + C_224: 2.16 + C_222: 2.16 + C_221: 2.16 + C_220: 2.15 + C_219: 2.15 + C_218: 2.15 + RC1: 2.15 + C_216: 2.15 + C_215: 2.15 + C_214: 2.15 + C_213: 2.15 + C_212: 2.10 + C_206: 2.9 + C_205_3: 2.9 + C_205_2: 2.8 + C_205_1: 2.7 + C_205: 2.6 + C_204_2: 2.5 + C_204_1: 2.4 + C_204: 2.3 + C_202_2: 2.2 + C_202_1: 2.2 + C_202: 2.1 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 31 +============================================================================= + +RCS file: src/RCS/transport.c,v +Working file: src/transport.c +head: 2.14 +branch: +locks: strict + dlpark: 2.14 +access list: +symbolic names: + C_260: 2.14 + C_259: 2.14 + C_258: 2.14 + C_257: 2.14 + C_256: 2.13 + C_255: 2.13 + C_254: 2.13 + C_253: 2.13 + C_252: 2.13 + C_251: 2.13 + C_250: 2.13 + C_249: 2.12 + C_248: 2.12 + C_247: 2.12 + C_246: 2.12 + C_245: 2.12 + C_244: 2.12 + C_243: 2.12 + C_242: 2.10 + C_241: 2.10 + C_240: 2.10 + C_239: 2.10 + C_238: 2.9 + C_237: 2.8 + C_236: 2.8 + C_235: 2.8 + C_234: 2.8 + C_233: 2.8 + C_232: 2.8 + C_231: 2.8 + C_230: 2.8 + C_229: 2.8 + C_227: 2.8 + C_226: 2.8 + C_225: 2.8 + C_224: 2.8 + C_222: 2.8 + C_221: 2.8 + C_220: 2.7 + C_219: 2.7 + C_218: 2.7 + RC1: 2.6 + C_216: 2.5 + C_215: 2.5 + C_214: 2.5 + C_213: 2.5 + C_212: 2.4 + C_206: 2.4 + C_205_3: 2.4 + C_205_2: 2.4 + C_205_1: 2.4 + C_205: 2.3 + C_204_2: 2.1 + C_204_1: 2.1 + C_204: 2.1 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 15 +============================================================================= + +RCS file: src/RCS/utilities.c,v +Working file: src/utilities.c +head: 2.30 +branch: +locks: strict + dlpark: 2.30 +access list: +symbolic names: + C_260: 2.30 + C_259: 2.30 + C_258: 2.30 + C_257: 2.30 + C_256: 2.29 + C_255: 2.29 + C_254: 2.29 + C_253: 2.28 + C_252: 2.28 + C_251: 2.28 + C_250: 2.28 + C_249: 2.27 + C_248: 2.27 + C_247: 2.27 + C_246: 2.27 + C_245: 2.27 + C_244: 2.27 + C_243: 2.27 + C_242: 2.25 + C_241: 2.24 + C_240: 2.24 + C_239: 2.24 + C_238: 2.23 + C_237: 2.22 + C_236: 2.22 + C_235: 2.21 + C_234: 2.21 + C_233: 2.21 + C_232: 2.19 + C_231: 2.18 + C_230: 2.18 + C_229: 2.16 + C_227: 2.15 + C_226: 2.15 + C_225: 2.15 + C_224: 2.15 + C_222: 2.15 + C_221: 2.15 + C_220: 2.14 + C_219: 2.13 + C_218: 2.13 + RC1: 2.13 + C_216: 2.13 + C_215: 2.13 + C_214: 2.11 + C_213: 2.11 + C_212: 2.9 + C_206: 2.9 + C_205_3: 2.8 + C_205_2: 2.8 + C_205_1: 2.7 + C_205: 2.6 + C_204_2: 2.5 + C_204_1: 2.5 + C_204: 2.5 + C_202_2: 2.4 + C_202_1: 2.4 + C_202: 2.3 + C_201: 2.1 + C_200: 2.0 +keyword substitution: kv +total revisions: 31 +============================================================================= + +RCS file: src/RCS/cvdense.h,v +Working file: src/cvdense.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/cvode.h,v +Working file: src/cvode.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/dense.h,v +Working file: src/dense.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/global.h,v +Working file: src/global.h +head: 2.47 +branch: +locks: strict + dlpark: 2.47 +access list: +symbolic names: + C_260: 2.47 + C_259: 2.47 + C_258: 2.46 + C_257: 2.44 + C_256: 2.44 + C_255: 2.44 + C_254: 2.43 + C_253: 2.42 + C_252: 2.42 + C_251: 2.42 + C_250: 2.42 + C_249: 2.41 + C_248: 2.41 + C_247: 2.40 + C_246: 2.40 + C_245: 2.40 + C_244: 2.39 + C_243: 2.39 + C_242: 2.36 + C_241: 2.35 + C_240: 2.35 + C_239: 2.34 + C_238: 2.33 + C_237: 2.32 + C_236: 2.32 + C_235: 2.32 + C_234: 2.31 + C_233: 2.31 + C_232: 2.30 + C_231: 2.30 + C_230: 2.30 + C_229: 2.30 + C_227: 2.29 + C_226: 2.28 + C_225: 2.28 + C_224: 2.28 + C_222: 2.28 + C_221: 2.28 + C_220: 2.28 + C_219: 2.27 + C_218: 2.27 + RC1: 2.27 + C_216: 2.27 + C_215: 2.26 + C_214: 2.25 + C_213: 2.24 + C_212: 2.19 + C_206: 2.18 + C_205_3: 2.17 + C_205_2: 2.16 + C_205_1: 2.15 + C_205: 2.13 + C_204_2: 2.11 + C_204_1: 2.11 + C_204: 2.11 + C_202_2: 2.7 + C_202_1: 2.5 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 48 +============================================================================= + +RCS file: src/RCS/input.h,v +Working file: src/input.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/kinetics.h,v +Working file: src/kinetics.h +head: 1.2 +branch: +locks: strict + dlpark: 1.2 +access list: +symbolic names: + C_260: 1.2 + C_259: 1.2 + C_258: 1.2 + C_257: 1.2 + C_256: 1.2 + C_255: 1.2 + C_254: 1.2 + C_253: 1.2 + C_252: 1.2 + C_251: 1.2 + C_250: 1.2 + C_249: 1.2 + C_248: 1.2 + C_247: 1.2 + C_246: 1.2 + C_245: 1.2 + C_244: 1.2 + C_243: 1.2 + C_242: 1.2 + C_241: 1.2 + C_240: 1.2 + C_239: 1.2 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: src/RCS/nvector.h,v +Working file: src/nvector.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/nvector_serial.h,v +Working file: src/nvector_serial.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/output.h,v +Working file: src/output.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/p2c.h,v +Working file: src/p2c.h +head: 2.2 +branch: +locks: strict + dlpark: 2.2 +access list: +symbolic names: + C_260: 2.2 + C_259: 2.2 + C_258: 2.2 + C_257: 2.2 + C_256: 2.2 + C_255: 2.2 + C_254: 2.2 + C_253: 2.2 + C_252: 2.2 + C_251: 2.2 + C_250: 2.2 + C_249: 2.2 + C_248: 2.2 + C_247: 2.2 + C_246: 2.2 + C_245: 2.2 + C_244: 2.2 + C_243: 2.2 + C_242: 2.2 + C_241: 2.2 + C_240: 2.2 + C_239: 2.2 + C_238: 2.1 + C_237: 2.1 + C_236: 2.1 + C_235: 2.1 + C_234: 2.1 + C_233: 2.1 + C_232: 2.1 + C_231: 2.1 + C_230: 2.1 + C_229: 2.1 + C_227: 2.1 + C_226: 2.1 + C_225: 2.1 + C_224: 2.1 + C_222: 2.1 + C_221: 2.1 + C_220: 2.1 + C_219: 2.1 + C_218: 2.1 + RC1: 2.1 + C_216: 2.1 + C_215: 2.1 + C_214: 2.1 + C_213: 2.1 + C_212: 2.0 + C_206: 2.0 + C_205_3: 2.0 + C_205_2: 2.0 + C_205_1: 2.0 + C_205: 2.0 + C_204_2: 2.0 + C_204_1: 2.0 + C_204: 2.0 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: src/RCS/phqalloc.h,v +Working file: src/phqalloc.h +head: 2.3 +branch: +locks: strict + dlpark: 2.3 +access list: +symbolic names: + C_260: 2.3 + C_259: 2.3 + C_258: 2.3 + C_257: 2.2 + C_256: 2.2 + C_255: 2.2 + C_254: 2.2 + C_253: 2.2 + C_252: 2.2 + C_251: 2.2 + C_250: 2.2 + C_249: 2.2 + C_248: 2.2 + C_247: 2.2 + C_246: 2.2 + C_245: 2.2 + C_244: 2.2 + C_243: 2.2 + C_242: 2.2 + C_241: 2.2 + C_240: 2.2 + C_239: 2.2 + C_238: 2.2 + C_237: 2.2 + C_236: 2.2 + C_235: 2.2 + C_234: 2.2 + C_233: 2.2 + C_232: 2.2 + C_231: 2.2 + C_230: 2.2 + C_229: 2.2 + C_227: 2.2 + C_226: 2.2 + C_225: 2.2 + C_224: 2.2 + C_222: 2.2 + C_221: 2.2 + C_220: 2.2 + C_219: 2.2 + C_218: 2.2 + RC1: 2.2 + C_216: 2.2 + C_215: 2.2 + C_214: 2.2 + C_213: 2.2 + C_212: 2.0 + C_206: 2.0 + C_205_3: 2.0 + C_205_2: 2.0 + C_205_1: 2.0 + C_205: 2.0 + C_204_2: 2.0 + C_204_1: 2.0 + C_204: 2.0 + C_202_2: 2.0 + C_202_1: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: src/RCS/phrqproto.h,v +Working file: src/phrqproto.h +head: 1.6 +branch: +locks: strict + dlpark: 1.6 +access list: +symbolic names: + C_260: 1.6 + C_259: 1.6 + C_258: 1.6 + C_257: 1.6 + C_256: 1.5 + C_255: 1.5 + C_254: 1.4 + C_253: 1.2 + C_252: 1.2 + C_251: 1.1 + C_250: 1.1 +keyword substitution: kv +total revisions: 6 +============================================================================= + +RCS file: src/RCS/phrqtype.h,v +Working file: src/phrqtype.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/smalldense.h,v +Working file: src/smalldense.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/sundialsmath.h,v +Working file: src/sundialsmath.h +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_260: 1.1 + C_259: 1.1 + C_258: 1.1 + C_257: 1.1 + C_256: 1.1 + C_255: 1.1 + C_254: 1.1 + C_253: 1.1 + C_252: 1.1 + C_251: 1.1 + C_250: 1.1 + C_249: 1.1 + C_248: 1.1 + C_247: 1.1 + C_246: 1.1 + C_245: 1.1 + C_244: 1.1 + C_243: 1.1 + C_242: 1.1 + C_241: 1.1 + C_240: 1.1 + C_239: 1.1 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: src/RCS/sundialstypes.h,v +Working file: src/sundialstypes.h +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_260: 1.4 + C_259: 1.4 + C_258: 1.4 + C_257: 1.4 + C_256: 1.4 + C_255: 1.4 + C_254: 1.4 + C_253: 1.4 + C_252: 1.4 + C_251: 1.4 + C_250: 1.4 + C_249: 1.3 + C_248: 1.3 + C_247: 1.3 + C_246: 1.3 + C_245: 1.3 + C_244: 1.3 + C_243: 1.3 + C_242: 1.3 + C_241: 1.3 + C_240: 1.3 + C_239: 1.2 + C_238: 1.1 + C_237: 1.1 + C_236: 1.1 + C_235: 1.1 + C_234: 1.1 + C_233: 1.1 + C_232: 1.1 + C_231: 1.1 + C_230: 1.1 + C_229: 1.1 + C_227: 1.1 + C_226: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: database/RCS/llnl.dat,v +Working file: database/llnl.dat +head: 1.14 +branch: +locks: strict +access list: +symbolic names: + C_210: 1.14 + C_209: 1.14 + C_224: 1.12 + C_207: 1.12 + C_206: 1.11 + C_205: 1.11 + C_204: 1.10 +keyword substitution: kv +total revisions: 14 +============================================================================= + +RCS file: database/RCS/minteq.dat,v +Working file: database/minteq.dat +head: 2.1 +branch: +locks: strict +access list: +symbolic names: + C_210: 2.1 + C_209: 2.1 + C_224: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: database/RCS/phreeqc.dat,v +Working file: database/phreeqc.dat +head: 2.3 +branch: +locks: strict + dlpark: 2.3 +access list: +symbolic names: + C_210: 2.3 + C_209: 2.3 + C_224: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.1 + C_204: 2.1 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: database/RCS/wateq4f.dat,v +Working file: database/wateq4f.dat +head: 2.6 +branch: +locks: strict + dlpark: 2.6 +access list: +symbolic names: + C_210: 2.6 + C_209: 2.6 + C_224: 2.4 + C_207: 2.2 + C_206: 2.2 + C_205: 2.2 + C_204: 2.2 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 7 +============================================================================= + +RCS file: database/RCS/iso.dat,v +Working file: database/iso.dat +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_210: 1.4 + C_209: 1.4 + C_224: 1.4 + C_207: 1.4 + C_206: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: examples/RCS/ex1,v +Working file: examples/ex1 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex1.out,v +Working file: examples/ex1.out +head: 1.7 +branch: +locks: strict + dlpark: 1.7 +access list: +symbolic names: + C_212: 1.7 + C_211: 1.5 + C_210: 1.5 + C_224: 1.4 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 7 +============================================================================= + +RCS file: examples/RCS/ex2,v +Working file: examples/ex2 +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex2.out,v +Working file: examples/ex2.out +head: 1.10 +branch: +locks: strict + dlpark: 1.10 +access list: +symbolic names: + C_212: 1.10 + C_211: 1.8 + C_210: 1.7 + C_224: 1.6 + C_208: 1.6 + C_207: 1.6 + C_206: 1.4 + C_205: 1.4 + C_204: 1.4 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: examples/RCS/ex2.sel,v +Working file: examples/ex2.sel +head: 1.10 +branch: +locks: strict + dlpark: 1.10 +access list: +symbolic names: + C_212: 1.10 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: examples/RCS/ex3,v +Working file: examples/ex3 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex3.out,v +Working file: examples/ex3.out +head: 1.11 +branch: +locks: strict + dlpark: 1.11 +access list: +symbolic names: + C_212: 1.11 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: examples/RCS/ex4,v +Working file: examples/ex4 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex4.out,v +Working file: examples/ex4.out +head: 1.6 +branch: +locks: strict + dlpark: 1.6 +access list: +symbolic names: + C_212: 1.6 + C_211: 1.4 + C_210: 1.4 + C_224: 1.3 + C_208: 1.3 + C_207: 1.3 + C_206: 1.2 + C_205: 1.2 + C_204: 1.2 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 6 +============================================================================= + +RCS file: examples/RCS/ex5,v +Working file: examples/ex5 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex5.out,v +Working file: examples/ex5.out +head: 1.11 +branch: +locks: strict + dlpark: 1.11 +access list: +symbolic names: + C_212: 1.11 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: examples/RCS/ex5.sel,v +Working file: examples/ex5.sel +head: 1.9 +branch: +locks: strict + dlpark: 1.9 +access list: +symbolic names: + C_212: 1.9 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: examples/RCS/ex6,v +Working file: examples/ex6 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex6.out,v +Working file: examples/ex6.out +head: 1.13 +branch: +locks: strict + dlpark: 1.13 +access list: +symbolic names: + C_212: 1.13 + C_211: 1.11 + C_210: 1.10 + C_224: 1.9 + C_208: 1.9 + C_207: 1.9 + C_206: 1.7 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 13 +============================================================================= + +RCS file: examples/RCS/ex6A-B.sel,v +Working file: examples/ex6A-B.sel +head: 1.10 +branch: +locks: strict + dlpark: 1.10 +access list: +symbolic names: + C_212: 1.10 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: examples/RCS/ex6C.sel,v +Working file: examples/ex6C.sel +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_212: 1.4 + C_211: 1.4 + C_210: 1.4 + C_224: 1.4 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: examples/RCS/ex7,v +Working file: examples/ex7 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex7.out,v +Working file: examples/ex7.out +head: 1.11 +branch: +locks: strict + dlpark: 1.11 +access list: +symbolic names: + C_212: 1.11 + C_211: 1.9 + C_210: 1.8 + C_224: 1.7 + C_208: 1.7 + C_207: 1.7 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: examples/RCS/ex7.sel,v +Working file: examples/ex7.sel +head: 1.9 +branch: +locks: strict + dlpark: 1.9 +access list: +symbolic names: + C_212: 1.9 + C_211: 1.8 + C_210: 1.7 + C_224: 1.6 + C_208: 1.6 + C_207: 1.6 + C_206: 1.4 + C_205: 1.4 + C_204: 1.4 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: examples/RCS/ex8,v +Working file: examples/ex8 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex8.out,v +Working file: examples/ex8.out +head: 1.12 +branch: +locks: strict + dlpark: 1.12 +access list: +symbolic names: + C_212: 1.12 + C_211: 1.10 + C_210: 1.9 + C_224: 1.8 + C_208: 1.8 + C_207: 1.8 + C_206: 1.6 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 12 +============================================================================= + +RCS file: examples/RCS/ex8.sel,v +Working file: examples/ex8.sel +head: 1.9 +branch: +locks: strict + dlpark: 1.9 +access list: +symbolic names: + C_212: 1.9 + C_211: 1.8 + C_210: 1.7 + C_224: 1.6 + C_208: 1.6 + C_207: 1.6 + C_206: 1.5 + C_205: 1.5 + C_204: 1.5 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 9 +============================================================================= + +RCS file: examples/RCS/ex9,v +Working file: examples/ex9 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex9.out,v +Working file: examples/ex9.out +head: 1.12 +branch: +locks: strict + dlpark: 1.12 +access list: +symbolic names: + C_212: 1.12 + C_211: 1.10 + C_210: 1.9 + C_224: 1.8 + C_208: 1.8 + C_207: 1.8 + C_206: 1.6 + C_205: 1.5 + C_204: 1.4 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 12 +============================================================================= + +RCS file: examples/RCS/ex9.sel,v +Working file: examples/ex9.sel +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.5 + C_210: 1.5 + C_224: 1.5 + C_208: 1.5 + C_207: 1.5 + C_206: 1.4 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex10,v +Working file: examples/ex10 +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex10.out,v +Working file: examples/ex10.out +head: 1.12 +branch: +locks: strict + dlpark: 1.12 +access list: +symbolic names: + C_212: 1.12 + C_211: 1.10 + C_210: 1.9 + C_224: 1.8 + C_208: 1.8 + C_207: 1.8 + C_206: 1.6 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 12 +============================================================================= + +RCS file: examples/RCS/ex10.sel,v +Working file: examples/ex10.sel +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_212: 1.4 + C_211: 1.4 + C_210: 1.4 + C_224: 1.4 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: examples/RCS/ex11,v +Working file: examples/ex11 +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.1 + C_204: 2.1 + C_202: 2.1 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex11.out,v +Working file: examples/ex11.out +head: 1.13 +branch: +locks: strict + dlpark: 1.13 +access list: +symbolic names: + C_212: 1.13 + C_211: 1.11 + C_210: 1.10 + C_224: 1.9 + C_208: 1.9 + C_207: 1.8 + C_206: 1.6 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 13 +============================================================================= + +RCS file: examples/RCS/ex11adv.sel,v +Working file: examples/ex11adv.sel +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_212: 1.4 + C_211: 1.4 + C_210: 1.4 + C_224: 1.4 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: examples/RCS/ex11trn.sel,v +Working file: examples/ex11trn.sel +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_212: 1.4 + C_211: 1.4 + C_210: 1.4 + C_224: 1.4 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: examples/RCS/ex12,v +Working file: examples/ex12 +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex12.out,v +Working file: examples/ex12.out +head: 1.3 +branch: +locks: strict + dlpark: 1.3 +access list: +symbolic names: + C_212: 1.3 + C_211: 1.1 + C_210: 1.1 + C_224: 1.1 + C_208: 1.1 + C_207: 1.1 + C_206: 1.1 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: examples/RCS/ex12.sel,v +Working file: examples/ex12.sel +head: 1.11 +branch: +locks: strict + dlpark: 1.11 +access list: +symbolic names: + C_212: 1.11 + C_211: 1.11 + C_210: 1.10 + C_224: 1.9 + C_208: 1.9 + C_207: 1.9 + C_206: 1.7 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: examples/RCS/ex13a,v +Working file: examples/ex13a +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex13a.out,v +Working file: examples/ex13a.out +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.3 + C_210: 1.3 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.1 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex13a.sel,v +Working file: examples/ex13a.sel +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.5 + C_210: 1.5 + C_224: 1.5 + C_208: 1.5 + C_207: 1.5 + C_206: 1.4 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex13b,v +Working file: examples/ex13b +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex13b.out,v +Working file: examples/ex13b.out +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.3 + C_210: 1.3 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.1 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex13b.sel,v +Working file: examples/ex13b.sel +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.5 + C_210: 1.5 + C_224: 1.5 + C_208: 1.5 + C_207: 1.5 + C_206: 1.4 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex13c,v +Working file: examples/ex13c +head: 2.1 +branch: +locks: strict + dlpark: 2.1 +access list: +symbolic names: + C_212: 2.1 + C_211: 2.1 + C_210: 2.1 + C_224: 2.1 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: examples/RCS/ex13c.out,v +Working file: examples/ex13c.out +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.3 + C_210: 1.3 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.1 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex13c.sel,v +Working file: examples/ex13c.sel +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.5 + C_210: 1.5 + C_224: 1.5 + C_208: 1.5 + C_207: 1.5 + C_206: 1.4 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex14,v +Working file: examples/ex14 +head: 2.2 +branch: +locks: strict + dlpark: 2.2 +access list: +symbolic names: + C_212: 2.2 + C_211: 2.2 + C_210: 2.2 + C_224: 2.2 + C_208: 2.1 + C_207: 2.1 + C_206: 2.1 + C_205: 2.1 + C_204: 2.1 + C_202: 2.1 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 3 +============================================================================= + +RCS file: examples/RCS/ex14.out,v +Working file: examples/ex14.out +head: 1.15 +branch: +locks: strict + dlpark: 1.15 +access list: +symbolic names: + C_212: 1.15 + C_211: 1.13 + C_210: 1.12 + C_224: 1.11 + C_208: 1.9 + C_207: 1.8 + C_206: 1.6 + C_205: 1.6 + C_204: 1.6 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 15 +============================================================================= + +RCS file: examples/RCS/ex14.sel,v +Working file: examples/ex14.sel +head: 1.8 +branch: +locks: strict + dlpark: 1.8 +access list: +symbolic names: + C_212: 1.8 + C_211: 1.7 + C_210: 1.7 + C_224: 1.6 + C_208: 1.4 + C_207: 1.4 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 8 +============================================================================= + +RCS file: examples/RCS/ex15,v +Working file: examples/ex15 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex15.dat,v +Working file: examples/ex15.dat +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex15.out,v +Working file: examples/ex15.out +head: 1.8 +branch: +locks: strict + dlpark: 1.8 +access list: +symbolic names: + C_212: 1.8 + C_211: 1.6 + C_210: 1.6 + C_224: 1.5 + C_208: 1.5 + C_207: 1.5 + C_206: 1.4 + C_205: 1.3 + C_204: 1.3 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 8 +============================================================================= + +RCS file: examples/RCS/ex15.sel,v +Working file: examples/ex15.sel +head: 1.7 +branch: +locks: strict + dlpark: 1.7 +access list: +symbolic names: + C_212: 1.7 + C_211: 1.7 + C_210: 1.7 + C_224: 1.6 + C_208: 1.6 + C_207: 1.6 + C_206: 1.5 + C_205: 1.4 + C_204: 1.4 + C_202: 1.3 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 7 +============================================================================= + +RCS file: examples/RCS/ex16,v +Working file: examples/ex16 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex16.out,v +Working file: examples/ex16.out +head: 1.5 +branch: +locks: strict + dlpark: 1.5 +access list: +symbolic names: + C_212: 1.5 + C_211: 1.3 + C_210: 1.3 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.1 + C_205: 1.1 + C_204: 1.1 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 5 +============================================================================= + +RCS file: examples/RCS/ex17,v +Working file: examples/ex17 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex17.out,v +Working file: examples/ex17.out +head: 1.10 +branch: +locks: strict + dlpark: 1.10 +access list: +symbolic names: + C_212: 1.10 + C_211: 1.8 + C_210: 1.7 + C_224: 1.6 + C_208: 1.6 + C_207: 1.6 + C_206: 1.4 + C_205: 1.4 + C_204: 1.4 + C_202: 1.1 + C_201: 1.1 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 10 +============================================================================= + +RCS file: examples/RCS/ex18,v +Working file: examples/ex18 +head: 2.0 +branch: +locks: strict + dlpark: 2.0 +access list: +symbolic names: + C_212: 2.0 + C_211: 2.0 + C_210: 2.0 + C_224: 2.0 + C_208: 2.0 + C_207: 2.0 + C_206: 2.0 + C_205: 2.0 + C_204: 2.0 + C_202: 2.0 + C_201: 2.0 + C_200: 2.0 + C_1: 2.0 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: examples/RCS/ex18.out,v +Working file: examples/ex18.out +head: 1.6 +branch: +locks: strict + dlpark: 1.6 +access list: +symbolic names: + C_212: 1.6 + C_211: 1.4 + C_210: 1.4 + C_224: 1.3 + C_208: 1.3 + C_207: 1.3 + C_206: 1.2 + C_205: 1.2 + C_204: 1.2 + C_202: 1.2 + C_201: 1.2 + C_200: 1.1 + C_1: 1.1 +keyword substitution: kv +total revisions: 6 +============================================================================= + +RCS file: doc/RCS/manual.pdf,v +Working file: doc/manual.pdf +head: 1.1 +branch: +locks: strict + dlpark: 1.1 +access list: +symbolic names: + C_211: 1.1 + C_210: 1.1 + C_224: 1.1 + C_208: 1.1 + C_207: 1.1 + C_206: 1.1 + C_205: 1.1 +keyword substitution: kv +total revisions: 1 +============================================================================= + +RCS file: doc/RCS/phreeqc.txt,v +Working file: doc/phreeqc.txt +head: 1.11 +branch: +locks: strict +access list: +symbolic names: + C_211: 1.11 + C_210: 1.10 + C_224: 1.9 + C_208: 1.8 + C_207: 1.8 + C_206: 1.7 + C_205: 1.6 + C_204_2: 1.5 + C_204: 1.4 + C_202: 1.1 + C_201: 1.1 +keyword substitution: kv +total revisions: 11 +============================================================================= + +RCS file: bin/RCS/phreeqc.orig,v +Working file: bin/phreeqc.orig +head: 1.4 +branch: +locks: strict + dlpark: 1.4 +access list: +symbolic names: + C_209: 1.4 + C_208: 1.4 + C_224: 1.4 + C_206: 1.4 + C_205: 1.4 + C_202: 1.4 + C_201: 1.4 + C_200: 1.4 + C_1: 1.4 +keyword substitution: kv +total revisions: 4 +============================================================================= + +RCS file: test/RCS/test.sh,v +Working file: test/test.sh +head: 1.2 +branch: +locks: strict + dlpark: 1.2 +access list: +symbolic names: + C_211: 1.2 + C_210: 1.2 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.2 + C_205: 1.2 + C_204: 1.2 + C_202: 1.2 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: test/RCS/clean.sh,v +Working file: test/clean.sh +head: 1.2 +branch: +locks: strict +access list: +symbolic names: + C_211: 1.2 + C_210: 1.2 + C_224: 1.2 + C_208: 1.2 + C_207: 1.2 + C_206: 1.2 + C_205: 1.2 + C_204: 1.2 + C_202: 1.2 +keyword substitution: kv +total revisions: 2 +============================================================================= + +RCS file: test/RCS/check.sh,v +Working file: test/check.sh +head: 1.3 +branch: +locks: strict +access list: +symbolic names: + C_211: 1.3 + C_210: 1.3 + C_224: 1.3 + C_208: 1.3 + C_207: 1.3 + C_206: 1.3 + C_205: 1.3 + C_204: 1.3 + C_202: 1.3 +keyword substitution: kv +total revisions: 3 +============================================================================= diff --git a/phreeqc_files.cpp b/phreeqc_files.cpp new file mode 100644 index 00000000..4d4990df --- /dev/null +++ b/phreeqc_files.cpp @@ -0,0 +1,524 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +#include "input.h" + +/* following line defines path for default data base file */ +const char *default_data_base = "phreeqc.dat"; + +static FILE *input_file = NULL; +static FILE *database_file = NULL; +static FILE *output = NULL; /* OUTPUT_MESSAGE */ +static FILE *log_file = NULL; /* OUTPUT_LOG */ +static FILE *punch_file = NULL; /* OUTPUT_PUNCH */ +static FILE *error_file = NULL; /* OUTPUT_ERROR */ +static FILE *dump_file = NULL; /* OUTPUT_DUMP */ + +static int fileop_handler(const int type, int (*PFN)(FILE*)); +static int open_handler(const int type, const char *file_name); +static int output_handler(const int type, const char *err_str, const int stop, void *cookie, const char *format, va_list args); +static int rewind_wrapper(FILE* file_ptr); + +static char const svnid[] = "$Id: phreeqc_files.c 78 2005-02-01 22:47:12Z dlpark $"; + +/* ---------------------------------------------------------------------- */ +int phreeqc_handler(const int action, const int type, const char *err_str, const int stop, void *cookie, const char *format, va_list args) +/* ---------------------------------------------------------------------- */ +{ + int i; + + switch (action) { + case ACTION_OPEN: + return open_handler(type, err_str); + break; + case ACTION_OUTPUT: + return output_handler(type, err_str, stop, cookie, format, args); + break; + case ACTION_FLUSH: + return fileop_handler(type, fflush); + break; + case ACTION_REWIND: + return fileop_handler(type, rewind_wrapper); + break; + case ACTION_CLOSE: + + i = fileop_handler(type, fclose); + switch (type) { + case OUTPUT_ERROR: + error_file = NULL; + break; + + case OUTPUT_WARNING: + break; + + case OUTPUT_MESSAGE: + output = NULL; + break; + + case OUTPUT_PUNCH: + punch_file = NULL; + break; + + case OUTPUT_SCREEN: + break; + + case OUTPUT_LOG: + log_file = NULL; + break; + + case OUTPUT_STDERR: + break; + + case OUTPUT_DUMP: + dump_file = NULL; + break; + } + + + return(i); + break; + } + return ERROR; +} +/* ---------------------------------------------------------------------- */ +int close_input_files(void) +/* ---------------------------------------------------------------------- */ +{ + int i = 0; + i |= fclose(database_file); + i |= fclose(input_file); + input_file = database_file = NULL; + return (i); +} +/* ---------------------------------------------------------------------- */ +int process_file_names(int argc, char *argv[], void **db_cookie, void **input_cookie, int log) +/* ---------------------------------------------------------------------- */ +{ + int l; + char token[2*MAX_LENGTH], default_name[2*MAX_LENGTH]; + char query[2*MAX_LENGTH]; + char in_file[2*MAX_LENGTH], out_file[2*MAX_LENGTH]; + char *env_ptr; + char *ptr; + int errors; + ENTRY item, *found_item; + +/* + * Prepare error handling + */ + errors = setjmp(mark); + if (errors != 0) { + return errors; + } + +/* + * Prep for get_line + */ + max_line = MAX_LINE; + space ((void **) ((void *) &line), INIT, &max_line, sizeof(char)); + space ((void **) ((void *) &line_save), INIT, &max_line, sizeof(char)); + hcreate_multi(5, &strings_hash_table); + hcreate_multi(2, &keyword_hash_table); + +/* + * Initialize hash table + */ + keyword_hash = (struct key *) PHRQ_malloc(sizeof(struct key)); + if (keyword_hash == NULL) { + malloc_error(); + } else { + keyword_hash->name = string_hsave("database"); + keyword_hash->keycount = 0; + item.key = keyword_hash->name; + item.data = keyword_hash; + found_item = hsearch_multi(keyword_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in keyword initialization."); + error_msg(error_string, STOP); + } + } + + +/* + * Open file for screen output + */ + if (argc > 4) { + error_file = fopen(argv[4], "w"); + if (error_file == NULL) { + error_file = stderr; + sprintf(error_string, "Error opening file, %s.", argv[4]); + warning_msg(error_string); + } + } else { + error_file = stderr; + } + +/* + * Open user-input file + */ + strcpy(query,"Name of input file?"); + if (argc <= 1) { + default_name[0]='\0'; + input_file = file_open(query, default_name, "r", FALSE); + } else { + strcpy(default_name, argv[1]); + input_file = file_open(query, default_name, "r", TRUE); + } + output_msg(OUTPUT_SCREEN, "Input file: %s\n\n", default_name); + output_msg(OUTPUT_SEND_MESSAGE, "Input file: %s\r\n\r\n", default_name); + strcpy(in_file, default_name); +/* + * Open file for output + */ + strcpy(query,"Name of output file?"); +#ifdef DOS + replace("."," ",default_name); +#endif + ptr = default_name; + copy_token(token, &ptr, &l); + strcat(token,".out"); + if (argc <= 1) { + output = file_open(query, token, "w", FALSE); + } else if (argc == 2) { + output = file_open(query, token, "w", TRUE); + } else if (argc >= 3) { + strcpy(token, argv[2]); + output = file_open(query, token, "w", TRUE); + } + output_msg(OUTPUT_SCREEN, "Output file: %s\n\n", token); + output_msg(OUTPUT_SEND_MESSAGE, "Output file: %s\r\n\r\n", token); + strcpy(out_file, token); +/* + * Open file for errors + */ + if (log == TRUE) { + if ((log_file = fopen("phreeqc.log","w")) == NULL) { + error_msg ("Can't open log file, phreeqc.log.", STOP); + } + } + /* + * Read input file for DATABASE keyword + */ + if (get_line(getc_callback, input_file) == KEYWORD) { + ptr = line; + copy_token(token, &ptr, &l); + if (strcmp_nocase(token, "database") == 0) { + user_database = string_duplicate(ptr); + if (string_trim(user_database) == EMPTY) { + warning_msg("DATABASE file name is missing; default database will be used."); + user_database = (char *) free_check_null(user_database); + } + } + } + fclose(input_file); + if ((input_file = fopen(in_file,"r")) == NULL) {; + error_msg ("Can't reopen input file.", STOP); + } +/* + * Open data base + */ + strcpy(query,"Name of database file?"); + env_ptr = getenv("PHREEQC_DATABASE"); + if (user_database != NULL) { + strcpy(token, user_database); + } else if (env_ptr != NULL) { + strcpy(token, env_ptr); + } else { + strcpy(token, default_data_base); + } + if (argc <= 1) { + database_file = file_open(query, token, "r", FALSE); + } else if (argc < 4) { + database_file = file_open(query, token, "r", TRUE); + } else if (argc >= 4) { + if (user_database == NULL) { + strcpy(token, argv[3]); + } else { +#ifndef PHREEQCI_GUI + warning_msg("Database file from DATABASE keyword is used; command line argument ignored."); +#endif + } + database_file = file_open(query, token, "r", TRUE); + } + output_msg(OUTPUT_SCREEN, "Database file: %s\n\n", token); + output_msg(OUTPUT_SEND_MESSAGE, "Database file: %s\r\n\r\n", token); + + + output_msg(OUTPUT_MESSAGE, " Input file: %s\n", in_file); + output_msg(OUTPUT_MESSAGE, " Output file: %s\n", out_file); + output_msg(OUTPUT_MESSAGE, "Database file: %s\n\n", token); + + +/* + * local cleanup + */ + user_database = (char *) free_check_null(user_database); + line = (char *) free_check_null(line); + line_save = (char *) free_check_null(line_save); + + hdestroy_multi(keyword_hash_table); + keyword_hash = (struct key *) free_check_null(keyword_hash); + keyword_hash_table = NULL; + + free_hash_strings(strings_hash_table); + hdestroy_multi(strings_hash_table); + strings_hash_table = NULL; + + *db_cookie = database_file; + *input_cookie = input_file; + + return 0; +} +/* ---------------------------------------------------------------------- */ +int getc_callback(void* cookie) +/* ---------------------------------------------------------------------- */ +{ + int i; + assert(cookie); + i = getc((FILE*)cookie); +#ifdef PHREEQ98 + if (i == '\n') ++inputlinenr; +#endif + return i; +} + +/* ---------------------------------------------------------------------- */ +static int output_handler(const int type, const char *err_str, const int stop, void *cookie, const char *format, va_list args) +/* ---------------------------------------------------------------------- */ +{ + int flush; + FILE *save_output = NULL; + + flush = TRUE; + + if (get_forward_output_to_log()) { + save_output = output; + output = log_file; + } + + switch (type) { + + case OUTPUT_ERROR: + if (status_on == TRUE) { + if (error_file != NULL) { + fprintf(error_file, "\n"); + } +#ifndef DOS + status_on = FALSE; +#endif + } + if (error_file != NULL) { + fprintf(error_file, "ERROR: %s\n", err_str); + if (flush) fflush(error_file); + } + if (output != NULL) { + fprintf(output, "ERROR: %s\n", err_str); + if (flush) fflush(output); + } + if (stop == STOP) { + if (error_file != NULL) { + fprintf(error_file, "Stopping.\n"); + fflush(error_file); + } + if (output != NULL) { + fprintf(output, "Stopping.\n"); + fflush(output); + } + } + break; + + case OUTPUT_WARNING: + if (pr.logfile == TRUE && log_file != NULL) { + fprintf(log_file,"WARNING: %s\n", err_str); + if (flush) fflush(log_file); + } + if (state == TRANSPORT && transport_warnings == FALSE) return(OK); + if (state == ADVECTION && advection_warnings == FALSE) return(OK); + if (pr.warnings >= 0) { + if (count_warnings > pr.warnings) return(OK); + } + if (status_on == TRUE) { + if (error_file != NULL) { + fprintf(error_file,"\n"); + } +#ifndef DOS + status_on = FALSE; +#endif + } + if (error_file != NULL) { + fprintf(error_file,"WARNING: %s\n", err_str); + if (flush) fflush(error_file); + } + if (output != NULL) { + fprintf(output,"WARNING: %s\n", err_str); + if (flush) fflush(output); + } + break; + case OUTPUT_CHECKLINE: + if (pr.echo_input == TRUE) { + if (output != NULL) { + vfprintf(output, format, args); + if (flush) fflush(output); + } + } + break; + case OUTPUT_MESSAGE: + case OUTPUT_BASIC: + if (output != NULL) { + vfprintf(output, format, args); + if (flush) fflush(output); + } + break; + case OUTPUT_PUNCH: + if (punch_file != NULL) { + if (pr.punch == TRUE && punch.in == TRUE) { + vfprintf(punch_file, format, args); + if (flush) fflush(punch_file); + } + } + break; + case OUTPUT_LOG: + if (pr.logfile == TRUE && log_file != NULL) { + vfprintf(log_file, format, args); + if (flush) fflush(log_file); + } + break; + case OUTPUT_SCREEN: + if (error_file != NULL) { + vfprintf(error_file, format, args); + if (flush) fflush(error_file); + } + break; + case OUTPUT_STDERR: + case OUTPUT_CVODE: + if (stderr != NULL) { + vfprintf(stderr, format, args); + fflush(stderr); + } + break; + case OUTPUT_DUMP: + if (dump_file != NULL) { + vfprintf(dump_file, format, args); + if (flush) fflush(dump_file); + } + break; + } + + if (get_forward_output_to_log()) { + output = save_output; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int close_output_files(void) +/* ---------------------------------------------------------------------- */ +{ + int ret = 0; + + if (output != NULL) ret |= fclose(output); + if (log_file != NULL) ret |= fclose(log_file); + if (punch_file != NULL) ret |= fclose(punch_file); + if (dump_file != NULL) ret |= fclose(dump_file); + if (error_file != NULL) ret |= fclose(error_file); + error_file = NULL; + output = log_file = punch_file = dump_file = NULL; + return ret; +} +/* ---------------------------------------------------------------------- */ +static int open_handler(const int type, const char *file_name) +/* ---------------------------------------------------------------------- */ +{ + switch (type) { + + case OUTPUT_PUNCH: + if (punch_file != NULL) { + fclose(punch_file); + punch_file = NULL; + } + if( (punch_file = fopen(file_name, "w")) == NULL) { + return ERROR; + } else { + free_check_null(selected_output_file_name); + selected_output_file_name = string_duplicate(file_name); + } + break; + + case OUTPUT_DUMP: + if (dump_file != NULL) { + fclose(dump_file); + dump_file = NULL; + } + if( (dump_file = fopen(file_name, "w")) == NULL) { + return ERROR; + } else { + free_check_null(dump_file_name); + dump_file_name = string_duplicate(file_name); + } + break; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int fileop_handler(const int type, int (*PFN)(FILE*)) +/* ---------------------------------------------------------------------- */ +{ + FILE *save_output = NULL; + + int forward = get_forward_output_to_log(); + if (forward) { + save_output = output; + output = log_file; + } + + switch (type) { + case OUTPUT_ERROR: + if (error_file) PFN(error_file); + break; + + case OUTPUT_WARNING: + if (error_file) PFN(error_file); + if (output) PFN(output); + break; + + case OUTPUT_MESSAGE: + case OUTPUT_CHECKLINE: + case OUTPUT_BASIC: + if (output) PFN(output); + break; + + case OUTPUT_PUNCH: + if (punch_file) PFN(punch_file); + break; + + case OUTPUT_SCREEN: + if (error_file) PFN(error_file); + break; + + case OUTPUT_LOG: + if (log_file) PFN(log_file); + break; + + case OUTPUT_CVODE: + case OUTPUT_STDERR: + if (stderr) PFN(stderr); + break; + + case OUTPUT_DUMP: + if (dump_file) PFN(dump_file); + break; + } + + if (forward) { + output = save_output; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int rewind_wrapper(FILE* file_ptr) +/* ---------------------------------------------------------------------- */ +{ + rewind(file_ptr); + return(OK); +} diff --git a/phrqproto.h b/phrqproto.h new file mode 100644 index 00000000..f83016db --- /dev/null +++ b/phrqproto.h @@ -0,0 +1,515 @@ +#ifdef PHREEQC_IDENT +static char const svnidphrqproto[] = "$Id$"; +#endif +/* advection.c */ +int advection(void); +/* basic.c */ +LDBLE system_total(char *total_name, LDBLE *count, char ***names, char ***types, LDBLE **moles); +int basic_main(char *commands); +void cmd_initialize(void); +void cmd_free(void); +int basic_compile(char *commands, void **lnbase, void **vbase, void **lpbase); +int basic_run(char *commands, void *lnbase, void *vbase, void *lpbase); +/* basicsubs.c */ +LDBLE activity (char *species_name); +LDBLE calc_logk_n(char *name); +LDBLE calc_logk_p(char *name); +LDBLE calc_logk_s(char *name); +LDBLE calc_surface_charge(char *surface_name); +LDBLE diff_layer_total(char *total_name, char *surface_name); +LDBLE equi_phase (char *phase_name); +LDBLE find_gas_comp (char *gas_comp_name); +LDBLE find_misc1 (char *s_s_name); +LDBLE find_misc2 (char *s_s_name); +LDBLE find_s_s_comp (char *s_s_comp_name); +LDBLE get_calculate_value(char *name); +LDBLE kinetics_moles (char *kinetics_name); +LDBLE log_activity (char *species_name); +LDBLE log_molality (char *species_name); +LDBLE molality (char *species_name); +LDBLE saturation_ratio (char *phase_name); +int saturation_index (char *phase_name, LDBLE *iap, LDBLE *si); +LDBLE solution_sum_secondary(char *total_name); +LDBLE sum_match_gases (char *stemplate, char *name); +LDBLE sum_match_species (char *stemplate, char *name); +LDBLE sum_match_s_s (char *stemplate, char *name); +int match_elts_in_species (char *name, char *stemplate); +int extract_bracket(char **string, char *bracket_string); +LDBLE surf_total(char *total_name, char *surface_name); +int system_species_compare(const void *ptr1, const void *ptr2); +LDBLE system_total(char *total_name, LDBLE *count, char ***names, char ***types, LDBLE **moles); +int system_total_elements(void); +int system_total_si(void); +int system_total_aq(void); +int system_total_ex(void); +int system_total_surf(void); +int system_total_gas(void); +int system_total_s_s(void); +int system_total_elt(char *total_name); +int system_total_elt_secondary(char *total_name); +LDBLE total (char *total_name); + +/* cl1.c */ +int cl1(int k, int l, int m, int n, + int nklmd, int n2d, + LDBLE *q, + int *kode, LDBLE toler, + int *iter, LDBLE *x, LDBLE *res, LDBLE *error, + LDBLE *cu, int *iu, int *s, + int check); + +/* default.c */ +int close_input_files(void); +int close_output_files(void); +int getc_callback(void* cookie); +int process_file_names(int argc, char *argv[], void **db_cookie, void **input_cookie, int log); + +/* integrate.c */ +int calc_all_g(void); +int calc_init_g(void); +int initial_surface_water(void); +int sum_diffuse_layer(struct surface_charge *surface_charge_ptr1); +int calc_all_donnan(void); +int calc_init_donnan(void); + +/* inverse.c */ +int inverse_models(void); + +/* isotopes.c */ +int add_isotopes(struct solution *solution_ptr); +int calculate_values(void); +int calculate_isotope_moles(struct element *elt_ptr, struct solution *solution_ptr, LDBLE total_moles); +LDBLE convert_isotope(struct master_isotope *master_isotope_ptr, LDBLE ratio); +int from_pcil(struct master_isotope *master_isotope_ptr); +int from_permil(struct master_isotope *master_isotope_ptr, LDBLE major_total); +int from_pct(struct master_isotope *master_isotope_ptr, LDBLE major_total); +int from_tu(struct master_isotope *master_isotope_ptr); +struct calculate_value *calculate_value_alloc(void); +int calculate_value_free(struct calculate_value *calculate_value_ptr); +struct calculate_value *calculate_value_search (char *name); +struct calculate_value *calculate_value_store (char *name, int replace_if_found); +struct isotope_alpha *isotope_alpha_alloc(void); +struct isotope_alpha *isotope_alpha_search (char *name); +struct isotope_alpha *isotope_alpha_store (char *name, int replace_if_found); +struct isotope_ratio *isotope_ratio_alloc(void); +struct isotope_ratio *isotope_ratio_search (char *name); +struct isotope_ratio *isotope_ratio_store (char *name, int replace_if_found); +struct master_isotope *master_isotope_store (char *name, int replace_if_found); +struct master_isotope *master_isotope_alloc(void); +struct master_isotope *master_isotope_search (char *name); +int print_initial_solution_isotopes(void); +int print_isotope_ratios(void); +int print_isotope_alphas(void); +int punch_isotopes(void); +int punch_calculate_values(void); +int read_calculate_values (void); +int read_isotopes(void); +int read_isotope_ratios (void); +int read_isotope_alphas (void); + +/* kinetics.c */ + +void cvode_init(void); +int run_reactions(int i, LDBLE kin_time, int use_mix, LDBLE step_fraction); +int set_and_run(int i, int use_mix, int use_kinetics, int nsaver, LDBLE step_fraction); +int set_and_run_wrapper(int i, int use_mix, int use_kinetics, int nsaver, LDBLE step_fraction); +int set_advection(int i, int use_mix, int use_kinetics, int nsaver); +int free_cvode(void); + +/* main.c */ +int main(int argc, char *argv[]); + +/* mainsubs.c */ +FILE *file_open (char *query, char *default_name, const char *status, int batch); +int copy_entities(void); +void initialize(void); +int initial_exchangers(int print); +int initial_gas_phases(int print); +int initial_solutions(int print); +int step_save_exch(int n_user); +int step_save_surf(int n_user); +int initial_surfaces(int print); +int k_temp(LDBLE tempc); +int reactions(void); +int saver(void); +int xsolution_save(int k_user); +int do_initialize(void); +int do_status(void); + +/* model.c */ +int check_residuals(void); +int free_model_allocs(void); +int ineq(int kode); +int model(void); +int jacobian_sums (void); +int mb_gases(void); +int mb_s_s(void); +int mb_sums (void); +int molalities (int allow_overflow); +int reset(void); +int residuals(void); +int set(int initial); +int sum_species(void); +int surface_model(void); + +/* p2clib.c */ + +/* parse.c */ +int check_eqn ( int association ); +int get_charge(char *charge, LDBLE *z); +int get_elt (char **t_ptr, char *element, int *i); +int get_elts_in_species (char **t_ptr, LDBLE coef); +int get_num (char **t_ptr, LDBLE *num); +int get_secondary_in_species (char **t_ptr, LDBLE coef); +int parse_eq(char *eqn, struct elt_list **elt_ptr, int association); + +/* pitzer.c */ +int gammas_pz(void); +int model_pz(void); +int pitzer (void); +int pitzer_clean_up(void); +int pitzer_init (void); +int pitzer_tidy (void); +int read_pitzer (void); +int set_pz(int initial); + +/* prep.c */ +int check_same_model(void); +int k_temp(LDBLE tc); +LDBLE k_calc(LDBLE *logk, LDBLE tempk); +int prep(void); +int reprep (void); +int rewrite_master_to_secondary(struct master *master_ptr1, struct master *master_ptr2); +int switch_bases(void); +int write_phase_sys_total (int n); + +/* print.c */ +int fpunchf(const char* name, const char* format, ...); +int fpunchf_user(int user_index, const char* format, ...); +char *sformatf(const char* format, ...); +int array_print(LDBLE *array_l, int row_count, int column_count, int max_column_count); +int print_all(void); +int print_exchange(void); +int print_gas_phase(void); +int print_master_reactions(void); +int print_reaction(struct reaction *rxn_ptr); +int print_species(void); +int print_surface(void); +int punch_all(void); + +/* read.c */ +int read_input(void); +int read_conc(int n, int count_mass_balance, char *str); +int *read_list_ints_range (char **ptr, int *count_ints, int positive, int *int_list ); +int read_log_k_only (char *ptr, LDBLE *log_k); +int read_number_description (char *ptr, int *n_user, int *n_user_end, + char **description); +int check_key (char *str); +int check_units (char *tot_units, int alkalinity, int check_compatibility, + const char *default_units, int print); +int find_option(char *item, int *n, const char **list, int count_list, int exact); +int get_option (const char **opt_list, int count_opt_list, char **next_char); +int get_true_false(char *string, int default_value); + +/* readtr.c */ +int read_transport (void); +int dump(void); +int dump_exchange(int k); +int dump_gas_phase(int k); +int dump_kinetics (int k); +int dump_mix (int k); +int dump_pp_assemblage(int k); +int dump_reaction (int k); +int dump_s_s_assemblage (int k); +int dump_solution (int k); +int dump_surface(int k); + +/* spread.c */ +int read_solution_spread(void); + +/* step.c */ +int step(LDBLE step_fraction); +int xsolution_zero (void); +int add_exchange (struct exchange *exchange_ptr); +int add_gas_phase (struct gas_phase *gas_phase_ptr); +int add_kinetics (struct kinetics *kinetics_ptr); +int add_mix (struct mix *mix_ptr); +int add_pp_assemblage (struct pp_assemblage *pp_assemblage_ptr); +int add_reaction (struct irrev *irrev_ptr, int step_number, LDBLE step_fraction); +int add_s_s_assemblage (struct s_s_assemblage *s_s_assemblage_ptr); +int add_solution (struct solution *solution_ptr, LDBLE extensive, + LDBLE intensive); +int add_surface (struct surface *surface_ptr); +int add_temperature(struct temperature *temperature_ptr, int step_number); + +/* structures.c */ +int clean_up(void); +int copier_add(struct copier *copier_ptr, int n_user, int start, int end); +int copier_free(struct copier *copier_ptr); +int copier_init(struct copier *copier_ptr); +int copy_entities(void); +int element_compare(const void *ptr1, const void *ptr2); +struct element *element_store (char *element); +int elt_list_combine(void); +int elt_list_compare(const void *ptr1, const void *ptr2); +struct elt_list *elt_list_dup(struct elt_list *elt_list_ptr_old); +int elt_list_print(struct elt_list *elt_list_ptr); +struct elt_list *elt_list_save(void); + +struct exchange *exchange_alloc (void); +struct exchange *exchange_bsearch (int k, int *n); +int exchange_comp_compare(const void *ptr1, const void *ptr2); +int exchange_copy(struct exchange *exchange_old_ptr, struct exchange *exchange_new_ptr, int n_user_new); +int exchange_compare (const void *ptr1, const void *ptr2); +int exchange_copy_to_last(int n, int n_user); +int exchange_delete(int n_user_old); +int exchange_duplicate(int n_user_old, int n_user_new); +int exchange_init (struct exchange *exchange_ptr, int n_user, int n_user_end, char *description); +int exchange_free (struct exchange *exchange_ptr); +int exchange_ptr_to_user(struct exchange *exchange_old_ptr, int n_user_new); +struct exchange *exchange_replicate(struct exchange *exchange_old_ptr, int n_user_new); +struct exchange *exchange_search(int n_user, int *n, int print); +int exchange_sort(void); + +int gas_comp_compare(const void *ptr1, const void *ptr2); +struct gas_phase *gas_phase_alloc (void); +struct gas_phase *gas_phase_bsearch (int k, int *n); +int gas_phase_compare (const void *ptr1, const void *ptr2); +int gas_phase_copy(struct gas_phase *gas_phase_old_ptr, + struct gas_phase *gas_phase_new_ptr, int n_user_new); +int gas_phase_copy_to_last(int n, int n_user); +int gas_phase_delete(int n_user_old); +int gas_phase_duplicate(int n_user_old, int n_user_new); +int gas_phase_init (struct gas_phase *gas_phase_ptr, int n_user, int n_user_end, char *description); +int gas_phase_free (struct gas_phase *gas_phase_ptr); +int gas_phase_ptr_to_user(struct gas_phase *gas_phase_ptr_old, int n_user_new); +struct gas_phase *gas_phase_replicate(struct gas_phase *gas_phase_old_ptr, int n_user_new); +struct gas_phase *gas_phase_search (int n_user, int *n); +int gas_phase_sort(void); + +enum entity_type get_entity_enum (char *name); + +struct inverse *inverse_alloc(void); +int inverse_delete (int i); +int inverse_isotope_compare (const void *ptr1, const void *ptr2); +struct inverse *inverse_search (int n_user, int *n); +int inverse_sort(void); + +struct irrev *irrev_bsearch (int k, int *n); +int irrev_copy(struct irrev *irrev_old_ptr, struct irrev *irrev_new_ptr, int n_user_new); +int irrev_duplicate(int n_user_old, int n_user_new); +int irrev_free (struct irrev *irrev_ptr); +struct irrev *irrev_search(int n_user, int *n); + +struct kinetics *kinetics_alloc (void); +struct kinetics *kinetics_bsearch (int k, int *n); +int kinetics_delete(int n_user_old); +int kinetics_comp_duplicate(struct kinetics_comp *kinetics_comp_new_ptr, struct kinetics_comp *kinetics_comp_old_ptr); +int kinetics_compare (const void *ptr1, const void *ptr2); +int kinetics_copy(struct kinetics *kinetics_old_ptr, + struct kinetics *kinetics_new_ptr, int n_user_new); +int kinetics_copy_to_last(int n, int n_user); +int kinetics_duplicate(int n_user_old, int n_user_new); +int kinetics_init (struct kinetics *kinetics_ptr, int n_user, int n_user_end, char *description); +int kinetics_free (struct kinetics *kinetics_ptr); +int kinetics_ptr_to_user(struct kinetics *kinetics_ptr_old, int n_user_new); +struct kinetics *kinetics_replicate(struct kinetics *kinetics_old_ptr, int n_user_new); +struct kinetics *kinetics_search(int n_user, int *n, int print); +int kinetics_sort(void); + +struct logk *logk_alloc(void); +struct logk *logk_store (char *name, int replace_if_found); +struct logk *logk_search (char *name); + +struct master *master_alloc(void); +int master_compare (const void *ptr1, const void *ptr2); +int master_delete(char *ptr); +struct master *master_bsearch (const char *ptr); +struct master *master_bsearch_primary (char *ptr); +struct master *master_search (char *ptr, int *n); + +struct mix *mix_bsearch (int k, int *n); +int mix_copy(struct mix *mix_old_ptr, + struct mix *mix_new_ptr, int n_user_new); +int mix_duplicate(int n_user_old, int n_user_new); +int mix_free (struct mix *mix_ptr); +struct mix *mix_search(int n_user, int *n, int print); +int mix_sort(void); + +struct pe_data *pe_data_alloc(void); +struct pe_data *pe_data_dup (struct pe_data *pe_ptr_old); +int pe_data_free (struct pe_data *pe_data_ptr); +int pe_data_store (struct pe_data **pe, const char *token); + +struct phase *phase_bsearch (char *ptr, int *j, int print); +int phase_compare(const void *ptr1, const void *ptr2); +int phase_delete(int i); +struct phase *phase_store (char *name); + +struct pp_assemblage *pp_assemblage_alloc (void); +struct pp_assemblage *pp_assemblage_bsearch (int k, int *n); +int pp_assemblage_compare(const void *ptr1, const void *ptr2); +int pp_assemblage_copy(struct pp_assemblage *pp_assemblage_old_ptr, struct pp_assemblage *pp_assemblage_new_ptr, int n_user_new); +int pp_assemblage_copy_to_last(int n, int n_user); +int pp_assemblage_delete(int n_user_old); +int pp_assemblage_duplicate(int n_user_old, int n_user_new); +int pp_assemblage_free (struct pp_assemblage *pp_assemblage_ptr); +int pp_assemblage_init (struct pp_assemblage *pp_assemblage_ptr, int n_user, int n_user_end, char *description); +int pp_assemblage_ptr_to_user(struct pp_assemblage *pp_assemblage_ptr_old, int n_user_new); +struct pp_assemblage *pp_assemblage_replicate(struct pp_assemblage *pp_assemblage_old_ptr, int n_user_new); +struct pp_assemblage *pp_assemblage_search (int n_user, int *n); +int pp_assemblage_sort(void); + +int pure_phase_compare (const void *ptr1, const void *ptr2); + +struct rate *rate_bsearch (char *ptr, int *j); +int rate_free(struct rate *rate_ptr); +struct rate *rate_search (char *name, int *n); +int rate_sort(void); + +struct reaction *rxn_alloc(int ntokens); +struct reaction *rxn_dup(struct reaction *rxn_ptr_old); +LDBLE rxn_find_coef(struct reaction *r_ptr, const char *str); +int rxn_free(struct reaction *rxn_ptr); + +int s_compare (const void *ptr1, const void *ptr2); +int s_delete (int i); +struct species *s_search (char *name); +struct species *s_store (char *name, LDBLE z, int replace_if_found); + +struct s_s_assemblage *s_s_assemblage_alloc (void); +struct s_s_assemblage *s_s_assemblage_bsearch (int k, int *n); +int s_s_assemblage_compare (const void *ptr1, const void *ptr2); + +int s_s_assemblage_copy(struct s_s_assemblage *s_s_assemblage_old_ptr, + struct s_s_assemblage *s_s_assemblage_new_ptr, int n_user_new); +int s_s_assemblage_copy_to_last(int n, int n_user); +int s_s_assemblage_duplicate(int n_user_old, int n_user_new); +int s_s_assemblage_delete(int n_user_old); +int s_s_assemblage_free (struct s_s_assemblage *s_s_assemblage_ptr); +int s_s_assemblage_init (struct s_s_assemblage *s_s_assemblage_ptr, int n_user, int n_user_end, char *description); +int s_s_assemblage_ptr_to_user(struct s_s_assemblage *s_s_assemblage_ptr_old, int n_user_new); +struct s_s_assemblage *s_s_assemblage_replicate(struct s_s_assemblage *s_s_assemblage_old_ptr, int n_user_new); +struct s_s_assemblage *s_s_assemblage_search (int n_user, int *n); +int s_s_assemblage_sort(void); +int s_s_compare (const void *ptr1, const void *ptr2); + +struct save_values *save_values_bsearch (struct save_values *k, int *n); +int save_values_compare(const void *ptr1, const void *ptr2); +int save_values_sort(void); +int save_values_store(struct save_values *s_v); + +int conc_compare(const void *ptr1, const void *ptr2); +int conc_init (struct conc *conc_ptr); +int isotope_compare (const void *ptr1, const void *ptr2); +struct solution *solution_alloc(void); +struct solution *solution_bsearch (int k, int *n, int print); +int solution_copy_to_last(int n, int n_user_new); +int solution_duplicate(int n_user_old, int n_user_new); +int solution_delete(int n_user_old); +int solution_free (struct solution *solution_ptr); +int solution_ptr_to_user(struct solution *solution_old_ptr, int n_user_new); +struct solution *solution_replicate(struct solution *solution_old_ptr, int n_user_new); +int solution_sort(void); + +int species_list_compare_alk (const void *ptr1, const void *ptr2); +int species_list_compare_master (const void *ptr1, const void *ptr2); +int species_list_sort(void); + +struct surface *surface_alloc (void); +struct surface *surface_bsearch (int k, int *n); +int surface_comp_compare(const void *ptr1, const void *ptr2); +int surface_compare (const void *ptr1, const void *ptr2); +int surface_copy(struct surface *surface_old_ptr, struct surface *surface_new_ptr, int n_user_new); +int surface_copy_to_last(int n, int n_user); +int surface_delete(int n_user_old); +int surface_duplicate(int n_user_old, int n_user_new); +int surface_free(struct surface *surface_ptr); +int surface_init(struct surface *surface_ptr, int n_user, int n_user_end, char *description); +int surface_ptr_to_user(struct surface *surface_ptr_old, int n_user_new); +struct surface *surface_replicate(struct surface *surface_old_ptr, int n_user_new); +struct surface *surface_search(int n_user, int *n, int print); +int surface_sort(void); + +int system_duplicate (int i, int save_old); + +struct temperature *temperature_bsearch (int k, int *n); +int temperature_copy(struct temperature *temperature_old_ptr, + struct temperature *temperature_new_ptr, int n_user_new); +int temperature_duplicate(int n_user_old, int n_user_new); +int temperature_free (struct temperature *temperature_ptr); +struct temperature *temperature_search(int n_user, int *n); +int temperature_sort(void); + +int trxn_add (struct reaction *r_ptr, LDBLE coef, int combine); +int trxn_combine (void); +int trxn_copy (struct reaction *rxn_ptr); +LDBLE trxn_find_coef(const char *str, int start); +int trxn_print (void); +int trxn_reverse_k (void); +int trxn_sort( void ); +int trxn_swap (const char *token); + +struct unknown *unknown_alloc(void); +int unknown_delete(int i); +int unknown_free(struct unknown *unknown_ptr); + +/* tally.c */ +void add_all_components_tally(void); +int build_tally_table(void); +int calc_dummy_kinetic_reaction_tally(struct kinetics *kinetics_ptr); +int diff_tally_table(void); +int extend_tally_table(void); +int free_tally_table(void); +int fill_tally_table(int *n_user, int index_conservative, int n_buffer); +int get_tally_table_rows_columns(int *rows, int *columns); +int get_tally_table_column_heading(int column, int *type, char *string); +int get_tally_table_row_heading(int column, char *string); +int store_tally_table(double *array, int row_dim, int col_dim, double fill_factor); +int zero_tally_table(void); + +/* tidy.c */ +int add_other_logk(LDBLE *source_k, int count_add_logk, struct name_coef *add_logk); +int select_log_k_expression(LDBLE *source_k, LDBLE *target_k); +int s_s_prep(LDBLE t, struct s_s *s_s_ptr, int print); +int tidy_punch(void); +int tidy_model(void); + +/* transport.c */ +int transport(void); +int set_initial_moles(int i); + +/* utilities.c */ +int add_elt_list(struct elt_list *elt_list_ptr, LDBLE coef); +int backspace_screen (int spaces); +LDBLE calc_alk(struct reaction *rxn_ptr); +int compute_gfw(const char *string, LDBLE *gfw); +int copy_token (char *token_ptr, char **ptr, int *length); +int dup_print(const char *ptr, int emphasis); +int equal (LDBLE a, LDBLE b, LDBLE eps); +void *free_check_null(void *ptr); +void free_hash_strings(HashTable *Table); +int get_token(char **eqnaddr, char *string, LDBLE *z, int *l); +int hcreate_multi(unsigned Count, HashTable **HashTable_ptr); +void hdestroy_multi(HashTable *HashTable_ptr); +ENTRY * hsearch_multi(HashTable *Table, ENTRY item, ACTION action); +int islegit(const char c); +void malloc_error (void); +int parse_couple(char *token); +int print_centered(const char *string); +int replace(const char *str1, const char *str2, char *str); +void space (void **ptr, int i, int *max, int struct_size); +void squeeze_white(char *s_l); +int status (int count, const char *str); +void str_tolower(char *str); +void str_toupper(char *str); +int strcmp_nocase(const char *str1, const char *str2); +int strcmp_nocase_arg1(const char *str1, const char *str2); +char * string_duplicate (const char *token); +char *string_hsave (const char *str); +char *string_pad (char *str, int i); +int string_trim (char *str); +int string_trim_right (char *str); +int string_trim_left (char *str); +LDBLE under (LDBLE xval); +int get_elts_in_species (char **t_ptr, LDBLE coef); diff --git a/phrqtype.h b/phrqtype.h new file mode 100644 index 00000000..01ff322c --- /dev/null +++ b/phrqtype.h @@ -0,0 +1,19 @@ +/* + * The following implements long double + * Many machines long double = double so there is no advantage + * Check float.h include file for number of digits (LDBL_DIG) + * Need to define here and in cl1.c + */ +#ifdef PHREEQC_IDENT +static char const svnidphrqtype[] = "$Id$"; +#endif + +/*#define USE_LONG_DOUBLE*/ +#ifdef USE_LONG_DOUBLE + #define LDBLE long double + #define SCANFORMAT "%Lf" +#else + #define LDBLE double + #define SCANFORMAT "%lf" +#endif + diff --git a/pitzer.cpp b/pitzer.cpp new file mode 100644 index 00000000..ddc59250 --- /dev/null +++ b/pitzer.cpp @@ -0,0 +1,1587 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +#define PITZER +#define PITZER_EXTERNAL +#include "pitzer.h" + +static char const svnid[] = "$Id: pitzer.c 248 2005-04-14 17:10:53Z dlpark $"; +/* variables */ +static double A0; +struct species **spec, **cations, **anions, **neutrals; +static int count_cations, count_anions, count_neutrals; +static int MAXCATIONS, FIRSTANION, MAXNEUTRAL; +struct pitz_param *mcb0, *mcb1, *mcc0; +static int *IPRSNT; +static double *M, *LGAMMA; +static double BK[23], DK[23]; + +/* routines */ +static int calc_pitz_param (struct pitz_param *pz_ptr, double TK, double TR); +static int check_gammas_pz(void); +static int ISPEC(char * name); +/*static int DH_AB (double TK, double *A, double *B);*/ +static double G (double Y); +static double GP (double Y); +#ifdef SKIP +static double ETHETAP (double ZJ, double ZK, double I); +static double ETHETA (double ZJ, double ZK, double I); +#endif +static int ETHETAS (double ZJ, double ZK, double I, double *etheta, double *ethetap); +static int BDK (double X); +static int initial_guesses(void); +static int revise_guesses(void); +static int remove_unstable_phases; + + +/* ---------------------------------------------------------------------- */ +int pitzer_init (void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Initialization for pitzer + */ + pitzer_model = FALSE; + max_pitz_param = 100; + count_pitz_param = 0; + space ((void **) ((void *) &pitz_params), INIT, &max_pitz_param, sizeof(struct pitz_param *)); + + max_theta_param = 100; + count_theta_param = 0; + space ((void **) ((void *) &theta_params), INIT, &max_theta_param, sizeof(struct theta_param *)); + + ICON = TRUE; + OTEMP=0.0; + for (i = 0; i < 23; i++) { + BK[i] = 0.0; + DK[i] = 0.0; + } + return OK; +} +/* ---------------------------------------------------------------------- */ +int pitzer_tidy (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make lists of species for cations, anions, neutral + */ + char * string1, *string2; + int i, j, order; + double z0, z1; + struct pitz_param *pzp_ptr; + struct theta_param *theta_param_ptr; + /* + * allocate pointers to species structures + */ + if (spec != NULL) spec = (struct species **) free_check_null(spec); + spec = (struct species **) PHRQ_malloc((size_t) (3*count_s*sizeof(struct species *))); + if (spec == NULL) malloc_error(); + for (i = 0; i < 3*count_s; i++) spec[i] = NULL; + cations = spec; + neutrals = &(spec[count_s]); + anions = &(spec[2*count_s]); + MAXCATIONS = count_s; + FIRSTANION = 2*count_s; + MAXNEUTRAL = count_s; + count_cations = 0; + count_anions = 0; + count_neutrals = 0; + if (itmax < 200) itmax = 200; + /* + * allocate other arrays for Pitzer + */ + if (IPRSNT != NULL) IPRSNT = (int *) free_check_null(IPRSNT); + IPRSNT = (int *) PHRQ_malloc((size_t) (3*count_s*sizeof(int))); + if (IPRSNT == NULL) malloc_error(); + if (M != NULL) M = (double *) free_check_null(M); + M = (double *) PHRQ_malloc((size_t) (3*count_s*sizeof(double))); + if (M == NULL) malloc_error(); + if (LGAMMA != NULL) LGAMMA = (double *) free_check_null(LGAMMA); + LGAMMA = (double *) PHRQ_malloc((size_t) (3*count_s*sizeof(double))); + if (LGAMMA == NULL) malloc_error(); + + + for (i = 0; i < count_s; i++) { + if (s[i] == s_eminus) continue; + if (s[i] == s_h2o) continue; + if (s[i]->z < -.001) { + anions[count_anions++] = s[i]; + } else if (s[i]->z > .001) { + cations[count_cations++] = s[i]; + } else { + neutrals[count_neutrals++] = s[i]; + } + } + /* + * Add etheta to parameter list in case theta not defined for + * cation-cation or anion-anion pair + * Remove old TYPE_ETHETA definitions + */ + j = 0; + for (i = 0; i < count_pitz_param; i++) { + if (pitz_params[i]->type == TYPE_ETHETA) { + pitz_params[i] = (struct pitz_param *) free_check_null(pitz_params[i]); + } else { + pitz_params[j++] = pitz_params[i]; + } + } + count_pitz_param = j; + for (i = 0; i < count_cations - 1; i++) { + for (j = i+1; j < count_cations; j++) { + sprintf(line,"%s %s 1", spec[i]->name, spec[j]->name); + pzp_ptr = pitz_param_read(line, 2); + pzp_ptr->type = TYPE_ETHETA; + if (count_pitz_param >= max_pitz_param) { + space ((void **) ((void *) &pitz_params), count_pitz_param, &max_pitz_param, sizeof(struct pitz_param *)); + } + pitz_params[count_pitz_param++] = pzp_ptr; + + } + } + for (i = 2*count_s; i < 2*count_s + count_anions - 1; i++) { + for (j = i+1; j < 2*count_s + count_anions; j++) { + sprintf(line,"%s %s 1", spec[i]->name, spec[j]->name); + pzp_ptr = pitz_param_read(line, 2); + pzp_ptr->type = TYPE_ETHETA; + if (count_pitz_param >= max_pitz_param) { + space ((void **) ((void *) &pitz_params), count_pitz_param, &max_pitz_param, sizeof(struct pitz_param *)); + } + pitz_params[count_pitz_param] = pzp_ptr; + count_pitz_param++; + } + } + /* + * put species numbers in pitz_params + */ + for (i = 0; i < count_pitz_param; i++) { + for (j = 0; j < 3; j++) { + if (pitz_params[i]->species[j] == NULL) continue; + pitz_params[i]->ispec[j] = ISPEC(pitz_params[i]->species[j]); + if ((j < 2 && pitz_params[i]->ispec[j] == -1) || + (j == 3 && (pitz_params[i]->type == TYPE_PSI || pitz_params[i]->type == TYPE_ZETA) && pitz_params[i]->ispec[j] == -1)) { + input_error++; + sprintf(error_string, "Species for Pitzer parameter not defined in SOLUTION_SPECIES, %s", pitz_params[i]->species[j]); + error_msg(error_string, CONTINUE); + return(ERROR); + } + } + } + /* + * McGinnis data + */ + string1 = string_hsave("K+"); + string2 = string_hsave("Cl-"); + IC = ISPEC(string2); + for (i = 0; i < count_pitz_param; i++) { + if (pitz_params[i]->species[0] == string1 && + pitz_params[i]->species[1] == string2) { + switch (pitz_params[i]->type) { + case TYPE_B0: + mcb0 = pitz_params[i]; + break; + case TYPE_B1: + mcb1 = pitz_params[i]; + break; + case TYPE_C0: + mcc0 = pitz_params[i]; + break; + case TYPE_B2: + case TYPE_THETA: + case TYPE_LAMDA: + case TYPE_ZETA: + case TYPE_PSI: + case TYPE_ETHETA: + case TYPE_Other: + break; + } + } + } + /* + * Set alpha values + */ + for (i = 0; i < count_pitz_param; i++) { + z0 = fabs(spec[pitz_params[i]->ispec[0]]->z); + z1 = fabs(spec[pitz_params[i]->ispec[1]]->z); + if (equal(z0, 1.0, 1e-8) || equal(z1, 1.0, 1e-8)) { + order = 1; + } else if (equal(z0,2.0, 1e-8) && equal(z1, 2.0, 1e-8)) { + order = 2; + } else { + order = 3; + } + if (pitz_params[i]->type == TYPE_B1) { + switch (order) { + case 1: + case 3: + pitz_params[i]->alpha = 2.0; + break; + case 2: + pitz_params[i]->alpha = 1.4; + break; + } + } else if (pitz_params[i]->type == TYPE_B2) { + switch (order) { + case 1: + pitz_params[i]->alpha = 12.0; + break; + case 2: + pitz_params[i]->alpha = 12.0; + break; + case 3: + pitz_params[i]->alpha = 50.0; + break; + } + } + } + /* + * Add thetas pointer to etheta pitzer parameters + */ + + if (count_theta_param > 0 ) { + for (i = 0; i < count_theta_param; i++) { + theta_params[i] = (struct theta_param *) free_check_null(theta_params[i]); + } + } + count_theta_param = 0; + for (i = 0; i < count_pitz_param; i++) { + if (pitz_params[i]->type == TYPE_ETHETA) { + z0 = spec[pitz_params[i]->ispec[0]]->z; + z1 = spec[pitz_params[i]->ispec[1]]->z; + theta_param_ptr = theta_param_search(z0, z1); + if (theta_param_ptr == NULL) { + if (count_theta_param >= max_theta_param) { + space ((void **) ((void *) &theta_params), count_theta_param, &max_theta_param, sizeof(struct theta_param *)); + } + theta_params[count_theta_param] = theta_param_alloc(); + theta_param_init(theta_params[count_theta_param]); + theta_params[count_theta_param]->zj = z0; + theta_params[count_theta_param]->zk = z1; + theta_param_ptr = theta_params[count_theta_param]; + count_theta_param++; + } + pitz_params[i]->thetas = theta_param_ptr; + } + } + return OK; +} +/* ---------------------------------------------------------------------- */ +int ISPEC(char * name) +/* ---------------------------------------------------------------------- */ +/* + * Find species number in spec for character string species name + */ +{ + int i; + for (i = 0; i < 3*count_s; i++) { + if (spec[i] == NULL) continue; + if (name == spec[i]->name) { + return(i); + } + } + return (-1); +} +/* ---------------------------------------------------------------------- */ +int read_pitzer (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads advection information + * + * 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 + * + */ +/* + * Read advection parameters: + * number of cells; + * number of shifts; + */ + int n, j; + struct pitz_param *pzp_ptr; + pitz_param_type pzp_type; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "b0", /* 0 */ + "b1", /* 1 */ + "b2", /* 2 */ + "c0", /* 3 */ + "theta", /* 4 */ + "lamda", /* 5 */ + "zeta", /* 6 */ + "psi", /* 7 */ + "macinnes", /* 8 */ + "macinnis", /* 9 */ + "mac" /* 10 */ + }; + int count_opt_list = 11; +/* + * Read lines + */ + opt_save = OPTION_ERROR; + return_value = UNKNOWN; + n = -1; + pzp_type = TYPE_Other; + 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_DEFAULT: + pzp_ptr = pitz_param_read(line, n); + if (pzp_ptr != NULL) { + pzp_ptr->type = pzp_type; + j = pitz_param_search(pzp_ptr); + if (j < 0) { + if (count_pitz_param >= max_pitz_param) { + space ((void **) ((void *) &pitz_params), count_pitz_param, &max_pitz_param, sizeof(struct pitz_param *)); + } + + pitz_params[count_pitz_param] = pzp_ptr; + count_pitz_param++; + } else { + pitz_params[j] = (struct pitz_param *) free_check_null(pitz_params[j]); + pitz_params[j] = pzp_ptr; + } + } + break; + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in PITZER keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* b0 */ + pzp_type = TYPE_B0; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 1: /* b1 */ + pzp_type = TYPE_B1; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 2: /* b2 */ + pzp_type = TYPE_B2; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 3: /* c0 */ + pzp_type = TYPE_C0; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 4: /* theta */ + pzp_type = TYPE_THETA; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 5: /* lambda */ + pzp_type = TYPE_LAMDA; + n = 2; + opt_save = OPTION_DEFAULT; + break; + case 6: /* zeta */ + pzp_type = TYPE_ZETA; + n = 3; + opt_save = OPTION_DEFAULT; + break; + case 7: /* psi */ + pzp_type = TYPE_PSI; + n = 3; + opt_save = OPTION_DEFAULT; + break; + case 8: /* macinnes */ + case 9: /* macinnis */ + case 10: /* mac */ + opt_save = OPTION_ERROR; + ICON = get_true_false(next_char, TRUE); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + if (count_pitz_param > 0) pitzer_model = TRUE; + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int PTEMP (double TK) +/* ---------------------------------------------------------------------- */ +{ +/* +C +C SUBROUTINE TO CALUCLATE TEMPERATURE DEPENDENCE OF PITZER PARAMETER +C +*/ + double DC0; + int i; + double TR=298.15; + + if (fabs(TK-OTEMP) < 0.01e0) return OK; + OTEMP=TK; +/* +C Set DW0 +*/ + DW(TK); + for (i = 0; i < count_pitz_param; i++) { + calc_pitz_param(pitz_params[i], TK, TR); + } + DC0=DC(TK); + if (fabs(TK-TR) < 0.01e0) { + A0=0.392e0; + } else { + DC0=DC(TK); + A0=1.400684e6*sqrt(DW0/(pow((DC0*TK),3.0e0))); + /*A0=1.400684D6*(DW0/(DC0*TK)**3.0D0)**0.5D0*/ + } + return OK; +} + +/* ---------------------------------------------------------------------- */ +int calc_pitz_param (struct pitz_param *pz_ptr, double TK, double TR) +/* ---------------------------------------------------------------------- */ +{ + double param; + /* + */ + + if (fabs(TK-TR) < 0.01) { + param = pz_ptr->a[0]; + } else { + param = (pz_ptr->a[0] + + pz_ptr->a[1]*(1.e0/TK-1.e0/TR) + + pz_ptr->a[2]*log(TK/TR) + + pz_ptr->a[3]*(TK - TR) + + pz_ptr->a[4]*(TK*TK - TR*TR)); + } + pz_ptr->p = param; + switch (pz_ptr->type) { + case TYPE_B0: + pz_ptr->U.b0 = param; + break; + case TYPE_B1: + pz_ptr->U.b1 = param; + break; + case TYPE_B2: + pz_ptr->U.b2 = param; + break; + case TYPE_C0: + pz_ptr->U.c0 = param; + break; + case TYPE_THETA: + pz_ptr->U.theta = param; + break; + case TYPE_LAMDA: + pz_ptr->U.lamda = param; + break; + case TYPE_ZETA: + pz_ptr->U.zeta = param; + break; + case TYPE_ETHETA: + break; + case TYPE_PSI: + pz_ptr->U.psi = param; + break; + case TYPE_Other: + error_msg("Should not be TYPE_Other in function calc_pitz_param", STOP); + break; + } + return OK; +} +/* ---------------------------------------------------------------------- */ +int pitzer (void) +/* ---------------------------------------------------------------------- */ +{ + int i, i0, i1, i2; + double param, alpha, z0, z1, z2; + double etheta, ethetap; + double dummy; + /* + double CONV, XI, XX, OSUM, BIGZ, DI, F, XXX, GAMCLM, + CSUM, PHIMAC, OSMOT, BMXP, ETHEAP, CMX, BMX, PHI, + BMXPHI, PHIPHI, AW, A, B; + */ + double CONV, XI, XX, OSUM, BIGZ, DI, F, XXX, GAMCLM, + CSUM, PHIMAC, OSMOT, B; + double I, TK; + int LNEUT; + /* + C + C INITIALIZE + C + */ + CONV = 1.0/log(10.0); + XI=0.0e0; + XX=0.0e0; + OSUM=0.0e0; + LNEUT=FALSE; + /*n + I = *I_X; + TK = *TK_X; + */ + I = mu_x; + TK = tk_x; + /* DH_AB(TK, &A, &B); */ + /* + C + C TRANSFER DATA FROM TO M + C + */ + for (i = 0; i < 3*count_s; i++) { + IPRSNT[i] = FALSE; + M[i] = 0.0; + if (spec[i] != NULL && spec[i]->in == TRUE) { + if (spec[i]->type == EX || + spec[i]->type == SURF || + spec[i]->type == SURF_PSI) continue; + M[i] = under(spec[i]->lm); + if (M[i] > MIN_TOTAL) IPRSNT[i] = TRUE; + } + } + if (ICON == TRUE) { + IPRSNT[IC] = TRUE; + } +#ifdef SKIP + for (i = count_s; i < count_s + count_neutrals; i++) { + if (M[i] > MIN_TOTAL) LNEUT = TRUE; + } +#endif + /* + ICON = 0; + M[1] = 1.40070736; + M[4] = 2.52131086E-05; + M[140] = 4.59985435E-09; + */ + +/* +C +C COMPUTE PITZER COEFFICIENTS' TEMPERATURE DEPENDENCE +C +*/ + PTEMP(TK); + for (i = 0; i < 2*count_s + count_anions; i++) { + LGAMMA[i] = 0.0; + if (IPRSNT[i] == TRUE) { + XX=XX+M[i]*fabs(spec[i]->z); + XI=XI+M[i]*spec[i]->z*spec[i]->z; + OSUM=OSUM+M[i]; + } + } + I=XI/2.0e0; +/* +C +C EQUATION (8) +C +*/ + BIGZ=XX; + DI=sqrt(I); +/* +C +C CALCULATE F & GAMCLM +C +*/ + B = 1.2; + F=-A0*(DI/(1.0e0+B*DI)+2.0e0*log(1.0e0+B*DI)/B); + XXX=2.0e0*DI; + XXX=(1.0e0-(1.0e0+XXX-XXX*XXX*0.5e0)*exp(-XXX))/(XXX*XXX); + /*GAMCLM=F+I*2.0e0*(BCX(1,IK,IC)+BCX(2,IK,IC)*XXX)+1.5e0*BCX(4,IK,IC)*I*I;*/ + /*GAMCLM=F+I*2.0e0*(mcb0->U.b0 + mcb1->U.b1*XXX) + 1.5e0*mcc0->U.c0*I*I;*/ + GAMCLM=F+I*2.0e0*(mcb0->p + mcb1->p*XXX) + 1.5e0*mcc0->p*I*I; + CSUM=0.0e0; + OSMOT=-(A0)*pow(I,1.5e0)/(1.0e0+B*DI); +/* + * Calculate ethetas + */ + for (i = 0; i < count_theta_param; i++) { + z0 = theta_params[i]->zj; + z1 = theta_params[i]->zk; + ETHETAS(z0, z1, I, ðeta, ðetap); + theta_params[i]->etheta = etheta; + theta_params[i]->ethetap = ethetap; + } +/* + * Sums for F, LGAMMA, and OSMOT + */ + dummy = LGAMMA[1]; + for (i = 0; i < count_pitz_param; i++) { + i0 = pitz_params[i]->ispec[0]; + i1 = pitz_params[i]->ispec[1]; + if (IPRSNT[i0] == FALSE || IPRSNT[i1] == FALSE) continue; + z0 = spec[i0]->z; + z1 = spec[i1]->z; + param = pitz_params[i]->p; + alpha = pitz_params[i]->alpha; + switch (pitz_params[i]->type) { + case TYPE_B0: + LGAMMA[i0] += M[i1]*2.0*param; + LGAMMA[i1] += M[i0]*2.0*param; + OSMOT += M[i0]*M[i1]*param; + break; + case TYPE_B1: + F += M[i0]*M[i1]*param*GP(alpha*DI)/I; + LGAMMA[i0] += M[i1]*2.0*param*G(alpha*DI); + LGAMMA[i1] += M[i0]*2.0*param*G(alpha*DI); + OSMOT += M[i0]*M[i1]*param*exp(-alpha*DI); + break; + case TYPE_B2: + F += M[i0]*M[i1]*param*GP(alpha*DI)/I; + LGAMMA[i0] += M[i1]*2.0*param*G(alpha*DI); + LGAMMA[i1] += M[i0]*2.0*param*G(alpha*DI); + OSMOT += M[i0]*M[i1]*param*exp(-alpha*DI); + break; + case TYPE_C0: + CSUM += M[i0]*M[i1]*pitz_params[i]->p/(2.0e0*sqrt(fabs(z0*z1))); + LGAMMA[i0] += M[i1]*BIGZ*param/(2.0*sqrt(fabs(z0*z1))); + LGAMMA[i1] += M[i0]*BIGZ*param/(2.0*sqrt(fabs(z0*z1))); + OSMOT += M[i0]*M[i1]*BIGZ*param/(2.0*sqrt(fabs(z0*z1))); + break; + case TYPE_THETA: + LGAMMA[i0] += 2.0*M[i1]*(param /*+ ETHETA(z0, z1, I) */ ); + LGAMMA[i1] += 2.0*M[i0]*(param /*+ ETHETA(z0, z1, I) */ ); + OSMOT += M[i0]*M[i1]*param; + break; + case TYPE_ETHETA: + /* + ETHETAS(z0, z1, I, ðeta, ðetap); + */ + etheta = pitz_params[i]->thetas->etheta; + ethetap = pitz_params[i]->thetas->ethetap; + F += M[i0]*M[i1]*ethetap; + LGAMMA[i0] += 2.0*M[i1]*etheta; + LGAMMA[i1] += 2.0*M[i0]*etheta; + OSMOT += M[i0]*M[i1]*(etheta + I*ethetap); + /* + F += M[i0]*M[i1]*ETHETAP(z0, z1, I); + LGAMMA[i0] += 2.0*M[i1]*(ETHETA(z0, z1, I) ); + LGAMMA[i1] += 2.0*M[i0]*(ETHETA(z0, z1, I) ); + OSMOT += M[i0]*M[i1]*(ETHETA(z0, z1, I) + I*ETHETAP(z0, z1, I) ); + */ + break; + case TYPE_PSI: + i2 = pitz_params[i]->ispec[2]; + if (IPRSNT[i2] == FALSE) continue; + z2 = spec[i2]->z; + LGAMMA[i0] += M[i1]*M[i2]*param; + LGAMMA[i1] += M[i0]*M[i2]*param; + LGAMMA[i2] += M[i0]*M[i1]*param; + OSMOT += M[i0]*M[i1]*M[i2]*param; + break; + case TYPE_LAMDA: + LGAMMA[i0] += 2.0*M[i1]*param; + LGAMMA[i1] += 2.0*M[i0]*param; + OSMOT += M[i0]*M[i1]*param; + break; + case TYPE_ZETA: + i2 = pitz_params[i]->ispec[2]; + if (IPRSNT[i2] == FALSE) continue; + LGAMMA[i0] += M[i1]*M[i2]*param; + LGAMMA[i1] += M[i0]*M[i2]*param; + LGAMMA[i2] += M[i0]*M[i1]*param; + OSMOT += M[i0]*M[i1]*M[i2]*param; + break; + case TYPE_Other: + error_msg("TYPE_Other in pitz_param list.", STOP); + break; + } + } + + /* + * Add F and CSUM terms to LGAMMA + */ + + for (i = 0; i < count_cations; i++) { + z0 = spec[i]->z; + LGAMMA[i] += z0*z0*F+fabs(z0)*CSUM; + } + for (i = 2*count_s; i < 2*count_s + count_anions; i++) { + z0 = spec[i]->z; + LGAMMA[i] += z0*z0*F+fabs(z0)*CSUM; + } +/* +C +C CONVERT TO MACINNES CONVENTION +C +*/ + if (ICON == TRUE) { + PHIMAC=LGAMMA[IC]-GAMCLM; +/* +C +C CORRECTED ERROR IN PHIMAC, NOVEMBER, 1989 +C +*/ + for (i = 0; i < 2*count_s + count_anions; i++) { + if (IPRSNT[i] == TRUE) { + LGAMMA[i]=LGAMMA[i]+spec[i]->z*PHIMAC; + } + } + } + + COSMOT = 1.0e0 + 2.0e0*OSMOT/OSUM; +/* +C +C CALCULATE THE ACTIVITY OF WATER +C +*/ + AW=exp(-OSUM*COSMOT/55.50837e0); + if (AW > 1.0) AW = 1.0; + /*s_h2o->la=log10(AW);*/ + mu_x = I; + for (i = 0; i < 2*count_s + count_anions; i++) { + if (IPRSNT[i] == FALSE) continue; + /*spec[i]->lg=LGAMMA[i]*CONV;*/ + spec[i]->lg_pitzer=LGAMMA[i]*CONV; + /* + output_msg(OUTPUT_MESSAGE, "%d %s:\t%e\t%e\t%e\t%e \n", i, spec[i]->name, M[i], spec[i]->la, spec[i]->lg_pitzer, spec[i]->lg); + */ + } + /* + output_msg(OUTPUT_MESSAGE, "OSUM: %e\n", OSUM); + output_msg(OUTPUT_MESSAGE, "OSMOT: %e\n", OSMOT); + output_msg(OUTPUT_MESSAGE, "COSMOT: %e\n", COSMOT); + output_msg(OUTPUT_MESSAGE, "F: %e\n", F); + output_msg(OUTPUT_MESSAGE, "AW: %e\n", AW); + */ + /* + *I_X = I; + *COSMOT_X = COSMOT; + */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +double JAY (double X) +/* ---------------------------------------------------------------------- */ +/* +C +C FUNCTION TO CALCULATE JAY AND JPRIME +C +C J0 AND J1, USED IN CALCULATION OF ETHETA AND ETHEAP +C +*/ +{ + double JAY; + BDK (X); + JAY=X/4.0e0-1.0e0+0.5e0*(BK[0]-BK[2]); + return JAY; +} +/* ---------------------------------------------------------------------- */ +double JPRIME (double Y) +/* ---------------------------------------------------------------------- */ +{ + double DZ; + BDK (Y); + if (Y > 1.0e0) { + DZ=-4.0e0*pow(Y,-1.1e0)/9.0e0; + } else { + DZ=0.8e0*pow(Y,-0.8e0); + } + return (Y*(.25e0+DZ*(DK[0]-DK[2])/2.0e0)); +} + + +/* ---------------------------------------------------------------------- */ +int BDK (double X) +/* ---------------------------------------------------------------------- */ +/* +C +C NUMERICAL APPROXIMATION TO THE INTEGRALS IN THE EXPRESSIONS FOR J0 +C AND J1. CHEBYSHEV APPROXIMATION IS USED. THE CONSTANTS 'AK' ARE +C DEFINED IN BLOCK COMMON. +C +*/ +/* +C +C AK IS USED TO CALCULATE HIGHER ORDER ELECTROSTATIC TERMS IN +C SUBROUTINE PITZER +C +*/ +{ + double AKX[42] = { + 1.925154014814667e0, -.060076477753119e0, -.029779077456514e0, + -.007299499690937e0, 0.000388260636404e0, 0.000636874599598e0, + 0.000036583601823e0, -.000045036975204e0, -.000004537895710e0, + 0.000002937706971e0, 0.000000396566462e0, -.000000202099617e0, + -.000000025267769e0, 0.000000013522610e0, 0.000000001229405e0, + -.000000000821969e0, -.000000000050847e0, 0.000000000046333e0, + 0.000000000001943e0, -.000000000002563e0, -.000000000010991e0, + 0.628023320520852e0, 0.462762985338493e0, 0.150044637187895e0, + -.028796057604906e0, -.036552745910311e0, -.001668087945272e0, + 0.006519840398744e0, 0.001130378079086e0, -.000887171310131e0, + -.000242107641309e0, 0.000087294451594e0, 0.000034682122751e0, + -.000004583768938e0, -.000003548684306e0, -.000000250453880e0, + 0.000000216991779e0, 0.000000080779570e0, 0.000000004558555e0, + -.000000006944757e0, -.000000002849257e0, 0.000000000237816e0}; +/* + DOUBLE PRECISION AK, BK, DK + COMMON / MX8 / AK(0:20,2),BK(0:22),DK(0:22) +*/ + double *AK; + double Z; + int II; + int i; + + if (X <= 1.0e0) { + II=1; + Z=4.0e0*pow(X,0.2e0)-2.0e0; + AK = &AKX[0]; + } else { + II=2; + Z=40.0e0*pow(X,-1.0e-1)/9.0e0-22.0e0/9.0e0; + AK = &AKX[21]; + } + for (i = 20; i >= 0; i--) { + BK[i]=Z*BK[i+1]-BK[i+2]+AK[i]; + DK[i]=BK[i+1]+Z*DK[i+1]-DK[i+2]; + } + return OK; +} +/* ---------------------------------------------------------------------- */ +double G (double Y) +/* ---------------------------------------------------------------------- */ +{ + return (2.0e0*(1.0e0-(1.0e0+Y)*exp(-Y))/(Y*Y)); +} +/* ---------------------------------------------------------------------- */ +double GP (double Y) +/* ---------------------------------------------------------------------- */ +{ + return (-2.0e0*(1.0e0-(1.0e0+Y+Y*Y/2.0e0)*exp(-Y))/(Y*Y)); +} +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +double ETHETA (double ZJ, double ZK, double I) +/* ---------------------------------------------------------------------- */ +{ + double XCON, ZZ; + double XJK, XJJ, XKK; + + if (ZJ == ZK) return(0.0); + XCON=6.0e0*A0*sqrt(I); + ZZ=ZJ*ZK; +/* +C +C NEXT 3 ARE EQUATION (A1) +C +*/ + XJK=XCON*ZZ; + XJJ=XCON*ZJ*ZJ; + XKK=XCON*ZK*ZK; +/* +C +C EQUATION (A2) +C +*/ + + return (ZZ*(JAY(XJK)-JAY(XJJ)/2.0e0-JAY(XKK)/2.0e0)/(4.0e0*I)); +} +/* ---------------------------------------------------------------------- */ +double ETHETAP (double ZJ, double ZK, double I) +/* ---------------------------------------------------------------------- */ +{ + double XCON, ZZ, ETHETA, ETHETAP; + double XJK, XJJ, XKK; + + if (ZJ == ZK) return(0.0); + XCON=6.0e0*A0*sqrt(I); + ZZ=ZJ*ZK; +/* +C +C NEXT 3 ARE EQUATION (A1) +C +*/ + XJK=XCON*ZZ; + XJJ=XCON*ZJ*ZJ; + XKK=XCON*ZK*ZK; +/* +C +C EQUATION (A3) +C +*/ + ETHETA=ZZ*(JAY(XJK)-JAY(XJJ)/2.0e0-JAY(XKK)/2.0e0)/(4.0e0*I); + ETHETAP=ZZ*(JPRIME(XJK)-JPRIME(XJJ)/2.0e0-JPRIME(XKK)/2.0e0)/(8.0e0*I*I) - ETHETA/I; + return (ETHETAP); +} +#endif +/* ---------------------------------------------------------------------- */ +int ETHETAS (double ZJ, double ZK, double I, double *etheta, double *ethetap) +/* ---------------------------------------------------------------------- */ +{ + double XCON, ZZ; + double XJK, XJJ, XKK; + + *etheta = 0.0; + *ethetap = 0.0; + if (ZJ == ZK) return(OK); + XCON=6.0e0*A0*sqrt(I); + ZZ=ZJ*ZK; +/* +C +C NEXT 3 ARE EQUATION (A1) +C +*/ + XJK=XCON*ZZ; + XJJ=XCON*ZJ*ZJ; + XKK=XCON*ZK*ZK; +/* +C +C EQUATION (A3) +C +*/ + *etheta=ZZ*(JAY(XJK)-JAY(XJJ)/2.0e0-JAY(XKK)/2.0e0)/(4.0e0*I); + *ethetap=ZZ*(JPRIME(XJK)-JPRIME(XJJ)/2.0e0-JPRIME(XKK)/2.0e0)/(8.0e0*I*I) - *etheta/I; + return (OK); +} +/* ---------------------------------------------------------------------- */ +int pitzer_clean_up(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free all allocated memory, except strings + */ + int i; + + if (svnid == NULL) fprintf(stderr," "); + for (i = 0; i < count_pitz_param; i++) { + pitz_params[i] = (struct pitz_param *) free_check_null(pitz_params[i]); + } + pitz_params = (struct pitz_param **) free_check_null(pitz_params); + for (i = 0; i < count_theta_param; i++) { + theta_params[i] = (struct theta_param *) free_check_null(theta_params[i]); + } + theta_params = (struct theta_param **) free_check_null(theta_params); + LGAMMA = (double *) free_check_null(LGAMMA); + IPRSNT = (int *) free_check_null(IPRSNT); + spec = (struct species **) free_check_null(spec); + M = (double *) free_check_null(M); + + return OK; +} + +/* ---------------------------------------------------------------------- */ +int set_pz(int initial) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sets initial guesses for unknowns if initial == TRUE + * Revises guesses whether initial is true or not + */ + int i; + struct solution *solution_ptr; +/* + * Set initial log concentrations to zero + */ + iterations = -1; + solution_ptr = use.solution_ptr; + for (i=0; i < count_s_x; i++) { + s_x[i]->lm = LOG_ZERO_MOLALITY; + /*s_x[i]->lg = 0.0;*/ + s_x[i]->lg_pitzer = 0.0; + } +/* + * Set master species activities + */ + + tc_x=solution_ptr->tc; + tk_x=tc_x+273.15; +/* + * H+, e-, H2O + */ + mass_water_aq_x = solution_ptr->mass_water; + mu_x = solution_ptr->mu; + s_h2o->moles = mass_water_aq_x/gfw_water; + s_h2o->la = log10(solution_ptr->ah2o); + AW = pow(10.0, s_h2o->la); + s_hplus->la = - solution_ptr->ph; + s_hplus->lm = s_hplus->la; + s_hplus->moles = exp(s_hplus->lm * LOG_10)*mass_water_aq_x; + s_eminus->la= - solution_ptr->solution_pe; + if (initial == TRUE) initial_guesses(); + if (diffuse_layer_x == TRUE) initial_surface_water(); + revise_guesses(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int initial_guesses(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make initial guesses for activities of master species and + * ionic strength + */ + int i; + struct solution *solution_ptr; + + solution_ptr = use.solution_ptr; + mu_x = s_hplus->moles + exp((solution_ptr->ph - 14.) * LOG_10) * mass_water_aq_x; + mu_x /= mass_water_aq_x; + s_h2o->la=0.0; + for ( i=0; i < count_unknowns; i++ ) { + if (x[i] == ph_unknown || x[i] == pe_unknown ) continue; + if (x[i]->type < CB) { + mu_x += x[i]->moles / mass_water_aq_x * 0.5 * x[i]->master[0]->s->z * + x[i]->master[0]->s->z; + x[i]->master[0]->s->la = log10(x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == CB) { + x[i]->master[0]->s->la = log10(0.001 * x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == SOLUTION_PHASE_BOUNDARY) { + x[i]->master[0]->s->la = log10(0.001 * x[i]->moles/mass_water_aq_x); + } else if (x[i]->type == EXCH) { + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + x[i]->master[0]->s->la = log10(x[i]->moles); + } + } else if (x[i]->type == SURFACE) { + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + x[i]->master[0]->s->la = log10(0.1 * x[i]->moles); + } + } else if (x[i]->type == SURFACE_CB) { + x[i]->master[0]->s->la = 0.0; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int revise_guesses(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Revise molalities species + */ + int i; + int iter, max_iter, repeat, fail; + LDBLE weight, f; + + max_iter = 10; + /* gammas(mu_x);*/ + iter = 0; + repeat = TRUE; + fail = FALSE;; + while ( repeat == TRUE ) { + iter++; + if (debug_set == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nBeginning set iteration %d.\n", iter); + } + if (iter == max_iter + 1) { + output_msg(OUTPUT_LOG, "Did not converge in set, iteration %d.\n", iterations); + fail = TRUE; + } + if (iter > 2*max_iter) { + output_msg(OUTPUT_LOG, "Did not converge with relaxed criteria in set.\n"); + return(OK); + } + molalities(TRUE); + /*pitzer();*/ + /*s_h2o->la = 0.0;*/ + /*molalities(TRUE);*/ + mb_sums(); + if (state < REACTION) { + sum_species(); + } else { + for (i = 0; i < count_unknowns; i++) { + x[i]->sum = x[i]->f; + } + } + /*n + if (debug_set == TRUE) { + pr.species = TRUE; + pr.all = TRUE; + print_species(); + } + */ + repeat=FALSE; + for ( i=0; i < count_unknowns; i++ ) { + if (x[i] == ph_unknown || x[i] == pe_unknown) continue; + if (x[i]->type == MB || +/* x[i]->type == ALK || */ + x[i]->type == CB || + x[i]->type == SOLUTION_PHASE_BOUNDARY || + x[i]->type == EXCH || + x[i]->type == SURFACE ) { + + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\t%5s at beginning of set %d: %e\t%e\t%e\n", x[i]->description, iter, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + if (fabs(x[i]->moles) < 1e-30) x[i]->moles = 0; + f = fabs(x[i]->sum); + if (f == 0 && x[i]->moles == 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + continue; + } else if (f == 0) { + repeat = TRUE; + x[i]->master[0]->s->la += 5; +/*!!!!*/ if (x[i]->master[0]->s->la < -999.) x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else if (fail == TRUE && f < 1.5 * fabs(x[i]->moles)) { + continue; + } else if (f > 1.5 * fabs(x[i]->moles) || f < 1e-5 * fabs(x[i]->moles) ) { + weight = (f < 1e-5 * fabs(x[i]->moles)) ? 0.3 : 1.0; + if (x[i]->moles <= 0) { + x[i]->master[0]->s->la = MIN_RELATED_LOG_ACTIVITY; + } else { + repeat = TRUE; + x[i]->master[0]->s->la += weight * log10(fabs(x[i]->moles / x[i]->sum)); + } + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t%5s not converged in set %d: %e\t%e\t%e\n", x[i]->description, iter, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + } + } else if (x[i]->type == ALK) { + f = total_co2; + if (fail == TRUE && f < 1.5 * fabs(x[i]->moles)) { + continue; + } + if (f > 1.5 * fabs(x[i]->moles) || f < 1e-5 * fabs(x[i]->moles) ) { + repeat = TRUE; + weight = (f < 1e-5 * fabs(x[i]->moles)) ? 0.3 : 1.0; + x[i]->master[0]->s->la += weight * + log10(fabs(x[i]->moles / x[i]->sum)); + if ( debug_set == TRUE ) { + output_msg(OUTPUT_MESSAGE,"%s not converged in set. %e\t%e\t%e\n", x[i]->description, (double) x[i]->sum, (double) x[i]->moles, (double) x[i]->master[0]->s->la); + } + } + } + } + } + output_msg(OUTPUT_LOG,"Iterations in revise_guesses: %d\n", iter); + /*mu_x = mu_unknown->f * 0.5 / mass_water_aq_x;*/ + if (mu_x <= 1e-8) { + mu_x = 1e-8; + } + /*gammas(mu_x);*/ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int jacobian_pz(void) +/* ---------------------------------------------------------------------- */ +{ + double *base; + double d, d1, d2; + int i, j; + + if (full_pitzer == TRUE) { + molalities(TRUE); + pitzer(); + residuals(); + } + base = (LDBLE *) PHRQ_malloc((size_t) count_unknowns * sizeof(LDBLE)); + if (base == NULL) malloc_error(); + for (i = 0; i < count_unknowns; i++) { + base[i] = residual[i]; + } + d = 0.0001; + d1 = d*log(10.0); + d2 = 0; + for (i = 0; i < count_unknowns; i++) { + switch (x[i]->type) { + case MB: + case ALK: + case CB: + case SOLUTION_PHASE_BOUNDARY: + case EXCH: + case SURFACE: + case SURFACE_CB: + x[i]->master[0]->s->la += d; + d2 = d1; + break; + case AH2O: + x[i]->master[0]->s->la += d; + d2 = d1; + break; + case PITZER_GAMMA: + x[i]->s->lg += d; + d2 = d; + break; + case MH2O: + mass_water_aq_x *= (1.0 + d); + x[i]->master[0]->s->moles = mass_water_aq_x/gfw_water; + d2 = log(1.0 + d); + break; + case MU: + case MH: + case PP: + case S_S_MOLES: + continue; + break; + } + molalities(TRUE); + if (full_pitzer == TRUE) pitzer(); + mb_sums(); + residuals(); + for (j = 0; j < count_unknowns; j++) { + array[j*(count_unknowns + 1) + i] = -(residual[j] - base[j])/d2; + } + switch (x[i]->type) { + case MB: + case ALK: + case CB: + case SOLUTION_PHASE_BOUNDARY: + case EXCH: + case SURFACE: + case SURFACE_CB: + case AH2O: + x[i]->master[0]->s->la -= d; + break; + case PITZER_GAMMA: + x[i]->s->lg -= d; + break; + case MH2O: + mass_water_aq_x /= (1 + d); + x[i]->master[0]->s->moles = mass_water_aq_x/gfw_water; + break; + } + } + molalities(TRUE); + if (full_pitzer == TRUE) pitzer(); + mb_sums(); + residuals(); + free_check_null(base); + return OK; +} +/* ---------------------------------------------------------------------- */ +int model_pz(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * model is called after the equations have been set up by prep + * and initial guesses have been made in set. + * + * Here is the outline of the calculation sequence: + * residuals--residuals are calculated, if small we are done + * sum_jacobian--jacobian is calculated + * ineq--inequality solver is called + * reset--estimates of unknowns revised, if changes are small solution + * has been found, usually convergence is found in residuals. + * gammas--new activity coefficients + * molalities--calculate molalities + * mb_sums--calculate mass-balance sums + * mb_gases--decide if gas_phase exists + * mb_s_s--decide if solid_solutions exists + * switch_bases--check to see if new basis species is needed + * reprep--rewrite equations with new basis species if needed + * revise_guesses--revise unknowns to get initial mole balance + * check_residuals--check convergence one last time + * sum_species--calculate sums of elements from species concentrations + * + * An additional pass through may be needed if unstable phases still exist + * in the phase assemblage. + */ + int kode, return_kode; + int r; + int count_infeasible, count_basis_change; + int debug_model_save; + int mass_water_switch_save; + if (svnid == NULL) fprintf(stderr," "); + +/* debug_model = TRUE; */ +/* debug_prep = TRUE; */ +/* debug_set = TRUE; */ + /* mass_water_switch == TRUE, mass of water is constant */ + mass_water_switch_save = mass_water_switch; + if (mass_water_switch_save == FALSE && delay_mass_water == TRUE) { + mass_water_switch = TRUE; + } + debug_model_save = debug_model; + pe_step_size_now = pe_step_size; + step_size_now = step_size; + status(0, NULL); + iterations=0; + gamma_iterations = 0; + count_basis_change = count_infeasible = 0; + stop_program = FALSE; + remove_unstable_phases = FALSE; + if (always_full_pitzer == TRUE) { + full_pitzer = TRUE; + } else { + full_pitzer = FALSE; + } + for (; ; ) { + mb_gases(); + mb_s_s(); + kode = 1; + while ( ( r = residuals() ) != CONVERGED || remove_unstable_phases == TRUE) { +#if defined(PHREEQCI_GUI) + if (WaitForSingleObject(g_hKill /*g_eventKill*/, 0) == WAIT_OBJECT_0) + { + error_msg("Execution canceled by user.", CONTINUE); + RaiseException(USER_CANCELED_RUN, 0, 0, NULL); + } +#endif + iterations++; + if (iterations > itmax - 1 && debug_model == FALSE && pr.logfile == TRUE) { + set_forward_output_to_log(TRUE); + debug_model = TRUE; + } + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nIteration %d\tStep_size = %f\n", + iterations, (double) step_size_now); + output_msg(OUTPUT_MESSAGE,"\t\tPe_step_size = %f\n\n", (double) pe_step_size_now); + } + /* + * Iterations exceeded + */ + if (iterations > itmax ) { + sprintf(error_string,"Maximum iterations exceeded, %d\n",itmax); + warning_msg(error_string); + stop_program = TRUE; + break; + } + /* + * Calculate jacobian + */ + gammas_pz(); + jacobian_sums(); + jacobian_pz(); + /* + * Full matrix with pure phases + */ + if ( r == OK || remove_unstable_phases == TRUE) { + return_kode = ineq(kode); + if ( return_kode != OK ) { + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE, "Ineq had infeasible solution, " + "kode %d, iteration %d\n", + return_kode, iterations); + } + output_msg(OUTPUT_LOG, "Ineq had infeasible solution, " + "kode %d, iteration %d\n", return_kode, iterations); + count_infeasible++; + } + if ( return_kode == 2 ) { + ineq(0); + } + reset(); + } + gammas_pz(); + if (full_pitzer == TRUE) pitzer(); + if (always_full_pitzer == TRUE) { + full_pitzer = TRUE; + } else { + full_pitzer = FALSE; + } + molalities(TRUE); + if(use.surface_ptr != NULL && + use.surface_ptr->diffuse_layer == TRUE && + use.surface_ptr->related_phases == TRUE) + initial_surface_water(); + mb_sums(); + mb_gases(); + mb_s_s(); + /* debug + species_list_sort(); + sum_species(); + print_species(); + print_exchange(); + print_surface(); + */ + if (stop_program == TRUE) { + break; + } + } +/* + * Check for stop_program + */ + + if (stop_program == TRUE) { + break; + } + if (check_residuals() == ERROR) { + stop_program = TRUE; + break; + } + if (remove_unstable_phases == FALSE && mass_water_switch_save == FALSE && + mass_water_switch == TRUE) { + output_msg(OUTPUT_LOG,"\nChanging water switch to FALSE. Iteration %d.\n", iterations); + mass_water_switch = FALSE; + continue; + } + gamma_iterations++; + if (gamma_iterations > itmax ) { + sprintf(error_string,"Maximum gamma iterations exceeded, %d\n", itmax); + warning_msg(error_string); + stop_program = TRUE; + break; + } + if (check_gammas_pz() != TRUE) { + full_pitzer = TRUE; + continue; + } + if (remove_unstable_phases == FALSE) break; + if (debug_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nRemoving unstable phases. Iteration %d.\n", iterations); + } + output_msg(OUTPUT_LOG,"\nRemoving unstable phases. Iteration %d.\n", iterations); + } + output_msg(OUTPUT_LOG,"\nNumber of infeasible solutions: %d\n",count_infeasible); + output_msg(OUTPUT_LOG,"Number of basis changes: %d\n\n",count_basis_change); + output_msg(OUTPUT_LOG,"Number of iterations: %d\n\n", iterations); + debug_model = debug_model_save; + set_forward_output_to_log(FALSE); + if (stop_program == TRUE) { + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int check_gammas_pz(void) +/* ---------------------------------------------------------------------- */ +{ + double old_aw, old_mu, tol; + int converge, i; + + old_mu = mu_x; + old_aw = s_h2o->la; + pitzer(); + molalities(TRUE); + mb_sums(); + converge = TRUE; + tol = convergence_tolerance*10.; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != PITZER_GAMMA) continue; + if (fabs(x[i]->s->lg - x[i]->s->lg_pitzer) > tol) { + converge = FALSE; + } + } + if (fabs(old_mu - mu_x) > tol) converge = FALSE; + if ((pow(10.0,s_h2o->la) - AW) > tol) converge = FALSE; + return converge; +} +/* ---------------------------------------------------------------------- */ +int gammas_pz () +/* ---------------------------------------------------------------------- */ +{ +/* + * Need exchange gammas for pitzer + */ + int i, j; + double coef; + /* Initialize */ +/* + * Calculate activity coefficients + */ + for (i=0; i < count_s_x; i++) { + switch (s_x[i]->gflag) { + case 0: /* uncharged */ + case 1: /* Davies */ + case 2: /* Extended D-H, WATEQ D-H */ + case 3: /* Always 1.0 */ + break; + case 4: /* Exchange */ + /* Now calculated in next loop */ + break; + case 5: /* Always 1.0 */ + break; + case 6: /* Surface */ +/* + * Find moles of sites. + * s_x[i]->equiv is stoichiometric coefficient of sites in species + */ + for (j=1; s_x[i]->rxn_x->token[j].s != NULL; j++) { + if (s_x[i]->rxn_x->token[j].s->type == SURF) { + s_x[i]->alk = s_x[i]->rxn_x->token[j].s->primary->unknown->moles; + break; + } + } + if (s_x[i]->alk > 0) { + s_x[i]->lg = log10(s_x[i]->equiv / s_x[i]->alk); + s_x[i]->dg = 0.0; + } else { + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + } + break; + case 7: /* LLNL */ + break; + case 8: /* LLNL CO2*/ + break; + case 9: /* activity water */ + s_x[i]->lg = log10(exp( s_h2o->la * LOG_10) * gfw_water); + s_x[i]->dg = 0.0; + break; + } +/* + if (mu_unknown != NULL) { + if (fabs(residual[mu_unknown->number]) > 0.1 && + fabs(residual[mu_unknown->number])/mu_x > 0.5) { + s_x[i]->dg = 0.0; + } + } + */ + } + /* + * calculate exchange gammas + */ + + if (use.exchange_ptr != NULL) { + for (i=0; i < count_s_x; i++) { + switch (s_x[i]->gflag) { + case 0: /* uncharged */ + case 1: /* Davies */ + case 2: /* Extended D-H, WATEQ D-H */ + case 3: /* Always 1.0 */ + case 5: /* Always 1.0 */ + case 6: /* Surface */ + case 7: /* LLNL */ + case 8: /* LLNL CO2*/ + case 9: /* activity water */ + break; + case 4: /* Exchange */ + + /* + * Find CEC + * z contains valence of cation for exchange species, alk contains cec + */ + /* !!!!! */ + for (j=1; s_x[i]->rxn_x->token[j].s != NULL; j++) { + if (s_x[i]->rxn_x->token[j].s->type == EX) { + s_x[i]->alk = s_x[i]->rxn_x->token[j].s->primary->unknown->moles; + break; + } + } + /* + * Master species is a dummy variable with meaningless activity and mass + */ + s_x[i]->lg = 0.0; + s_x[i]->dg = 0.0; + if (s_x[i]->primary != NULL) { + break; + } + /* + * All other species + */ + + /* modific 29 july 2005... */ + if (s_x[i]->equiv != 0 && s_x[i]->alk > 0) { + s_x[i]->lg = log10(fabs(s_x[i]->equiv) / s_x[i]->alk); + } + if (use.exchange_ptr->pitzer_exchange_gammas == TRUE) { + /* Assume equal gamma's of solute and exchangeable species... */ + for (j=1; s_x[i]->rxn_x->token[j].s != NULL; j++) { + if (s_x[i]->rxn_x->token[j].s->type == EX) continue; + coef = s_x[i]->rxn_x->token[j].coef; + s_x[i]->lg += coef * s_x[i]->rxn_x->token[j].s->lg; + s_x[i]->dg += coef * s_x[i]->rxn_x->token[j].s->dg; + } + } + } + } + } +/* ...end modific 29 july 2005 */ + + return(OK); +} diff --git a/pitzer.h b/pitzer.h new file mode 100644 index 00000000..46c50843 --- /dev/null +++ b/pitzer.h @@ -0,0 +1,50 @@ +typedef enum { TYPE_B0, TYPE_B1, TYPE_B2, TYPE_C0, TYPE_THETA, TYPE_LAMDA, TYPE_ZETA, TYPE_PSI, TYPE_ETHETA, TYPE_Other } pitz_param_type; + + +PITZER_EXTERNAL double VP, DW0; + +struct pitz_param { + char * species[3]; + int ispec[3]; + pitz_param_type type; + double p; + union {double b0; + double b1; + double b2; + double c0; + double theta; + double lamda; + double zeta; + double psi;} U; + double a[5]; + double alpha; + struct theta_param *thetas; +}; + +PITZER_EXTERNAL struct pitz_param **pitz_params; +PITZER_EXTERNAL int count_pitz_param, max_pitz_param; + + + +/* routines define in pitzer_structures.c */ +PITZER_EXTERNAL struct pitz_param *pitz_param_read (char *string, int n); +PITZER_EXTERNAL int pitz_param_search(struct pitz_param *pzp_ptr); +PITZER_EXTERNAL struct theta_param *theta_param_search(double zj, double zk); +PITZER_EXTERNAL struct theta_param *theta_param_alloc (void); +PITZER_EXTERNAL int theta_param_init (struct theta_param *theta_param_ptr); + + + +/* defined in DW */ +PITZER_EXTERNAL int DW (double T); +PITZER_EXTERNAL double DC (double T); + +struct theta_param { + double zj; + double zk; + double etheta; + double ethetap; +}; +PITZER_EXTERNAL struct theta_param **theta_params; +PITZER_EXTERNAL int count_theta_param, max_theta_param; +PITZER_EXTERNAL double OTEMP; diff --git a/pitzer_structures.cpp b/pitzer_structures.cpp new file mode 100644 index 00000000..e42d13d1 --- /dev/null +++ b/pitzer_structures.cpp @@ -0,0 +1,195 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +#define PITZER_EXTERNAL extern +#include "pitzer.h" + +static char const svnid[] = "$Id: structures.c 269 2005-04-27 19:54:25Z dlpark $"; + + +static struct pitz_param *pitz_param_alloc (void); +static int pitz_param_init (struct pitz_param *pitz_param_ptr); +static struct pitz_param *pitz_param_duplicate(struct pitz_param *old_ptr); +static int pitz_param_copy(struct pitz_param *old_ptr, struct pitz_param *new_ptr); + + +/* ********************************************************************** + * + * Routines related to structure "pitz_param" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct pitz_param *pitz_param_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct pitz_param *pitz_param_ptr; + pitz_param_ptr = (struct pitz_param *) PHRQ_malloc(sizeof (struct pitz_param)); + if (pitz_param_ptr == NULL) malloc_error(); + return ( pitz_param_ptr ); +} +/* ---------------------------------------------------------------------- */ +int pitz_param_init (struct pitz_param *pitz_param_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Frees all data associated with pitz_param structure. + */ + + if (pitz_param_ptr == NULL) return(ERROR); + pitz_param_ptr->species[0] = NULL; + pitz_param_ptr->species[1] = NULL; + pitz_param_ptr->species[2] = NULL; + pitz_param_ptr->ispec[0] = -1; + pitz_param_ptr->ispec[1] = -1; + pitz_param_ptr->ispec[2] = -1; + pitz_param_ptr->type = TYPE_Other; + pitz_param_ptr->p = 0.0; + pitz_param_ptr->U.b0 = 0.0; + for (i = 0; i < 5; i++) { + pitz_param_ptr->a[i] = 0.0; + } + pitz_param_ptr->alpha = 0.0; + pitz_param_ptr->thetas = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct pitz_param *pitz_param_read (char *string, int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read pitzer parameter info from string + * n is number of species (character values) + * + */ + int l, i, j, k; + char *ptr; + char token[2*MAX_LENGTH]; + struct pitz_param pzp, *pzp_ptr; + + if (n != 2 && n != 3) return (NULL); + if (string == NULL) return (NULL); + + pitz_param_init(&pzp); + ptr = string; + if (copy_token(token, &ptr, &l) == EMPTY) return(NULL); + ptr = string; + for (i = 0; i < n; i++) { + if (copy_token(token, &ptr, &l) == EMPTY) return(NULL); + pzp.species[i] = string_hsave(token); + } + k = 0; + for (i = 0; i < 5; i++) { + if (copy_token(token, &ptr, &l) == EMPTY) break; + j=sscanf(token,"%le", &pzp.a[i]); + if (j <= 0) break; + k++; + } + if (k <= 0) return(NULL); + pzp_ptr = pitz_param_duplicate(&pzp); + return ( pzp_ptr); +} +/* ---------------------------------------------------------------------- */ +struct pitz_param *pitz_param_duplicate(struct pitz_param *old_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Allocates space and makes duplicate copy of pitz_param structure + */ + struct pitz_param *new_ptr; + + new_ptr = pitz_param_alloc(); + pitz_param_init(new_ptr); +/* + * Copy data + */ + pitz_param_copy(old_ptr, new_ptr); + return(new_ptr); +} +/* ---------------------------------------------------------------------- */ +int pitz_param_copy(struct pitz_param *old_ptr, + struct pitz_param *new_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies pitz_param data from old_ptr to new location, new_ptr. + * Space for the new_ptr structure must already be malloced. + */ +/* + * Store data for structure pitz_param + */ + memcpy(new_ptr, old_ptr, sizeof(struct pitz_param)); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pitz_param_search(struct pitz_param *pzp_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Does linear search of pitz_params for same type and species + * Returns -1 if not found, index number in pitz_params if found + */ + int i; + if (pzp_ptr == NULL) return -1; + if (pzp_ptr->type == TYPE_Other) return -1; + for (i = 0; i < count_pitz_param; i++) { + if (pitz_params[i]->type == pzp_ptr->type && + pitz_params[i]->species[0] == pzp_ptr->species[0] && + pitz_params[i]->species[1] == pzp_ptr->species[1] && + pitz_params[i]->species[2] == pzp_ptr->species[2] ) { + break; + } + } + if (i >= count_pitz_param) { + return -1; + } + return i; +} +/* ********************************************************************** + * + * Routines related to structure "theta_parm" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct theta_param *theta_param_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct theta_param *theta_param_ptr; + theta_param_ptr = (struct theta_param *) PHRQ_malloc(sizeof (struct theta_param)); + if (theta_param_ptr == NULL) malloc_error(); + return ( theta_param_ptr ); +} +/* ---------------------------------------------------------------------- */ +int theta_param_init (struct theta_param *theta_param_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees all data associated with theta_param structure. + */ + + if (theta_param_ptr == NULL) return(ERROR); + theta_param_ptr->zj = 0; + theta_param_ptr->zk = 0; + theta_param_ptr->etheta = 0; + theta_param_ptr->ethetap = 0; + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct theta_param *theta_param_search(double zj, double zk) +/* ---------------------------------------------------------------------- */ +{ +/* + * Does linear search of theta_params for same charge + * Returns NULL if not found, index number in theta_params if found + */ + int i; + for (i = 0; i < count_theta_param; i++) { + if ((theta_params[i]->zj == zj && theta_params[i]->zk == zk) || + (theta_params[i]->zj == zk && theta_params[i]->zk == zj)) { + return theta_params[i]; + } + } + return NULL; +} diff --git a/prep.cpp b/prep.cpp new file mode 100644 index 00000000..880aa76d --- /dev/null +++ b/prep.cpp @@ -0,0 +1,4055 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: prep.c 655 2005-11-14 23:06:29Z dlpark $"; + +static int add_potential_factor(void); +static int add_surface_charge_balance(void); +static int build_gas_phase(void); +static int build_jacobian_sums (int k); +static int build_mb_sums(void); +static int build_min_exch(void); +static int build_model(void); +static int build_pure_phases(void); +static int build_s_s_assemblage(void); +static int build_solution_phase_boundaries(void); +static int build_species_list(int n); +static int build_min_surface(void); +static int change_hydrogen_in_elt_list(LDBLE charge); +static int clear (void); +static int convert_units(struct solution *solution_ptr); +static struct unknown *find_surface_charge_unknown(char *str_ptr); +static struct master **get_list_master_ptrs(char *ptr, struct master *master_ptr); +static int inout(void); +static int is_special(struct species *spec); +static int mb_for_species_aq(int n); +static int mb_for_species_ex(int n); +static int mb_for_species_surf(int n); +static int quick_setup (void); +static int resetup_master (void); +static int save_model(void); +static int setup_exchange (void); +static int setup_gas_phase(void); +static int setup_master_rxn(struct master **master_ptr_list, struct reaction **pe_rxn); +static int setup_pure_phases(void); +static int setup_related_surface (void); +static int setup_s_s_assemblage(void); +static int setup_solution (void); +static int setup_surface (void); +static int setup_unknowns (void); +static int store_dn (int k, LDBLE *source, int row, LDBLE coef_in, LDBLE *gamma_source); +static int store_jacob(LDBLE *source, LDBLE *target, LDBLE coef); +static int store_jacob0(int row, int column, LDBLE coef); +int store_mb(LDBLE *source, LDBLE *target, LDBLE coef); +static int store_mb_unknowns(struct unknown *unknown_ptr, LDBLE *LDBLE_ptr, LDBLE coef, LDBLE *gamma_ptr); +static int store_sum_deltas(LDBLE *source, LDBLE *target, LDBLE coef); +static int tidy_redox (void); +static struct master **unknown_alloc_master(void); +static int write_mb_eqn_x (void); +static int write_mb_for_species_list (int n); +static int write_mass_action_eqn_x (int stop); + +/* ---------------------------------------------------------------------- */ +int prep(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Input is model defined by the structure use. + * Most of routine is skipped if model, as defined by master.total + * plus use.pure_phases, is same as previous calculation. + * Routine sets up struct unknown for each unknown. + * Determines elements, species, and phases that are in the model. + * Calculates mass-action equations for each species and phase. + * Routine builds a set of lists for calculating mass balance and + * for building jacobian. + */ + struct solution *solution_ptr; + if (svnid == NULL) fprintf(stderr," "); + + if (state >= REACTION) { + same_model = check_same_model(); + } else { + same_model = FALSE; + last_model.force_prep = TRUE; + } + /*same_model = FALSE;*/ +/* + * Initialize s, master, and unknown pointers + */ + solution_ptr = use.solution_ptr; + if (solution_ptr == NULL) { + error_msg("Solution needed for calculation not found, stopping.", STOP); + } + description_x = (char *) free_check_null(description_x); + description_x = string_duplicate(solution_ptr->description); +/* + * Allocate space for unknowns + * Must allocate all necessary space before pointers to + * X are set. + */ + + if (same_model == FALSE) { + clear(); + setup_unknowns(); +/* + * Set unknown pointers, unknown types, validity checks + */ + if (state == INITIAL_SOLUTION) convert_units(solution_ptr); + setup_solution(); + setup_exchange(); + setup_surface(); + setup_pure_phases(); + setup_gas_phase(); + setup_s_s_assemblage(); + setup_related_surface(); + tidy_redox(); + if (input_error > 0) { + error_msg("Program terminating due to input errors.", STOP); + } +/* + * Allocate space for array + */ +/* + array = (LDBLE *) PHRQ_malloc( (size_t) (count_unknowns+1) * count_unknowns * sizeof( LDBLE )); + if (array == NULL) malloc_error(); + delta = (LDBLE *) PHRQ_malloc( (size_t) count_unknowns * sizeof( LDBLE )); + if (delta == NULL) malloc_error(); + residual = (LDBLE *) PHRQ_malloc( (size_t) count_unknowns * sizeof( LDBLE )); + if (residual == NULL) malloc_error(); +*/ + array = (LDBLE *) PHRQ_malloc( (size_t) (max_unknowns+1) * max_unknowns * sizeof( LDBLE )); + if (array == NULL) malloc_error(); + delta = (LDBLE *) PHRQ_malloc( (size_t) max_unknowns * sizeof( LDBLE )); + if (delta == NULL) malloc_error(); + residual = (LDBLE *) PHRQ_malloc( (size_t) max_unknowns * sizeof( LDBLE )); + if (residual == NULL) malloc_error(); +/* + * Build lists to fill Jacobian array and species list + */ + build_model(); + } else { +/* + * If model is same, just update masses, don't rebuild unknowns and lists + */ + quick_setup(); + } + if (input_error > 0) { + error_msg("Program stopping due to input errors.", STOP); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int quick_setup (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Routine is used if model is the same as previous model + * Assumes moles of elements, exchangers, surfaces, gases, and solid solutions have + * been accumulated in array master, usually by subroutine step. + * Updates essential information for the model. + */ + int i, j, k, l; + + for (i = 0; i < count_master; i++) { + if (master[i]->s->type == SURF_PSI) continue; + if (master[i]->s == s_eminus || + master[i]->s == s_hplus || + master[i]->s == s_h2o || + master[i]->s == s_h2 || + master[i]->s == s_o2) continue; + if(master[i]->total > 0) { + if (master[i]->s->secondary != NULL) { + master[i]->s->secondary->unknown->moles = master[i]->total; + } else { + master[i]->unknown->moles = master[i]->total; + } + } + } +/* + * Reaction: pH for charge balance + */ + ph_unknown->moles = use.solution_ptr->cb; +/* + * Reaction: pe for total hydrogen + */ + if (mass_hydrogen_unknown != NULL) { +#define COMBINE + /*#define COMBINE_CHARGE*/ +#ifdef COMBINE +#ifndef COMBINE_CHARGE + mass_hydrogen_unknown->moles = use.solution_ptr->total_h - 2 * use.solution_ptr->total_o; +#else + mass_hydrogen_unknown->moles = use.solution_ptr->total_h - 2 * use.solution_ptr->total_o - use.solution_ptr->cb; +#endif +#else + mass_hydrogen_unknown->moles = use.solution_ptr->total_h; +#endif + } +/* + * Reaction H2O for total oxygen + */ + if (mass_oxygen_unknown != NULL) { + mass_oxygen_unknown->moles = use.solution_ptr->total_o; + } + +/* + * pp_assemblage + */ + j = 0; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == PP) { + x[i]->moles = use.pp_assemblage_ptr->pure_phases[j].moles; + x[i]->dissolve_only = use.pp_assemblage_ptr->pure_phases[j].dissolve_only; + use.pp_assemblage_ptr->pure_phases[j].delta = 0.0; + x[i]->pure_phase = &(use.pp_assemblage_ptr->pure_phases[j]); + j++; + } + } +/* + * gas phase + */ + if (gas_unknown != NULL) { + gas_unknown->moles = 0.0; + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + gas_unknown->moles += use.gas_phase_ptr->comps[i].moles; + } + if (gas_unknown->moles <= 0) gas_unknown->moles = MIN_TOTAL; + gas_unknown->ln_moles = log(gas_unknown->moles); + gas_unknown->gas_phase = use.gas_phase_ptr; + } +/* + * s_s_assemblage + */ + if (s_s_unknown != NULL) { + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == S_S_MOLES) break; + } + for (j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (k = 0; k < use.s_s_assemblage_ptr->s_s[j].count_comps; k++) { + x[i]->s_s = &(use.s_s_assemblage_ptr->s_s[j]); + x[i]->s_s_comp = &(use.s_s_assemblage_ptr->s_s[j].comps[k]); + x[i]->s_s_comp_number = j; + x[i]->moles = x[i]->s_s_comp->moles; + if (x[i]->moles <= 0) { + x[i]->moles = MIN_TOTAL; + x[i]->s_s_comp->moles = MIN_TOTAL; + } + x[i]->s_s_comp->initial_moles = x[i]->moles; + x[i]->ln_moles = log(x[i]->moles); + + x[i]->phase->dn = x[i]->s_s_comp->dn; + x[i]->phase->dnb = x[i]->s_s_comp->dnb; + x[i]->phase->dnc = x[i]->s_s_comp->dnc; + x[i]->phase->log10_fraction_x = x[i]->s_s_comp->log10_fraction_x; + x[i]->phase->log10_lambda = x[i]->s_s_comp->log10_lambda; + i++; + } + } + } +/* + * exchange + */ + if (use.exchange_ptr != NULL) { + k = 0; + for (i = 0 ; i < count_unknowns; i++) { + if (x[i]->type == EXCH) { + x[i]->exch_comp = &(use.exchange_ptr->comps[k++]); + if (x[i]->exch_comp->rate_name != NULL) { + for (l = 0; x[i]->exch_comp->totals[l].elt != NULL; l++) { + if (x[i]->exch_comp->totals[l].elt->master->type != EX) continue; + if (strcmp_nocase(x[i]->description, x[i]->exch_comp->totals[l].elt->name) == 0) { + x[i]->moles = x[i]->exch_comp->totals[l].coef; +/* printf("%s moles %e\n", x[i]->description, x[i]->moles); */ + break; + } + } + } + +#ifdef SKIP + if (count_kin_exch > 0) { + for (l = 0; x[i]->exch_comp->totals[l].elt != NULL; l++) { + if (x[i]->exch_comp->totals[l].elt->master->type != EX) continue; + if (strcmp_nocase(x[i]->description, x[i]->exch_comp->totals[l].elt->name) == 0) { + x[i]->moles = x[i]->exch_comp->totals[l].coef; +/* printf("%s moles %e\n", x[i]->description, x[i]->moles); */ + } + } + } +#endif + } + } + } +/* + * surface + */ + if (use.surface_ptr != NULL) { + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == SURFACE) { + break; + } + } + j = 0; + k = 0; + for ( ; i < count_unknowns; i++) { + if (x[i]->type == SURFACE_CB) { + x[i]->surface_charge = &(use.surface_ptr->charge[j]); + x[i]->related_moles = x[i]->surface_charge->grams; + x[i]->mass_water = use.surface_ptr->charge[j++].mass_water; + x[i]->surface_comp = x[i-1]->surface_comp; + /* moles picked up from master->total */ + } else if (x[i]->type == SURFACE) { + x[i]->surface_comp = &(use.surface_ptr->comps[k++]); + /* moles picked up from master->total + except for surfaces related to kinetic minerals ... */ + if (x[i]->surface_comp->rate_name != NULL) { + for (l = 0; x[i]->surface_comp->totals[l].elt != NULL; l++) { + if (x[i]->surface_comp->totals[l].elt->master->type != SURF) continue; + if (strcmp_nocase(x[i]->description, x[i]->surface_comp->totals[l].elt->name) == 0) { + x[i]->moles = x[i]->surface_comp->totals[l].coef; + /* printf("%s moles %e\n", x[i]->description, x[i]->moles); */ + } + } + } +/* !!!! */ +#ifdef SKIP + if (count_kin_surf > 0) { + for (l = 0; x[i]->surface_comp->totals[l].elt != NULL; l++) { + if (x[i]->surface_comp->totals[l].elt->master->type != SURF) continue; + + if (strcmp_nocase(x[i]->description, x[i]->surface_comp->totals[l].elt->name) == 0) { + x[i]->moles = x[i]->surface_comp->totals[l].coef; +/* printf("%s moles %e\n", x[i]->description, x[i]->moles); */ + } + } + } +#endif + } else { + break; + } + + } + } + save_model(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Put coefficients into lists to sum iaps to test for equilibrium + * Put coefficients into lists to build jacobian for + * sum of partial pressures equation and + * mass balance equations for elements contained in gases + */ + int i, j; + int row, col; + struct master *master_ptr; + struct rxn_token *rxn_ptr; + struct gas_comp *gas_comp_ptr; + struct phase *phase_ptr; + struct unknown *unknown_ptr; + LDBLE coef, coef_elt; + + if (gas_unknown == NULL) return(OK); + for (i = 0; i < use.gas_phase_ptr->count_comps; i++) { +/* + * Determine elements in gas component + */ + count_elts = 0; + paren_count = 0; + gas_comp_ptr = &(use.gas_phase_ptr->comps[i]); + phase_ptr = gas_comp_ptr->phase; + if (phase_ptr->rxn_x == NULL) continue; + add_elt_list(phase_ptr->next_elt, 1.0); +#ifdef COMBINE + change_hydrogen_in_elt_list(0); +#endif +/* + * Build mass balance sums for each element in gas + */ + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\tMass balance summations %s.\n\n", + gas_comp_ptr->phase->name); + } + + /* All elements in gas */ + for (j = 0; j < count_elts; j++) { + unknown_ptr = NULL; + if (strcmp(elt_list[j].elt->name,"H") == 0) { + unknown_ptr = mass_hydrogen_unknown; + } else if (strcmp(elt_list[j].elt->name,"O") == 0) { + unknown_ptr = mass_oxygen_unknown; + } else { + if (elt_list[j].elt->primary->in == TRUE) { + unknown_ptr = elt_list[j].elt->primary->unknown; + } else if (elt_list[j].elt->primary->s->secondary != NULL) { + unknown_ptr = elt_list[j].elt->primary->s->secondary->unknown; + } + } + if (unknown_ptr != NULL) { + coef = elt_list[j].coef; + store_mb(&(gas_comp_ptr->phase->moles_x), &(unknown_ptr->f), coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\n", + unknown_ptr->description, + (double) coef); + } + } + } + if (use.gas_phase_ptr->type == PRESSURE) { + /* Total pressure of gases */ + store_mb(&(gas_comp_ptr->phase->p_soln_x), &(gas_unknown->f), 1.0); + } +/* + * Build jacobian sums for mass balance equations + */ + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\tJacobian summations %s.\n\n", + phase_ptr->name); + } + for (j = 0; j < count_elts; j++) { + unknown_ptr = NULL; + if (strcmp(elt_list[j].elt->name,"H") == 0) { + unknown_ptr = mass_hydrogen_unknown; + } else if (strcmp(elt_list[j].elt->name,"O") == 0) { + unknown_ptr = mass_oxygen_unknown; + } else { + if (elt_list[j].elt->primary->in == TRUE) { + unknown_ptr = elt_list[j].elt->primary->unknown; + } else if (elt_list[j].elt->primary->s->secondary != NULL) { + unknown_ptr = elt_list[j].elt->primary->s->secondary->unknown; + } + } + if (unknown_ptr == NULL) { +#ifdef SKIP + error_msg("NULL pointer in subroutine build_gas_phase.", STOP); +#endif + continue; + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\t%s.\n", + unknown_ptr->description); + } + row = unknown_ptr->number * (count_unknowns + 1); + coef_elt = elt_list[j].coef; + for (rxn_ptr = phase_ptr->rxn_x->token+1; + rxn_ptr->s != NULL; rxn_ptr++) { + + if (rxn_ptr->s->secondary != NULL && rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if (master_ptr == NULL) { + sprintf(error_string, "Element needed for gas component, %s, is not in model.", phase_ptr->name); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\n",master_ptr->s->name); + } + if (master_ptr->unknown == NULL) { +#ifdef SKIP + input_error++; +#endif + continue; + } + if (master_ptr->in == FALSE ) { + sprintf(error_string, "Element, %s, in phase, %s, is not in model.", master_ptr->elt->name, phase_ptr->name); + error_msg(error_string, CONTINUE); + input_error++; + } + col = master_ptr->unknown->number; + coef = coef_elt * rxn_ptr->coef; + store_jacob (&(gas_comp_ptr->phase->moles_x), &(array[row + col]), coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n",master_ptr->s->name, (double) coef, row/(count_unknowns+1), col); + } + } + if (use.gas_phase_ptr->type == PRESSURE) { + /* derivative wrt total moles of gas */ + store_jacob (&(gas_comp_ptr->phase->fraction_x), &(array[row + gas_unknown->number]), coef_elt); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n","gas moles", (double) elt_list[j].coef, row/(count_unknowns+1), gas_unknown->number); + } + } + } +/* + * Build jacobian sums for sum of partial pressures equation + */ + if (use.gas_phase_ptr->type != PRESSURE) continue; + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\tPartial pressure eqn %s.\n\n", + phase_ptr->name); + } + unknown_ptr = gas_unknown; + row = unknown_ptr->number * (count_unknowns + 1); + for (rxn_ptr = phase_ptr->rxn_x->token+1; + rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s->secondary != NULL && rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\n",master_ptr->s->name); + } + if (master_ptr->unknown == NULL) { +#ifdef SKIP + input_error++; +#endif + continue; + } + if (master_ptr->in == FALSE ) { + sprintf(error_string, "Element, %s, in phase, %s, is not in model.", master_ptr->elt->name, phase_ptr->name); + error_msg(error_string, CONTINUE); + input_error++; + } + col = master_ptr->unknown->number; + coef = rxn_ptr->coef; + store_jacob (&(gas_comp_ptr->phase->p_soln_x), &(array[row + col]), coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n",master_ptr->s->name, (double) coef, + row/(count_unknowns+1), col); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_s_s_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Put coefficients into lists to sum iaps to test for equilibrium + * Put coefficients into lists to build jacobian for + * mass action equation for component + * mass balance equations for elements contained in solid solutions + */ + int i, j, k, l, stop; + int row, col; + struct master *master_ptr; + struct rxn_token *rxn_ptr; + struct s_s *s_s_ptr, *s_s_ptr_old; + char token[MAX_LENGTH]; + char *ptr; + + if (s_s_unknown == NULL) return(OK); + s_s_ptr_old = NULL; + col = 0; + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != S_S_MOLES) continue; + s_s_ptr = x[i]->s_s; + if (s_s_ptr != s_s_ptr_old) { + col = x[i]->number; + s_s_ptr_old = s_s_ptr; + } +/* + * Calculate function value (inverse saturation index) + */ + if (x[i]->phase->rxn_x == NULL) continue; + store_mb(&(x[i]->phase->lk), &(x[i]->f), 1.0); + for (rxn_ptr = x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + store_mb(&(rxn_ptr->s->la), &(x[i]->f), -rxn_ptr->coef); + } + /* include mole fraction */ + store_mb(&(x[i]->phase->log10_fraction_x), &(x[i]->f), 1.0); + + /* include activity coeficient */ + store_mb(&(x[i]->phase->log10_lambda), &(x[i]->f), 1.0); +/* + * Put coefficients into mass action equations + */ + /* first IAP terms */ + for (rxn_ptr=x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s->secondary != NULL && + rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if (master_ptr == NULL || master_ptr->unknown == NULL) continue; + store_jacob0(x[i]->number, master_ptr->unknown->number, rxn_ptr->coef); + } + + if (s_s_ptr->a0 != 0.0 || s_s_ptr->a1 != 0.0) { +/* + * For binary solid solution + */ + /* next dnc terms */ + row = x[i]->number * (count_unknowns + 1); + if (x[i]->s_s_comp_number == 0) { + col = x[i]->number; + } else { + col = x[i]->number -1; + } + store_jacob (&(x[i]->phase->dnc), &(array[row + col]), -1); + + /* next dnb terms */ + col++; + store_jacob (&(x[i]->phase->dnb), &(array[row + col]), -1); + } else { +/* + * For ideal solid solution + */ + row = x[i]->number * (count_unknowns + 1); + for (j = 0; j < s_s_ptr->count_comps; j++) { + if (j != x[i]->s_s_comp_number) { +/* store_jacob (&(s_s_ptr->dn), &(array[row + col + j]), -1.0); */ + store_jacob (&(x[i]->phase->dn), &(array[row + col + j]), -1.0); + } else { + store_jacob (&(x[i]->phase->dnb), &(array[row + col + j]), -1.0); + } + } + } +/* + * Put coefficients into mass balance equations + */ + count_elts = 0; + paren_count = 0; + strcpy(token, x[i]->phase->formula); + ptr = token; + get_elts_in_species (&ptr, 1.0); +/* + * Go through elements in phase + */ +#ifdef COMBINE + change_hydrogen_in_elt_list(0); +#endif + for (j = 0; j < count_elts; j++) { + + if (strcmp(elt_list[j].elt->name, "H") == 0 && mass_hydrogen_unknown != NULL) { + store_jacob0(mass_hydrogen_unknown->number, x[i]->number, -elt_list[j].coef); + store_sum_deltas(&(delta[i]), &mass_hydrogen_unknown->delta, elt_list[j].coef); + + } else if (strcmp(elt_list[j].elt->name, "O") == 0 && mass_oxygen_unknown != NULL) { + store_jacob0(mass_oxygen_unknown->number, x[i]->number, -elt_list[j].coef); + store_sum_deltas(&(delta[i]), &mass_oxygen_unknown->delta, elt_list[j].coef); + + } else { + master_ptr = elt_list[j].elt->primary; + if (master_ptr->in == FALSE) { + master_ptr = master_ptr->s->secondary; + } + if (master_ptr == NULL || master_ptr->in == FALSE) { + if (state != ADVECTION && state != TRANSPORT && state != PHAST ) { + sprintf(error_string, "Element in phase, %s, is not in model.", x[i]->phase->name); + warning_msg(error_string); + } + if (master_ptr != NULL) { + master_ptr->s->la = -999.9; + } +/* + * Master species is in model + */ + } else if (master_ptr->in == TRUE ) { + store_jacob0(master_ptr->unknown->number, x[i]->number, + -elt_list[j].coef); + store_sum_deltas(&delta[i], &master_ptr->unknown->delta, elt_list[j].coef); +/* + * Master species in equation needs to be rewritten + */ + } else if (master_ptr->in == REWRITE ) { + stop = FALSE; + for (k=0; k < count_unknowns; k++) { + if (x[k]->type != MB) continue; + for (l = 0; x[k]->master[l] != NULL; l++) { + if (x[k]->master[l] == master_ptr) { + store_jacob0(x[k]->master[0]->unknown->number, x[i]->number, + -elt_list[j].coef); + store_sum_deltas(&delta[i], &x[k]->master[0]->unknown->delta, + elt_list[j].coef); + stop = TRUE; + break; + } + } + if (stop == TRUE) break; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_jacobian_sums (int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function builds lists sum_jacob1 and sum_jacob2 that describe how to sum molalities + * to form jacobian. + */ + int i, j, kk; + int count_g; + LDBLE coef; + LDBLE *source, *target; + + if (debug_prep == TRUE) output_msg(OUTPUT_MESSAGE,"\n\tJacobian summations.\n"); +/* + * Calculate jacobian coefficients for each mass balance equation + */ + for (i = 0; i < count_mb_unknowns; i++) { +#ifdef SKIP + /* switch for mu term */ + if (diffuse_layer_x == TRUE && ((mb_unknowns[i].unknown == charge_balance_unknown) || + (mb_unknowns[i].unknown == ah2o_unknown) || + (mb_unknowns[i].unknown == mu_unknown))) { + use_tot_g = 1; + } else if (diffuse_layer_x == TRUE && mb_unknowns[i].unknown->type == SURFACE_CB) { + use_tot_g = 2; + } else { + use_tot_g = 0; + } +#endif +/* + * Store d(moles) for a mass balance equation + */ + /* initial solution only */ + if (mb_unknowns[i].unknown->type == SOLUTION_PHASE_BOUNDARY) { + continue; + } + coef = mb_unknowns[i].coef; + if (debug_prep == TRUE) output_msg(OUTPUT_MESSAGE,"\n\tMass balance eq: %s\t%f\n", + mb_unknowns[i].unknown->description, (double) coef); + store_dn(k, mb_unknowns[i].source, mb_unknowns[i].unknown->number, coef, mb_unknowns[i].gamma_source); +/* + * Add extra terms for change in dg/dx in diffuse layer model + */ + if (s[k]->type >= H2O || diffuse_layer_x == FALSE) { + continue; + } else if ( (mb_unknowns[i].unknown->type == MB || + mb_unknowns[i].unknown->type == MH || + mb_unknowns[i].unknown->type == MH2O) && state >= REACTION) { + if (mass_oxygen_unknown != NULL) { + /* term for water, sum of all surfaces */ + source = &s[k]->tot_dh2o_moles; + target = &(array[mb_unknowns[i].unknown->number * (count_unknowns + 1) + mass_oxygen_unknown->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", "sum[dn(i,s)/dlnwater]", (double) coef, + mb_unknowns[i].unknown->number, mass_oxygen_unknown->number); + } + } + + /* terms for psi, one for each surface */ + count_g = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + source = &s[k]->diff_layer[count_g].dx_moles; + target = &(array[mb_unknowns[i].unknown->number * + (count_unknowns + 1) + + x[j]->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + "dg/dlny", (double) coef, + mb_unknowns[i].unknown->number, + x[j]->number); + } + count_g++; + if (count_g >= use.surface_ptr->count_charge) break; + } + + /* terms for related phases */ + count_g = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + + /* has related phase */ + if (x[j-1]->surface_comp->phase_name == NULL) continue; + + /* now find the related phase */ + for (kk = count_unknowns - 1; kk >= 0; kk--) { + if (x[kk]->type != PP) continue; + if (x[kk]->phase->name == x[j-1]->surface_comp->phase_name) break; + } + + if (kk >= 0) { + source = &s[k]->diff_layer[count_g].drelated_moles; + target = &(array[mb_unknowns[i].unknown->number * + (count_unknowns + 1) + + x[kk]->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + "dphase", (double) coef, + mb_unknowns[i].unknown->number, + x[kk]->number); + } + } + count_g++; + if (count_g >= use.surface_ptr->count_charge) break; + } + + } else if (mb_unknowns[i].unknown->type == SURFACE_CB) { + count_g = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + if (mb_unknowns[i].unknown->number == x[j]->number) { + source = &s[k]->diff_layer[count_g].dx_moles; + target = &(array[mb_unknowns[i].unknown->number * + (count_unknowns + 1) + + x[j]->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + "dg/dlny", (double) coef, + mb_unknowns[i].unknown->number, + x[j]->number); + } + + /* term for related phase */ + /* has related phase */ + if (x[j-1]->surface_comp->phase_name != NULL) { + + /* now find the related phase */ + for (kk = count_unknowns - 1; kk >= 0; kk--) { + if (x[kk]->type != PP) continue; + if (x[kk]->phase->name == x[j-1]->surface_comp->phase_name) break; + } + if (kk >= 0) { + source = &s[k]->diff_layer[count_g].drelated_moles; + target = &(array[mb_unknowns[i].unknown->number * + (count_unknowns + 1) + + x[kk]->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + "dphase", (double) coef, + mb_unknowns[i].unknown->number, + x[kk]->number); + } + } + } + + if (mass_oxygen_unknown != NULL) { + /* term for water, for same surfaces */ + source = &s[k]->diff_layer[count_g].dh2o_moles; + target = &(array[mb_unknowns[i].unknown->number * + (count_unknowns + 1) + mass_oxygen_unknown->number]); + store_jacob(source, target, coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + "dn(i,s)/dlnwater", (double) coef, + mb_unknowns[i].unknown->number, + mass_oxygen_unknown->number); + } + } + break; + } + count_g++; + if (count_g >= use.surface_ptr->count_charge) break; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_mb_sums(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function builds lists sum_mb1 and sum_mb2 that describe how to sum molalities + * to calculate mass balance sums, including activity of water, ionic strength, + * charge balance, and alkalinity. + */ + int i; + LDBLE *target; +/* + * Make space for lists + */ + if (count_sum_mb1 + count_mb_unknowns >= max_sum_mb1) { + space ((void **) ((void *) &sum_mb1), count_sum_mb1 + count_mb_unknowns, + &max_sum_mb1, sizeof(struct list1)); + } + if (count_sum_mb2 + count_mb_unknowns >= max_sum_mb2) { + space ((void **) ((void *) &sum_mb2), count_sum_mb2 + count_mb_unknowns, + &max_sum_mb2, sizeof(struct list2)); + } + + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\n\tMass balance summations.\n\n"); + } + for (i = 0; i < count_mb_unknowns; i++) { + target = &(mb_unknowns[i].unknown->f); + store_mb(mb_unknowns[i].source, target, mb_unknowns[i].coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\n", + mb_unknowns[i].unknown->description, + (double) mb_unknowns[i].coef); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_model(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Guts of prep. Determines species in model, rewrites equations, + * builds lists for mass balance and jacobian sums. + */ + int i, j, j0, k; + LDBLE coef_e; + + if (s_hplus == NULL || s_eminus == NULL || s_h2o == NULL) { + error_msg("Data base is missing H+, H2O, or e- species.", CONTINUE); + input_error++; + } +/* + * Make space for lists of pointers to species in the model + */ + + max_s_x = MAX_S; + space ((void **) ((void *) &s_x), INIT, &max_s_x, sizeof(struct species *)); + + max_sum_mb1=MAX_SUM_MB; + count_sum_mb1=0; + space ((void **) ((void *) &sum_mb1), INIT, &max_sum_mb1, sizeof(struct list1)); + + max_sum_mb2=MAX_SUM_MB; + count_sum_mb2=0; + space ((void **) ((void *) &sum_mb2), INIT, &max_sum_mb2, sizeof(struct list2)); + + max_sum_jacob0=MAX_SUM_JACOB0; + count_sum_jacob0=0; + space ((void **) ((void *) &sum_jacob0), INIT, &max_sum_jacob0, + sizeof(struct list0)); + + max_sum_jacob1=MAX_SUM_JACOB1; + count_sum_jacob1=0; + space ((void **) ((void *) &sum_jacob1), INIT, &max_sum_jacob1, + sizeof(struct list1)); + + max_sum_jacob2=MAX_SUM_JACOB2; + count_sum_jacob2=0; + space ((void **) ((void *) &sum_jacob2), INIT, &max_sum_jacob2, + sizeof(struct list2)); + + + max_sum_delta=MAX_SUM_JACOB0; + count_sum_delta=0; + space ((void **) ((void *) &sum_delta), INIT, &max_sum_delta, + sizeof(struct list2)); + + max_species_list = 5 * MAX_S; + count_species_list = 0; + species_list = (struct species_list *) free_check_null(species_list); + space ((void **) ((void *) &species_list), INIT, &max_species_list, + sizeof (struct species_list)); + +/* + * Pick species in the model, determine reaction for model, build jacobian + */ + count_s_x=0; + compute_gfw("H2O", &gfw_water); + gfw_water *= 0.001; + for (i=0; i < count_s; i++) { + if (s[i]->type > H2O && s[i]->type != EX && s[i]->type != SURF) continue; + s[i]->in=FALSE; + count_trxn=0; + trxn_add (s[i]->rxn_s, 1.0, FALSE); /* rxn_s is set in tidy_model */ +/* + * Check if species is in model + */ + s[i]->in = inout(); + if (s[i]->in == TRUE) { + /* for isotopes, activity of water is for 1H and 16O */ + if (s[i]->gflag == 9 ) { + gfw_water = 18.0/1000.0; + } + if (pitzer_model == FALSE) s[i]->lg = 0.0; + if (count_s_x + 1 >= max_s_x) { + space ((void **) ((void *) &s_x), count_s_x + 1, + &max_s_x, + sizeof (struct species *)); + } + s_x[count_s_x++] = s[i]; +/* + * Write mass action equation for current model + */ + write_mass_action_eqn_x(STOP); + if (s[i]->type == SURF) { + add_potential_factor(); + } + rxn_free(s[i]->rxn_x); + s[i]->rxn_x = rxn_alloc(count_trxn+1); + trxn_copy (s[i]->rxn_x); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\nSpecies: %s\n", s[i]->name); + trxn_print(); + } +/* + * Determine mass balance equations, build sums for mass balance, build sums for jacobian + */ + count_trxn=0; + trxn_add (s[i]->rxn_s, 1.0, FALSE); + if (s[i]->next_secondary == NULL) { + write_mb_eqn_x(); + } else { + count_elts = 0; + add_elt_list(s[i]->next_secondary, 1.0); + } + if (s[i]->type == SURF) { + add_potential_factor(); + add_surface_charge_balance(); + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"%s\n", trxn.token[0].s->name); + for (j = 0; j < count_elts; j++) { + output_msg(OUTPUT_MESSAGE,"\t%s\t%f\n", elt_list[j].elt->name, (double) elt_list[j].coef); + } + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\nSpecies: %s\n", s[i]->name); + trxn_print(); + } + if (s[i]->type < EMINUS) { + mb_for_species_aq(i); + } else if (s[i]->type == EX) { + mb_for_species_ex(i); + } else if (s[i]->type == SURF) { + mb_for_species_surf(i); + } +#ifdef COMBINE + build_mb_sums(); +#else + if (s[i] != s_h2o) { + build_mb_sums(); + } +#endif + if (!pitzer_model) build_jacobian_sums(i); +/* + * Build list of species for summing and printing + */ + if (s[i]->next_secondary == NULL) { + write_mb_for_species_list(i); + } else { + count_elts = 0; + add_elt_list(s[i]->next_secondary, 1.0); + } + build_species_list(i); + } + } + if (diffuse_layer_x == TRUE && pitzer_model == TRUE) { + error_msg("-diffuse_layer option not available for Pizer model", STOP); + } +/* + * Sum diffuse layer water into hydrogen and oxygen mass balances + */ + if (diffuse_layer_x == TRUE && state >= REACTION) { + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == SURFACE_CB) { +#ifndef COMBINE + store_mb(&(x[i]->mass_water), + &(mass_hydrogen_unknown->f), + 2 / gfw_water); +#endif + if (mass_oxygen_unknown != NULL) { + store_mb(&(x[i]->mass_water), + &(mass_oxygen_unknown->f), + 1 / gfw_water); + } + } + } + } +/* + * For Pizer model add lg unknown for each aqueous species + */ + + if (pitzer_model == TRUE) { + j0 = count_unknowns; + j = count_unknowns + count_s_x; + k = j0; + for (i = j0; i < j; i++) { + if (s_x[i - j0]->type == EX) continue; + if (s_x[i - j0]->type == SURF) continue; + x[k]->number = k; + x[k]->type = PITZER_GAMMA; + x[k]->s = s_x[i - j0]; + x[k]->description = s_x[i - j0]->name; + k++; + count_unknowns++; + } + } +/* + * Rewrite phases to current master species + */ + for (i=0; i < count_phases; i++) { + count_trxn=0; + trxn_add(phases[i]->rxn_s, 1.0, FALSE); + trxn_reverse_k(); + phases[i]->in = inout(); + if (phases[i]->in == TRUE) { +/* + * Replace e- in original equation with default redox reaction + */ + coef_e=trxn_find_coef ("e-", 1); + if ( equal(coef_e,0.0,TOL) == FALSE ) { + trxn_add( pe_x[default_pe_x].rxn, coef_e, TRUE); + } +/* + * Rewrite reaction to current master species + */ + write_mass_action_eqn_x(STOP); + trxn_reverse_k(); + rxn_free(phases[i]->rxn_x); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\nPhase: %s\n", phases[i]->name); + trxn_print(); + } + phases[i]->rxn_x = rxn_alloc(count_trxn+1); + trxn_copy (phases[i]->rxn_x); + write_phase_sys_total(i); + } + } + build_solution_phase_boundaries(); + build_pure_phases(); + build_min_exch(); + build_min_surface(); + build_gas_phase(); + build_s_s_assemblage(); +/* + * Sort species list, by master only + */ + qsort (&species_list[0], (size_t) count_species_list, + (size_t) sizeof(struct species_list), species_list_compare_master); +/* + * Print size information to logfile + */ +/* + output_msg(OUTPUT_LOG, "\nMemory used:\n"); + output_msg(OUTPUT_LOG, "count_s: %d\tmax_s: %d\t\tbytes: %d\n", count_s, max_s, (int) (max_s * sizeof(struct species))); + output_msg(OUTPUT_LOG, "count_s_x: %d\tmax_s_x: %d\t\tbytes: %d\n", count_s_x, max_s_x, (int) (max_s_x * sizeof(struct species *))); + output_msg(OUTPUT_LOG, "count_sum_mb1: %d\tmax_sum_mb1: %d\t\tbytes: %d\n", count_sum_mb1, max_sum_mb1, (int) (max_sum_mb1 * sizeof(struct list1))); + output_msg(OUTPUT_LOG, "count_sum_mb2: %d\tmax_sum_mb2: %d\t\tbytes: %d\n", count_sum_mb2, max_sum_mb2, (int) (max_sum_mb2 * sizeof(struct list2))); + output_msg(OUTPUT_LOG, "count_sum_jacob0: %d\tmax_sum_jacob0: %d\t\tbytes: %d\n", count_sum_jacob0, max_sum_jacob0, (int) (max_sum_jacob0 * sizeof(struct list0))); + output_msg(OUTPUT_LOG, "count_sum_jacob1: %d\tmax_sum_jacob1: %d\t\tbytes: %d\n", count_sum_jacob1, max_sum_jacob1, (int) (max_sum_jacob1 * sizeof(struct list1))); + output_msg(OUTPUT_LOG_LOG, "count_sum_jacob2: %d\tmax_sum_jacob2: %d\t\tbytes: %d\n", count_sum_jacob2, max_sum_jacob2, (int) (max_sum_jacob2 * sizeof(struct list2))); + output_msg(OUTPUT_LOG_LOG, "count_sum_delta: %d\tmax_sum_delta: %d\t\tbytes: %d\n", count_sum_delta, max_sum_delta, (int) (max_sum_delta * sizeof(struct list2))); + output_msg(OUTPUT_LOG, "count_unknowns: %d\n", count_unknowns); + output_msg(OUTPUT_LOG_LOG, "\n"); + */ +/* + * Save model description + */ + /* if (state >= REACTION) save_model(); */ + save_model(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_pure_phases(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Includes calculation of inverse saturation index in sum_mb. + * Puts coefficients in iap and mass balance equations for each phase. + */ + int i; + int stop, j, k, l; + char token[MAX_LENGTH]; + char *ptr; + struct master *master_ptr; + struct rxn_token *rxn_ptr; +/* + * Build into sums the logic to calculate inverse saturation indices for + * pure phases + */ + if (pure_phase_unknown == NULL) return(OK); +/* + * Calculate inverse saturation index + */ + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != PP || x[i]->phase->rxn_x == NULL) continue; + if (pure_phase_unknown == NULL) pure_phase_unknown = x[i]; + + store_mb(&(x[i]->phase->lk), &(x[i]->f), 1.0); + store_mb(&(x[i]->si), &(x[i]->f), 1.0); + + for (rxn_ptr = x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + store_mb(&(rxn_ptr->s->la), &(x[i]->f), -rxn_ptr->coef); + } + } + for (i = 0; i < count_unknowns; i++) { +/* + * rxn_x is null if an element in phase is not in solution + */ + if (x[i]->type != PP || x[i]->phase->rxn_x == NULL) continue; +/* + * Put coefficients into IAP equations + */ + for (rxn_ptr=x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s->secondary != NULL && + rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if (master_ptr == NULL || master_ptr->unknown == NULL) continue; + store_jacob0(x[i]->number, master_ptr->unknown->number, rxn_ptr->coef); + } +/* + * Put coefficients into mass balance equations + */ + count_elts = 0; + paren_count = 0; + if (x[i]->pure_phase->add_formula != NULL) { + strcpy(token, x[i]->pure_phase->add_formula); + ptr = token; + get_elts_in_species (&ptr, 1.0); + } else { + strcpy(token, x[i]->phase->formula); + ptr = token; + get_elts_in_species (&ptr, 1.0); + } +/* + * Go through elements in phase + */ + +#ifdef COMBINE + change_hydrogen_in_elt_list(0); +#endif + for (j = 0; j < count_elts; j++) { + + if (strcmp(elt_list[j].elt->name, "H") == 0 && mass_hydrogen_unknown != NULL) { + store_jacob0(mass_hydrogen_unknown->number, x[i]->number, -elt_list[j].coef); + store_sum_deltas(&(delta[i]), &mass_hydrogen_unknown->delta, elt_list[j].coef); + + } else if (strcmp(elt_list[j].elt->name, "O") == 0 && mass_oxygen_unknown != NULL) { + store_jacob0(mass_oxygen_unknown->number, x[i]->number, -elt_list[j].coef); + store_sum_deltas(&(delta[i]), &mass_oxygen_unknown->delta, elt_list[j].coef); + + } else { + master_ptr = elt_list[j].elt->primary; + if (master_ptr->in == FALSE) { + master_ptr = master_ptr->s->secondary; + } + if (master_ptr == NULL || master_ptr->in == FALSE) { + if (state != ADVECTION && state != TRANSPORT && state != PHAST ) { + sprintf(error_string, "Element in phase, %s, is not in model.", x[i]->phase->name); + warning_msg(error_string); + } + if (master_ptr != NULL) { + master_ptr->s->la = -999.9; + } +/* + * Master species is in model + */ + } else if (master_ptr->in == TRUE ) { + store_jacob0(master_ptr->unknown->number, x[i]->number, + -elt_list[j].coef); + store_sum_deltas(&delta[i], &master_ptr->unknown->delta, elt_list[j].coef); +/* + * Master species in equation needs to be rewritten + */ + } else if (master_ptr->in == REWRITE ) { + stop = FALSE; + for (k=0; k < count_unknowns; k++) { + if (x[k]->type != MB) continue; + for (l = 0; x[k]->master[l] != NULL; l++) { + if (x[k]->master[l] == master_ptr) { + store_jacob0(x[k]->master[0]->unknown->number, x[i]->number, + -elt_list[j].coef); + store_sum_deltas(&delta[i], &x[k]->master[0]->unknown->delta, + elt_list[j].coef); + stop = TRUE; + break; + } + } + if (stop == TRUE) break; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_solution_phase_boundaries(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct master *master_ptr; + struct rxn_token *rxn_ptr; +/* + * Build into sums the logic to calculate inverse saturation indices for + * solution phase boundaries + */ + if (solution_phase_boundary_unknown == NULL) return(OK); +/* + * Calculate inverse saturation index + */ + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != SOLUTION_PHASE_BOUNDARY) continue; + + store_mb(&(x[i]->phase->lk), &(x[i]->f), 1.0); + store_mb(&(x[i]->si), &(x[i]->f), 1.0); + if (x[i]->phase->in != TRUE) { + sprintf(error_string, "Solution does not contain all elements for phase-boundary mineral, %s.", x[i]->phase->name); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + for (rxn_ptr = x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + store_mb(&(rxn_ptr->s->la), &(x[i]->f), -rxn_ptr->coef); + } + } + if (input_error > 0) return(ERROR); +/* + * Put coefficients into array + */ + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != SOLUTION_PHASE_BOUNDARY) continue; + for (rxn_ptr=x[i]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s->secondary != NULL && + rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if (master_ptr->unknown == NULL) continue; + store_jacob0(x[i]->number, master_ptr->unknown->number, rxn_ptr->coef); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_species_list(int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Builds a list that includes an entry for each master species in each + * secondary reaction. Used for summing species of each element and + * printing results. + */ + int j; + struct master *master_ptr; +/* + * Check space and store reaction token name and pointer to species + */ + if (count_species_list + count_elts >= max_species_list) { + space ((void **) ((void *) &species_list), count_species_list + count_elts, + &max_species_list, sizeof (struct species_list)); + } +/* + * Treat species made only with H+, e-, and H2O specially + */ + if ( is_special(s[n]) == TRUE ) { + species_list[count_species_list].master_s = s_hplus; + species_list[count_species_list].s = s[n]; + species_list[count_species_list].coef = 0.0; + count_species_list++; + return(OK); + } +/* + * Treat exchange species specially + */ + if (s[n]->type == EX) { + if (s[n]->primary != NULL) return(OK); /* master species has zero molality */ + for (j = 0; j < count_elts; j++) { + if ( elt_list[j].elt->master->s->type != EX ) continue; + master_ptr = elt_list[j].elt->master; + species_list[count_species_list].master_s = elt_list[j].elt->master->s; + species_list[count_species_list].s = s[n]; + species_list[count_species_list].coef = master_ptr->coef * + elt_list[j].coef; + count_species_list++; + } + return(OK); + } +/* + * Treat surface species specially + */ + if (s[n]->type == SURF_PSI) return(OK); + if (s[n]->type == SURF) { + for (j=0; j < count_elts; j++) { + if ( elt_list[j].elt->master->s->type != SURF ) continue; + master_ptr = elt_list[j].elt->master; + species_list[count_species_list].master_s = elt_list[j].elt->master->s; + species_list[count_species_list].s = s[n]; + species_list[count_species_list].coef = master_ptr->coef * + elt_list[j].coef; + count_species_list++; + } + return(OK); + } +/* + * Other aqueous species + */ + for (j=0; j < count_elts; j++) { + if ( is_special(elt_list[j].elt->master->s) == TRUE ) continue; + if (elt_list[j].elt->master->s->secondary != NULL) { + master_ptr = elt_list[j].elt->master->s->secondary; + } else { + master_ptr = elt_list[j].elt->master->s->primary; + } + species_list[count_species_list].master_s = master_ptr->s; + species_list[count_species_list].s = s[n]; +/* + * Find coefficient for element represented by master species + */ + species_list[count_species_list].coef = master_ptr->coef * + elt_list[j].coef; + count_species_list++; + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int clear (void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Resets information for setting up a new model + */ + struct solution *solution_ptr; +/* + * Clear species solution-dependent data + */ + solution_ptr = use.solution_ptr; + + for (i=0; i < count_s; i++) { + s[i]->in=FALSE; + } +/* + * Set pe structure + */ + pe_data_free(pe_x); + pe_x = pe_data_dup(solution_ptr->pe); + default_pe_x = solution_ptr->default_pe; +/* + * Clear master species solution-dependent data + */ + for (i=0; i < count_master; i++) { + master[i]->in=FALSE; + master[i]->unknown=NULL; + master[i]->pe_rxn = &(pe_x[solution_ptr->default_pe].rxn); +/* + * copy primary reaction to secondary reaction + */ + rxn_free (master[i]->rxn_secondary); + master[i]->rxn_secondary = rxn_dup (master[i]->rxn_primary); + } + + if (state == INITIAL_SOLUTION) { + s_h2o->secondary->in=TRUE; + s_hplus->secondary->in=TRUE; + } else { + s_h2o->primary->in=TRUE; + s_hplus->primary->in=TRUE; + } + s_eminus->primary->in=TRUE; +/* + * Set all unknown pointers to NULL + */ + mb_unknown = NULL; + ah2o_unknown = NULL; + mass_hydrogen_unknown = NULL; + mass_oxygen_unknown = NULL; + mu_unknown = NULL; + alkalinity_unknown = NULL; + carbon_unknown = NULL; + ph_unknown = NULL; + pe_unknown = NULL; + charge_balance_unknown = NULL; + solution_phase_boundary_unknown = NULL; + pure_phase_unknown = NULL; + exchange_unknown = NULL; + surface_unknown = NULL; + gas_unknown = NULL; + s_s_unknown = NULL; +/* + * Free arrays used in model + */ + free_model_allocs(); + + return (OK); +} +/* ---------------------------------------------------------------------- */ +int convert_units(struct solution *solution_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Converts solution concentrations to moles/kg water + * Uses totals.input conc to calculate totals.moles. + */ + int i, l; + LDBLE sum_solutes; + char c; + struct master *master_ptr; + struct conc *tot_ptr; + char token[MAX_LENGTH]; + char *ptr; +/* + * Convert units + */ + sum_solutes= exp(-solution_ptr->ph * LOG_10); + for ( i=0; solution_ptr->totals[i].description != NULL; i++) { + master_ptr = master_bsearch (solution_ptr->totals[i].description); + if (master_ptr != NULL) { + if (master_ptr->minor_isotope == TRUE) continue; + } + tot_ptr=&(solution_ptr->totals[i]); + tot_ptr->moles = 0.0; + if (strcmp(tot_ptr->description,"H(1)") == 0 || + strcmp(tot_ptr->description,"E" ) == 0 ) { + continue; + } + if (tot_ptr->input_conc <= 0) continue; +/* + * Get gfw + */ + /* use given gfw if gfw > 0.0 */ + /* use formula give with "as" */ + if (tot_ptr->gfw <= 0.0) { + if ( tot_ptr->as != NULL ) { + /* use given chemical formula to calculate gfw */ + if (compute_gfw(tot_ptr->as, &(tot_ptr->gfw) ) == ERROR ) { + sprintf(error_string, "Could not compute gfw, %s.", tot_ptr->as); + error_msg(error_string, CONTINUE); + input_error++; + } + if (strcmp (tot_ptr->description,"Alkalinity") == 0 && + strcmp (tot_ptr->as, "CaCO3") == 0) { + tot_ptr->gfw /= 2.; + sprintf(error_string, "Equivalent wt for alkalinity should be Ca.5(CO3).5. Using %g g/eq.", (double) tot_ptr->gfw); + warning_msg(error_string); + } + /* use gfw of master species */ + } else { + ptr = tot_ptr->description; + copy_token(token, &ptr, &l); + master_ptr = master_bsearch (token); + if (master_ptr != NULL) { + /* use gfw for element redox state*/ + tot_ptr->gfw = master_ptr->gfw; + } else { + sprintf(error_string, "Could not find gfw, %s.", tot_ptr->description); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + } + } +/* + * Convert liters to kg solution + */ + tot_ptr->moles=tot_ptr->input_conc; + if (strstr (solution_ptr->units, "/l") != NULL ) { + tot_ptr->moles *= 1.0/(solution_ptr->density); + } +/* + * Convert milli or micro + */ + c=tot_ptr->units[0]; + if (c == 'm') { + tot_ptr->moles *= 1e-3; + } else if ( c == 'u' ) { + tot_ptr->moles *= 1e-6; + } +/* + * Sum grams of solute, convert from moles necessary + */ + if (strstr (tot_ptr->units, "g/kgs") != NULL || + strstr (tot_ptr->units,"g/l") != NULL ) { + sum_solutes += tot_ptr->moles; + } else if (strstr (tot_ptr->units, "Mol/kgs") != NULL || + strstr (tot_ptr->units, "Mol/l") != NULL || + strstr (tot_ptr->units, "eq/l") != NULL ) { + sum_solutes += (tot_ptr->moles)*(tot_ptr->gfw); + } +/* + * Convert grams to moles, if necessary + */ + if ( strstr (tot_ptr->units, "g/") != NULL && tot_ptr->gfw != 0.0) { + tot_ptr->moles /= tot_ptr->gfw; + } + } +/* + * Convert /kgs to /kgw + */ + if (strstr( solution_ptr->units, "kgs") != NULL || + strstr( solution_ptr->units, "/l") != NULL ) { + mass_water_aq_x = 1.0 - 1e-3*sum_solutes; + for ( i=0; solution_ptr->totals[i].description != NULL; i++) { + solution_ptr->totals[i].moles /= mass_water_aq_x; + } + } +/* + * Scale by mass of water in solution + */ + mass_water_aq_x = solution_ptr->mass_water; + for ( i=0; solution_ptr->totals[i].description != NULL; i++) { + solution_ptr->totals[i].moles *= mass_water_aq_x; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct master **get_list_master_ptrs(char *ptr, struct master *master_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Input: ptr contains a list of one or more master species names + * Output: space is allocated and a list of master species pointers is + * returned. + */ + int j, l, count_list; + char token[MAX_LENGTH]; + struct master **master_ptr_list; + struct master *master_ptr0; +/* + * Make list of master species pointers + */ + count_list = 0; + master_ptr_list = unknown_alloc_master(); + master_ptr0=master_ptr; + if (master_ptr0 == master_ptr->s->primary) { +/* + * First in list is primary species + */ + for (j = 0; j < count_master; j++) { + if (master[j] == master_ptr0) break; + } + j++; +/* + * Element has only one valence + */ + if ( j >= count_master || master[j]->elt->primary != master_ptr0) { + master_ptr_list[count_list++] = master_ptr0; +/* + * Element has multiple valences + */ + } else { + if (master_ptr0->s->secondary == NULL) { + sprintf(error_string, "Master species for valence states of element %s are not correct.\n\tPossibly related to master species for %s.", master_ptr0->elt->name, master[j]->elt->name); + error_msg(error_string, CONTINUE); + input_error++; + } + master_ptr_list[count_list++] = master_ptr0->s->secondary; + while (j < count_master && master[j]->elt->primary == master_ptr0) { + if (master[j]->s->primary == NULL) { + master_ptr_list = (struct master **) PHRQ_realloc((void *) master_ptr_list, (size_t) (count_list + 2) * sizeof(struct master *)); + if (master_ptr_list == NULL) malloc_error(); + master_ptr_list[count_list++] = master[j]; + } + j++; + } + } + } else { +/* + * First in list is secondary species, Include all valences from input + */ + master_ptr_list[count_list++]=master_ptr0; + while (copy_token(token,&ptr, &l) != EMPTY) { + master_ptr = master_bsearch(token); + if (master_ptr != NULL) { + master_ptr_list = (struct master **) PHRQ_realloc((void *) master_ptr_list, (size_t) (count_list + 2) * sizeof(struct master *)); + if (master_ptr_list == NULL) malloc_error(); + master_ptr_list[count_list++] = master_ptr; + } + } + } + master_ptr_list[count_list] = NULL; + return (master_ptr_list); +} +/* ---------------------------------------------------------------------- */ +int inout(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct rxn_token_temp *token_ptr; +/* + * Routine goes through trxn to determine if each master species is + * in this model. + * Assumes equation is written in terms of primary and secondary species + * Checks to see if in is TRUE or REWRITE for each species + * Returns TRUE if in model + * FALSE if not + */ + for (i=1; i < count_trxn; i++) { + token_ptr = &(trxn.token[i]); + /* Check primary master species in */ + if (token_ptr->s->primary != NULL && (token_ptr->s->primary->in == TRUE) ) continue; + /* Check secondary master species */ + if ( (token_ptr->s->secondary != NULL) && (token_ptr->s->secondary->in != FALSE) ) { + continue; + } + /* Must be primary master species that is out */ + return(FALSE); + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int is_special(struct species *spec) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks to see if a species is composed of only H, O, and e- + * Returns TRUE if true + * FALSE if not + */ + int special; + struct rxn_token *token_ptr; + + special = TRUE; + for ( token_ptr = spec->rxn_s->token + 1; token_ptr->s != NULL; token_ptr++) { + if (token_ptr->s != s_hplus && + token_ptr->s != s_h2o && + token_ptr->s != s_eminus ) { + special = FALSE; + break; + } + } + return(special); +} +/* ---------------------------------------------------------------------- */ +int store_mb_unknowns(struct unknown *unknown_ptr, LDBLE *LDBLE_ptr, LDBLE coef, LDBLE *gamma_ptr) +/* ---------------------------------------------------------------------- */ +/* + * Takes an unknown pointer and a coefficient and puts in + * list of mb_unknowns + */ +{ + if (equal(coef, 0.0, TOL) == TRUE) return(OK); + if ( (count_mb_unknowns + 1) >= max_mb_unknowns) { + space ((void **) ((void *) &mb_unknowns), count_mb_unknowns + 1, &max_mb_unknowns, + sizeof(struct unknown_list)); + } + mb_unknowns[count_mb_unknowns].unknown = unknown_ptr; + mb_unknowns[count_mb_unknowns].source = LDBLE_ptr; + mb_unknowns[count_mb_unknowns].gamma_source = gamma_ptr; + mb_unknowns[count_mb_unknowns].coef = coef; + count_mb_unknowns++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_for_species_aq(int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make list of mass balance and charge balance equations in which + * to insert species n. + * + * count_mb_unknowns - number of equations and summation relations + * mb_unknowns.unknown - pointer to unknown which contains row number + * mb_unknowns.source - pointer to the LDBLE number to be multiplied + * by coef, usually moles. + * mb_unknowns.coef - coefficient of s[n] in equation or relation + */ + int i, j; + struct master *master_ptr; + + count_mb_unknowns = 0; +/* + * e- does not appear in any mass balances + */ + if (s[n]->type == EMINUS) return(OK); +/* + * Do not include diffuse layer in cb, alk, ah2o, mu + */ + if (charge_balance_unknown != NULL && s[n]->type < H2O) { + store_mb_unknowns(charge_balance_unknown, &s[n]->moles, s[n]->z, &s[n]->dg); + } + if (alkalinity_unknown != NULL && s[n]->type < H2O ) { + store_mb_unknowns(alkalinity_unknown, &s[n]->moles, s[n]->alk, &s[n]->dg); + } + if (ah2o_unknown != NULL && s[n]->type < H2O ) { + store_mb_unknowns(ah2o_unknown, &s[n]->moles, 1.0, &s[n]->dg); + } + if (mu_unknown != NULL && s[n]->type < H2O ) { + store_mb_unknowns(mu_unknown, &s[n]->moles, s[n]->z * s[n]->z, &s[n]->dg); + } +/* + * Include diffuse layer in hydrogen and oxygen mass balance + */ + if (mass_hydrogen_unknown != NULL ) { + if (diffuse_layer_x == TRUE && state >= REACTION) { +#ifdef COMBINE +#ifndef COMBINE_CHARGE + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->tot_g_moles, s[n]->h - 2 *s[n]->o, &s[n]->dg_total_g); +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->tot_g_moles, s[n]->h - 2 *s[n]->o - s[n]->z, &s[n]->dg_total_g); +#endif +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->tot_g_moles, s[n]->h, &s[n]->dg_total_g ); +#endif + } else { +#ifdef COMBINE +#ifndef COMBINE_CHARGE + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2* s[n]->o, &s[n]->dg); +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2* s[n]->o - s[n]->z, &s[n]->dg); +#endif +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h, &s[n]->dg); +#endif + } + } + if (mass_oxygen_unknown != NULL ) { + if (diffuse_layer_x == TRUE && state >= REACTION) { + store_mb_unknowns(mass_oxygen_unknown, &s[n]->tot_g_moles, s[n]->o, &s[n]->dg_total_g ); + } else { + store_mb_unknowns(mass_oxygen_unknown, &s[n]->moles, s[n]->o, &s[n]->dg ); + } + } +/* + * Sum diffuse layer charge into (surface + DL) charge balance + */ + if (use.surface_ptr != NULL && s[n]->type < H2O && diffuse_layer_x == TRUE) { + j = 0; + for(i = 0; i < count_unknowns; i++) { + if (x[i]->type == SURFACE_CB) { + store_mb_unknowns(x[i], &s[n]->diff_layer[j].g_moles, s[n]->z, &s[n]->diff_layer[j].dg_g_moles); + j++; + } + } + } +/* + * Other mass balances + */ + for (i = 0; i < count_elts; i++) { + if (elt_list[i].elt->master->s->type > AQ && + elt_list[i].elt->master->s->type < SOLID) continue; + master_ptr = elt_list[i].elt->master; + if (master_ptr->primary == TRUE) { + if (master_ptr->s->secondary != NULL) { + master_ptr = master_ptr->s->secondary; + } + } + if (master_ptr->unknown == ph_unknown ) { + continue; + } else if (master_ptr->unknown == pe_unknown ) { + continue; + } else if (master_ptr->unknown == charge_balance_unknown ) { + continue; + } else if (master_ptr->unknown == alkalinity_unknown ) { + continue; + } else if (master_ptr->unknown->type == SOLUTION_PHASE_BOUNDARY ) { + continue; + } + if (diffuse_layer_x == TRUE && state >= REACTION) { + store_mb_unknowns(master_ptr->unknown, + &s[n]->tot_g_moles, + elt_list[i].coef * master_ptr->coef, &s[n]->dg_total_g ); + } else { + store_mb_unknowns(master_ptr->unknown, + &s[n]->moles, + elt_list[i].coef * master_ptr->coef, &s[n]->dg); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_for_species_ex(int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make list of mass balance and charge balance equations in which + * to insert exchange species n. + * + * count_mb_unknowns - number of equations and summation relations + * mb_unknowns.source - pointer to the LDBLE number to be multiplied + * by coef, usually moles. + * mb_unknowns.unknown - pointer to unknown which contains row number + * mb_unknowns.coef - coefficient of s[n] in equation or relation + */ + int i; + struct master *master_ptr; + count_mb_unknowns = 0; +/* + * Master species for exchange do not appear in any mass balances + */ + if (s[n]->type == EX && s[n]->primary != NULL) return(OK); +/* + * Include diffuse layer in hydrogen and oxygen mass balance + */ + if (charge_balance_unknown != NULL) { + store_mb_unknowns(charge_balance_unknown, &s[n]->moles, s[n]->z, &s[n]->dg); + } + if (mass_hydrogen_unknown != NULL ) { +#ifdef COMBINE +#ifndef COMBINE_CHARGE + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2 * s[n]->o, &s[n]->dg); +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2 * s[n]->o - s[n]->z, &s[n]->dg); +#endif +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h, &s[n]->dg ); +#endif + } + if (mass_oxygen_unknown != NULL ) { + store_mb_unknowns(mass_oxygen_unknown, &s[n]->moles, s[n]->o, &s[n]->dg ); + } +/* + * Other mass balances + */ + for (i = 0; i < count_elts; i++) { + if (elt_list[i].elt->master->s->type > AQ && + elt_list[i].elt->master->s->type < SOLID) continue; + master_ptr = elt_list[i].elt->master; + if (master_ptr->primary == TRUE) { + if (master_ptr->s->secondary != NULL) { + master_ptr = master_ptr->s->secondary; + } + } +/* + * Special for ph_unknown, pe_unknown, and alkalinity_unknown + */ + if (master_ptr->unknown == ph_unknown ) { + continue; + } else if (master_ptr->unknown == pe_unknown ) { + continue; + } else if (master_ptr->unknown == alkalinity_unknown ) { + continue; + } +/* + * EX, sum exchange species only into EXCH mass balance in initial calculation + * into all mass balances in reaction calculation + */ + if ( state >= REACTION || master_ptr->s->type == EX) { + store_mb_unknowns(master_ptr->unknown, &s[n]->moles, + elt_list[i].coef * master_ptr->coef, &s[n]->dg); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mb_for_species_surf(int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Make list of mass balance and charge balance equations in which + * to insert species n. + * + * count_mb_unknowns - number of equations and summation relations + * mb_unknowns.source - pointer to the LDBLE number to be multiplied + * by coef, usually moles. + * mb_unknowns.unknown - pointer to unknown which contains row number + * mb_unknowns.coef - coefficient of s[n] in equation or relation + */ + int i; + struct master *master_ptr; + + count_mb_unknowns = 0; +/* + * Include in charge balance, if diffuse_layer_x == FALSE + */ + if (charge_balance_unknown != NULL && diffuse_layer_x == FALSE) { + store_mb_unknowns(charge_balance_unknown, &s[n]->moles, s[n]->z, &s[n]->dg); + } +/* + * Include diffuse layer in hydrogen and oxygen mass balance + */ + if (mass_hydrogen_unknown != NULL ) { +#ifdef COMBINE +#ifndef COMBINE_CHARGE + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2*s[n]->o, &s[n]->dg); +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h - 2*s[n]->o -s[n]->z, &s[n]->dg); + +#endif +#else + store_mb_unknowns(mass_hydrogen_unknown, &s[n]->moles, s[n]->h, &s[n]->dg ); +#endif + } + if (mass_oxygen_unknown != NULL ) { + store_mb_unknowns(mass_oxygen_unknown, &s[n]->moles, s[n]->o, &s[n]->dg ); + } +/* + * Other mass balances + */ +/* + * Other mass balances + */ + for (i = 0; i < count_elts; i++) { +/* Skip H+, e-, and H2O */ + if (elt_list[i].elt->master->s->type > AQ && + elt_list[i].elt->master->s->type < SOLID) continue; + master_ptr = elt_list[i].elt->master; + if (master_ptr->primary == TRUE) { + if (master_ptr->s->secondary != NULL) { + master_ptr = master_ptr->s->secondary; + } + } +/* + * SURF_PSI, sum surface species in (surface + DL) charge balance + */ + if (master_ptr->s->type == SURF_PSI) { + store_mb_unknowns(master_ptr->unknown, &s[n]->moles, s[n]->z, &s[n]->dg ); + continue; + } +/* + * Special for ph_unknown, pe_unknown, and alkalinity_unknown + */ + if (master_ptr->unknown == ph_unknown ) { + continue; + } else if (master_ptr->unknown == pe_unknown ) { + continue; + } else if (master_ptr->unknown == alkalinity_unknown ) { + continue; + } +/* + * SURF, sum surface species only into SURFACE mass balance in initial calculation + * into all mass balances in reaction calculation + */ + if ( state >= REACTION || master_ptr->s->type == SURF) { + store_mb_unknowns(master_ptr->unknown, &s[n]->moles, + elt_list[i].coef * master_ptr->coef, &s[n]->dg); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int reprep (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * If a basis species has been switched, makes new model. + * Unknowns are not changed, but mass-action equations are + * rewritten and lists for mass balance and jacobian are regenerated + */ + int i; +/* + * Initialize s, master, and unknown pointers + */ + for (i=0; i < count_master; i++) { + if (master[i]->in == FALSE) continue; + rxn_free (master[i]->rxn_secondary); + master[i]->rxn_secondary = rxn_dup (master[i]->rxn_primary); + } + resetup_master(); +/* + * Set unknown pointers, unknown types, validity checks + */ + tidy_redox(); + if (input_error > 0) { + error_msg("Program terminating due to input errors.", STOP); + } +/* + * Free arrays built in build_model + */ + s_x = (struct species **) free_check_null(s_x); + sum_mb1 = (struct list1 *) free_check_null(sum_mb1); + sum_mb2 = (struct list2 *) free_check_null(sum_mb2); + sum_jacob0 = (struct list0 *) free_check_null(sum_jacob0); + sum_jacob1 = (struct list1 *) free_check_null(sum_jacob1); + sum_jacob2 = (struct list2 *) free_check_null(sum_jacob2); + sum_delta = (struct list2 *) free_check_null(sum_delta); +/* + * Build model again + */ + build_model(); + same_model = FALSE; + k_temp(tc_x); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int resetup_master (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * For basis switch, rewrite equations for master species + * Set master_ptr->rxn_secondary, + * master_ptr->pe_rxn, + * and special cases for alkalinity, carbon, and pH. + */ + int i, j; + struct master *master_ptr, *master_ptr0; + + for (i = 0; i < count_unknowns; i++ ) { + if (x[i]->type != MB) continue; + master_ptr0=x[i]->master[0]; + for (j = 0; (master_ptr = x[i]->master[j]) != NULL; j++) { +/* + * Set flags + */ + if (j == 0) { + if (master_ptr->s->primary == NULL) { + rxn_free(master_ptr->rxn_secondary); + master_ptr->rxn_secondary = rxn_dup(master_ptr->s->rxn_s); + } + } else { + if (master_ptr0->s->primary == NULL) { + rewrite_master_to_secondary(master_ptr, master_ptr0); + rxn_free(master_ptr->rxn_secondary); + master_ptr->rxn_secondary = rxn_alloc(count_trxn+1); + trxn_copy (master_ptr->rxn_secondary); + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int write_mass_action_eqn_x (int stop) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reduce mass-action equation to the master species that are in the model + */ + LDBLE coef_e; + int count, repeat; + int i, count_rxn_orig; +/* + * Rewrite any secondary master species flagged REWRITE + * Replace pe if necessary + */ + count = 0; + repeat = TRUE; + while (repeat == TRUE) { + count++; + if (count > MAX_ADD_EQUATIONS) { + sprintf(error_string, "Could not reduce equation " + "to primary and secondary species that are " + "in the model\n\t Species: %s.", + trxn.token[0].s->name); + if (stop == STOP) { + input_error++; + error_msg(error_string, CONTINUE); + } else { + warning_msg(error_string); + } + return(ERROR); + } + repeat = FALSE; + count_rxn_orig=count_trxn; + for (i=1; i < count_rxn_orig; i++) { + if (trxn.token[i].s->secondary == NULL) continue; + if (trxn.token[i].s->secondary->in == REWRITE ) { + repeat=TRUE; + coef_e=rxn_find_coef (trxn.token[i].s->secondary->rxn_secondary, + "e-"); + trxn_add(trxn.token[i].s->secondary->rxn_secondary, + trxn.token[i].coef, FALSE); + if ( equal(coef_e,0.0,TOL) == FALSE ) { + trxn_add( *(trxn.token[i].s->secondary->pe_rxn), + trxn.token[i].coef*coef_e, FALSE); + } + } + } + trxn_combine(); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_potential_factor(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Add the potential factor to surface mass-action equations. + * Factor is essentially the activity coefficient, representing + * the work required to bring charged ions to the surface + */ + int i; + char token[MAX_LENGTH]; + LDBLE sum_z; + struct master *master_ptr; + struct unknown *unknown_ptr; + + if (use.surface_ptr->edl == FALSE) return(OK); + sum_z = 0.0; + master_ptr = NULL; +/* + * Find sum of charge of aqueous species and surface master species + */ + for (i=1; i < count_trxn; i++) { + if (trxn.token[i].s->type == AQ || trxn.token[i].s == s_hplus || + trxn.token[i].s == s_eminus) { + sum_z += trxn.token[i].s->z * trxn.token[i].coef; + } + if (trxn.token[i].s->type == SURF) { + master_ptr = trxn.token[i].s->primary; + } + } +/* + * Find potential unknown for surface species + */ + if (master_ptr == NULL) { + sprintf(error_string,"Did not find a surface species in equation defining %s", trxn.token[0].name); + error_msg(error_string, CONTINUE); + sprintf(error_string,"One of the following must be defined with SURFACE_SPECIES:"); + error_msg(error_string, CONTINUE); + for (i=1; i < count_trxn; i++) { + sprintf(error_string," %s", trxn.token[i].name); + error_msg(error_string, CONTINUE); + } + input_error++; + return(ERROR); + } + strcpy(token, master_ptr->elt->name); + unknown_ptr = find_surface_charge_unknown(token); + if (unknown_ptr == NULL) { + sprintf(error_string, "No potential unknown found for surface species %s.", token); + error_msg(error_string, STOP); + } + master_ptr = unknown_ptr->master[0]; /* potential for surface component */ +/* + * Make sure there is space + */ + if (count_trxn + 1 >= max_trxn) { + space ((void **) &(trxn.token), count_trxn+1, &max_trxn, + sizeof(struct rxn_token_temp)); + } +/* + * Include psi in mass action equation + */ + if (master_ptr != NULL) { + trxn.token[count_trxn].name = master_ptr->s->name; + trxn.token[count_trxn].s = master_ptr->s; + trxn.token[count_trxn].coef = -2.0 * sum_z; + count_trxn++; + } else { + output_msg(OUTPUT_MESSAGE, "How did this happen in add potential factor?\n"); + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_surface_charge_balance(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Add the potential factor to surface mass-action equations. + * Factor is essentially the activity coefficient, representing + * the work required to bring charged ions to the surface + */ + int i; + char *ptr; + char token[MAX_LENGTH]; + + struct master *master_ptr; + struct unknown *unknown_ptr; + + if (use.surface_ptr->edl == FALSE) return(OK); + master_ptr = NULL; +/* + * Find master species + */ + for (i=0; i < count_elts; i++) { + if (elt_list[i].elt->primary->s->type == SURF) { + master_ptr = elt_list[i].elt->primary; + break; + } + } + if (i >= count_elts) { + sprintf(error_string, "No surface master species found for surface species."); + error_msg(error_string, STOP); + } +/* + * Find potential unknown for surface species + */ + strcpy(token, master_ptr->elt->name); + unknown_ptr = find_surface_charge_unknown(token); + if (unknown_ptr == NULL) { + sprintf(error_string, "No potential unknown found for surface species %s.", token); + error_msg(error_string, STOP); + } + master_ptr = unknown_ptr->master[0]; /* potential for surface component */ +/* + * Include charge balance in list for mass-balance equations + */ + ptr = master_ptr->elt->name; + get_secondary_in_species(&ptr, 1.0); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int rewrite_master_to_secondary(struct master *master_ptr1, struct master *master_ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Write equation for secondary master species in terms of another secondary master species + * Store result in rxn_secondary of master_ptr. + */ + LDBLE coef1, coef2; + struct master *master_ptr_p1, *master_ptr_p2; +/* + * Check that the two master species have the same primary master species + */ + master_ptr_p1 = master_ptr1->elt->primary; + master_ptr_p2 = master_ptr2->elt->primary; + if (master_ptr_p1 != master_ptr_p2 || + master_ptr_p1 == NULL ) { + sprintf(error_string, "All redox states must be for the same element. %s\t%s.", + master_ptr1->elt->name, master_ptr2->elt->name); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find coefficient of primary master in reaction + */ + coef1=rxn_find_coef(master_ptr1->rxn_primary, master_ptr_p1->s->name); + coef2=rxn_find_coef(master_ptr2->rxn_primary, master_ptr_p1->s->name); + if ( equal(coef1,0.0,TOL) == TRUE || equal(coef2,0.0,TOL) == TRUE ) { + sprintf(error_string, "One of these equations does not contain master species for element, %s or %s.", + master_ptr1->s->name, master_ptr2->s->name); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Rewrite equation to secondary master species + */ + count_trxn=0; + trxn_add(master_ptr1->rxn_primary, 1.0, FALSE); + trxn_add(master_ptr2->rxn_primary, -coef1/coef2, TRUE); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_exchange (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in data for exchanger in unknowns structures + */ + int i, j; + struct master *master_ptr; + struct master **master_ptr_list; + + if (use.exchange_ptr == NULL) return(OK); + + for (j = 0; j < use.exchange_ptr->count_comps; j++) { + for (i = 0; use.exchange_ptr->comps[j].totals[i].elt != NULL; i++ ) { +/* + * Find master species + */ + master_ptr = use.exchange_ptr->comps[j].totals[i].elt->master; + if (master_ptr == NULL) { + sprintf(error_string, "Master species not in data " + "base for %s, skipping element.", + use.exchange_ptr->comps[j].totals[i].elt->name); + input_error++; + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != EX) continue; +/* + * Check for data already given + */ + if (master_ptr->in != FALSE ) { + x[master_ptr->unknown->number]->moles += use.exchange_ptr->comps[j].totals[i].coef; + + } else { +/* + * Set flags + */ + master_ptr_list = unknown_alloc_master(); + master_ptr_list[0] = master_ptr; + master_ptr->in = TRUE; +/* + * Set unknown data + */ + x[count_unknowns]->type = EXCH; + x[count_unknowns]->exch_comp = &(use.exchange_ptr->comps[j]); + x[count_unknowns]->description = use.exchange_ptr->comps[j].totals[i].elt->name; + x[count_unknowns]->moles = use.exchange_ptr->comps[j].totals[i].coef; + x[count_unknowns]->master = master_ptr_list; + x[count_unknowns]->master[0]->unknown = x[count_unknowns]; + count_unknowns++; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in data for gas phase unknown (sum of partial pressures) + * in unknown structure + */ + int i; + if (use.gas_phase_ptr == NULL) return(OK); +/* + * One for total moles in gas + */ + x[count_unknowns]->type = GAS_MOLES; + x[count_unknowns]->description = string_hsave("gas moles"); + x[count_unknowns]->moles = 0.0; + for (i=0; i < use.gas_phase_ptr->count_comps; i++) { + x[count_unknowns]->moles += use.gas_phase_ptr->comps[i].moles; + } + if (x[count_unknowns]->moles <= 0) x[count_unknowns]->moles = MIN_TOTAL; + x[count_unknowns]->ln_moles = log(x[count_unknowns]->moles); + x[count_unknowns]->gas_phase = use.gas_phase_ptr; + gas_unknown = x[count_unknowns]; + count_unknowns++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_s_s_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in data for solid solution unknowns (sum of partial pressures) + * in unknown structure + */ + int i, j; + if (use.s_s_assemblage_ptr == NULL) return(OK); +/* + * One for each component in each solid solution + */ + s_s_unknown = NULL; + for (j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i=0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + x[count_unknowns]->type = S_S_MOLES; + x[count_unknowns]->description = string_hsave(use.s_s_assemblage_ptr->s_s[j].comps[i].name); + x[count_unknowns]->moles = 0.0; + if (use.s_s_assemblage_ptr->s_s[j].comps[i].moles <= 0) { + use.s_s_assemblage_ptr->s_s[j].comps[i].moles = MIN_TOTAL; + } + x[count_unknowns]->moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + use.s_s_assemblage_ptr->s_s[j].comps[i].initial_moles = x[count_unknowns]->moles; + x[count_unknowns]->ln_moles = log(x[count_unknowns]->moles); + x[count_unknowns]->s_s = &(use.s_s_assemblage_ptr->s_s[j]); + x[count_unknowns]->s_s_comp = &(use.s_s_assemblage_ptr->s_s[j].comps[i]); + x[count_unknowns]->s_s_comp_number = i; + x[count_unknowns]->phase = use.s_s_assemblage_ptr->s_s[j].comps[i].phase; + x[count_unknowns]->number = count_unknowns; + x[count_unknowns]->phase->dn = use.s_s_assemblage_ptr->s_s[j].comps[i].dn; + x[count_unknowns]->phase->dnb = use.s_s_assemblage_ptr->s_s[j].comps[i].dnb; + x[count_unknowns]->phase->dnc = use.s_s_assemblage_ptr->s_s[j].comps[i].dnc; + x[count_unknowns]->phase->log10_fraction_x = use.s_s_assemblage_ptr->s_s[j].comps[i].log10_fraction_x; + x[count_unknowns]->phase->log10_lambda = use.s_s_assemblage_ptr->s_s[j].comps[i].log10_lambda; + if (s_s_unknown == NULL) s_s_unknown = x[count_unknowns]; + count_unknowns++; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_surface (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in data for surface assemblage in unknown structure + */ + int i, j, k; + struct master *master_ptr; + struct master **master_ptr_list; + struct unknown *unknown_ptr; + char token[MAX_LENGTH]; + char *name1, *name2; + if (use.surface_ptr == NULL) return(OK); + + for (i = 0; i < use.surface_ptr->count_comps; i++ ) { +/* + * Find master species for each surface, setup unknown structure + */ + for (j = 0; use.surface_ptr->comps[i].totals[j].elt != NULL; j++) { + master_ptr = use.surface_ptr->comps[i].totals[j].elt->master; + if (master_ptr == NULL) { + sprintf(error_string, "Master species not in data base for %s, skipping element.", use.surface_ptr->comps[i].totals[j].elt->name); + warning_msg(error_string); + continue; + } + if (master_ptr->type != SURF) continue; +/* + * Check that data not already given + */ if (master_ptr->in != FALSE ) { + sprintf(error_string, "Analytical data entered twice for %s.", master_ptr->s->name); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } +/* + * Set flags + */ + use.surface_ptr->comps[i].master = master_ptr; + master_ptr_list = unknown_alloc_master(); + master_ptr_list[0] = master_ptr; + master_ptr->in = TRUE; +/* + * Setup mass balance unknown + */ + x[count_unknowns]->type = SURFACE; + x[count_unknowns]->description = use.surface_ptr->comps[i].totals[j].elt->name; + x[count_unknowns]->number = count_unknowns; + x[count_unknowns]->surface_comp = &(use.surface_ptr->comps[i]); + x[count_unknowns]->master = master_ptr_list; + x[count_unknowns]->master[0]->unknown = x[count_unknowns]; + x[count_unknowns]->moles = use.surface_ptr->comps[i].totals[j].coef; + if (surface_unknown == NULL) surface_unknown = x[count_unknowns]; + x[count_unknowns]->potential_unknown = NULL; + count_unknowns++; + if (use.surface_ptr->edl == FALSE) continue; +/* + * Setup surface-potential unknown + */ + strcpy(token, master_ptr->elt->name); + unknown_ptr = find_surface_charge_unknown(token); + if (unknown_ptr != NULL) { + x[count_unknowns - 1]->potential_unknown = unknown_ptr; + } else { +/* + * Find master species + */ + replace ("_CB", "_psi", token); + master_ptr = master_bsearch (token); + master_ptr_list = unknown_alloc_master(); + master_ptr_list[0] = master_ptr; + master_ptr->in = TRUE; +/* + * Find surface charge structure + */ + x[count_unknowns]->type = SURFACE_CB; + k = use.surface_ptr->comps[i].charge; + x[count_unknowns]->surface_charge = &use.surface_ptr->charge[k]; + x[count_unknowns]->related_moles = x[count_unknowns]->surface_charge->grams; + x[count_unknowns]->mass_water = use.surface_ptr->charge[k].mass_water; + replace("_psi","_CB",token); + x[count_unknowns]->description = string_hsave(token); + x[count_unknowns]->master = master_ptr_list; + use.surface_ptr->charge[k].psi_master = x[count_unknowns]->master[0]; + x[count_unknowns]->master[0]->unknown = x[count_unknowns]; + x[count_unknowns]->moles = 0.0; + x[count_unknowns - 1]->potential_unknown = x[count_unknowns]; + x[count_unknowns]->surface_comp = x[count_unknowns - 1]->surface_comp; + count_unknowns++; + } + } + } +/* + * check related phases + */ + if (use.surface_ptr->related_phases == TRUE) { + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != SURFACE_CB) continue; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE) continue; + if (x[j]->potential_unknown != x[i]) continue; + if (x[j]->surface_comp->phase_name != x[i]->surface_comp->phase_name) { + if (x[i]->surface_comp->phase_name == NULL) { + name1 = string_hsave("None"); + } else { + name1 = x[i]->surface_comp->phase_name; + } + if (x[j]->surface_comp->phase_name == NULL) { + name2 = string_hsave("None"); + } else { + name2 = x[j]->surface_comp->phase_name; + } + input_error++; + sprintf(error_string,"All surface sites for a single component must be related to the same phase.\n\tSite: %s is related to %s, Site: %s is related to %s", + x[i]->surface_comp->master->s->name, name1, + x[j]->surface_comp->master->s->name, name2); + + error_msg(error_string, CONTINUE); + } + } + } + } +/* + * check related kinetics + */ + if (use.surface_ptr->related_rate == TRUE) { + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type != SURFACE_CB) continue; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE) continue; + if (x[j]->potential_unknown != x[i]) continue; + if (x[j]->surface_comp->rate_name != x[i]->surface_comp->rate_name) { + if (x[i]->surface_comp->rate_name == NULL) { + name1 = string_hsave("None"); + } else { + name1 = x[i]->surface_comp->rate_name; + } + if (x[j]->surface_comp->rate_name == NULL) { + name2 = string_hsave("None"); + } else { + name2 = x[j]->surface_comp->rate_name; + } + input_error++; + sprintf(error_string,"All surface sites for a single component must be related to the same kinetic reaction.\n\tSite: %s is related to %s, Site: %s is related to %s", + x[i]->surface_comp->master->s->name, name1, + x[j]->surface_comp->master->s->name, name2); + + error_msg(error_string, CONTINUE); + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct unknown *find_surface_charge_unknown(char *str_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Makes name for the potential unknown and returns in str_ptr + * Returns NULL if this unknown not in unknown list else + * returns a pointer to the potential unknown + */ + int i; + char *ptr; + char token[MAX_LENGTH]; + + replace ("_", " ", str_ptr); + ptr = str_ptr; + copy_token(token, &ptr, &i); + strcat(token, "_CB"); + strcpy(str_ptr, token); + for (i = 0; i < count_unknowns; i++) { + if ( strcmp(token, x[i]->description) == 0 ) { + return(x[i]); + } + } + return(NULL); +} + +/* ---------------------------------------------------------------------- */ +int setup_master_rxn(struct master **master_ptr_list, struct reaction **pe_rxn) +/* ---------------------------------------------------------------------- */ +{ +/* + * Rewrites rxn_secondary for all redox states in list + * First, in = TRUE; others, in = REWRITE + */ + int j; + struct master *master_ptr, *master_ptr0; +/* + * Set master_ptr->in, master_ptr->rxn + */ + master_ptr0 = master_ptr_list[0]; + for (j = 0; (master_ptr = master_ptr_list[j]) != NULL; j++) { +/* + * Check that data not already given + */ + if (master_ptr->s == s_h2o) { + sprintf(error_string, "Can not enter concentration data for O(-2),\n\tdissolved oxygen is O(0),\n\tfor mass of water, use -water identifier."); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + + if (master_ptr->in != FALSE ) { + if (master_ptr->s != s_eminus && master_ptr->s != s_hplus) { + sprintf(error_string, "Analytical data entered twice for %s.", master_ptr->s->name); + error_msg(error_string, CONTINUE); + input_error++; + continue; + } + } +/* + * Set flags + */ + if (j == 0) { + master_ptr->in = TRUE; + if (master_ptr->s->primary == NULL) { + rxn_free (master_ptr->rxn_secondary); + master_ptr->rxn_secondary = rxn_dup (master_ptr->s->rxn_s); +/* debug + trxn_print (); + */ + } + } else { + master_ptr->in = REWRITE; + if (master_ptr0->s->primary == NULL) { + rewrite_master_to_secondary(master_ptr, master_ptr0); + rxn_free (master_ptr->rxn_secondary); + master_ptr->rxn_secondary = rxn_alloc(count_trxn+1); + trxn_copy (master_ptr->rxn_secondary); +/* debug + trxn_print (); + */ + } + } + master_ptr->pe_rxn = pe_rxn; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_pure_phases(void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Fills in data for pure_phase assemglage in unknown structure + */ + + if (use.pp_assemblage_ptr == NULL) return(OK); +/* + * Setup unknowns + */ + for (i=0; i < use.pp_assemblage_ptr->count_comps; i++) { + x[count_unknowns]->type = PP; + x[count_unknowns]->description = use.pp_assemblage_ptr->pure_phases[i].name; + x[count_unknowns]->moles = use.pp_assemblage_ptr->pure_phases[i].moles; + x[count_unknowns]->phase = use.pp_assemblage_ptr->pure_phases[i].phase; + x[count_unknowns]->si = use.pp_assemblage_ptr->pure_phases[i].si; + x[count_unknowns]->delta = use.pp_assemblage_ptr->pure_phases[i].delta; + x[count_unknowns]->pure_phase = &(use.pp_assemblage_ptr->pure_phases[i]); + x[count_unknowns]->dissolve_only = use.pp_assemblage_ptr->pure_phases[i].dissolve_only; + if (pure_phase_unknown == NULL) pure_phase_unknown = x[count_unknowns]; + count_unknowns++; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_solution (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fills in data in unknown structure for the solution + */ + int l, i, j; + struct master *master_ptr; + struct solution *solution_ptr; + char *ptr; + char token[MAX_LENGTH]; + struct master_isotope *master_isotope_ptr; + + solution_ptr = use.solution_ptr; + count_unknowns = 0; + for (i = 0; solution_ptr->totals[i].description != NULL; i++ ) { + /*solution_ptr->totals[i].skip = FALSE;*/ + ptr=solution_ptr->totals[i].description; + copy_token(token, &ptr, &l); + master_ptr = master_bsearch(token); + /* + * Treat minor isotopes as special in initial solution calculation + */ + if ((state == INITIAL_SOLUTION) && (master_ptr != NULL) && (master_ptr->minor_isotope == TRUE) && (initial_solution_isotopes == FALSE)) { + master_isotope_ptr = master_isotope_search(token); + if (master_isotope_ptr != NULL) { + master_isotope_ptr->ratio = solution_ptr->totals[i].input_conc; + } + /*solution_ptr->totals[i].skip = TRUE;*/ + continue; + } +/* + * Check that total not <= zero + */ + if (solution_ptr->totals[i].input_conc <= 0.0) { + if (strcmp(token,"H(1)") != 0 && + strcmp(token,"E") != 0 ) { + /*solution_ptr->totals[i].skip = TRUE;*/ + continue; + } + } +/* + * Find master species + */ + master_ptr = master_bsearch(token); + if (master_ptr == NULL) { + /*solution_ptr->totals[i].skip = TRUE;*/ + sprintf(error_string,"Master species not in data base for %s, skipping element.", solution_ptr->totals[i].description); + warning_msg(error_string); + continue; + } + if (master_ptr->type != AQ) { + /*solution_ptr->totals[i].skip = TRUE;*/ + sprintf(error_string, "Only aqueous concentrations are allowed in solution data, ignoring %s.", solution_ptr->totals[i].description); + warning_msg(error_string); + continue; + } +/* + * Store list of master species pointers, set master[i].in and master[i].rxn for list + */ + x[count_unknowns]->master = get_list_master_ptrs(ptr, master_ptr); + setup_master_rxn(x[count_unknowns]->master, &(pe_x[solution_ptr->totals[i].n_pe].rxn)); +/* + * Set default unknown data + */ + x[count_unknowns]->type = MB; + x[count_unknowns]->description = solution_ptr->totals[i].description; + x[count_unknowns]->total = &(solution_ptr->totals[i]); + for (j=0; x[count_unknowns]->master[j] != NULL; j++) { + x[count_unknowns]->master[j]->unknown = x[count_unknowns]; + } + x[count_unknowns]->moles = solution_ptr->totals[i].moles; +/* + * Set pointers + */ + ptr=solution_ptr->totals[i].description; + copy_token(token, &ptr, &l); + str_tolower(token); + if (strstr( token,"alk") != NULL) { + if (alkalinity_unknown == NULL) { + x[count_unknowns]->type = ALK; + alkalinity_unknown=x[count_unknowns]; + } else { + error_msg("Alkalinity entered more than once.", CONTINUE); + input_error++; + } + } else if (strcmp(token,"c") == 0 || strcmp(token,"c(4)") == 0 ) { + if (carbon_unknown == NULL) { + carbon_unknown=x[count_unknowns]; + } else { + error_msg("Carbon entered more than once.", CONTINUE); + input_error++; + } + } else if (strcmp(token,"h(1)") == 0 ) { + if (ph_unknown == NULL) { + ph_unknown=x[count_unknowns]; + } else { + error_msg("pH entered more than once.", CONTINUE); + input_error++; + } + } else if (strcmp(token,"e") == 0 ) { + if (pe_unknown == NULL) { + pe_unknown=x[count_unknowns]; + } else { + error_msg("pe entered more than once.", CONTINUE); + input_error++; + } + } +/* + * Charge balance unknown + */ + if (solution_ptr->totals[i].equation_name != NULL ) { + ptr = solution_ptr->totals[i].equation_name; + copy_token(token, &ptr, &l); + str_tolower(token); + if (strstr(token,"charge") != NULL) { + if (charge_balance_unknown == NULL) { + charge_balance_unknown=x[count_unknowns]; + x[count_unknowns]->type = CB; + if (charge_balance_unknown == ph_unknown ) { + x[count_unknowns]->moles = solution_ptr->cb; + } + } else { + error_msg("Charge balance specified for more" + " than one species.", CONTINUE); + input_error++; + } + } else { +/* + * Solution phase boundaries + */ + solution_ptr->totals[i].phase= + phase_bsearch(solution_ptr->totals[i].equation_name, &l, FALSE); + if (solution_ptr->totals[i].phase == NULL) { + sprintf(error_string, "Expected a mineral name, %s.", solution_ptr->totals[i].equation_name); + error_msg(error_string, CONTINUE); + input_error++; + } + x[count_unknowns]->type = SOLUTION_PHASE_BOUNDARY; + x[count_unknowns]->phase=solution_ptr->totals[i].phase; + x[count_unknowns]->si=solution_ptr->totals[i].phase_si; + if (solution_phase_boundary_unknown == NULL) { + solution_phase_boundary_unknown = x[count_unknowns]; + } + } + } + count_unknowns++; + } +/* + * Set mb_unknown + */ + if (count_unknowns > 0) mb_unknown=x[0]; +/* + * Special for alkalinity + */ + if (alkalinity_unknown != NULL) { + if (carbon_unknown != NULL) { +/* + * pH adjusted to obtain given alkalinity + */ + if (ph_unknown == NULL) { + output_msg(OUTPUT_MESSAGE,"\npH will be adjusted to obtain desired alkalinity.\n\n"); + ph_unknown = alkalinity_unknown; + master_ptr=master_bsearch("H(1)"); + alkalinity_unknown->master[0] = master_ptr; + master_ptr->in = TRUE; + master_ptr->unknown = ph_unknown; + ph_unknown->master[0] = master_ptr; + ph_unknown->description = string_hsave( "H(1)" ); + } else { + error_msg("pH adjustment is needed for alkalinity but" + " charge balance or a phase boundary was also specified.", CONTINUE); + input_error++; + } +/* + * Carbonate ion adjusted to obtain given alkalintiy + */ + } else { + if (alkalinity_unknown->master[0]->s->secondary != NULL) { + alkalinity_unknown->master[0]->s->secondary->in=TRUE; + alkalinity_unknown->master[0]->s->secondary->unknown=alkalinity_unknown; + } else { + error_msg("Error in definition of Alkalinity in SOLUTION_MASTER_SPECIES and SOLUTION_SPECIES.\n\tAlkalinity master species should be same as master species for C(4).", CONTINUE); + input_error++; + } + } + } + if (pitzer_model == FALSE) { + /* + * Ionic strength + */ + mu_unknown=x[count_unknowns]; + x[count_unknowns]->description= string_hsave( "Mu" ); + x[count_unknowns]->type=MU; + x[count_unknowns]->number=count_unknowns; + x[count_unknowns]->moles = 0.0; + mu_unknown = x[count_unknowns]; + count_unknowns++; + } + /* + * Activity of water + */ + ah2o_unknown=x[count_unknowns]; + ah2o_unknown->description= string_hsave( "A(H2O)" ); + ah2o_unknown->type=AH2O; + ah2o_unknown->number=count_unknowns; + ah2o_unknown->master = unknown_alloc_master(); + ah2o_unknown->master[0] = master_bsearch ("O"); + ah2o_unknown->master[0]->unknown = ah2o_unknown; + ah2o_unknown->moles = 0.0; + count_unknowns++; + + if (state >= REACTION) { +/* + + * Reaction: pH for charge balance + */ + ph_unknown = x[count_unknowns]; + ph_unknown->description = string_hsave( "pH" ); + ph_unknown->type = CB; + ph_unknown->moles = solution_ptr->cb; + ph_unknown->number = count_unknowns; + ph_unknown->master = unknown_alloc_master(); + ph_unknown->master[0] = s_hplus->primary; + ph_unknown->master[0]->unknown = ph_unknown; + charge_balance_unknown = ph_unknown; + count_unknowns++; +/* + * Reaction: pe for total hydrogen + */ + pe_unknown = x[count_unknowns]; + mass_hydrogen_unknown = x[count_unknowns]; + mass_hydrogen_unknown->description = string_hsave( "Hydrogen" ); + mass_hydrogen_unknown->type = MH; +#ifdef COMBINE +#ifndef COMBINE_CHARGE + mass_hydrogen_unknown->moles = solution_ptr->total_h - 2*solution_ptr->total_o ; +#else + mass_hydrogen_unknown->moles = solution_ptr->total_h - 2*solution_ptr->total_o - solution_ptr->cb ; +#endif +#else + mass_hydrogen_unknown->moles = solution_ptr->total_h; +#endif + mass_hydrogen_unknown->number = count_unknowns; + mass_hydrogen_unknown->master = unknown_alloc_master(); + mass_hydrogen_unknown->master[0] = s_eminus->primary; + mass_hydrogen_unknown->master[0]->unknown = mass_hydrogen_unknown; + count_unknowns++; +/* + * Reaction H2O for total oxygen + */ + mass_oxygen_unknown = x[count_unknowns]; + mass_oxygen_unknown->description = string_hsave( "Oxygen" ); + mass_oxygen_unknown->type = MH2O; + mass_oxygen_unknown->moles = solution_ptr->total_o; + mass_oxygen_unknown->number = count_unknowns; + mass_oxygen_unknown->master = unknown_alloc_master(); + mass_oxygen_unknown->master[0] = s_h2o->primary; + count_unknowns++; + } +/* + * Validity tests + */ + if ( (ph_unknown != NULL) && + (ph_unknown == charge_balance_unknown) && + (alkalinity_unknown != NULL) ) { + error_msg("pH adustment can not attain charge balance" + " when alkalinity is fixed.", CONTINUE); + input_error++; + } + if ( (alkalinity_unknown != NULL) && + (alkalinity_unknown->type == CB || + alkalinity_unknown->type == SOLUTION_PHASE_BOUNDARY)) { + error_msg("Alkalinity can not be used with charge balance" + " or solution phase boundary constraints.", CONTINUE); + input_error++; + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct master **unknown_alloc_master(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Allocates space for a list of 2 master pointers + */ + struct master **master_ptr; + + master_ptr = (struct master **) PHRQ_malloc( 2 * sizeof(struct master *) ); + if (master_ptr == NULL) malloc_error(); + master_ptr[0] = NULL; + master_ptr[1] = NULL; + return(master_ptr); +} +/* ---------------------------------------------------------------------- */ +int setup_unknowns (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Counts unknowns and allocates space for unknown structures + */ + int i, j; + struct solution *solution_ptr; + + solution_ptr = use.solution_ptr; +/* + * Calculate maximum number of unknowns + */ + max_unknowns = 0; +/* + * Count mass balance in solution + */ + for (i = 0; solution_ptr->totals[i].description != NULL; i++ ) max_unknowns++; +/* + * Add 5 for ionic strength, activity of water, charge balance, total H, total O + */ + max_unknowns += 5; +/* + * Count pure phases + */ + if (use.pp_assemblage_ptr != NULL) { + max_unknowns += use.pp_assemblage_ptr->count_comps; +/* + for (i = 0; use.pp_assemblage_ptr->pure_phases[i].name != NULL; i++ ) { + max_unknowns++; + } + */ + } +/* + * Count exchange + */ + if (use.exchange_ptr != NULL) { + for (j = 0; j < use.exchange_ptr->count_comps; j++) { + for (i = 0; use.exchange_ptr->comps[j].totals[i].elt != NULL; i++) { + if (use.exchange_ptr->comps[j].totals[i].elt->master == NULL) { + sprintf(error_string, "Master species missing for element %s", use.exchange_ptr->comps[j].totals[i].elt->name); + error_msg(error_string, STOP); + } + if (use.exchange_ptr->comps[j].totals[i].elt->master->type == EX) { + max_unknowns++; + } + } + } + } +/* + * Count surfaces + */ + if (use.surface_ptr != NULL) { + max_unknowns += use.surface_ptr->count_comps + use.surface_ptr->count_charge; + } +/* + * Count gas components + */ + if (use.gas_phase_ptr != NULL) { + max_unknowns++; + } +/* + * Count solid solutions + */ + if (use.s_s_assemblage_ptr != NULL) { + /* max_unknowns += 2 * use.s_s_assemblage_ptr->count_s_s;*/ + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + max_unknowns += use.s_s_assemblage_ptr->s_s[i].count_comps; + } + } + +/* + * One for luck + */ + max_unknowns++; + if (pitzer_model == TRUE) { + max_unknowns += count_s; + } +/* + * Allocate space for pointer array and structures + */ + + space ((void **) ((void *) &x), INIT, &max_unknowns, sizeof(struct unknown *)); + for (i = 0; i < max_unknowns; i++) { + x[i] = (struct unknown *) unknown_alloc (); + x[i]->number = i; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_dn (int k, LDBLE *source, int row, LDBLE coef_in, LDBLE *gamma_source) +/* ---------------------------------------------------------------------- */ +{ +/* + * Stores the terms for d moles of species k in solution into row, multiplied + * by coef_in + */ + int col; + LDBLE coef; + struct rxn_token *rxn_ptr; + struct master *master_ptr; + + if (equal(coef_in, 0.0, TOL) == TRUE) { + return(OK); + } +/* Gamma term for d molality of species */ +/* Note dg includes molality as a factor */ + + row = row * (count_unknowns + 1); + if (s[k]->type != SURF && s[k] != s_h2o ) { + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n","Activity coefficient", (double) (-1.0 * coef_in), row/(count_unknowns + 1), mu_unknown->number); + } + /* mu term */ + if (gamma_source != NULL) { + store_jacob(gamma_source, &array[row + mu_unknown->number], -1.0 * coef_in); +#ifdef SKIP + if (use_tot_g == 0) { + store_jacob(&(s[k]->dg_total_g), &array[row + mu_unknown->number], -1.0 * coef_in); + } else if (use_tot_g == 1) { + store_jacob(&(s[k]->dg), &array[row + mu_unknown->number], -1.0 * coef_in); + } +#endif + } + } +/* + * Mass of water factor + */ + if (mass_oxygen_unknown != NULL && s[k]->type != EX && s[k]->type != SURF) { + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n", + mass_oxygen_unknown->master[0]->s->name, (double) coef_in, + row/(count_unknowns+1), + mass_oxygen_unknown->number); + } + store_jacob(source, &(array[row + mass_oxygen_unknown->number]), coef_in); + } + if ( s[k] == s_h2o ) return(OK); + for ( rxn_ptr = s[k]->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s->secondary != NULL && rxn_ptr->s->secondary->in == TRUE ) { + master_ptr=rxn_ptr->s->secondary; + } else { + master_ptr=rxn_ptr->s->primary; + } + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\n",master_ptr->s->name); + } + if (master_ptr->unknown == NULL) continue; + col = master_ptr->unknown->number; + coef = coef_in * rxn_ptr->coef; + store_jacob (source, &(array[row + col]), coef); + if ( debug_prep == TRUE ) { + output_msg(OUTPUT_MESSAGE,"\t\t%-24s%10.3f\t%d\t%d\n",master_ptr->s->name, (double) coef, + row/(count_unknowns+1), col); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_jacob(LDBLE *source, LDBLE *target, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Adds a new item to either sum_jacob1 or sum_jacob2 + * If coef is 1.0, adds to sum_jacob1, which does not require a multiply + * Otherwise, adds to sum_jacob2, which allows multiply by coef + */ + if (equal(coef, 1.0, TOL) == TRUE) { + if (debug_prep == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t\tjacob1 %d\n", count_sum_jacob1); + } + sum_jacob1[count_sum_jacob1].source = source; + sum_jacob1[count_sum_jacob1++].target = target; + /* Check space */ + if (count_sum_jacob1 >= max_sum_jacob1) { + space ((void **) ((void *) &sum_jacob1), count_sum_jacob1, + &max_sum_jacob1, + sizeof(struct list1)); + } + } else { + if (debug_prep == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t\tjacob2 %d\n", count_sum_jacob2); + } + sum_jacob2[count_sum_jacob2].source = source; + sum_jacob2[count_sum_jacob2].target = target; + sum_jacob2[count_sum_jacob2++].coef=coef; + /* Check space */ + if (count_sum_jacob2 >= max_sum_jacob2) { + space ((void **) ((void *) &sum_jacob2), count_sum_jacob2, &max_sum_jacob2, + sizeof(struct list2)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_jacob0(int row, int column, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Stores in list a constant coef which will be added into jacobian array + */ + sum_jacob0[count_sum_jacob0].target = &(array[row*(count_unknowns+1) + column]); + sum_jacob0[count_sum_jacob0++].coef=coef; + /* Check space */ + if (count_sum_jacob0 >= max_sum_jacob0) { + space ((void **) ((void *) &sum_jacob0), count_sum_jacob0, + &max_sum_jacob0, + sizeof(struct list0)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_mb(LDBLE *source, LDBLE *target, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Adds item to list sum_mb1 or sum_mb2 + * If coef is 1.0, adds to sum_mb1, which does not require a multiply + * else, adds to sum_mb2, which will multiply by coef + */ + if (equal(coef, 1.0, TOL) == TRUE ) { + sum_mb1[count_sum_mb1].source = source; + sum_mb1[count_sum_mb1++].target = target; + if (count_sum_mb1 >= max_sum_mb1) { + space ((void **) ((void *) &sum_mb1), count_sum_mb1 + count_trxn + 4, + &max_sum_mb1, sizeof(struct list1)); + } + } else { + sum_mb2[count_sum_mb2].source = source; + sum_mb2[count_sum_mb2].coef = coef; + sum_mb2[count_sum_mb2++].target = target; + if (count_sum_mb2 >= max_sum_mb2) { + space ((void **) ((void *) &sum_mb2), count_sum_mb2, + &max_sum_mb2, sizeof(struct list2)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_sum_deltas(LDBLE *source, LDBLE *target, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * List sum_delta is summed to determine the change in the mass of + * each element due to mass transfers of minerals, changes show up + * in x[i]->delta. These may be multiplied by a factor under some + * situations where the entire calculated step is not taken + */ + sum_delta[count_sum_delta].source = source; + sum_delta[count_sum_delta].target = target; + sum_delta[count_sum_delta++].coef=coef; + /* Check space */ + if (count_sum_delta >= max_sum_delta) { + space ((void **) ((void *) &sum_delta), count_sum_delta, &max_sum_delta, + sizeof(struct list2)); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int switch_bases(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check if activity of first master species is predominant among activities of + * secondary master species included in mass balance. + */ + int i, j; + int first; + int return_value; + LDBLE la, la1; + struct master *master_ptr; + + return_value = FALSE; + for (i=0; i < count_unknowns; i++) { + if (x[i]->type != MB) continue; + first = 0; + la = x[i]->master[0]->s->la; + for (j=1; x[i]->master[j] != NULL; j++) { + la1 = x[i]->master[j]->s->lm + x[i]->master[j]->s->lg; + if (first == 0 && la1 > la + 10.) { + la = la1; + first = j; + } else if (first != 0 && la1 > la ) { + la = la1; + first = j; + } + } + if (first != 0) { + master_ptr = x[i]->master[0]; + x[i]->master[0] = x[i]->master[first]; + x[i]->master[0]->in = TRUE; + x[i]->master[first] = master_ptr; + x[i]->master[first]->in = REWRITE; + output_msg(OUTPUT_LOG,"Switching bases to %s.\tIteration %d\n", + x[i]->master[0]->s->name, iterations); + return_value = TRUE; + } + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int tidy_redox (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Write pe redox reactions (rxn in struct pe_data) in terms of master species + * defined in analytical data + * + */ + int i, j, l; + char *ptr; + char token[MAX_LENGTH], tok1[MAX_LENGTH], tok2[MAX_LENGTH]; + struct pe_data *pe_data_ptr; + struct master *master_ptr1, *master_ptr2; +/* + * Keep valences of oxygen and hydrogen in model, if not already in + */ + for (i=0; i < count_master; i++) { + if (master[i]->primary == TRUE && + (master[i]->s == s_hplus || + master[i]->s == s_h2o ) ) { + j = i+1; + while (j < count_master && master[j]->elt->primary == master[i]) { + if (master[j]->in == FALSE && + master[j]->s != master[i]->s) { + master[j]->in = REWRITE; + master[j]->pe_rxn = master[i]->pe_rxn; + } + j++; + } + } + } +/* + * Writes equations for e- for each redox couple used in solution n + */ + for (pe_data_ptr = pe_x; pe_data_ptr->name != NULL; pe_data_ptr++) { + if (strcmp_nocase_arg1(pe_data_ptr->name,"pe") == 0 ) { + rxn_free(pe_data_ptr->rxn); + pe_data_ptr->rxn = rxn_dup(s_eminus->rxn); + } else { + strcpy(token, pe_data_ptr->name); + replace ("/"," ",token); + ptr=token; +/* + * Get redox states and elements from redox couple + */ + copy_token (tok1, &ptr, &l); + copy_token (tok2, &ptr, &l); +/* + * Find master species + */ + master_ptr1 = master_bsearch(tok1); + master_ptr2 = master_bsearch(tok2); + if (master_ptr1 != NULL && master_ptr2 != NULL ) { + rewrite_master_to_secondary (master_ptr1, master_ptr2); +/* + * Rewrite equation to e- + */ + trxn_swap ("e-"); + } else { + sprintf(error_string, "Can not find master species for redox couple, %s.", pe_data_ptr->name); + error_msg(error_string, STOP); + } + if (inout() == FALSE) { + sprintf(error_string, "Analytical data missing for redox couple, %s\n\t Using pe instead.", pe_data_ptr->name ); + warning_msg(error_string); + rxn_free(pe_data_ptr->rxn); + pe_data_ptr->rxn = rxn_dup(s_eminus->rxn); + pe_data_ptr->name = pe_x[0].name; + } else { + rxn_free(pe_data_ptr->rxn); + pe_data_ptr->rxn = rxn_alloc(count_trxn+1); + trxn_copy (pe_data_ptr->rxn); + } + } + } +/* + * Rewrite equations to master species that are "in" the model + */ + for (pe_data_ptr = pe_x; pe_data_ptr->name != NULL; pe_data_ptr++) { + count_trxn=0; + trxn_add(pe_data_ptr->rxn, 1.0, FALSE); + if (write_mass_action_eqn_x(CONTINUE) == FALSE) { + sprintf(error_string, "Could not rewrite redox " + "couple equation for %s\n\t Possibly missing data for one " + "of the redox states.", pe_data_ptr->name); + warning_msg(error_string); + sprintf(error_string, "Using pe instead of %s.", pe_data_ptr->name); + warning_msg(error_string); + rxn_free(pe_data_ptr->rxn); + pe_data_ptr->rxn = rxn_dup (pe_x[0].rxn); + pe_data_ptr->name = pe_x[0].name; + } else { + rxn_free(pe_data_ptr->rxn); + pe_data_ptr->rxn = rxn_alloc(count_trxn+1); + trxn_copy (pe_data_ptr->rxn); + } + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int write_mb_eqn_x (void) +/* ---------------------------------------------------------------------- */ +{ + int count, repeat; + int i, count_rxn_orig; + int j, k; + char *ptr; + struct master *master_ptr; +/* + * Rewrite any secondary master species flagged REWRITE + * Don't add in any pe reactions + */ + count = 0; + repeat = TRUE; + while (repeat == TRUE) { + count++; + if (count > MAX_ADD_EQUATIONS) { + sprintf(error_string, "Could not reduce equation " + "to primary and secondary species that are " + "in the model, %s.", trxn.token[0].s->name); + error_msg(error_string, CONTINUE); + return(ERROR); + } + repeat = FALSE; + count_rxn_orig=count_trxn; + for (i=1; i < count_rxn_orig; i++) { + if (trxn.token[i].s->secondary == NULL) continue; + if (trxn.token[i].s->secondary->in == REWRITE ) { + repeat=TRUE; + trxn_add(trxn.token[i].s->secondary->rxn_secondary, + trxn.token[i].coef, FALSE); + } + } + trxn_combine(); + } +/* + * + */ + count_elts = 0; + paren_count = 0; + for (i = 1; i < count_trxn; i++) { + j = count_elts; + ptr = trxn.token[i].s->name; + get_elts_in_species(&ptr, trxn.token[i].coef); + for (k = j; k < count_elts; k++) { + if (trxn.token[i].s->secondary != NULL) { + master_ptr = trxn.token[i].s->secondary->elt->primary; + } else { + master_ptr = trxn.token[i].s->primary; + } + if (elt_list[k].elt == master_ptr->elt) { + elt_list[k].coef = 0.0; + break; + } + } + if (trxn.token[i].s->secondary == NULL) { + ptr = trxn.token[i].s->primary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } else { + ptr = trxn.token[i].s->secondary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int write_mb_for_species_list (int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sets up data to add to species_list + * Original secondary redox states are retained + */ + int i; + char *ptr; +/* + * Start with secondary reaction + */ + count_trxn=0; + trxn_add (s[n]->rxn_s, 1.0, FALSE); +/* + * Copy to elt_list + */ + count_elts = 0; + paren_count = 0; + for (i = 1; i < count_trxn; i++) { + if (trxn.token[i].s->secondary == NULL) { + ptr = trxn.token[i].s->primary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } else { + ptr = trxn.token[i].s->secondary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } + } + for (i = 0; i < count_elts; i++) { + if (strcmp(elt_list[i].elt->name, "O(-2)") == 0) { + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + elt_list[count_elts].elt = element_h_one; + elt_list[count_elts].coef = elt_list[i].coef*2; + count_elts++; + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } + s[n]->next_sys_total = (struct elt_list *) free_check_null(s[n]->next_sys_total); + s[n]->next_sys_total = elt_list_save(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int write_phase_sys_total (int n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sets up data to add to species_list + * Original secondary redox states are retained + */ + int i; + char *ptr; +/* + * Start with secondary reaction + */ + count_trxn=0; + trxn_add (phases[n]->rxn_s, 1.0, FALSE); +/* + * Copy to elt_list + */ + count_elts = 0; + paren_count = 0; + for (i = 1; i < count_trxn; i++) { + if (trxn.token[i].s->secondary == NULL) { + ptr = trxn.token[i].s->primary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } else { + ptr = trxn.token[i].s->secondary->elt->name; + get_secondary_in_species(&ptr, trxn.token[i].coef); + } + } + for (i = 0; i < count_elts; i++) { + if (strcmp(elt_list[i].elt->name, "O(-2)") == 0) { + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + elt_list[count_elts].elt = element_h_one; + elt_list[count_elts].coef = elt_list[i].coef*2; + count_elts++; + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } + phases[n]->next_sys_total = (struct elt_list *) free_check_null(phases[n]->next_sys_total); + phases[n]->next_sys_total = elt_list_save(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int k_temp(LDBLE tempc) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates log k's for all species and pure_phases + */ + int i; + LDBLE tempk; + + if (same_model == TRUE && same_temperature == TRUE) return(OK); + + tempk=tempc+273.15; +/* + * Calculate log k for all aqueous species + */ + for (i=0; i < count_s_x; i++) { + s_x[i]->lk = k_calc(s_x[i]->rxn_x->logk, tempk); + } +/* + * Calculate log k for all pure phases + */ + for (i=0; i < count_phases; i++) { + if (phases[i]->in == TRUE) { + phases[i]->lk = k_calc(phases[i]->rxn_x->logk, tempk); + } + } +/* + * Calculate miscibility gaps for solid solutions + */ + if (use.s_s_assemblage_ptr != NULL ) { + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + if (fabs(tempk - use.s_s_assemblage_ptr->s_s[i].tk) > 0.01) { + s_s_prep(tempk, &(use.s_s_assemblage_ptr->s_s[i]), FALSE); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE k_calc(LDBLE *logk, LDBLE tempk) +/* ---------------------------------------------------------------------- */ +{ +/* + * Calculates log k at specified temperature + * + * Input: + * *logk is pointer to logkt0, deltah, and analytical expression data + * tempk is temperature in degrees K. + * + * Returns calculated log k. + */ + return(logk[0] + - logk[1]*(298.15-tempk)/(298.15*tempk*LOG_10*R_KJ_DEG_MOL) + + logk[2] + + logk[3]*tempk + + logk[4]/tempk + + logk[5]*log10(tempk) + + logk[6]/(tempk*tempk) ); +} +/* ---------------------------------------------------------------------- */ +static int save_model(void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * save temperature + */ + last_model.temperature = tc_x; +/* + * mark master species + */ + for (i = 0; i < count_master; i++) { + master[i]->last_model = FALSE; + if (master[i]->total > 0) { + if (master[i]->primary == TRUE) { + master[i]->last_model = TRUE; + } else { + /* mark primary master */ + master[i]->s->secondary->elt->primary->last_model = TRUE; + } + } + } +/* + * save list of phase pointers for gas phase + */ + last_model.gas_phase = (struct phase **) free_check_null(last_model.gas_phase); + if (use.gas_phase_ptr != NULL) { + last_model.count_gas_phase = use.gas_phase_ptr->count_comps; + last_model.gas_phase = (struct phase **) PHRQ_malloc((size_t) use.gas_phase_ptr->count_comps * sizeof(struct phase *)); + if (last_model.gas_phase == NULL) malloc_error(); + for (i = 0; i < use.gas_phase_ptr->count_comps; i++) { + last_model.gas_phase[i] = use.gas_phase_ptr->comps[i].phase; + } + } else { + last_model.count_gas_phase = 0; + last_model.gas_phase = NULL; + } +/* + * save list of names of solid solutions + */ + last_model.s_s_assemblage = (char **) free_check_null(last_model.s_s_assemblage); + if (use.s_s_assemblage_ptr != NULL) { + last_model.count_s_s_assemblage = use.s_s_assemblage_ptr->count_s_s; + last_model.s_s_assemblage = (char **) PHRQ_malloc((size_t) use.s_s_assemblage_ptr->count_s_s * sizeof(char *)); + if (last_model.s_s_assemblage == NULL) malloc_error(); + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + last_model.s_s_assemblage[i] = use.s_s_assemblage_ptr->s_s[i].name; + } + } else { + last_model.count_s_s_assemblage = 0; + last_model.s_s_assemblage = NULL; + } +/* + * save list of phase pointers for pp_assemblage + */ + last_model.pp_assemblage = (struct phase **) free_check_null(last_model.pp_assemblage); + last_model.add_formula = (char **) free_check_null(last_model.add_formula); + last_model.si = (double *) free_check_null(last_model.si); + if (use.pp_assemblage_ptr != NULL) { + last_model.count_pp_assemblage = use.pp_assemblage_ptr->count_comps; + last_model.pp_assemblage = (struct phase **) PHRQ_malloc((size_t) use.pp_assemblage_ptr->count_comps * sizeof(struct phase *)); + if (last_model.pp_assemblage == NULL) malloc_error(); + last_model.add_formula = (char **) PHRQ_malloc((size_t) use.pp_assemblage_ptr->count_comps * sizeof(char *)); + if (last_model.add_formula == NULL) malloc_error(); + last_model.si = (double *) PHRQ_malloc((size_t) use.pp_assemblage_ptr->count_comps * sizeof(LDBLE)); + if (last_model.si == NULL) malloc_error(); + for (i = 0; i < use.pp_assemblage_ptr->count_comps; i++) { + last_model.pp_assemblage[i] = use.pp_assemblage_ptr->pure_phases[i].phase; + last_model.add_formula[i] = use.pp_assemblage_ptr->pure_phases[i].add_formula; + last_model.si[i] = use.pp_assemblage_ptr->pure_phases[i].si; + } + } else { + last_model.count_pp_assemblage = 0; + last_model.pp_assemblage = NULL; + last_model.add_formula = NULL; + last_model.si = NULL; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int check_same_model(void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Force new model to be built in prep + */ + if (last_model.force_prep == TRUE) { + last_model.force_prep = FALSE; + same_temperature = FALSE; + return(FALSE); + } +/* + * Check temperature + */ + if (fabs(tc_x - last_model.temperature) < 0.05) { + same_temperature = TRUE; + } else { + same_temperature = FALSE; + } +/* + * Check master species + */ + for (i = 0; i < count_master; i++) { +/* + output_msg(OUTPUT_MESSAGE,"%s\t%e\t%d\n", master[i]->elt->name, + master[i]->total, master[i]->last_model); + */ + if (master[i]->s == s_hplus || master[i]->s == s_h2o) continue; + if (master[i]->total > MIN_TOTAL && master[i]->last_model == TRUE) continue; + if (master[i]->total <= MIN_TOTAL && master[i]->last_model == FALSE) continue; + return(FALSE); + } +/* + * Check gas_phase + */ + if (use.gas_phase_ptr != NULL) { + if (last_model.count_gas_phase != use.gas_phase_ptr->count_comps) return(FALSE); + for (i = 0; i < use.gas_phase_ptr->count_comps; i++) { + if(last_model.gas_phase[i] != use.gas_phase_ptr->comps[i].phase) { + return(FALSE); + } + } + } else { + if(last_model.gas_phase != NULL) return(FALSE); + } +/* + * Check solid solutions + */ + if (use.s_s_assemblage_ptr != NULL) { + if (last_model.count_s_s_assemblage != use.s_s_assemblage_ptr->count_s_s) return(FALSE); + for (i = 0; i < use.s_s_assemblage_ptr->count_s_s; i++) { + if(last_model.s_s_assemblage[i] != use.s_s_assemblage_ptr->s_s[i].name) { + return(FALSE); + } + } + } else { + if(last_model.s_s_assemblage != NULL) return(FALSE); + } +/* + * Check pure_phases + */ + if (use.pp_assemblage_ptr != NULL) { + if (last_model.count_pp_assemblage != use.pp_assemblage_ptr->count_comps) return(FALSE); + for (i = 0; i < use.pp_assemblage_ptr->count_comps; i++) { + if(last_model.pp_assemblage[i] != use.pp_assemblage_ptr->pure_phases[i].phase) { + return(FALSE); + } + if(last_model.add_formula[i] != use.pp_assemblage_ptr->pure_phases[i].add_formula) { + return(FALSE); + } + if(last_model.si[i] != use.pp_assemblage_ptr->pure_phases[i].si) { + return(FALSE); + } + } + } else { + if(last_model.pp_assemblage != NULL) return(FALSE); + } +/* + * Model is the same + */ + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int build_min_exch(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Defines proportionality factor between mineral and exchanger to + * jacob0 + */ + int i, j, k, n, jj; + int row; + struct exch_comp *comp_ptr; + struct master *master_ptr; + struct unknown *unknown_ptr; + LDBLE coef; + + if (use.exchange_ptr == NULL) return(OK); + if (exchange_bsearch(use.exchange_ptr->n_user, &n) == NULL) { + input_error++; + sprintf(error_string,"Exchange %d not found.", use.exchange_ptr->n_user); + error_msg(error_string, CONTINUE); + } + if (exchange[n].related_phases == FALSE) return(OK); + for (i=0; i=0; j--) { + if (x[j]->type != EXCH) continue; + if (x[j]->master[0] == exchange[n].comps[i].master) break; + } + for (k=count_unknowns-1; k>=0; k--) { + if (x[k]->type != PP) continue; + if (x[k]->phase->name == exchange[n].comps[i].phase_name) break; + } + if (j == -1 ) { + input_error++; + sprintf(error_string,"Did not find unknown for master exchange species %s", exchange[n].comps[i].master->s->name); + error_msg(error_string, CONTINUE); + } + if (j == -1 || k == -1) continue; +/* + * Build jacobian + */ + comp_ptr = &exchange[n].comps[i]; + + /* charge balance */ + store_jacob0(charge_balance_unknown->number, x[k]->number, comp_ptr->formula_z * comp_ptr->phase_proportion); + store_sum_deltas(&delta[k], &charge_balance_unknown->delta, -comp_ptr->formula_z * comp_ptr->phase_proportion); + + + /* mole balance balance */ + for (jj = 0; comp_ptr->formula_totals[jj].elt != NULL; jj++) { + master_ptr = comp_ptr->formula_totals[jj].elt->primary; + if (master_ptr->in == FALSE) { + master_ptr = master_ptr->s->secondary; + } + if (master_ptr == NULL) { + input_error++; + sprintf(error_string,"Did not find unknown for exchange related to mineral %s", exchange[n].comps[i].phase_name); + error_msg(error_string, STOP); + } + if (master_ptr->s->type == EX) { + if (equal(x[j]->moles, x[k]->moles * comp_ptr->formula_totals[jj].coef * comp_ptr->phase_proportion, 1.e-8) == FALSE) { + input_error++; + sprintf(error_string,"Number of sites in exchanger %s (=%e) not consistent with moles calculated from phase %s (%e).", master_ptr->s->name, (double) x[j]->moles, comp_ptr->phase_name, (double) (x[k]->moles * comp_ptr->formula_totals[jj].coef * comp_ptr->phase_proportion)); + error_msg(error_string, CONTINUE); + } + } + coef = comp_ptr->formula_totals[jj].coef; + if (master_ptr->s == s_hplus) { + row = mass_hydrogen_unknown->number; + unknown_ptr = mass_hydrogen_unknown; +#ifdef COMBINE +#ifndef COMBINE_CHARGE + coef = x[j]->master[0]->s->h - 2 * x[j]->master[0]->s->o; +#else + coef = x[j]->master[0]->s->h - 2 * x[j]->master[0]->s->o - x[j]->master[0]->s->z ; +#endif +#endif + } else if (master_ptr->s == s_h2o) { + row = mass_oxygen_unknown->number; + unknown_ptr = mass_oxygen_unknown; + } else { + row = master_ptr->unknown->number; + unknown_ptr = master_ptr->unknown; + } + store_jacob0(row, x[k]->number, coef * comp_ptr->phase_proportion); + store_sum_deltas(&delta[k], &unknown_ptr->delta, -coef * comp_ptr->phase_proportion); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_min_surface(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Defines proportionality factor between mineral and surface to + * jacob0 + */ + int i, j, k, n, jj, row; + struct elt_list *next_elt; + struct surface_comp *comp_ptr; + struct unknown *unknown_ptr; + struct master *master_ptr; + LDBLE coef; + + if (use.surface_ptr == NULL) return(OK); + if (surface_bsearch(use.surface_ptr->n_user, &n) == NULL) { + input_error++; + sprintf(error_string,"Surface %d not found.", use.surface_ptr->n_user); + error_msg(error_string, CONTINUE); + } + if (surface[n].related_phases == FALSE) return(OK); + for (i=0; i=0; j--) { + if (x[j]->type != SURFACE) continue; + if (x[j]->master[0] == surface[n].comps[i].master) break; + } + for (k=count_unknowns-1; k>=0; k--) { + if (x[k]->type != PP) continue; + if (x[k]->phase->name == surface[n].comps[i].phase_name) break; + } + if (j == -1 ) { + input_error++; + sprintf(error_string,"Did not find unknown for master surface species %s", surface[n].comps[i].master->s->name); + error_msg(error_string, CONTINUE); + } + if (j == -1 || k == -1) continue; + + next_elt = x[j]->master[0]->s->next_elt; + comp_ptr = x[j]->surface_comp; + + /* update grams == moles in this case */ + if(j < count_unknowns - 1 && x[j+1]->type == SURFACE_CB) { +#ifdef SKIP +/* Major error, can't use "use." because it changes every time + have to use only things allocated in prep.c Now put + grams into unknown structure. */ +/* + store_sum_deltas(&delta[k], &(use.surface_ptr->charge[comp_ptr->charge].grams), -1.0); + */ +#endif + store_sum_deltas(&delta[k], &(x[j+1]->related_moles), -1.0); + } + /* mole balance balance */ + for (jj = 0; next_elt[jj].elt != NULL; jj++) { + master_ptr = next_elt[jj].elt->primary; + if (master_ptr->in == FALSE) { + master_ptr = master_ptr->s->secondary; + } + if (master_ptr == NULL) { + input_error++; + sprintf(error_string,"Did not find unknown for surface related to mineral %s", surface[n].comps[i].phase_name); + error_msg(error_string, STOP); + } + if (master_ptr->s->type == SURF) { + if (equal(x[j]->moles, x[k]->moles * next_elt[jj].coef * comp_ptr->phase_proportion, 1.e-8) == FALSE) { + input_error++; + sprintf(error_string,"Number of sites in surface %s (=%e) not consistent with moles of phase %s (=%e).\n%s", master_ptr->s->name, (double) x[j]->moles, comp_ptr->phase_name, (double) (x[k]->moles * next_elt[jj].coef * comp_ptr->phase_proportion), "\tHas equilibrium_phase assemblage been redefined?\n"); + error_msg(error_string, CONTINUE); + } + } + coef = next_elt[jj].coef; + if (master_ptr->s == s_hplus) { + row = mass_hydrogen_unknown->number; + unknown_ptr = mass_hydrogen_unknown; +#ifdef COMBINE +#ifndef COMBINE_CHARGE + coef = x[j]->master[0]->s->h - 2 * x[j]->master[0]->s->o; +#else + coef = x[j]->master[0]->s->h - 2 * x[j]->master[0]->s->o - x[j]->master[0]->s->z; +#endif +#endif + } else if (master_ptr->s == s_h2o) { + row = mass_oxygen_unknown->number; + unknown_ptr = mass_oxygen_unknown; + } else { + row = master_ptr->unknown->number; + unknown_ptr = master_ptr->unknown; + } + store_jacob0(row, x[k]->number, coef * comp_ptr->phase_proportion); + store_sum_deltas(&delta[k], &unknown_ptr->delta, -coef * comp_ptr->phase_proportion); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int setup_related_surface (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Fill in data for surface assemblage in unknown structure + */ + int i, k; + struct surface_comp *comp_ptr; + + if (use.surface_ptr == NULL) return(OK); + if (use.surface_ptr->related_phases == FALSE) return(OK); + + for (i = 0; i < count_unknowns; i++) { + if (x[i]->type == SURFACE && x[i]->surface_comp->phase_name != NULL) { + for (k=count_unknowns-1; k>=0; k--) { + if (x[k]->type != PP) continue; + if (x[k]->phase->name == x[i]->surface_comp->phase_name) break; + } + if (k == -1) continue; + + comp_ptr = x[i]->surface_comp; + x[i]->phase_unknown = x[k]; +/* !!!!! */ + x[i]->moles = x[k]->moles * comp_ptr->phase_proportion; + + } else if (x[i]->type == SURFACE_CB && x[i-1]->surface_comp->phase_name != NULL) { + for (k=count_unknowns-1; k>=0; k--) { + if (x[k]->type != PP) continue; + if (x[k]->phase->name == x[i]->surface_comp->phase_name) break; + } + if (k == -1) continue; + + comp_ptr = x[i]->surface_comp; + x[i]->phase_unknown = x[k]; +/* !!!! Added for security, not checked... */ + x[i]->related_moles = x[k]->moles * comp_ptr->phase_proportion; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int change_hydrogen_in_elt_list(LDBLE charge) +/* ---------------------------------------------------------------------- */ +{ + int j; + int found_h, found_o; + LDBLE coef_h, coef_o, coef; + found_h = -1; + found_o = -1; + coef_h = 0.0; + coef_o = 0.0; + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + for (j = 0; j < count_elts; j++) { + if (strcmp(elt_list[j].elt->name,"H") == 0) { + found_h = j; + coef_h = elt_list[j].coef; + } else if (strcmp(elt_list[j].elt->name,"O") == 0) { + found_o = j; + coef_o = elt_list[j].coef; + } + } + coef = coef_h-2*coef_o - charge; + if (found_h < 0 && found_o < 0) return(OK); + if (found_h >= 0 && found_o < 0) return(OK); + if (found_h < 0 && found_o >= 0) { + elt_list[count_elts].elt = s_hplus->primary->elt; + elt_list[count_elts].coef = coef; + count_elts++; + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + return(OK); + } + elt_list[found_h].coef = coef; + return(OK); +} diff --git a/print.cpp b/print.cpp new file mode 100644 index 00000000..223c3e72 --- /dev/null +++ b/print.cpp @@ -0,0 +1,2259 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +#define PITZER_EXTERNAL extern +#include "pitzer.h" +#include + +static char const svnid[] = "$Id: print.c 701 2005-12-22 15:20:59Z dlpark $"; + +static int print_alkalinity(void); +static int print_diffuse_layer(struct surface_charge *surface_charge_ptr); +static int print_eh(void); +static int print_irrev(void); +static int print_kinetics(void); +static int print_mix(void); +static int print_pp_assemblage(void); +static int print_s_s_assemblage(void); +static int print_saturation_indices(void); +static int print_totals(void); +static int print_using(void); +static int print_user_print(void); +static int punch_gas_phase(void); +static int punch_identifiers(void); +static int punch_kinetics(void); +static int punch_molalities(void); +static int punch_activities(void); +static int punch_pp_assemblage(void); +static int punch_s_s_assemblage(void); +static int punch_saturation_indices(void); +static int punch_totals(void); +static int punch_user_punch(void); + +#ifdef PHREEQ98 +static int punch_user_graph(void); +extern int colnr, rownr; +extern int graph_initial_solutions; +extern int prev_advection_step, prev_transport_step; /*, prev_reaction_step*/ +/* extern int shifts_as_points; */ +extern int chart_type; +extern int AddSeries; +extern int FirstCallToUSER_GRAPH; +#endif + +#if defined(SWIG_SHARED_OBJ) +extern void EndRow(void); +extern void AddSelectedOutput(const char* name, const char* format, va_list argptr); +#endif + +/* ---------------------------------------------------------------------- */ +int array_print(LDBLE *array_l, int row_count, int column_count, int max_column_count) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + if (svnid == NULL) fprintf(stderr," "); + + + for (i=0; i < row_count; i++) { + k = 0; + output_msg(OUTPUT_MESSAGE,"%d\n", i); + for (j=0; j < column_count; j++) { + if (k > 7) { + output_msg(OUTPUT_MESSAGE,"\n"); + k = 0; + } + output_msg(OUTPUT_MESSAGE,"%11.2e", (double) array_l[i*max_column_count + j]); + k++; + } + if (k != 0) { + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_all(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print each block of results in sequence to file output + * also print selected output to punch_file + * Each routine is controlled by a variable in structure print. + * print.all == FALSE will turn off all prints. + */ +/* + * Makes sorted list including all species for each valence state + */ + if (pr.all == FALSE) return(OK); + if(pr.surface == TRUE || + pr.exchange == TRUE || + pr.species == TRUE ) { + species_list_sort(); + } +/* + * Print results + */ + s_h2o->lm = s_h2o->la; + print_using(); + print_mix(); + print_irrev(); + print_kinetics(); + print_user_print(); + print_gas_phase(); + print_pp_assemblage(); + print_s_s_assemblage(); + print_surface(); + print_exchange(); + print_initial_solution_isotopes(); + print_isotope_ratios(); + print_isotope_alphas(); + print_totals(); + print_eh(); + print_species(); + print_alkalinity(); + print_saturation_indices(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_all(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + +#ifndef PHREEQ98 /* if not PHREEQ98 use the standard declaration */ + if (pr.hdf == FALSE && (punch.in == FALSE || pr.punch == FALSE)) return(OK); +/* + * Punch results + */ + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + use.kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &i); + } else if (use.kinetics_in != FALSE) { + use.kinetics_ptr = kinetics_bsearch(-2, &i); + } +#else /* if PHREEQ98 execute punch_user_graph first, that is, before punch.in and pr.punch is checked */ + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + use.kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &i); + } else if (use.kinetics_in != FALSE) { + use.kinetics_ptr = kinetics_bsearch(-2, &i); + } + if (pr.user_graph == TRUE) punch_user_graph(); + + if (pr.hdf == FALSE && (punch.in == FALSE || pr.punch == FALSE)) return(OK); +#endif + punch_identifiers(); + punch_totals(); + punch_molalities(); + punch_activities(); + punch_pp_assemblage(); + punch_saturation_indices(); + punch_gas_phase(); + punch_kinetics(); + punch_s_s_assemblage(); + punch_isotopes(); + punch_calculate_values(); + punch_user_punch(); +/* + * new line for punch_file + */ + fpunchf(NULL, "\n"); + +#if defined(SWIG_SHARED_OBJ) + EndRow(); +#endif + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_diffuse_layer(struct surface_charge *surface_charge_ptr1) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints total moles of each element in diffuse layer + * Remove comment to print total moles of each species + */ + int i, j, count_g; + LDBLE mass_water_surface; + LDBLE molality, moles_excess, moles_surface; + + if (use.surface_ptr == NULL) return(OK); +/* + * Find position of component in surface charge data + */ + i = 0; + for (j = 0; j < count_unknowns; j++) { + if (x[j]->type != SURFACE_CB) continue; + if (x[j]->surface_charge == surface_charge_ptr1) { + break; + } + i++; + } + if (j >= count_unknowns) { + sprintf(error_string, "In print_diffuse_layer: component not found, %s.", surface_charge_ptr1->name); + error_msg(error_string, STOP); + } +/* + * Loop through all surface components, calculate each H2O surface (diffuse layer), + * H2O aq, and H2O bulk (diffuse layers plus aqueous). + */ + + output_msg(OUTPUT_MESSAGE,"\tKg water in diffuse layer: %e\n", + (double) surface_charge_ptr1->mass_water); + + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE,"\n\t\tDistribution of species in diffuse layer\n\n"); + output_msg(OUTPUT_MESSAGE,"\n\tSpecies \t Moles \tMoles excess\t g\n"); + } + mass_water_surface = surface_charge_ptr1->mass_water; + count_elts = 0; + paren_count = 0; + for (j = 0; j < count_s_x; j++) { + if (s_x[j]->type > HPLUS) continue; + molality = under(s_x[j]->lm); + count_g = s_x[j]->diff_layer[i].count_g; +#ifdef SKIP + moles_excess = mass_water_bulk_x * +/* s_x[j]->diff_layer[i].charge->g[count_g].g * molality; */ + surface_charge_ptr1->g[count_g].g * molality; +#endif + moles_excess = mass_water_aq_x * molality * surface_charge_ptr1->g[count_g].g; + moles_surface = mass_water_surface * molality + moles_excess; + if (debug_diffuse_layer == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t%-12s\t%12.3e\t%12.3e\t%12.3e\n", s_x[j]->name, + moles_surface, moles_excess, s_x[j]->diff_layer[i].charge->g[count_g].g); + } +/* + * Accumulate elements in diffuse layer + */ + add_elt_list(s_x[j]->next_elt, moles_surface); + } +/* + strcpy(token, s_h2o->name); + ptr = &(token[0]); + get_elts_in_species (&ptr, mass_water_surface / gfw_water); + */ + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } +/* + * Print totals + */ + if (use.surface_ptr->donnan == FALSE) { + output_msg(OUTPUT_MESSAGE,"\n\tTotal moles in diffuse layer (excluding water)\n\n"); + } else { + output_msg(OUTPUT_MESSAGE,"\n\tTotal moles in diffuse layer (excluding water), Donnan calculation \n\n"); + } + output_msg(OUTPUT_MESSAGE,"\tElement \t Moles\n"); + for ( j=0; j < count_elts; j++ ) { + output_msg(OUTPUT_MESSAGE, "\t%-14s\t%12.4e\n", + elt_list[j].elt->name, + (double) elt_list[j].coef); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_eh(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints eh calculated from redox couples + * Only calculates eh if two redox states of an element have mass balance + * equations. + */ + int i, j, k, first; + LDBLE pe, eh; + struct master *master_ptr0, *master_ptr1; + char token[MAX_LENGTH]; + + if (pr.eh == FALSE || pr.all == FALSE) return(OK); + + tk_x=tc_x+273.15; + + first = TRUE; + for (i=0; i < count_master; i++) { + if (master[i]->in != TRUE ) continue; + if (master[i]->primary == TRUE) continue; +/* + * Secondary master species has mass balance equation + */ + master_ptr0 = master[i]->elt->primary; + for (k = i + 1; k < count_master; k++) { + if (master[k]->in != TRUE) continue; + master_ptr1 = master[k]->elt->primary; + if ( master_ptr1 != master_ptr0) break; +/* + * Another secondary master species of same element has mass balance equation + * Rewrite equations to calculate pe + */ + rewrite_master_to_secondary ( master[k], master[i] ); + trxn_swap ("e-"); +/* debug + trxn_print(); + */ +/* + * Calculate pe, eh + */ + pe = -k_calc(trxn.logk, tk_x); + for (j = 1; j < count_trxn; j++) { + pe -= trxn.token[j].s->la * trxn.token[j].coef; + } + eh = ( (LOG_10 * R_KJ_DEG_MOL * tk_x) / F_KJ_V_EQ ) * pe; +/* + * Print heading + */ + if (first == TRUE) { + print_centered("Redox couples"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s\n\n","Redox couple","pe","Eh (volts)"); + first = FALSE; + } +/* + * Print result + */ + strcpy(token,master[i]->elt->name); + strcat(token,"/"); + strcat(token,master[k]->elt->name); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.4f%12.4f\n", token, (double) pe, (double) eh); + } + } + if (first == FALSE) output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_exchange(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print moles of each exchange species + */ + int i; + struct exchange *exchange_ptr; + char *name, *name1; + struct master *master_ptr; + LDBLE dum, dum2; +/* + * Print exchange data + */ + exchange_ptr = use.exchange_ptr; + if (exchange_ptr == NULL || pr.exchange == FALSE || pr.all == FALSE) return(OK); + + if (state >= REACTION) { + print_centered("Exchange composition"); + } +/* + * Print list of species + */ + + s_h2o->lm = s_h2o->la; + name = s_hplus->secondary->elt->name; + for (i=0; i < count_species_list; i++) { +/* + * Get name of master species + */ + if (species_list[i].s->type != EX) continue; + if (species_list[i].master_s->secondary != NULL ) { + master_ptr = species_list[i].master_s->secondary; + name1=species_list[i].master_s->secondary->elt->name; + } else { + master_ptr = species_list[i].master_s->primary; + name1=species_list[i].master_s->primary->elt->name; + } +/* + * Check if new master species, print total molality + */ + if (name1 != name) { + name = name1; + output_msg(OUTPUT_MESSAGE,"%-14s%12.3e mol", name, (double) master_ptr->unknown->moles); + if (master_ptr->unknown->exch_comp->phase_name != NULL) { + output_msg(OUTPUT_MESSAGE, "\t[%g (mol %s)/(mol %s)]", + (double) master_ptr->unknown->exch_comp->phase_proportion, + master_ptr->unknown->exch_comp->formula, + master_ptr->unknown->exch_comp->phase_name); + } else + if (master_ptr->unknown->exch_comp->rate_name != NULL) { + output_msg(OUTPUT_MESSAGE, "\t[%g (mol %s)/(mol kinetic reactant %s)]", + (double) master_ptr->unknown->exch_comp->phase_proportion, + master_ptr->unknown->exch_comp->formula, + master_ptr->unknown->exch_comp->rate_name); + } + output_msg(OUTPUT_MESSAGE, "\n\n"); + /* Heading for species */ + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%10s\n"," "," ","Equiv- ", + "Equivalent","Log "); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%10s\n\n","Species","Moles ","alents ", + "Fraction", "Gamma"); + } +/* + * Print species data + */ +/* !!!!! */ + if (master_ptr->total > 1.0e-10) { + if (species_list[i].s->equiv != 0.0) { + dum = fabs(species_list[i].s->equiv)/master_ptr->total; + } else { + if (species_list[i].master_s->z == 0) { + dum = 1 / master_ptr->total; + } else { + dum = 1; + } + } + if (species_list[i].master_s->z != 0.0) { + dum2 = fabs(species_list[i].master_s->z); + } else { + dum2 =1; + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e%12.3e%10.3f\n", + species_list[i].s->name, + (double) species_list[i].s->moles, + (double) (species_list[i].s->moles * dum2 * species_list[i].s->equiv), + (double) (species_list[i].s->moles * dum /* / dum2 */), + (double) (species_list[i].s->lg - log10(dum)) ); + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints gas phase composition if present + */ + int j; + LDBLE lp, moles, initial_moles, delta_moles; + struct rxn_token *rxn_ptr; + + if (pr.gas_phase == FALSE || pr.all == FALSE) return(OK); + if (use.gas_phase_ptr == NULL) return(OK); + if (use.gas_phase_ptr->type == PRESSURE) { + if (gas_unknown == NULL) return(OK); + if (gas_unknown->moles < 1e-12) return(OK); + use.gas_phase_ptr->total_moles = gas_unknown->moles; + use.gas_phase_ptr->volume = use.gas_phase_ptr->total_moles * R_LITER_ATM * tk_x / use.gas_phase_ptr->total_p; + } +/* + * Print heading + */ + print_centered("Gas phase"); + output_msg(OUTPUT_MESSAGE,"\n"); + output_msg(OUTPUT_MESSAGE, "Total pressure: %8.4f atmospheres\n", (double) use.gas_phase_ptr->total_p); + output_msg(OUTPUT_MESSAGE, " Gas volume: %10.2e liters\n", (double) use.gas_phase_ptr->volume); + + output_msg(OUTPUT_MESSAGE, "\n%66s\n%75s\n", "Moles in gas", "----------------------------------"); + output_msg(OUTPUT_MESSAGE,"%-15s%12s%12s%12s%12s%12s\n","Component","log P", "P", "Initial", "Final", + "Delta"); + + for( j = 0; j < use.gas_phase_ptr->count_comps; j++) { +/* + * Calculate partial pressure + */ + if (use.gas_phase_ptr->comps[j].phase->in == TRUE) { + lp=-use.gas_phase_ptr->comps[j].phase->lk; + for (rxn_ptr = use.gas_phase_ptr->comps[j].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + lp += rxn_ptr->s->la * rxn_ptr->coef; + } + moles = use.gas_phase_ptr->comps[j].phase->moles_x; + } else { + lp = -99.99; + moles = 0; + use.gas_phase_ptr->comps[j].phase->p_soln_x = 0; + } +/* + * Print gas composition + */ + if (state != TRANSPORT && state != PHAST) { + initial_moles = use.gas_phase_ptr->comps[j].moles; + delta_moles = use.gas_phase_ptr->comps[j].phase->moles_x - + use.gas_phase_ptr->comps[j].moles; + } else { + initial_moles = use.gas_phase_ptr->comps[j].initial_moles; + delta_moles = use.gas_phase_ptr->comps[j].initial_moles - + use.gas_phase_ptr->comps[j].moles; + } + if (moles <= MIN_TOTAL) moles = 0.0; + if (fabs(delta_moles) <= MIN_TOTAL) delta_moles = 0.0; + output_msg(OUTPUT_MESSAGE,"%-15s%12.2f%12.3e%12.3e%12.3e%12.3e\n", + use.gas_phase_ptr->comps[j].phase->name, + (double) lp, + (double) use.gas_phase_ptr->comps[j].phase->p_soln_x, + (double) initial_moles, + (double) moles, + (double) delta_moles); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_s_s_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ + /* + * Prints solid solution composition if present + */ + int i, j; + LDBLE delta_moles; + LDBLE nb, nc, xb, xb1, xb2, xb1moles, xb2moles; + struct s_s *s_s_ptr; + + if (pr.s_s_assemblage == FALSE || pr.all == FALSE) return(OK); + if (use.s_s_assemblage_ptr == NULL) return(OK); + /* + * Print heading + */ + print_centered("Solid solutions"); + output_msg(OUTPUT_MESSAGE,"\n"); + output_msg(OUTPUT_MESSAGE, "\t%-15s %15s %11s %11s %11s\n", "Solid solution", "Component", "Moles", + "Delta moles", "Mole fract"); + /* + * Print solid solutions + */ + for( j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + if (use.s_s_assemblage_ptr->s_s[j].s_s_in == TRUE) { + /* solid solution name, moles */ + output_msg(OUTPUT_MESSAGE,"\t%-15s %15s %11.2e\n", use.s_s_assemblage_ptr->s_s[j].name," ", + (double) use.s_s_assemblage_ptr->s_s[j].total_moles); + /* component name, moles, delta moles, mole fraction */ + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (state != TRANSPORT && state != PHAST) { + delta_moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].initial_moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].delta; + } else { + delta_moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].init_moles; + } + output_msg(OUTPUT_MESSAGE, "\t%15s %15s %11.2e %11.2e %11.2e\n", " ", + use.s_s_assemblage_ptr->s_s[j].comps[i].name, + (double) use.s_s_assemblage_ptr->s_s[j].comps[i].moles, + (double) delta_moles, + (double) (use.s_s_assemblage_ptr->s_s[j].comps[i].moles/ + use.s_s_assemblage_ptr->s_s[j].total_moles)); + } + s_s_ptr = &(use.s_s_assemblage_ptr->s_s[j]); + if(s_s_ptr->miscibility == TRUE) { + nc = s_s_ptr->comps[0].moles; + nb = s_s_ptr->comps[1].moles; + xb = nb/(nb + nc); + xb1 = s_s_ptr->xb1; + xb2 = s_s_ptr->xb2; + + if (xb > xb1 && xb < xb2) { + xb2moles = (xb1 - 1)/xb1*nb + nc; + xb2moles = xb2moles / ((xb1 - 1)/xb1*xb2 + (1 - xb2)); + xb1moles = (nb - xb2moles*xb2)/xb1; + output_msg(OUTPUT_MESSAGE, "\n\t%15s Solid solution is in miscibility gap\n", " "); + output_msg(OUTPUT_MESSAGE, "\t%15s End members in pct of %s\n\n", " ", s_s_ptr->comps[1].name); + output_msg(OUTPUT_MESSAGE, "\t%15s %11g pct %11.2e\n", " ", (double) xb1, (double) xb1moles); + output_msg(OUTPUT_MESSAGE, "\t%15s %11g pct %11.2e\n", " ", (double) xb2, (double) xb2moles); + } + } + } else { + /* solid solution name, moles */ + output_msg(OUTPUT_MESSAGE,"\t%-15s %15s %11.2e\n", use.s_s_assemblage_ptr->s_s[j].name," ", + (double) 0.0); + /* component name, moles, delta moles, mole fraction */ + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (state != TRANSPORT && state != PHAST) { + delta_moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].initial_moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].delta; + } else { + delta_moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles - + use.s_s_assemblage_ptr->s_s[j].comps[i].init_moles; + } + output_msg(OUTPUT_MESSAGE, "\t%15s %15s %11.2e %11.2e %11.2e\n", " ", + use.s_s_assemblage_ptr->s_s[j].comps[i].name, + (double) 0, + (double) delta_moles, + (double) 0 ); + } + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int print_irrev(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * prints irreversible reaction as defined and as + * relative moles of each element and total amount + * of reaction + */ + int i; + struct irrev *irrev_ptr; + + if (pr.use == FALSE || pr.all == FALSE) return(OK); + if (state < REACTION || use.irrev_in == FALSE) return(OK); + if (state == TRANSPORT && transport_step == 0) return(OK); + irrev_ptr = use.irrev_ptr; +/* + * Print amount of reaction + */ + output_msg(OUTPUT_MESSAGE,"Reaction %d.\t%s\n\n", use.n_irrev_user, irrev_ptr->description); + output_msg(OUTPUT_MESSAGE,"\t%11.3e moles of the following reaction have been added:\n\n", (double) step_x); +/* + * Print reaction + */ + output_msg(OUTPUT_MESSAGE,"\t%-15s%10s\n", " ", "Relative"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%10s\n\n", "Reactant", "moles"); + for (i = 0; i < irrev_ptr->count_list; i++) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%10.2f\n", irrev_ptr->list[i].name, (double) irrev_ptr->list[i].coef); + } + output_msg(OUTPUT_MESSAGE,"\n"); +/* + * Debug + */ + + output_msg(OUTPUT_MESSAGE,"\t%-15s%10s\n", " ", "Relative"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%10s\n", "Element", "moles"); + for (i = 0; irrev_ptr->elts[i].elt != NULL; i++) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%10.2f\n", irrev_ptr->elts[i].elt->name, (double) irrev_ptr->elts[i].coef); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int print_kinetics(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * prints kinetic reaction, + * should be called only on final kinetic step + */ + int i, j; + LDBLE sim_time; + struct kinetics *kinetics_ptr; + if (pr.kinetics == FALSE || pr.all == FALSE) return(OK); + if (state < REACTION) return(OK); + kinetics_ptr = NULL; + if (use.kinetics_in == TRUE) { + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &i); + } else { + kinetics_ptr = kinetics_bsearch(-2, &i); + } + } + if (kinetics_ptr == NULL) return(OK); +/* + * determine time step + */ + if (state == TRANSPORT || state == PHAST) { + kin_time_x = timest; + } else if (state == ADVECTION) { + kin_time_x =advection_kin_time; + } + sim_time = 0.; + if (incremental_reactions == TRUE) { + if (kinetics_ptr->count_steps > 0) { + for (i = 0; i < reaction_step; i++) { + if (i < kinetics_ptr->count_steps) { + sim_time += kinetics_ptr->steps[i]; + } else { + sim_time += kinetics_ptr->steps[kinetics_ptr->count_steps - 1]; + } + } + } else if (kinetics_ptr->count_steps < 0) { + if (reaction_step > -kinetics_ptr->count_steps) { + sim_time = kinetics_ptr->steps[0]; + } else { + sim_time = reaction_step * kinetics_ptr->steps[0] / ( (LDBLE) (-kinetics_ptr->count_steps)); + } + } + } +/* + * Print amount of reaction + */ + if (phast == FALSE) { + output_msg(OUTPUT_MESSAGE,"Kinetics %d.\t%s\n\n", use.n_kinetics_user, kinetics_ptr->description); + } else { + output_msg(OUTPUT_MESSAGE,"Kinetics.\n\n"); + } +/* + * Print reaction + */ + if (state == TRANSPORT) { + output_msg(OUTPUT_MESSAGE, "\tTime: %g seconds\n",(double) (initial_total_time + transport_step * timest)); + output_msg(OUTPUT_MESSAGE,"\tTime step: %g seconds\n\n", (double) kin_time_x); + } else if (state == ADVECTION) { + output_msg(OUTPUT_MESSAGE, "\tTime: %g seconds\n",(double) (initial_total_time + advection_step * advection_kin_time)); + output_msg(OUTPUT_MESSAGE,"\tTime step: %g seconds\n\n", (double) kin_time_x); + } else if (state == PHAST) { + output_msg(OUTPUT_MESSAGE, "\tTime: %g seconds\n", (double) rate_sim_time_end); + output_msg(OUTPUT_MESSAGE,"\tTime step: %g seconds\n\n", (double) kin_time_x); + } else if (state == REACTION) { + if (incremental_reactions == FALSE) { + output_msg(OUTPUT_MESSAGE,"\tTime step: %g seconds\n\n", (double) kin_time_x); + } else { + output_msg(OUTPUT_MESSAGE,"\tTime step: %g seconds (Incremented time: %g seconds)\n\n", (double) kin_time_x, (double) sim_time); + } + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s %-15s%12s\n\n", "Rate name", "Delta Moles","Total Moles","Reactant","Coefficient"); + for (i = 0; i < kinetics_ptr->count_comps; i++) { + if (state != TRANSPORT && state != PHAST) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e", + kinetics_ptr->comps[i].rate_name, + (double) -kinetics_ptr->comps[i].moles, + (double) kinetics_ptr->comps[i].m); + } else { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e", + kinetics_ptr->comps[i].rate_name, + (double) (kinetics_ptr->comps[i].m - kinetics_ptr->comps[i].initial_moles), + (double) kinetics_ptr->comps[i].m); + } + for (j = 0; j < kinetics_ptr->comps[i].count_list; j++) { + if (j == 0) { + output_msg(OUTPUT_MESSAGE," %-15s%12g\n", kinetics_ptr->comps[i].list[j].name, + (double) kinetics_ptr->comps[i].list[j].coef); + } else { + output_msg(OUTPUT_MESSAGE,"\t%39s %-15s%12g\n"," ", kinetics_ptr->comps[i].list[j].name, + (double) kinetics_ptr->comps[i].list[j].coef); + } + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_master_reactions(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Debugging print routine to test primary and secondary reactions + */ + int i; + struct rxn_token *next_token; + + for ( i=0; i < count_master; i++) { + output_msg(OUTPUT_MESSAGE,"%s\t%s\n\tPrimary reaction\n",master[i]->elt->name, master[i]->s->name); + next_token=master[i]->rxn_primary->token; + for (; next_token->s != NULL; next_token++) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\t%f\n",next_token->s->name, (double) next_token->coef); + } + output_msg(OUTPUT_MESSAGE,"\n\tSecondary reaction:\n"); + if (master[i]->rxn_secondary != NULL) { + next_token=master[i]->rxn_secondary->token; + for (; next_token->s != NULL; next_token++) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\t%f\n",next_token->s->name, (double) next_token->coef); + } + } + output_msg(OUTPUT_MESSAGE,"\n\tRedox reaction:\n"); + if (*(master[i]->pe_rxn) != NULL) { + next_token=(*(master[i]->pe_rxn))->token; + for (; next_token->s != NULL; next_token++) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\t%f\n",next_token->s->name, (double) next_token->coef); + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int print_mix(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * prints definition of mixing, solution number and multiplier + */ + int i, n; + struct mix *mix_ptr; + struct solution *solution_ptr; + + if (pr.use == FALSE || pr.all == FALSE) return(OK); + if (use.mix_in == FALSE || state < REACTION) return(OK); + if (state == TRANSPORT) { + mix_ptr = mix_bsearch(use.n_mix_user, &i); + } else { + mix_ptr = mix_bsearch(use.n_mix_user_orig, &i); + } + if (mix_ptr == NULL) { + mix_ptr = use.mix_ptr; + } +/* + * Print mixture data + */ + if (mix_ptr == NULL) { + return(OK); + + } + if (state == TRANSPORT) { + output_msg(OUTPUT_MESSAGE,"Mixture %d.\t%s\n\n", use.n_mix_user, mix_ptr->description); + } else { + output_msg(OUTPUT_MESSAGE,"Mixture %d.\t%s\n\n", mix_ptr->n_user, mix_ptr->description); + } + for (i = 0; i < mix_ptr->count_comps; i++) { + solution_ptr = solution_bsearch (mix_ptr->comps[i].n_solution, &n, TRUE); + if (solution_ptr == NULL) { + input_error++; + return(ERROR); + } + output_msg(OUTPUT_MESSAGE,"\t%11.3e Solution %d\t%-55s\n", (double) mix_ptr->comps[i].fraction, + mix_ptr->comps[i].n_solution, solution[n]->description); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_reaction(struct reaction *rxn_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Debugging print of individual chemical reactions for + * species or phases + */ + int j; + struct rxn_token *next_token; + + if (pr.use == FALSE || pr.all == FALSE) return(OK); + + output_msg(OUTPUT_MESSAGE,"%s\t\n",rxn_ptr->token[0].s->name); + output_msg(OUTPUT_MESSAGE,"\n\tlog k:\n"); + for (j=0;j<7;j++) { + output_msg(OUTPUT_MESSAGE,"\t%f",(double) rxn_ptr->logk[j]); + } + output_msg(OUTPUT_MESSAGE,"\n\nReaction:\n"); + for (next_token=rxn_ptr->token; next_token->s != NULL; next_token++) { + output_msg(OUTPUT_MESSAGE,"\t\t%s\t%f\n",next_token->s->name, (double) next_token->coef); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_saturation_indices(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints saturation indices of all applicable pure_phases + */ + int i; + LDBLE si, iap; + LDBLE lk; + LDBLE la_eminus; + struct rxn_token *rxn_ptr; + + if (pr.saturation_indices == FALSE || pr.all == FALSE) return(OK); + if (state == INITIAL_SOLUTION) { + iap = 0; + for (rxn_ptr = pe_x[default_pe_x].rxn->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->coef*rxn_ptr->s->la; + /* fprintf(output,"\t%s\t%f\t%f\n", rxn_ptr->s->name, rxn_ptr->coef, rxn_ptr->s->la ); */ + } + lk = k_calc(pe_x[default_pe_x].rxn->logk, tk_x); + la_eminus = lk + iap; + /* fprintf(output,"\t%s\t%f\n", "pe", si ); */ + } else { + la_eminus = s_eminus->la; + } +/* + * Print heading + */ + print_centered("Saturation indices"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%7s%8s%8s\n\n","Phase","SI","log IAP", "log KT"); + + for (i=0; i < count_phases; i++) { + if (phases[i]->in == FALSE || phases[i]->type != SOLID) continue; +/* + * Print saturation index + */ +#ifdef SKIP + iap = 0.0; + for (rxn_ptr = phases[i]->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->s->la * rxn_ptr->coef; + /* fprintf(output,"\t%s\t%f\t%e\n", rxn_ptr->s->name, rxn_ptr->s->la, rxn_ptr->coef); */ + } + si=-phases[i]->lk + iap; + output_msg(OUTPUT_MESSAGE,"\t%-15s%7.2f%8.2f%8.2f %s\n",phases[i]->name, (double) si, (double) iap, (double) phases[i]->lk, phases[i]->formula); + si1 = si; +#endif + + /* pe_value_x = pe_x[default_pe_x].rxn;*/ + lk = k_calc(phases[i]->rxn->logk, tk_x); + iap = 0.0; + for (rxn_ptr = phases[i]->rxn->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + /* iap += rxn_ptr->s->la * rxn_ptr->coef; */ + if (rxn_ptr->s != s_eminus) { + iap += (rxn_ptr->s->lm + rxn_ptr->s->lg) * rxn_ptr->coef; + } else { + iap += la_eminus * rxn_ptr->coef; + } + /* output_msg(OUTPUT_MESSAGE,"\t%s\t%f\t%e\t%e\t%e\n", rxn_ptr->s->name, rxn_ptr->s->la, rxn_ptr->coef, rxn_ptr->s->lm, rxn_ptr->s->lg ); */ + } + si=-lk + iap; + output_msg(OUTPUT_MESSAGE,"\t%-15s%7.2f%8.2f%8.2f %s\n",phases[i]->name, (double) si, (double) iap, (double) lk, phases[i]->formula); + +#ifdef SKIP + if (fabs(si1-si) > convergence_tolerance) { + sprintf(error_string, "SI1 != SI, %s SI1 %e, SI %e, diff %e\n", phases[i]->name, si1, si, si1 - si); + error_msg(error_string, CONTINUE); + } +#endif + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_pp_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints saturation indices and masses of pure_phases in pp_assemblage + */ + int j, k; + LDBLE si, iap, lk; + char token[MAX_LENGTH]; + struct rxn_token *rxn_ptr; + struct phase *phase_ptr; + + if (pr.pp_assemblage == FALSE || pr.all == FALSE) return(OK); + if (pure_phase_unknown == NULL) return(OK); +/* + * Print heading + */ + print_centered("Phase assemblage"); + output_msg(OUTPUT_MESSAGE, "%74s\n", "Moles in assemblage"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%7s%8s%8s","Phase","SI","log IAP", "log KT"); + output_msg(OUTPUT_MESSAGE,"%12s%12s%12s", " Initial", " Final", " Delta"); + output_msg(OUTPUT_MESSAGE,"\n\n"); + + for( j = 0; j < count_unknowns; j++) { + if (x[j]->type != PP) continue; +/* + * Print saturation index + */ + iap = 0.0; + phase_ptr=x[j]->phase; + if (x[j]->phase->rxn_x == NULL || phase_ptr->in == FALSE) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%23s", x[j]->phase->name, "Element not present."); + } else { + phase_ptr=x[j]->phase; + lk = k_calc(phase_ptr->rxn->logk, tk_x); + for (rxn_ptr = phase_ptr->rxn->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + if (rxn_ptr->s != s_eminus) { + iap += (rxn_ptr->s->lm + rxn_ptr->s->lg) * rxn_ptr->coef; + } else { + iap += s_eminus->la * rxn_ptr->coef; + } + } + si=-lk + iap; + /* + for (rxn_ptr = x[j]->phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->s->la * rxn_ptr->coef; + } + si = -x[j]->phase->lk + iap; + output_msg(OUTPUT_MESSAGE,"\t%-15s%7.2f%8.2f%8.2f", x[j]->phase->name, (double) si, (double) iap, (double) x[j]->phase->lk); + */ + output_msg(OUTPUT_MESSAGE,"\t%-15s%7.2f%8.2f%8.2f", x[j]->phase->name, (double) si, (double) iap, (double) lk); + } +/* + * Print pure phase assemblage data + */ + if (x[j]->moles < 0.0) x[j]->moles = 0.0; + if (state != TRANSPORT && state != PHAST) { + sprintf(token, " %11.3e %11.3e %11.3e", + (double) (x[j]->pure_phase->moles + x[j]->pure_phase->delta), + (double) x[j]->moles, + (double) (x[j]->moles - x[j]->pure_phase->moles - x[j]->pure_phase->delta)); + } else { + sprintf(token, " %11.3e %11.3e %11.3e", + (double) x[j]->pure_phase->initial_moles, + (double) x[j]->moles, + (double) (x[j]->moles - x[j]->pure_phase->initial_moles)); + } + if (x[j]->moles <= 0.0) { + for (k=0; k < 11; k++) { + token[12+k] = ' '; + } + } + if (x[j]->pure_phase->add_formula == NULL) { + output_msg(OUTPUT_MESSAGE, "%36s\n", token); + } else { + output_msg(OUTPUT_MESSAGE,"\n\t\t%-15s%-15s%36s\n",x[j]->pure_phase->add_formula," is reactant", token); + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_species(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints description of solution, uses array species_list for + * order of aqueous species. + */ + int i; + char *name, *name1; + struct master *master_ptr; + LDBLE min; + LDBLE lm; + + if (pr.species == FALSE || pr.all == FALSE) return(OK); + min = -1000; + print_centered("Distribution of species"); +/* + * Heading for species + */ + if (pitzer_model == TRUE) { + if (ICON == TRUE) { + output_msg(OUTPUT_MESSAGE,"%67s%11s\n","MacInnes","MacInnes"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%10s%10s%10s\n"," "," ","MacInnes","Log ","Log ","Log "); + } else { + output_msg(OUTPUT_MESSAGE,"%67s%11s\n","Unscaled","Unscaled"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%10s%10s%10s\n"," "," ","Unscaled","Log ","Log ","Log "); + } + } else { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%10s%10s%10s\n"," "," "," ","Log ","Log ","Log "); + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%10s%10s%10s\n\n","Species","Molality","Activity", + "Molality","Activity","Gamma"); +/* + * Print list of species + */ + s_h2o->lm = s_h2o->la; + name = s_hplus->secondary->elt->name; + for (i=0; i < count_species_list; i++) { +/* + * Get name of master species + */ + if (species_list[i].s->type == EX) continue; + if (species_list[i].s->type == SURF) continue; + if (species_list[i].master_s->secondary != NULL ) { + master_ptr = species_list[i].master_s->secondary; + name1=species_list[i].master_s->secondary->elt->name; + } else { + master_ptr = species_list[i].master_s->primary; + name1=species_list[i].master_s->primary->elt->name; + } +/* + * Check if new master species, print total molality + */ + if (name1 != name) { + name = name1; + output_msg(OUTPUT_MESSAGE,"%-14s%12.3e\n",name, (double) (master_ptr->total/mass_water_aq_x)); + min = censor*master_ptr->total/mass_water_aq_x; + if (min > 0) { + min = log10(min); + } else { + min = -1000.; + } + } +/* + * Print species data + */ + if (species_list[i].s->lm > min) { + if (species_list[i].s == s_h2o) { + lm = log10(s_h2o->moles / mass_water_aq_x); + } else { + lm = species_list[i].s->lm; + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e%10.3f%10.3f%10.3f\n", + species_list[i].s->name, + (double) ((species_list[i].s->moles)/mass_water_aq_x), + (double) under(species_list[i].s->lm + species_list[i].s->lg), + (double) lm, + (double) (species_list[i].s->lm+species_list[i].s->lg), + (double) species_list[i].s->lg ); + } + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_surface(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints description of surface, including charge and potential, + * grams and specific area, moles of each species on surface sites, + * and description of diffuse layer if applicable. + */ + int i, j, k; + struct surface *surface_ptr; + char name[MAX_LENGTH], token[MAX_LENGTH]; + struct master *master_ptr; + LDBLE molfrac, charge; + char *ptr; +/* + * Print surface speciation + */ + surface_ptr = use.surface_ptr; + if (surface_ptr == NULL || pr.surface == FALSE || pr.all == FALSE) return(OK); + + if (state >= REACTION) { + print_centered("Surface composition"); + } +/* + * Print list of species + */ + + s_h2o->lm = s_h2o->la; + for (j =0; j < count_unknowns; j++) { + if (use.surface_ptr->edl == TRUE) { + if (x[j]->type != SURFACE_CB) continue; + strcpy(name, x[j]->master[0]->elt->name); + replace ("_psi", "", name); + } else { + if (x[j]->type != SURFACE) continue; + strcpy(token, x[j]->master[0]->elt->name); + replace ("_", " ", token); + ptr = token; + copy_token(name, &ptr, &k); + } + output_msg(OUTPUT_MESSAGE,"%-14s\n",name); +/* + * Description of surface + */ + if (diffuse_layer_x == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t%11.3e Surface + diffuse layer charge, eq\n", (double) x[j]->f ); + } + if (use.surface_ptr->edl == TRUE && diffuse_layer_x == FALSE) { + charge = x[j]->f; + } else { + charge = calc_surface_charge(name); + } + output_msg(OUTPUT_MESSAGE,"\t%11.3e Surface charge, eq\n", (double) charge); + if (x[j]->type == SURFACE_CB) { + if ((x[j]->surface_charge->specific_area * + x[j]->surface_charge->grams) > 0) { + output_msg(OUTPUT_MESSAGE,"\t%11.3e sigma, C/m**2\n", + (double) (charge * F_C_MOL / + (x[j]->surface_charge->specific_area * + x[j]->surface_charge->grams))); + } else { + output_msg(OUTPUT_MESSAGE,"\tundefined sigma, C/m**2\n"); + } + output_msg(OUTPUT_MESSAGE,"\t%11.3e psi, V\n", + (double) (x[j]->master[0]->s->la * 2 * R_KJ_DEG_MOL * + tk_x * LOG_10 / F_KJ_V_EQ)); + output_msg(OUTPUT_MESSAGE,"\t%11.3e -F*psi/RT\n", + (double) (x[j]->master[0]->s->la * (-2) * LOG_10)); + output_msg(OUTPUT_MESSAGE,"\t%11.3e exp(-F*psi/RT)\n", + exp(x[j]->master[0]->s->la * (-2) * LOG_10)); + if (x[j]->surface_comp->phase_name != NULL) { + output_msg(OUTPUT_MESSAGE,"\t%11.3e specific area, m**2/mol %s\n", + (double) x[j]->surface_charge->specific_area, + x[j]->surface_comp->phase_name); + output_msg(OUTPUT_MESSAGE,"\t%11.3e m**2 for %11.3e moles of %s\n\n", + (double) (x[j]->surface_charge->grams * x[j]->surface_charge->specific_area), + (double) x[j]->surface_charge->grams, + x[j]->surface_comp->phase_name); + } else if (x[j]->surface_comp->rate_name != NULL) { + output_msg(OUTPUT_MESSAGE,"\t%11.3e specific area, m**2/mol %s\n", + (double) x[j]->surface_charge->specific_area, + x[j]->surface_comp->rate_name); + output_msg(OUTPUT_MESSAGE,"\t%11.3e m**2 for %11.3e moles of %s\n\n", + (double) (x[j]->surface_charge->grams * x[j]->surface_charge->specific_area), + (double) x[j]->surface_charge->grams, + x[j]->surface_comp->rate_name); + } else { + output_msg(OUTPUT_MESSAGE,"\t%11.3e specific area, m**2/g\n", + (double) x[j]->surface_charge->specific_area); + output_msg(OUTPUT_MESSAGE,"\t%11.3e m**2 for %11.3e g\n\n", + (double) (x[j]->surface_charge->specific_area * x[j]->surface_charge->grams), + (double) x[j]->surface_charge->grams); + } + if (diffuse_layer_x == TRUE) print_diffuse_layer(x[j]->surface_charge); + output_msg(OUTPUT_MESSAGE,"\n"); +/* + * Heading for species + */ + for (k = j - 1; k < count_unknowns; k++) { + if (x[k]->type != SURFACE) continue; + if (x[j] != x[k]->potential_unknown) continue; + master_ptr = x[k]->master[0]; + output_msg(OUTPUT_MESSAGE,"%-14s\n",x[k]->master[0]->elt->name); + output_msg(OUTPUT_MESSAGE,"\t%11.3e moles", (double) x[k]->moles); + if (x[k]->surface_comp->phase_name != NULL) { + output_msg(OUTPUT_MESSAGE,"\t[%g mol/(mol %s)]\n", (double) x[k]->surface_comp->phase_proportion, x[k]->surface_comp->phase_name); + } else + if (x[k]->surface_comp->rate_name != NULL) { + output_msg(OUTPUT_MESSAGE,"\t[%g mol/(mol kinetic reactant %s)]\n", (double) x[k]->surface_comp->phase_proportion, x[k]->surface_comp->rate_name); + } else { + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%12s\n"," "," ","Mole", + " ", "Log"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%12s\n\n","Species", + "Moles", "Fraction", "Molality", "Molality"); + for (i=0; i < count_species_list; i++) { + if (species_list[i].master_s != master_ptr->s) continue; +/* + * Print species data + */ + if (x[k]->moles >= MIN_RELATED_SURFACE) { + molfrac = (LDBLE) (species_list[i].s->moles) / x[k]->moles * species_list[i].s->equiv; + } else { + molfrac = 0.0; + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3f%12.3e%12.3f\n", + species_list[i].s->name, + (double) species_list[i].s->moles, + (double) molfrac, + (double) (species_list[i].s->moles/mass_water_aq_x), + log10(species_list[i].s->moles/mass_water_aq_x)); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + } else { + k = j; + master_ptr = x[k]->master[0]; + output_msg(OUTPUT_MESSAGE,"%-14s\n",x[k]->master[0]->elt->name); + output_msg(OUTPUT_MESSAGE,"\t%11.3e moles\n", (double) x[k]->moles); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%12s\n"," "," ","Mole", + " ", "Log"); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%12s%12s\n\n","Species", + "Moles", "Fraction", "Molality", "Molality"); + for (i=0; i < count_species_list; i++) { + if (species_list[i].master_s != master_ptr->s) continue; +/* + * Print species data + */ + if (x[k]->moles >= MIN_RELATED_SURFACE) { + molfrac = (double) (species_list[i].s->moles) / x[k]->moles * species_list[i].s->equiv; + } else { + molfrac = 0.0; + } + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3f%12.3e%12.3f\n", + species_list[i].s->name, + (double) species_list[i].s->moles, + (double) molfrac, + (double) (species_list[i].s->moles/mass_water_aq_x), + log10(species_list[i].s->moles/mass_water_aq_x)); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_totals(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print total concentrations of elements, molality and moles. + */ + int i, pure_water; + + if (pr.totals == FALSE || pr.all == FALSE) return(OK); + print_centered("Solution composition"); + pure_water = TRUE; + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s\n\n","Elements","Molality","Moles"); + for (i = 0; i < count_unknowns; i++) { + if (x[i] == alkalinity_unknown) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e\n", x[i]->total->description, + (double) (x[i]->f/mass_water_aq_x), (double) x[i]->f); + pure_water = FALSE; + } + if (x[i] == ph_unknown) continue; + if (x[i] == pe_unknown) continue; + if (x[i] == charge_balance_unknown ) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e", x[i]->description, + (double) (x[i]->sum/mass_water_aq_x), (double) x[i]->sum); + output_msg(OUTPUT_MESSAGE," Charge balance\n"); + pure_water = FALSE; + continue; + } + if (x[i]->type == SOLUTION_PHASE_BOUNDARY) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e", x[i]->description, + (double) (x[i]->sum/mass_water_aq_x), (double) x[i]->sum); + output_msg(OUTPUT_MESSAGE," Equilibrium with %s\n", x[i]->phase->name); + pure_water = FALSE; + continue; + } + if (x[i]->type == MB) { + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e\n", x[i]->description, + (double) (x[i]->sum/mass_water_aq_x), (double) x[i]->sum); + pure_water = FALSE; + } + } + + if (pure_water == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t%-15s\n","Pure water"); + } +/* + * Description of solution + */ + output_msg(OUTPUT_MESSAGE,"\n"); + print_centered("Description of solution"); +/* + * pH + */ + output_msg(OUTPUT_MESSAGE,"%45s%7.3f ","pH = ",(double) (-(s_hplus->la))); + if (ph_unknown == NULL) { + output_msg(OUTPUT_MESSAGE,"\n"); + } else if (ph_unknown == charge_balance_unknown) { + output_msg(OUTPUT_MESSAGE," Charge balance\n"); + } else if (ph_unknown->type == SOLUTION_PHASE_BOUNDARY) { + output_msg(OUTPUT_MESSAGE," Equilibrium with %s\n", ph_unknown->phase->name); + } else if (ph_unknown->type == ALK) { + output_msg(OUTPUT_MESSAGE," Adjust alkalinity\n"); + } +/* + * pe + */ + output_msg(OUTPUT_MESSAGE,"%45s%7.3f ","pe = ",(double) (-(s_eminus->la))); + if (pe_unknown == NULL) { + output_msg(OUTPUT_MESSAGE,"\n"); + } else if (pe_unknown == charge_balance_unknown) { + output_msg(OUTPUT_MESSAGE," Charge balance\n"); + } else if (pe_unknown->type == SOLUTION_PHASE_BOUNDARY) { + output_msg(OUTPUT_MESSAGE," Equilibrium with %s\n", pe_unknown->phase->name); + } else if (pe_unknown->type == MH) { + output_msg(OUTPUT_MESSAGE," Adjusted to redox equilibrium\n"); + } +/* + * Others + */ + output_msg(OUTPUT_MESSAGE,"%45s%7.3f\n","Activity of water = ",exp( s_h2o->la * LOG_10)); + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Ionic strength = ", (double) mu_x); + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Mass of water (kg) = ", (double) mass_water_aq_x); + if (alkalinity_unknown == NULL) { + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Total alkalinity (eq/kg) = ", (double) (total_alkalinity/mass_water_aq_x)); + } + if (carbon_unknown == NULL) { + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Total carbon (mol/kg) = ", (double) (total_carbon/mass_water_aq_x)); + } + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Total CO2 (mol/kg) = ", (double) (total_co2/mass_water_aq_x)); + output_msg(OUTPUT_MESSAGE,"%45s%7.3f\n","Temperature (deg C) = ", (double) tc_x); + output_msg(OUTPUT_MESSAGE,"%45s%11.3e\n","Electrical balance (eq) = ", (double) cb_x); + output_msg(OUTPUT_MESSAGE,"%45s%6.2f\n","Percent error, 100*(Cat-|An|)/(Cat+|An|) = ", (double) (100*cb_x/total_ions_x)); + output_msg(OUTPUT_MESSAGE,"%45s%3d\n","Iterations = ",iterations); + if (pitzer_model == TRUE) { + output_msg(OUTPUT_MESSAGE,"%45s%3d\n","Gamma iterations = ",gamma_iterations); + output_msg(OUTPUT_MESSAGE,"%45s%9.5f\n","Osmotic coefficient = ", COSMOT); + output_msg(OUTPUT_MESSAGE,"%45s%9.5f\n","Density of water = ", DW0); + } + output_msg(OUTPUT_MESSAGE,"%45s%e\n","Total H = ", (double) total_h_x); + output_msg(OUTPUT_MESSAGE,"%45s%e\n","Total O = ", (double) total_o_x); + output_msg(OUTPUT_MESSAGE,"\n"); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_user_print(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print with user defined BASIC print routine + */ + int i; + struct kinetics *kinetics_ptr; + + char command[] = "run"; + + if (pr.user_print == FALSE || pr.all == FALSE) return(OK); + if (user_print->commands == NULL) return(OK); + kinetics_ptr = NULL; + if (use.kinetics_in == TRUE) { + kinetics_ptr = use.kinetics_ptr; + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + use.kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &i); + } else { + use.kinetics_ptr = kinetics_bsearch(-2, &i); + } + } + print_centered("User print"); + if (user_print->new_def == TRUE) { + /* basic_renumber(user_print->commands, &user_print->linebase, &user_print->varbase, &user_print->loopbase); */ + if (basic_compile(user_print->commands, &user_print->linebase, &user_print->varbase, &user_print->loopbase) != 0) { + error_msg("Fatal Basic error in USER_PRINT.", STOP); + } + user_print->new_def = FALSE; + } + if (basic_run(command, user_print->linebase, user_print->varbase, user_print->loopbase) != 0) { + error_msg("Fatal Basic error in USER_PRINT.", STOP); + } + output_msg(OUTPUT_MESSAGE,"\n"); + if (use.kinetics_in == TRUE) { + use.kinetics_ptr = kinetics_ptr; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_using(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print entities used in calculation + */ + struct mix *mix_ptr; + struct solution *solution_ptr; + struct exchange *exchange_ptr; + struct surface *surface_ptr; + struct pp_assemblage *pp_assemblage_ptr; + struct s_s_assemblage *s_s_assemblage_ptr; + struct gas_phase *gas_phase_ptr; + struct temperature *temperature_ptr; + struct irrev *irrev_ptr; + struct kinetics *kinetics_ptr; + int n; + + if (pr.use == FALSE || pr.all == FALSE) return(OK); + if (state < REACTION || phast == TRUE) return(OK); +/* + * Mixture or Solution + */ + if (use.mix_in == TRUE) { + if (state == TRANSPORT) { + mix_ptr = mix_bsearch(use.n_mix_user, &n); + } else { + mix_ptr = mix_bsearch(use.n_mix_user_orig, &n); + } + if (mix_ptr == NULL) { + mix_ptr = use.mix_ptr; + } + if (mix_ptr != NULL) { + if (state == TRANSPORT) { + output_msg(OUTPUT_MESSAGE,"Using mix %d.\t%s\n", use.n_mix_user, mix_ptr->description); + } else { + output_msg(OUTPUT_MESSAGE,"Using mix %d.\t%s\n", use.n_mix_user_orig, mix_ptr->description); + } + + } + } else { + solution_ptr = solution_bsearch (use.n_solution_user, &n, TRUE); + output_msg(OUTPUT_MESSAGE,"Using solution %d.\t%s\n", use.n_solution_user, solution_ptr->description); + } +/* + * Exchange and surface + */ + if (use.exchange_in == TRUE) { + exchange_ptr = exchange_bsearch(use.n_exchange_user, &n); + output_msg(OUTPUT_MESSAGE,"Using exchange %d.\t%s\n", use.n_exchange_user, exchange_ptr->description); + } + if (use.surface_in == TRUE) { + surface_ptr = surface_bsearch(use.n_surface_user, &n); + output_msg(OUTPUT_MESSAGE,"Using surface %d.\t%s\n", use.n_surface_user, surface_ptr->description); + } + if (use.pp_assemblage_in == TRUE) { + pp_assemblage_ptr = pp_assemblage_bsearch(use.n_pp_assemblage_user, &n); + output_msg(OUTPUT_MESSAGE,"Using pure phase assemblage %d.\t%s\n", use.n_pp_assemblage_user, + pp_assemblage_ptr->description); + } + if (use.s_s_assemblage_in == TRUE) { + s_s_assemblage_ptr = s_s_assemblage_bsearch(use.n_s_s_assemblage_user, &n); + output_msg(OUTPUT_MESSAGE,"Using solid solution assemblage %d.\t%s\n", use.n_s_s_assemblage_user, + s_s_assemblage_ptr->description); + } + if (use.gas_phase_in == TRUE) { + gas_phase_ptr = gas_phase_bsearch(use.n_gas_phase_user, &n); + output_msg(OUTPUT_MESSAGE,"Using gas phase %d.\t%s\n", use.n_gas_phase_user, gas_phase_ptr->description); + } + if (use.temperature_in == TRUE) { + temperature_ptr = temperature_bsearch(use.n_temperature_user, &n); + output_msg(OUTPUT_MESSAGE,"Using temperature %d.\t%s\n", use.n_temperature_user, temperature_ptr->description); + } + if (use.irrev_in == TRUE) { + if (state != TRANSPORT || transport_step > 0) { + irrev_ptr = irrev_bsearch(use.n_irrev_user, &n); + output_msg(OUTPUT_MESSAGE,"Using reaction %d.\t%s\n", use.n_irrev_user, irrev_ptr->description); + } + } + if (use.kinetics_in == TRUE) { + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &n); + } else { + kinetics_ptr = kinetics_bsearch(-2, &n); + } + output_msg(OUTPUT_MESSAGE,"Using kinetics %d.\t%s\n", use.n_kinetics_user, kinetics_ptr->description); + } + output_msg(OUTPUT_MESSAGE,"\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints selected gas phase data + */ + int i, j; + LDBLE p, total_moles, volume; + LDBLE moles; + + if (punch.count_gases <= 0) return(OK); + p = 0.0; + total_moles = 0.0; + volume = 0.0; + if (gas_unknown != NULL && use.gas_phase_ptr != NULL){ + if (use.gas_phase_ptr->type == PRESSURE) { + use.gas_phase_ptr->total_moles = gas_unknown->moles; + use.gas_phase_ptr->volume = use.gas_phase_ptr->total_moles * R_LITER_ATM * tk_x / use.gas_phase_ptr->total_p; + } + p = use.gas_phase_ptr->total_p; + total_moles = use.gas_phase_ptr->total_moles; + volume = total_moles * R_LITER_ATM * tk_x / use.gas_phase_ptr->total_p; + } + if (punch.high_precision == FALSE) { + fpunchf("pressure", "%12.4e\t", p); + fpunchf("total mol", "%12.4e\t",total_moles); + fpunchf("volume", "%12.4e\t",volume); + } else { + fpunchf("pressure", "%20.12e\t", p); + fpunchf("total mol", "%20.12e\t",total_moles); + fpunchf("volume", "%20.12e\t",volume); + } + for (i = 0; i < punch.count_gases; i++) { + moles = 0.0; + if (use.gas_phase_ptr != NULL && punch.gases[i].phase != NULL) { + for( j = 0; j < use.gas_phase_ptr->count_comps; j++) { + + if (use.gas_phase_ptr->comps[j].phase != punch.gases[i].phase) continue; + moles = use.gas_phase_ptr->comps[j].phase->moles_x; + if ( moles <= MIN_TOTAL ) moles = 0.0; + break; + } + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("g_%s", punch.gases[i].name),"%12.4e\t", moles); + } else { + fpunchf(sformatf("g_%s", punch.gases[i].name),"%20.12e\t", moles); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_s_s_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints solid solution composition if present + */ + int i, j, k; + int found; + LDBLE moles; + +/* + * Print solid solutions + */ + for (k = 0; k < punch.count_s_s; k++) { + found = FALSE; + if (use.s_s_assemblage_ptr != NULL) { + for( j = 0; j < use.s_s_assemblage_ptr->count_s_s; j++) { + for (i = 0; i < use.s_s_assemblage_ptr->s_s[j].count_comps; i++) { + if (strcmp_nocase(punch.s_s[k].name, use.s_s_assemblage_ptr->s_s[j].comps[i].name) == 0) { + if (use.s_s_assemblage_ptr->s_s[j].s_s_in == TRUE) { + moles = use.s_s_assemblage_ptr->s_s[j].comps[i].moles; + } else { + moles = 0; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("s_%s", punch.s_s[k].name), "%12.4e\t", + (double) moles); + } else { + fpunchf(sformatf("s_%s", punch.s_s[k].name), "%20.12e\t", + (double) moles); + } + found = TRUE; + break; + } + } + if (found == TRUE) break; + } + } + if (found == FALSE) { + if (punch.high_precision == FALSE) { + fpunchf(sformatf("s_%s", punch.s_s[k].name),"%12.4e\t", 0.0); + } else { + fpunchf(sformatf("s_%s", punch.s_s[k].name),"%20.12e\t", 0.0); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_totals(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print total concentrations of elements, molality and moles. + */ + int j; + LDBLE molality; + + for (j = 0; j < punch.count_totals; j++) { + if (punch.totals[j].master == NULL) { + molality =0.0; + } else if (punch.totals[j].master->primary == TRUE) { + molality = punch.totals[j].master->total_primary / mass_water_aq_x; + } else { + molality = punch.totals[j].master->total / mass_water_aq_x; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("%s(mol/kgw)", punch.totals[j].name),"%12.4e\t", molality); + } else { + fpunchf(sformatf("%s(mol/kgw)", punch.totals[j].name),"%20.12e\t", molality); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_molalities(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print concentrations of species (aq, ex, surf) + */ + int j; + LDBLE molality; + + for (j = 0; j < punch.count_molalities; j++) { + molality = 0.0; + if (punch.molalities[j].s != NULL && punch.molalities[j].s->in == TRUE) { + molality = punch.molalities[j].s->moles / mass_water_aq_x; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("m_%s(mol/kgw)", punch.molalities[j].name),"%12.4e\t", molality); + } else { + fpunchf(sformatf("m_%s(mol/kgw)", punch.molalities[j].name),"%20.12e\t", molality); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_activities(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print concentrations of species (aq, ex, surf) + */ + int j; + LDBLE la; + + for (j = 0; j < punch.count_activities; j++) { + la = -999.999; + if (punch.activities[j].s != NULL && punch.activities[j].s->in == TRUE) { + la = punch.activities[j].s->lm + punch.activities[j].s->lg; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("la_%s", punch.activities[j].name),"%12.4e\t", la); + } else { + fpunchf(sformatf("la_%s", punch.activities[j].name),"%20.12e\t", la); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_pp_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints masses of selected pure_phases in pp_assemblage + */ + int i, j; + LDBLE moles, delta_moles; + + for (i = 0; i < punch.count_pure_phases; i++) { + delta_moles = 0; + moles = 0.0; + if (punch.pure_phases[i].phase != NULL) { + for( j = 0; j < count_unknowns; j++) { + if (x == NULL || x[j]->type != PP) continue; +/* + * Print pure phase assemblage data + */ + if (punch.pure_phases[i].phase != x[j]->pure_phase->phase) continue; + if (state != TRANSPORT && state != PHAST) { + moles = x[j]->moles; + delta_moles = x[j]->moles - x[j]->pure_phase->moles - x[j]->pure_phase->delta; + } else { + moles = x[j]->moles; + delta_moles = x[j]->moles - x[j]->pure_phase->initial_moles; + } + break; + } + } + if (punch.high_precision == FALSE) { + fpunchf(punch.pure_phases[i].name,"%12.4e\t", moles); + fpunchf(sformatf("d_%s", punch.pure_phases[i].name),"%12.4e\t", delta_moles); + } else { + fpunchf(punch.pure_phases[i].name,"%20.12e\t", moles); + fpunchf(sformatf("d_%s", punch.pure_phases[i].name),"%20.12e\t", delta_moles); + } + } + return(OK); +} +#define PHAST_NULL(x) (phast ? NULL : x) +/* ---------------------------------------------------------------------- */ +int punch_identifiers(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * prints series of integers to identify simulation number, + * state of calculations, reaction or transport step number, + * and temp, ph, pe, and mass of water for each line + * of selected output. + */ + const char *sformat; + const char *dformat; + const char *gformat; + int i, l; + char token[MAX_LENGTH]; + if (punch.in == FALSE) return(OK); + if (punch.high_precision == FALSE) { + l = 12; + sformat = "%12s\t"; + dformat = "%12d\t"; + gformat = "%12g\t"; + } else { + l = 20; + sformat = "%20s\t"; + dformat = "%20d\t"; + gformat = "%20g\t"; + } + +/* + * simulation or simul_tr + */ + + if (punch.sim == TRUE) { + if (state != TRANSPORT && state != PHAST) { + fpunchf(PHAST_NULL("sim"), dformat, simulation); + } else { + fpunchf(PHAST_NULL("sim"), dformat, simul_tr); + } + } + if (punch.state == TRUE) { + switch (state) { + case 0: + strcpy(token,"init"); + break; + case 1: + strcpy(token,"i_soln"); + break; + case 2: + strcpy(token,"i_exch"); + break; + case 3: + strcpy(token,"i_surf"); + break; + case 4: + strcpy(token,"i_gas"); + break; + case 5: + strcpy(token,"react"); + break; + case 6: + strcpy(token,"inverse"); + break; + case 7: + strcpy(token,"advect"); + break; + case 8: + strcpy(token,"transp"); + break; + } + fpunchf(PHAST_NULL("state"), sformat, token); + + } +/* + * solution number or cell number and time + */ + if (punch.soln == TRUE) { + if (state == TRANSPORT || state == PHAST) { + fpunchf(PHAST_NULL("soln"), dformat, cell); + } else if (state == ADVECTION) { + fpunchf(PHAST_NULL("soln"), dformat, use.n_solution_user); + } else if (state < REACTION) { + fpunchf(PHAST_NULL("soln"), dformat, use.solution_ptr->n_user); + } else { + if (use.mix_in == TRUE) { + if (state != TRANSPORT) { + fpunchf(PHAST_NULL("soln"),dformat, use.n_mix_user_orig); + } else { + fpunchf(PHAST_NULL("soln"),dformat, use.n_mix_user); + } + + } else { + fpunchf(PHAST_NULL("soln"), dformat, use.n_solution_user); + } + } + } + if (punch.dist == TRUE) { + if (state == ADVECTION) { + fpunchf(PHAST_NULL("dist_x"), dformat, use.n_solution_user); + } else if (state == TRANSPORT) { + fpunchf(PHAST_NULL("dist_x"), gformat, cell_data[cell-1 ].mid_cell_x); + } else { + fpunchf(PHAST_NULL("dist_x"), dformat, -99); + } + } + if (punch.time == TRUE) { + if (state == REACTION && incremental_reactions == TRUE && use.kinetics_ptr != NULL) { + if (use.kinetics_ptr->count_steps > 0) { + kin_time_x = 0.; + for (i = 0; i < reaction_step; i++) { + if (i < use.kinetics_ptr->count_steps) { + kin_time_x += use.kinetics_ptr->steps[i]; + } else { + kin_time_x += use.kinetics_ptr->steps[use.kinetics_ptr->count_steps - 1]; + } + } + } else if (use.kinetics_ptr->count_steps < 0) { + if (reaction_step > -use.kinetics_ptr->count_steps) { + kin_time_x = use.kinetics_ptr->steps[0]; + } else { + kin_time_x = reaction_step * use.kinetics_ptr->steps[0] / ( (LDBLE) (-use.kinetics_ptr->count_steps)); + } + } + } + if (state == REACTION) { + fpunchf(PHAST_NULL("time"), gformat, kin_time_x); + } else if (state == TRANSPORT || state == PHAST ) { + fpunchf(PHAST_NULL("time"), gformat, initial_total_time + rate_sim_time); + } else if (state == ADVECTION) { + if (advection_kin_time_defined == TRUE) { + fpunchf(PHAST_NULL("time"), gformat, initial_total_time + rate_sim_time); + } else { + fpunchf(PHAST_NULL("time"), dformat, advection_step); + } + } else { + fpunchf(PHAST_NULL("time"), dformat, -99); + } + } + +/* + * reaction or transport step + */ + if (punch.step == TRUE) { + if (state == REACTION) { + fpunchf(PHAST_NULL("step"), dformat, reaction_step); + } else if (state == ADVECTION) { + fpunchf(PHAST_NULL("step"), dformat, advection_step); + } else if (state == TRANSPORT) { + fpunchf(PHAST_NULL("step"), dformat, transport_step); + } else { + fpunchf(PHAST_NULL("step"), dformat, -99); + } + } + if (punch.ph == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("pH","%12g\t", (double) (-s_hplus->la)); + } else { + fpunchf("pH","%20.12e\t", (double) (-s_hplus->la)); + } + } + if (punch.pe == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("pe","%12g\t", (double) (-s_eminus->la)); + } else { + fpunchf("pe","%20.12e\t", (double) (-s_eminus->la)); + } + } + if (punch.rxn == TRUE) { + if (state >= REACTION && use.irrev_in == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("reaction","%12.4e\t", step_x); + } else { + fpunchf("reaction","%20.12e\t", step_x); + } + } else { + if (punch.high_precision == FALSE) { + fpunchf("reaction","%12d\t", -99); + } else { + fpunchf("reaction","%20d\t", -99); + } + } + } + if (punch.temp == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("temp(C)","%12.3f\t", tc_x); + } else { + fpunchf("temp(C)","%20.12e\t", tc_x); + } + } + if (punch.alk == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("Alk(eq/kgw)","%12g\t", (double) (total_alkalinity/mass_water_aq_x)); + } else { + fpunchf("Alk(eq/kgw)","%20.12e\t", (double) (total_alkalinity/mass_water_aq_x)); + } + } + if (punch.mu == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("mu","%12g\t", (double) mu_x); + } else { + fpunchf("mu","%20.12e\t", (double) mu_x); + } + } + if (punch.water == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("mass_H2O","%12g\t", (double) mass_water_aq_x); + } else { + fpunchf("mass_H2O","%20.12e\t", (double) mass_water_aq_x); + } + } + if (punch.charge_balance == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("charge(eq)","%12g\t", (double) cb_x); + } else { + fpunchf("charge(eq)","%20.12e\t", (double) cb_x); + } + } + if (punch.percent_error == TRUE) { + if (punch.high_precision == FALSE) { + fpunchf("pct_err","%12g\t", (double) (100*cb_x/total_ions_x)); + } else { + fpunchf("pct_err","%20.12e\t", (double) (100*cb_x/total_ions_x)); + } + } + + return(OK); +} +#undef PHAST_NULL +/* ---------------------------------------------------------------------- */ +int punch_saturation_indices(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints saturation indices of selected phases + */ + int i; + LDBLE si, iap; + struct rxn_token *rxn_ptr; + + for (i=0; i < punch.count_si; i++) { + if (punch.si[i].phase == NULL || punch.si[i].phase->in == FALSE) { + si = -999.999; + } else { +/* + * Print saturation index + */ + iap = 0.0; + for (rxn_ptr = punch.si[i].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + iap += rxn_ptr->s->la * rxn_ptr->coef; + } + si=-punch.si[i].phase->lk + iap; + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("si_%s", punch.si[i].name),"%12.4f\t", si); + } else { + fpunchf(sformatf("si_%s", punch.si[i].name),"%20.12e\t", si); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int punch_kinetics(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * prints kinetic reaction, + * should be called only on final kinetic step + */ + int i, j; + struct kinetics *kinetics_ptr; + LDBLE moles, delta_moles; + + kinetics_ptr = NULL; + if (use.kinetics_in == TRUE) { + if (state == TRANSPORT || state == PHAST || state == ADVECTION) { + kinetics_ptr = kinetics_bsearch(use.n_kinetics_user, &i); + } else { + kinetics_ptr = kinetics_bsearch(-2, &i); + } + } + for (i = 0; i < punch.count_kinetics; i++) { + moles = 0.0; + delta_moles = 0.0; + if (kinetics_ptr != NULL) { + for (j = 0; j < kinetics_ptr->count_comps; j++) { + if (strcmp_nocase(punch.kinetics[i].name, kinetics_ptr->comps[j].rate_name) == 0) { + if (state != TRANSPORT && state != PHAST) { + moles = kinetics_ptr->comps[j].m; + delta_moles = -kinetics_ptr->comps[j].moles; + } else { + moles = kinetics_ptr->comps[j].m; + delta_moles = kinetics_ptr->comps[j].m - kinetics_ptr->comps[j].initial_moles; + } + break; + } + } + } + if (punch.high_precision == FALSE) { + fpunchf(sformatf("k_%s", punch.kinetics[i].name),"%12.4e\t", moles); + fpunchf(sformatf("dk_%s", punch.kinetics[i].name),"%12.4e\t", -delta_moles); + } else { + fpunchf(sformatf("k_%s", punch.kinetics[i].name),"%20.12e\t", moles); + fpunchf(sformatf("dk_%s", punch.kinetics[i].name),"%20.12e\t", -delta_moles); + } + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int punch_user_punch(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Punch with user defined BASIC print routine + */ + char command[] = "run"; + + extern int n_user_punch_index; + n_user_punch_index = 0; + if (punch.user_punch == FALSE) return(OK); + if (user_punch->commands == NULL) return(OK); + if (user_punch->new_def == TRUE) { + if (basic_compile(user_punch->commands, &user_punch->linebase, &user_punch->varbase, &user_punch->loopbase) != 0) { + error_msg("Fatal Basic error in USER_PUNCH.", STOP); + } + user_punch->new_def = FALSE; + } + if (basic_run(command, user_punch->linebase, user_punch->varbase, user_punch->loopbase) != 0) { + error_msg("Fatal Basic error in USER_PUNCH.", STOP); + } + return(OK); +} + +#ifdef PHREEQ98 +/* ---------------------------------------------------------------------- */ +int punch_user_graph(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Graph with user defined BASIC print routine + */ + char command[] = "run"; + + colnr = 0; +/* //if (pr.user_graph == FALSE || pr.all == FALSE) return(OK); */ +/* //if (punch.user_punch == FALSE) return(OK); */ +/* //if (punch.in == FALSE) return(OK); */ + if (user_graph->commands == NULL) return(OK); + if (((state == INITIAL_SOLUTION) || (state == INITIAL_EXCHANGE) || (state == INITIAL_SURFACE) || (state == INITIAL_GAS_PHASE)) && (graph_initial_solutions == FALSE)) return(OK); + if (FirstCallToUSER_GRAPH) AddSeries = TRUE; + if (state == REACTION) { + /*if (reaction_step == 1) AddSeries = TRUE; + else AddSeries = FALSE; */ + if (reaction_step > 1) AddSeries = FALSE; + } + if (state == ADVECTION) { + if (advection_step == 0 && graph_initial_solutions == FALSE) return(OK); + if (((chart_type == 1) && (advection_step == punch_ad_modulus)) || + ((chart_type == 0) && (advection_step != prev_advection_step))) AddSeries = TRUE; + else AddSeries = FALSE; + } + if (state == TRANSPORT) { + if (transport_step == 0 && graph_initial_solutions == FALSE) return(OK); + if (((chart_type == 1) && (transport_step == punch_modulus)) || + ((chart_type == 0) && (transport_step != prev_transport_step))) AddSeries = TRUE; + else AddSeries = FALSE; + } + if (user_graph->new_def == TRUE) { + if (basic_compile(user_graph->commands, &user_graph->linebase, &user_graph->varbase, &user_graph->loopbase) != 0) { + error_msg("Fatal Basic error in USER_GRAPH.", STOP); + } + user_graph->new_def = FALSE; + } + if (basic_run(command, user_graph->linebase, user_graph->varbase, user_graph->loopbase) != 0) { + error_msg("Fatal Basic error in USER_GRAPH.", STOP); + } + if (state == ADVECTION) prev_advection_step = advection_step; + if (state == TRANSPORT) prev_transport_step = transport_step; + /*if (state == REACTION) prev_reaction_step = reaction_step;*/ + + FirstCallToUSER_GRAPH = FALSE; + + return(OK); +} +#endif + +#if defined(HDF5_CREATE) +extern void HDFWriteHyperSlabV(const char* name, const char* format, va_list argptr); +#endif + +#if defined(USE_MPI) && defined(HDF5_CREATE) && defined(MERGE_FILES) +extern int Merge_fpunchf(const int length, const char* format, va_list argptr); +#endif + +int output_message(const int type, const char *err_str, const int stop, const char *format, va_list args); + +int fpunchf(const char* name, const char* format, ...) +{ + int retval = 0; + va_list args; + + va_start(args, format); + retval = output_message(OUTPUT_PUNCH, name, CONTINUE, format, args); + va_end(args); + + return retval; +} +int fpunchf_user(int user_index, const char* format, ...) +{ + static int s_warning = 0; + int retval = 0; + va_list args; + static char buffer[80]; + char* name; + + if (user_index < user_punch_count_headings) { + name = user_punch_headings[user_index]; + } + else { + if (s_warning == 0) { + sprintf(error_string, "USER_PUNCH: Headings count doesn't match number of calls to PUNCH.\n"); + warning_msg(error_string); + s_warning = 1; + } + sprintf(buffer, "no_heading_%d", (user_index - user_punch_count_headings) + 1); + name = buffer; + } + + va_start(args, format); + retval = output_message(OUTPUT_PUNCH, name, CONTINUE, format, args); + va_end(args); + + return retval; +} +#ifdef SAVE +int fpunchf(const char* name, const char* format, ...) +{ + int retval = 0; + va_list args; + static char big_buffer[200]; + +#if defined(HDF5_CREATE) + if (pr.hdf == TRUE) { + va_start(args, format); + HDFWriteHyperSlabV(name, format, args); + va_end(args); + } +#endif + if (pr.punch == TRUE && punch.in == TRUE) { + va_start(args, format); + retval = output_message(OUTPUT_PUNCH, NULL, CONTINUE, format, args); + va_end(args); +#if defined(USE_MPI) && defined(HDF5_CREATE) && defined(MERGE_FILES) + va_start(args, format); + retval = vsprintf(big_buffer, format, args); + Merge_fpunchf(retval, format, args); + va_end(args); +#endif +#if defined(SWIG_SHARED_OBJ) + va_start(args, format); + AddSelectedOutput(name, format, args); + va_end(args); +#endif + } + return retval; +} +int fpunchf_user(int user_index, const char* format, ...) +{ + extern int warning_msg(const char* err_str); + static int s_warning = 0; + int retval = 0; + va_list args; + static char buffer[80]; + char* name; + + if (user_index < user_punch_count_headings) { + name = user_punch_headings[user_index]; + } + else { + if (s_warning == 0) { + sprintf(error_string, "USER_PUNCH: Headings count doesn't match number of calls to PUNCH.\n"); + warning_msg(error_string); + s_warning = 1; + } + sprintf(buffer, "no_heading_%d", (user_index - user_punch_count_headings) + 1); + name = buffer; + } + +#if defined(HDF5_CREATE) + if (pr.hdf == TRUE) { + va_start(args, format); + HDFWriteHyperSlabV(name, format, args); + va_end(args); + } +#endif + + if (punch.in == TRUE && pr.punch == TRUE) { + va_start(args, format); + retval = output_message(OUTPUT_PUNCH, NULL, CONTINUE, format, args); + va_end(args); +#if defined(USE_MPI) && defined(HDF5_CREATE) && defined(MERGE_FILES) + va_start(args, format); + Merge_fpunchf(retval, format, args); + va_end(args); +#endif +#if defined(SWIG_SHARED_OBJ) + va_start(args, format); + AddSelectedOutput(name, format, args); + va_end(args); +#endif + } + return retval; +} +#endif + +char *sformatf(const char* format, ...) +{ +#if defined(HDF5_CREATE) || defined SWIG_SHARED_OBJ + static char scratch[240]; + va_list args; + + va_start(args, format); + if (vsprintf(scratch, format, args) > 239) { + error_msg("buffer overwrite in sformatf", STOP); + } + va_end(args); + return scratch; +#else + return NULL; +#endif +} + +/* ---------------------------------------------------------------------- */ +int print_alkalinity(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints description of solution, uses array species_list for + * order of aqueous species. + */ + int i, j; + struct species_list *alk_list; + int count_alk_list; + double min; + + if (pr.alkalinity == FALSE || pr.all == FALSE) return(OK); + print_centered("Distribution of alkalinity"); + alk_list = (struct species_list *) PHRQ_malloc((size_t) (count_s_x *sizeof(struct species_list))); + if (alk_list == NULL) malloc_error(); + j = 0; + for (i = 0; i < count_s_x; i++) { + if (s_x[i]->alk == 0.0) continue; + alk_list[j].master_s = s_hplus; + alk_list[j].s = s_x[i]; + alk_list[j].coef = s_x[i]->alk; + j++; + } + count_alk_list = j; + min = fabs(censor*total_alkalinity/mass_water_aq_x); + if (count_alk_list > 0) { + output_msg(OUTPUT_MESSAGE,"\t%26s%11.3e\n\n","Total alkalinity (eq/kgw) = ", (double) (total_alkalinity/mass_water_aq_x)); + output_msg(OUTPUT_MESSAGE,"\t%-15s%12s%12s%10s\n\n","Species","Alkalinity","Molality", "Alk/Mol"); + qsort (&alk_list[0], (size_t) count_alk_list, + (size_t) sizeof(struct species_list), species_list_compare_alk); + for (i = 0; i < count_alk_list; i++) { + if (fabs(alk_list[i].s->alk*(alk_list[i].s->moles)/mass_water_aq_x) < min) continue; + output_msg(OUTPUT_MESSAGE,"\t%-15s%12.3e%12.3e%10.2f\n", + alk_list[i].s->name, + (double) (alk_list[i].s->alk*(alk_list[i].s->moles)/mass_water_aq_x), + (double) ((alk_list[i].s->moles)/mass_water_aq_x), + (double) (alk_list[i].s->alk)); + } + } + + output_msg(OUTPUT_MESSAGE,"\n"); + alk_list = (struct species_list *) free_check_null(alk_list); + return(OK); +} diff --git a/read.cpp b/read.cpp new file mode 100644 index 00000000..949ce156 --- /dev/null +++ b/read.cpp @@ -0,0 +1,7904 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" +extern int read_solution_raw (void); +extern int read_exchange_raw (void); +extern int read_surface_raw (void); +extern int read_equilibrium_phases_raw (void); +extern int read_kinetics_raw (void); +extern int read_solid_solutions_raw (void); +extern int read_gas_phase_raw (void); +extern int read_reaction_raw (void); +extern int read_mix_raw (void); +extern int read_temperature_raw (void); +static char const svnid[] = "$Id: read.c 715 2006-01-18 01:26:29Z dlpark $"; + +#if defined(SWIG_SHARED_OBJ) +#define STATIC +#else +#define STATIC static +#endif +STATIC int read_advection (void); +STATIC int read_analytical_expression_only (char *ptr, LDBLE *log_k); +STATIC int read_copy (void); +STATIC int read_debug (void); +STATIC int read_delta_h_only (char *ptr, LDBLE *delta_h, DELTA_H_UNIT *units); +STATIC int read_llnl_aqueous_model_parameters(void); +STATIC int read_exchange(void); +STATIC int read_exchange_master_species (void); +STATIC int read_exchange_species (void); +STATIC int read_gas_phase(void); +STATIC int read_incremental_reactions(void); +STATIC int read_inverse(void); +STATIC int read_inv_balances (struct inverse *inverse_ptr, char *next_char); +STATIC int read_inv_isotopes (struct inverse *inverse_ptr, char *ptr); +STATIC int read_inv_phases (struct inverse *inverse_ptr, char *next_char); +STATIC int read_kinetics (void); +STATIC int read_line_doubles(char *next_char, LDBLE **d, int *count_d, int *count_alloc); +STATIC int read_lines_doubles(char *next_char, LDBLE **d, int *count_d, int *count_alloc, const char **opt_list, int count_opt_list, int *opt); +STATIC LDBLE *read_list_doubles(char **ptr, int *count_doubles ); +STATIC int *read_list_ints (char **ptr, int *count_ints, int positive ); +STATIC int *read_list_t_f (char **ptr, int *count_ints ); +STATIC int read_master_species (void); +STATIC int read_mix (void); +STATIC int read_named_logk(void); +STATIC int read_phases(void); +STATIC int read_print (void); +STATIC int read_pure_phases(void); +STATIC int read_rates (void); +STATIC int read_reaction (void); +STATIC int read_reaction_reactants(struct irrev *irrev_ptr); +STATIC int read_reaction_steps(struct irrev *irrev_ptr); +STATIC int read_solid_solutions(void); +STATIC int read_temperature (void); +STATIC int read_reaction_temps(struct temperature *temperature_ptr); +STATIC int read_save(void); +STATIC int read_selected_output (void); +STATIC int read_solution(void); +STATIC int read_species (void); +STATIC int read_surf(void); +STATIC int read_surface_master_species (void); +STATIC int read_surface_species (void); +STATIC int read_use(void); +STATIC int read_title (void); +STATIC int read_user_print (void); +STATIC int read_user_punch (void); +#ifdef PHREEQ98 +STATIC int read_user_graph (void); +extern int connect_simulations, graph_initial_solutions; +/*extern*/ int shifts_as_points; +extern int chart_type; +extern int ShowChart; +extern int RowOffset, ColumnOffset; +#endif + +extern int reading_database(void); +extern int check_line(const char *string, int allow_empty, int allow_eof, int allow_keyword, + int print); + +#ifdef PHREEQ98 +extern int copy_title(char *token_ptr, char **ptr, int *length); +extern int OpenCSVFile(char file_name[MAX_LENGTH]); +void GridHeadings(char* s, int i); +void SetAxisTitles(char* s, int i); +void SetAxisScale(char* a, int c, char* v, int l); +void SetChartTitle(char* s); +#endif + +static LDBLE dummy; + +/* ---------------------------------------------------------------------- */ +int read_input(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, l; + char *ptr; + char token[2*MAX_LENGTH]; + if (svnid == NULL) fprintf(stderr," "); + + parse_error = 0; + input_error = 0; + next_keyword = 0; + count_warnings = 0; +/* + * Initialize keyword flags + */ + for (i=0; i < NKEYS; i++) { + keyword[i].keycount=0; + } +/* + * Initialize use and save pointers + */ + use.solution_in = FALSE; + use.solution_ptr = NULL; + use.pp_assemblage_in = FALSE; + use.pp_assemblage_ptr = NULL; + use.mix_in = FALSE; + use.mix_ptr = NULL; + use.irrev_in = FALSE; + use.irrev_ptr = NULL; + use.kinetics_in = FALSE; + use.kinetics_ptr = NULL; + use.exchange_in = FALSE; + use.exchange_ptr = NULL; + use.surface_in = FALSE; + use.surface_ptr = NULL; + use.temperature_in = FALSE; + use.temperature_ptr = NULL; + use.gas_phase_in = FALSE; + use.gas_phase_ptr = NULL; + use.s_s_assemblage_in = FALSE; + use.s_s_assemblage_ptr = NULL; + use.trans_in = FALSE; + use.advect_in = FALSE; + + save.solution = FALSE; + save.mix = FALSE; + save.irrev = FALSE; + save.pp_assemblage = FALSE; + save.exchange = FALSE; + save.surface = FALSE; + save.gas_phase = FALSE; + save.s_s_assemblage = FALSE; + title_x = (char *) free_check_null(title_x); + + while ( (i = check_line("Subroutine Read", FALSE, TRUE, TRUE, TRUE)) != KEYWORD) { + /* empty, eof, keyword, print */ + + if ( i == EOF) return(EOF); + sprintf(error_string, "Unknown input, no keyword has been specified."); + warning_msg(error_string); + } +/* + 0 "eof" + 1 "end" + 2 "species" + 3 "master" + 4 "solution" + 5 "phases" + 6 "pure_phases" + 7 "reaction" + 8 "mix" + 9 "use" + 10 "save" + 11 "exchange_species" + 12 "master_exchange_species" + 13 "exchange" + 14 "surface_species" + 15 "master_surface_species" + 16 "surface" + 17 "reacton_temperature" + 18 "inverse_modeling" + 19 "gas_phase" + 20 "transport" + 21 "debug" + 22 "selected_output" + 23 "select_output" + 24 "knobs" + 25 "print" + 26 "equilibrium_phases" + 27 "equilibria" + 28 "equilibrium" + 29 "pure" + 30 "title" + 31 "comment" + 32 "advection" + 33 "kinetics" + 34 "incremental_reactions" + 35 "incremental" + 36 "rates" + 37 "solution_s" + 38 "user_print" + 39 "user_punch" + 40 "solid_solutions" + 41 "solid_solution" + 42 "solution_spread" + 43 "spread_solution" + 44 "selected_out" + 45 "select_out" + 46 "user_graph" + 47 "llnl_aqueous_model_parameters" + 48 "llnl_aqueous_model" + 49 "database" + 50 "named_analytical_expression" + 51 "named_analytical_expressions" + 52 "named_expressions" + 53 "named_log_k" + 54 "isotopes" + 55 "calculate_values" + 56 "isotopes_ratios", + 57 "isotopes_alphas" + 58 "copy" + 59 "pitzer" + 60 "solution_raw" + 61 "exchange_raw" + 62 "surface_raw" + 63 "equilibrium_phases_raw" + 64 "kinetics_raw" + 65 "solid_solutions_raw" + 66 "gas_phase_raw" + 67 "reaction_raw" + 68 "mix_raw" + 69 "reaction_temperature_raw" + */ + for (;;) { + if (next_keyword >= 0) { + /* keyword[next_keyword].keycount++;*/ + if (next_keyword != 49 && !reading_database()) first_read_input = FALSE; + } + switch(next_keyword) { + case -1: /* Have not read line with keyword */ + sprintf(error_string, "Unknown input, no keyword has been specified."); + warning_msg(error_string); + while ((j = check_line ("No keyword", FALSE, TRUE, TRUE, TRUE)) != KEYWORD + && j != EOF ) { + warning_msg(error_string); + } + break; + case 0: /* End encountered */ + case 1: /* EOF encountered */ + goto END_OF_SIMULATION_INPUT; + case 2: /* Read aqueous model */ + keyword[2].keycount++; + read_species(); + break; + case 3: /* Read master species */ + keyword[3].keycount++; + read_master_species(); + break; + case 4: /* Read solution data */ + keyword[4].keycount++; + read_solution(); + solution_sort(); + break; + case 5: + keyword[5].keycount++; + read_phases(); + break; + case 6: + case 26: + case 27: + case 28: + case 29: + keyword[6].keycount++; + keyword[26].keycount++; + keyword[27].keycount++; + keyword[28].keycount++; + keyword[29].keycount++; + read_pure_phases(); + break; + case 7: + keyword[7].keycount++; + read_reaction(); + break; + case 8: + keyword[8].keycount++; + read_mix(); + break; + case 9: + keyword[9].keycount++; + read_use(); + break; + case 10: + keyword[10].keycount++; + read_save(); + break; + case 11: + keyword[11].keycount++; + read_exchange_species(); + break; + case 12: + keyword[12].keycount++; + read_exchange_master_species(); + break; + case 13: + keyword[13].keycount++; + read_exchange(); + break; + case 14: + keyword[14].keycount++; + read_surface_species(); + break; + case 15: + keyword[15].keycount++; + read_surface_master_species(); + break; + case 16: + keyword[16].keycount++; + read_surf(); + break; + case 17: + keyword[17].keycount++; + read_temperature(); + break; + case 18: + keyword[18].keycount++; + read_inverse(); + break; + case 19: + keyword[19].keycount++; + read_gas_phase(); + break; + case 20: + keyword[20].keycount++; + read_transport(); + break; + case 21: + case 24: + keyword[21].keycount++; + keyword[24].keycount++; + read_debug(); + break; + case 22: + case 23: + case 44: + case 45: + keyword[22].keycount++; + keyword[23].keycount++; + keyword[44].keycount++; + keyword[45].keycount++; + read_selected_output(); + break; + case 25: + keyword[25].keycount++; + read_print(); + break; + case 30: + case 31: + keyword[30].keycount++; + keyword[31].keycount++; + read_title(); + break; + case 32: + keyword[32].keycount++; + read_advection(); + break; + case 33: + keyword[33].keycount++; + read_kinetics(); + break; + case 34: + case 35: + keyword[34].keycount++; + keyword[35].keycount++; + read_incremental_reactions(); + break; + case 36: + keyword[36].keycount++; + read_rates(); + break; + case 37: + case 42: + case 43: + keyword[37].keycount++; + keyword[42].keycount++; + keyword[43].keycount++; + read_solution_spread(); +#ifdef SKIP + solution_sort(); +#endif + break; + case 38: + keyword[38].keycount++; + read_user_print(); + break; + case 39: + keyword[39].keycount++; + read_user_punch(); + break; + case 40: + case 41: + keyword[40].keycount++; + keyword[41].keycount++; + read_solid_solutions(); + break; + case 46: + keyword[46].keycount++; +#ifdef PHREEQ98 + read_user_graph(); +# else + for (;;) { + j=check_line ("Reading user_graph", FALSE, TRUE, TRUE, TRUE); + if (j == EOF || j == KEYWORD ) { + break; + } + } +#endif + break; + case 47: + case 48: + keyword[47].keycount++; + keyword[48].keycount++; + read_llnl_aqueous_model_parameters(); + break; + case 49: + keyword[49].keycount++; + if (reading_database()) { + /* warning_msg("DATABASE is ignored in the database file."); */ + } else if (first_read_input == FALSE) { + error_msg("DATABASE must be the first keyword in the input file.", CONTINUE); + input_error++; + } else { + ptr = line; + copy_token(token, &ptr, &l); + user_database = string_duplicate(ptr); + if (string_trim(user_database) == EMPTY) { + error_msg("DATABASE file name is missing.", CONTINUE); + input_error++; + user_database = (char *) free_check_null(user_database); + } + first_read_input = FALSE; + } + j=check_line ("Reading after DATABASE", FALSE, TRUE, TRUE, TRUE); + break; + case 50: + case 51: + case 52: + case 53: + keyword[50].keycount++; + keyword[51].keycount++; + keyword[52].keycount++; + keyword[53].keycount++; + read_named_logk(); + break; + case 54: + keyword[54].keycount++; + read_isotopes(); + break; + case 55: + keyword[55].keycount++; + read_calculate_values(); + break; + case 56: + keyword[56].keycount++; + read_isotope_ratios(); + break; + case 57: + keyword[57].keycount++; + read_isotope_alphas(); + break; + case 58: + keyword[58].keycount++; + read_copy(); + break; + case 59: + keyword[59].keycount++; + read_pitzer(); + break; + case 60: + keyword[60].keycount++; + read_solution_raw(); + break; + case 61: + keyword[61].keycount++; + read_exchange_raw(); + break; + case 62: + keyword[62].keycount++; + read_surface_raw(); + break; + case 63: + keyword[63].keycount++; + read_equilibrium_phases_raw(); + break; + case 64: + keyword[64].keycount++; + read_kinetics_raw(); + break; + case 65: + keyword[65].keycount++; + read_solid_solutions_raw(); + break; + case 66: + keyword[66].keycount++; + read_gas_phase_raw(); + break; + case 67: + keyword[67].keycount++; + read_reaction_raw(); + break; + case 68: + keyword[68].keycount++; + read_mix_raw(); + break; + case 69: + keyword[69].keycount++; + read_temperature_raw(); + break; + } + } + END_OF_SIMULATION_INPUT: + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_conc(int n, int count_mass_balance, char *str) +/* ---------------------------------------------------------------------- */ +{ + int j, l; + int alk; + int count_redox_states; + + char *ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH]; +/* + * Set defaults + */ + /* + solution[n]->totals[count_mass_balance].equation_name = NULL; + solution[n]->totals[count_mass_balance].phase = NULL; + solution[n]->totals[count_mass_balance].phase_si = 0.0; + solution[n]->totals[count_mass_balance].units=NULL; + solution[n]->totals[count_mass_balance].n_pe=-1; + solution[n]->totals[count_mass_balance].as=NULL; + solution[n]->totals[count_mass_balance].gfw= 0.0; + */ + conc_init(&(solution[n]->totals[count_mass_balance])); + +/* + * Remove space between "kg" and "solution" or "water" in units + */ + replace("Kg","kg",str); + replace("KG","kg",str); + while (replace("kg ","kg",str) == TRUE); + ptr=str; +/* + * Read master species list for mass balance equation + */ + token1[0]='\0'; + count_redox_states=0; + while ( ((j = copy_token(token, &ptr, &l)) == UPPER ) || + ( token[0] == '[' ) || + ( strcmp_nocase_arg1(token,"ph") == 0 ) || + ( strcmp_nocase_arg1(token,"pe") == 0 ) ) { + count_redox_states++; + replace("(+","(",token); + if (count_redox_states > 1) strcat(token1," "); + strcat(token1,token); + } + if (count_redox_states == 0) { + input_error++; + error_msg ("No element or master species given for concentration input.", CONTINUE); + return(ERROR); + } + solution[n]->totals[count_mass_balance].description = string_hsave (token1); +/* + * Determine if reading alkalinity, allow equivalents for units + */ + str_tolower(token1); + if (strstr(token1,"alk") == token1) { + alk=TRUE; + } else { + alk=FALSE; + } +/* + * Read concentration + */ + + j=sscanf(token,SCANFORMAT, &(solution[n]->totals[count_mass_balance].input_conc)); + if (j == 0 ) { + sprintf(error_string,"Concentration data error for %s in solution input.", token1); + error_msg(error_string, CONTINUE); + return(ERROR); + } + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); +/* + * Read optional data + */ + strcpy(token1,token); +/* + * Check for units info + */ + if (check_units (token1, alk, FALSE, solution[n]->units, FALSE) == OK) { + if (check_units (token1, alk, FALSE, solution[n]->units, TRUE) == OK) { + solution[n]->totals[count_mass_balance].units = + string_hsave( token1 ); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); + } else { + return(ERROR); + } + } +/* + * Check for "as" followed by formula to be used for gfw + */ + strcpy(token1,token); + str_tolower(token1); + if ( strcmp(token1,"as") == 0 ) { + copy_token(token, &ptr, &l); + solution[n]->totals[count_mass_balance].as = string_hsave(token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); +/* + * Check for "gfw" followed by gram formula weight + */ + } else if (strcmp(token1,"gfw") == 0 ) { + if (copy_token(token, &ptr, &l) != DIGIT) { + error_msg("Expecting gram formula weight.", CONTINUE); + return(ERROR); + } else { + sscanf(token,SCANFORMAT, &(solution[n]->totals[count_mass_balance].gfw)); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); + } + } +/* + * Check for redox couple for pe + */ + if ( strcmp_nocase_arg1(token,"pe") == 0 ) { + solution[n]->totals[count_mass_balance].n_pe = pe_data_store (&(solution[n]->pe), token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); + } else if ( strstr(token,"/") != NULL) { + if (parse_couple(token) == OK ) { + solution[n]->totals[count_mass_balance].n_pe = + pe_data_store (&(solution[n]->pe), token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); + } else { + return(ERROR); + } + } +/* + * Must have phase + */ + solution[n]->totals[count_mass_balance].equation_name = string_hsave(token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) return(OK); +/* + * Check for saturation index + */ + j=sscanf(token,SCANFORMAT, &(solution[n]->totals[count_mass_balance].phase_si)); + if (j != 1 ) { + error_msg("Expected saturation index.", CONTINUE); + return(ERROR); + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int read_exchange_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read data for exchange species, parse equations + */ + int i; + int association; + char token[MAX_LENGTH]; + char *ptr; + struct phase *phase_ptr; + + struct species *s_ptr; + struct elt_list *next_elt; + struct rxn_token *token_ptr; + LDBLE exchange_coef; + LDBLE offset; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "no_check", /* 0 */ + "check", /* 1 */ + "mb", /* 2 */ + "mass_balance", /* 3 */ + "log_k", /* 4 */ + "logk", /* 5 */ + "delta_h", /* 6 */ + "deltah", /* 7 */ + "analytical_expression", /* 8 */ + "a_e", /* 9 */ + "ae", /* 10 */ + "mole_balance", /* 11 */ + "gamma", /* 12 */ + "davies", /* 13 */ + "offset", /* 14 */ + "llnl_gamma", /* 15 */ + "add_logk", /* 16 */ + "add_log_k", /* 17 */ + "add_constant" /* 18 */ + }; + int count_opt_list = 19; + + association=TRUE; + s_ptr = NULL; +/* + * Read eqn from file and call parser + */ + 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 EXCHANGE_SPECIES keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* no_check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = FALSE; + break; + case 1: /* check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = TRUE; + break; + case 2: /* mb */ + case 3: /* mass_balance */ + case 11: /* mole_balance */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + count_elts = 0; + paren_count =0; + copy_token(token, &next_char, &i); + s_ptr->mole_balance = string_hsave(token); + ptr = token; + get_secondary_in_species(&ptr, 1.0); + s_ptr->next_secondary = elt_list_save(); +/* debug + for (i = 0; i < count_elts; i++) { + output_msg(OUTPUT_MESSAGE,"%s\t%f\n", elt_list[i].elt->name, + elt_list[i].coef); + } + */ + opt_save = OPTION_DEFAULT; + break; + case 4: /* log_k */ + case 5: /* logk */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_log_k_only(next_char, &s_ptr->logk[0]); + opt_save = OPTION_DEFAULT; + break; + case 6: /* delta_h */ + case 7: /* deltah */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_delta_h_only(next_char, &s_ptr->logk[1], &s_ptr->original_units); + opt_save = OPTION_DEFAULT; + break; + case 8: /* analytical_expression */ + case 9: /* a_e */ + case 10: /* ae */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_analytical_expression_only(next_char, &(s_ptr->logk[2])); + opt_save = OPTION_DEFAULT; + break; + case 12: /* gamma data */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->exch_gflag = 2; + i = sscanf(next_char,SCANFORMAT SCANFORMAT, &s_ptr->dha, &s_ptr->dhb ); + if (i < 2) { + sprintf(error_string, "Expecting 2 activity-" + "coefficient parameters, a and b."); + warning_msg(error_string); + } + if (s_ptr->dha == 0 && s_ptr->dhb == 0) { + s_ptr->dhb = 99.9; + s_ptr->exch_gflag = 1; + } + opt_save = OPTION_DEFAULT; + break; + case 13: /* davies eqn */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->exch_gflag = 1; + s_ptr->dha = 0; + s_ptr->dhb = 99.9; + opt_save = OPTION_DEFAULT; + break; + case 14: /* offset */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (sscanf(next_char, SCANFORMAT, &offset) != 1) { + error_msg("No offset for log K given", STOP); + } + s_ptr->logk[0] += offset; + opt_save = OPTION_DEFAULT; + break; + case 15: /* llnl_gamma */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->exch_gflag = 7; /* llnl D-H */ + i = sscanf(next_char,SCANFORMAT, &s_ptr->dha); + if (i < 1) { + sprintf(error_string, "Expecting activity-coefficient parameter, a."); + warning_msg(error_string); + } + opt_save = OPTION_DEFAULT; + break; + case 16: /* add_logk */ + case 17: /* add_log_k */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + /* read name */ + if (copy_token(token, &next_char, &i) == EMPTY) { + input_error++; + sprintf(error_string, "Expected the name of a NAMED_EXPRESSION."); + error_msg(error_string, CONTINUE); + break; + } + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave(token); + /* read coef */ + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + s_ptr->add_logk[s_ptr->count_add_logk].coef = 1; + } + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case 18: /* add_constant */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + input_error++; + sprintf(error_string, "Expected the constant to add for log_K definition."); + error_msg(error_string, CONTINUE); + break; + } + /* set name */ + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave("XconstantX"); + /* read coef */ + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: +/* + * Get exchange species information and parse equation + */ + s_ptr = NULL; + if ( parse_eq(line, &next_elt, association ) == ERROR) { + parse_error++; + error_msg("Parsing equation.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + } +/* + * Get pointer to each species in the reaction, store new species if necessary + */ + trxn.token[0].s = s_store(trxn.token[0].name, trxn.token[0].z, TRUE); + for (i=1; inext_elt=next_elt; + for ( ; next_elt->elt != NULL; next_elt++) { + if ( strcmp (next_elt->elt->name,"C") == 0 ) { + trxn.token[0].s->carbon = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"H") == 0 ) { + trxn.token[0].s->h = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"O") == 0 ) { + trxn.token[0].s->o = next_elt->coef; + } + } +/* + * Find valence of cation from coefficients of reaction components + * Changed to be coefficient of exchanger + */ + exchange_coef = 0.0; + for (i=1; itype == EX) { + exchange_coef = trxn.token[i].coef; + } + } + trxn.token[0].s->equiv = exchange_coef; +/* + * Malloc space for species reaction + */ + trxn.token[0].s->rxn = rxn_alloc (count_trxn+1); +/* + * Copy reaction to reaction for species + */ + token_ptr=trxn.token[0].s->rxn->token; + for (i=0; itype = EX; + s_ptr=trxn.token[0].s; +/* + * Set gamma data + */ + s_ptr->gflag = 4; + s_ptr->exch_gflag = 3; + s_ptr->dha = 0.0; + s_ptr->dhb = 0.0; + opt_save = OPTION_DEFAULT; +/* + * Save as a phase for inverse modeling only + */ + phase_ptr = phase_store(s_ptr->name); + if (phase_ptr == NULL) { + input_error++; + sprintf(error_string, "Copying exchange to phases."); + error_msg(error_string, CONTINUE); + } + phase_ptr->formula=s_ptr->name; + phase_ptr->check_equation = FALSE; + phase_ptr->type = EX; + phase_ptr->next_elt = elt_list_dup(s_ptr->next_elt); + phase_ptr->rxn = rxn_dup(s_ptr->rxn); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_exchange(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads exchange data + * + * 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 i, j, l, n, count_comps; + int n_user, n_user_end; + LDBLE conc; + char *ptr; + char *description; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + struct exchange *exchange_ptr; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "equilibrate", /* 0 */ + "equil", /* 1 */ + "pitzer_exchange_gammas", /* 2 */ + "exchange_gammas", /* 3 */ + "gammas" /* 4 */ + }; + int count_opt_list = 5; +/* + * kin_exch is for exchangers, related to kinetically reacting minerals + * they are defined if "sites" is followed by mineral name: + * Z Manganite ('equi' or 'kine') 0.25 + * ^Name ^equi or kinetic mineral ^switch ^prop.factor + */ +/* + * Read exchange number and description + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Find space for exchange data + */ + exchange_ptr = exchange_search(n_user, &n, FALSE); + if (exchange_ptr != NULL) { + exchange_free(exchange_ptr); + } else { + n = count_exchange++; + space ((void **) ((void *) &exchange), count_exchange, &max_exchange, sizeof(struct exchange)); + } +/* + * Default values + */ + exchange_init(&(exchange[n]), n_user, n_user_end, description); + free_check_null(description); + if (use.exchange_in == FALSE) { + use.exchange_in = TRUE; + use.n_exchange_user = n_user; + } +/* + * Read exchange data + */ + count_comps = 0; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + 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 EXCHANGE keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* equilibrate */ + case 1: + /* + * Read solution to equilibrate with + */ + for (;;) { + i = copy_token(token, &next_char, &l); + if (i == DIGIT) { + sscanf(token, "%d", &exchange[n].n_solution); + exchange[n].new_def = TRUE; + exchange[n].solution_equilibria = TRUE; + break; + } + if (i == EMPTY) { + error_msg("Expected a solution number with which to equilibrate exchanger.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + } + break; + case 2: /* pitzer_exchange_gammas */ + case 3: /* exchange_gammas */ + case 4: /* gammas */ + exchange[n].pitzer_exchange_gammas = get_true_false(next_char, TRUE); + break; + case OPTION_DEFAULT: + exchange[n].comps = (struct exch_comp *) PHRQ_realloc(exchange[n].comps, (size_t) (count_comps + 1) * sizeof (struct exch_comp)); + if (exchange[n].comps == NULL) malloc_error(); + exchange[n].comps[count_comps].formula = NULL; + exchange[n].comps[count_comps].formula_totals = NULL; + exchange[n].comps[count_comps].phase_name = NULL; + exchange[n].comps[count_comps].phase_proportion = 0.0; + exchange[n].comps[count_comps].rate_name = NULL; + ptr=line; + i = copy_token(token, &ptr, &l); + /* + * Species formula is stored in token + */ + if (i != UPPER && token[0] != '[') { + error_msg("Expected exchanger name to begin with a capital letter.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + exchange[n].comps[count_comps].formula = string_hsave(token); + i = copy_token(token1, &ptr, &l); + if (i == DIGIT) { + /* + * Read exchange concentration + */ + + /* exchanger conc. is read directly .. */ + if ( sscanf(token1, SCANFORMAT, &conc) < 1) { + error_msg("Expected concentration of exchanger.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + j = copy_token(token1, &ptr, &l); + if( j == UPPER || j == LOWER) { + exchange[n].comps[count_comps].rate_name = string_hsave(token1); + if (copy_token(token1, &ptr, &l) != DIGIT) { + error_msg("Expected a coefficient to relate exchange to kinetic reaction.\n", CONTINUE); + input_error++; + break; + } + sscanf(token1, SCANFORMAT, &exchange[n].comps[count_comps].phase_proportion); + exchange[n].related_rate = TRUE; + } + /* + * Read equilibrium phase name or kinetics rate name + */ + } else if (i != EMPTY) { + + /* exchanger conc. is related to mineral or kinetics */ + exchange[n].comps[count_comps].phase_name = string_hsave(token1); + j = copy_token(token1, &ptr, &l); + if (j == DIGIT) { + exchange[n].related_phases = TRUE; + } else { + if (token1[0] == 'K' || token1[0] == 'k') { + exchange[n].comps[count_comps].rate_name = exchange[n].comps[count_comps].phase_name; + exchange[n].comps[count_comps].phase_name = NULL; + exchange[n].related_rate = TRUE; + } else if (token1[0] == 'E' || token1[0] == 'e') { + exchange[n].related_phases = TRUE; + } else { + error_msg("Character string expected to be 'equilibrium_phase' or 'kinetics' to relate exchange to mineral or kinetic reaction.\n", CONTINUE); + input_error++; + break; + } + j = copy_token(token1, &ptr, &l); + } + + + if (j != DIGIT) { + error_msg("Expected a coefficient to relate exchanger to mineral or kinetic reaction.\n", CONTINUE); + input_error++; + break; + } + sscanf(token1, SCANFORMAT, &exchange[n].comps[count_comps].phase_proportion); + /* real conc must be defined in tidy_model */ + conc = 1.0; + } else { + error_msg("Expected concentration of exchanger, mineral name, or kinetic reaction name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + /* + * Accumulate elements in elt_list + */ + count_elts = 0; + paren_count = 0; + ptr = token; + get_elts_in_species(&ptr, conc); + /* + * save formula for adjusting number of exchange sites + */ + ptr = token; + get_token(&ptr, token1, &exchange[n].comps[count_comps].formula_z, &l); + exchange[n].comps[count_comps].formula_totals = elt_list_save(); + /* + * Save elt_list + */ + exchange[n].comps[count_comps].moles = conc; + exchange[n].comps[count_comps].totals = elt_list_save(); + exchange[n].comps[count_comps].charge_balance = 0.0; + count_comps++; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + exchange[n].count_comps = count_comps; + return(return_value); +} + +/* ---------------------------------------------------------------------- */ +int read_exchange_master_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads master species data from data file or input file + */ + int j, l; + char *ptr, *ptr1; + LDBLE z; + struct element *elts_ptr; + struct species *s_ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + for (;;) { + j=check_line ("Exchange species equation", FALSE, TRUE, TRUE, TRUE); + if (j == EOF || j == KEYWORD ) { + break; + } +/* + * Get element name with valence, allocate space, store + */ + ptr=line; +/* + * Get element name and save pointer to character string + */ + if ( copy_token(token, &ptr, &l) != UPPER && token[0] != '[' ) { + parse_error++; + error_msg("Reading element for master species.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } + /* + if (token[0] == '[') { + ptr1 = token; + get_elt(&ptr, element, &l); + strcpy(token, element); + } + */ + replace ("(+", "(", token); +/* + * Delete master if it exists + */ + master_delete(token); +/* + * Increase pointer array, if necessary, and malloc space + */ + if (count_master >= max_master) { + space ((void **) ((void *) &master), count_master+1, &max_master, sizeof(struct master *)); + } + master[count_master] = master_alloc(); +/* + * Set type to EX + */ + master[count_master]->type = EX; +/* + * Save element name + */ + master[count_master]->elt = element_store ( token ); +/* + * Save pointer to species data for master species + */ + if ( ( copy_token(token, &ptr, &l) != UPPER ) && + token[0] != '[' && + ( strcmp_nocase_arg1(token, "e-") != 0 ) ) { + parse_error++; + error_msg("Reading master species name.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } + s_ptr=s_search (token); + if (s_ptr != NULL) { + master[count_master]->s = s_ptr; + } else { + ptr1=token; + get_token(&ptr1, token1, &z, &l); + master[count_master]->s = s_store(token1, z, FALSE); + } +/* + * MAKE LISTS OF PRIMARY AND SECONDARY MASTER SPECIES + */ + master[count_master]->primary=TRUE; + if ( strcmp(master[count_master]->elt->name,"E") != 0 ) { + elts_ptr = element_store(master[count_master]->elt->name); + elts_ptr->gfw = 0.0; + } + + count_master++; + if (count_master >= max_master) { + space ((void **) ((void *) &master), count_master, &max_master, + sizeof(struct master *)); + } + } + return (j); +} +/* ---------------------------------------------------------------------- */ +int read_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads gas phase data + * + * 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 i, j, n, l; + int count_comps; + int n_user, n_user_end; + char *ptr; + char *description; + char token[MAX_LENGTH]; + struct gas_phase *gas_phase_ptr; + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "pressure", /* 0 */ + "volume", /* 1 */ + "temp", /* 2 */ + "temperature", /* 3 */ + "fixed_pressure", /* 4 */ + "fixed_volume", /* 5 */ + "equilibrium", /* 6 */ + "equilibrate", /* 7 */ + "equil" /* 8 */ + }; + int count_opt_list = 9; +/* + * Read gas_phase number + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Find old gas_phase or alloc space for new gas_phase + */ + gas_phase_ptr = gas_phase_search(n_user, &n); + if (gas_phase_ptr != NULL) { + gas_phase_free(gas_phase_ptr); + } else { + n=count_gas_phase; + count_gas_phase++; + space ((void **) ((void *) &gas_phase), count_gas_phase, &max_gas_phase, sizeof(struct gas_phase)); + } +/* + * Initialize + */ + gas_phase_init(&(gas_phase[n]), n_user, n_user_end, description); + free_check_null(description); +/* + * Set use data to first read + */ + if (use.gas_phase_in == FALSE) { + use.gas_phase_in = TRUE; + use.n_gas_phase_user = n_user; + } +/* + * Read phases + */ + count_comps = 0; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + 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 GAS_PHASE keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* pressure */ + sscanf( next_char,SCANFORMAT, &dummy); + gas_phase[n].total_p = (LDBLE) dummy; + break; + case 1: /* Volume */ + sscanf( next_char,SCANFORMAT, &(gas_phase[n].volume) ); + break; + case 2: /* Temperature */ + case 3: + j = sscanf( next_char,SCANFORMAT, &(gas_phase[n].temperature) ); + if (j == 1) { + gas_phase[n].temperature += 273.15; + } + break; + case 4: /* fixed_pressure */ + gas_phase[n].type = PRESSURE; + break; + case 5: /* fixed_volume */ + gas_phase[n].type = VOLUME; + break; + case 6: /* equilibrate */ + case 7: /* equilibrium */ + case 8: /* equil */ +/* + * Read solution to equilibrate with + */ + for (;;) { + i = copy_token(token, &next_char, &l); + if (i == DIGIT) { + sscanf(token, "%d", &gas_phase[n].n_solution); + gas_phase[n].new_def = TRUE; + gas_phase[n].solution_equilibria = TRUE; + break; + } + if (i == EMPTY) { + error_msg("Expected a solution number with which to equilibrate gas phase.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + } + break; + case OPTION_DEFAULT: +/* + * Make space, set default + */ + gas_phase[n].comps = (struct gas_comp *) PHRQ_realloc(gas_phase[n].comps, (size_t) (count_comps + 1) * sizeof(struct gas_comp)); + if (gas_phase[n].comps == NULL) malloc_error(); + gas_phase[n].comps[count_comps].p_read = 0.0; + gas_phase[n].comps[count_comps].moles = 0.0; + count_comps++; +/* + * Read name + */ + ptr = line; + copy_token(token, &ptr, &l); + gas_phase[n].comps[count_comps - 1].name = string_hsave(token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) { + gas_phase[n].comps[count_comps - 1].p_read = NAN; + break; + } +/* + * Read initial partial pressure of gas + */ + + j=sscanf( token,SCANFORMAT, &(gas_phase[n].comps[count_comps - 1].p_read) ); + if (j != 1 ) { + error_msg("Expected partial pressure of gas in gas phase.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* + * Sort components by name (lowercase) + */ + gas_phase[n].count_comps = count_comps; + qsort (gas_phase[n].comps, + (size_t) count_comps, + (size_t) sizeof(struct gas_comp), + gas_comp_compare); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_inverse(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads data for mass_balance calculations + * + * 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 n, j; + int n_user, n_user_end; + char *ptr; + char *description; + LDBLE range_max, inv_tol, water_uncertainty; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "solutions", /* 0 */ + "uncertainty", /* 1 */ + "uncertainties", /* 2 */ + "balances", /* 3 */ + "phase_data", /* 4 */ + "range", /* 5 */ + "minimal", /* 6 */ + "minimum", /* 7 */ + "balance", /* 8 */ + "bal", /* 9 */ + "sol", /* 10 */ + "phases", /* 11 */ + "ranges", /* 12 */ + "tolerance", /* 13 */ + "u_water", /* 14 */ + "uncertainty_water", /* 15 */ + "force", /* 16 */ + "force_solution", /* 17 */ + "force_solutions", /* 18 */ + "isotopes", /* 19 */ + "mineral_water", /* 20 */ + "phase", /* 21 */ + "multiple_precision", /* 22 */ + "mp_tolerance", /* 23 */ + "censor_mp" /* 24 */ + }; + int count_opt_list = 25; + + ptr=line; +/* + * Read solution number and description + */ + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Malloc space for solution data + */ + if (inverse_search(n_user, &n) != NULL) { + inverse_delete(n); + } + inverse_alloc(); + n = count_inverse - 1; +/* + * Initialize structure and use + */ + inverse[n].new_def = TRUE; + inverse[n].n_user = n_user; + inverse[n].range = FALSE; + inverse[n].range_max = 1000.; + inverse[n].tolerance = 1e-10; + inverse[n].minimal = FALSE; + inverse[n].description = description; + inverse[n].count_uncertainties = 1; + inverse[n].uncertainties[0] = 0.05; + inverse[n].count_ph_uncertainties = 1; + inverse[n].ph_uncertainties[0] = 0.05; + inverse[n].water_uncertainty = 0.0; + inverse[n].mineral_water = TRUE; + inverse[n].mp = FALSE; + inverse[n].mp_tolerance = 1e-12; + inverse[n].mp_censor = 1e-20; +/* + * Read data for inverse modeling + */ + opt_save = OPTION_ERROR; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + if (opt == OPTION_DEFAULT) { + opt = opt_save; + } + opt_save = opt; + switch (opt) { + case OPTION_EOF: /* end of file */ + return_value = EOF; + break; + case OPTION_KEYWORD: /* keyword */ + return_value = KEYWORD; + break; + case OPTION_DEFAULT: + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in INVERSE_MODELING keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* solutions */ + case 10: /* solution */ + inverse[n].solns = read_list_ints(&next_char, &inverse[n].count_solns, TRUE); + opt_save = OPTION_ERROR; + break; + case 1: /* uncertainty */ + case 2: /* uncertainties */ + inverse[n].uncertainties = (double *) free_check_null (inverse[n].uncertainties); + inverse[n].uncertainties = read_list_doubles(&next_char, &inverse[n].count_uncertainties); + opt_save = OPTION_ERROR; + break; + case 3: /* balances */ + case 8: /* balance */ + case 9: /* bal */ + read_inv_balances( &(inverse[n]), next_char ); + break; + case 4: /* phase_data */ + case 11: /* phases */ + case 21: /* phase */ + read_inv_phases( &(inverse[n]), next_char ); + break; + case 5: /* range */ + case 12: /* ranges */ + inverse[n].range = TRUE; + j = sscanf( next_char, SCANFORMAT, &range_max ) ; + if (j == 1 ) { + inverse[n].range_max = range_max; + } + opt_save = OPTION_ERROR; + break; + case 6: /* minimal */ + case 7: /* minimum */ + inverse[n].minimal = TRUE; + opt_save = OPTION_ERROR; + break; + case 13: /* tolerance */ + j = sscanf( next_char, SCANFORMAT, &inv_tol ) ; + if (j == 1 ) { + inverse[n].tolerance = inv_tol; + } + opt_save = OPTION_ERROR; + break; + case 14: /* u_water */ + case 15: /* uncertainty_water */ + j = sscanf( next_char, SCANFORMAT, &water_uncertainty ) ; + if (j == 1 ) { + inverse[n].water_uncertainty = water_uncertainty; + } + opt_save = OPTION_ERROR; + break; + case 16: /* force */ + case 17: /* force_solution */ + case 18: /* force_solutions */ + inverse[n].force_solns = (int *) free_check_null (inverse[n].force_solns); + inverse[n].force_solns = read_list_t_f(&next_char, + &inverse[n].count_force_solns); + opt_save = OPTION_ERROR; + break; + case 19: /* isotope values */ + read_inv_isotopes( &(inverse[n]), next_char ); + break; + case 20: /* mineral_water */ + inverse[n].mineral_water = get_true_false(next_char, TRUE); + break; + case 22: /* multiple_precision */ + inverse[n].mp = get_true_false(next_char, TRUE); + break; + case 23: /* mp_tolerance */ + j = sscanf( next_char, SCANFORMAT, &inv_tol ) ; + if (j == 1 ) { + inverse[n].mp_tolerance = fabs(inv_tol); + } + break; + case 24: /* censor_mp */ + j = sscanf( next_char, SCANFORMAT, &inv_tol ) ; + if (j == 1 ) { + inverse[n].mp_censor = fabs(inv_tol); + } + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* + * Default: soln 1 -> soln 2 + */ + if (inverse[n].count_solns == 0) { + inverse[n].solns = (int *) PHRQ_malloc( 2 * sizeof( int ) ); + if (inverse[n].solns == NULL) malloc_error(); + inverse[n].solns[0] = 1; + inverse[n].solns[1] = 2; + inverse[n].count_solns = 2; + } +/* + * Sort isotopes + */ + if (inverse[n].count_isotopes > 0) { + qsort (inverse[n].isotopes, + (size_t) inverse[n].count_isotopes, + (size_t) sizeof(struct inv_isotope), + inverse_isotope_compare); + } + + if (inverse[n].count_i_u > 0) { + qsort (inverse[n].i_u, + (size_t) inverse[n].count_i_u, + (size_t) sizeof(struct inv_isotope), + inverse_isotope_compare); + } + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_inv_balances (struct inverse *inverse_ptr, char *ptr) +/* ---------------------------------------------------------------------- */ +{ + int j, l, count; + char token[MAX_LENGTH]; +/* + * Read element name + */ + j = copy_token(token, &ptr, &l); + if (j == EMPTY) { + return(OK); + } else if (j == LOWER && strcmp_nocase_arg1(token,"ph") != 0) { + error_msg("Expecting element name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } else if (strcmp_nocase_arg1(token, "ph") != 0) { + inverse_ptr->elts = (struct inv_elts *) PHRQ_realloc(inverse_ptr->elts, (size_t) (inverse_ptr->count_elts + 1) * sizeof( struct inv_elts)); + if (inverse_ptr->elts == NULL) malloc_error(); + replace("(+","(",token); + inverse_ptr->elts[inverse_ptr->count_elts].name = string_hsave(token); +/* + * Read element uncertainties + */ + inverse_ptr->elts[inverse_ptr->count_elts].uncertainties = read_list_doubles(&ptr, &count); + inverse_ptr->elts[inverse_ptr->count_elts].count_uncertainties = count; + inverse_ptr->count_elts++; + } else if (strcmp_nocase_arg1(token, "ph") == 0) { + inverse_ptr->ph_uncertainties = (double *) free_check_null (inverse_ptr->ph_uncertainties); + inverse_ptr->ph_uncertainties = read_list_doubles(&ptr, &count); + inverse_ptr->count_ph_uncertainties = count; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_inv_isotopes (struct inverse *inverse_ptr, char *ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, j, l, l1, l2, count; + LDBLE isotope_number; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + char *ptr1, *ptr2, *redox_name, *element_name; +/* + * Read element name + */ + ptr1 = ptr; + j = copy_token(token, &ptr1, &l); +/* + * ptr1 is start of uncertainties + */ + if (j == EMPTY) { + return(OK); + } else if (j != DIGIT) { + error_msg("Expecting isotope to begin with isotope number.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Read isotope name + */ + ptr2 = token; + get_num(&ptr2, &isotope_number); + if (ptr2[0] == '\0' || isupper((int) ptr2[0]) == FALSE) { + error_msg("Expecting element name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + + /* redox state name with parentheses */ + redox_name = string_hsave(ptr2); + + copy_token(token, &ptr2, &l1); + replace("("," ",token); + ptr2 = token; + + /* element name, without parentheses */ + copy_token(token1, &ptr2, &l2); + element_name = string_hsave(token1); + +/* + * add element name to inv_ptr->isotopes + */ + for (i = 0; i < inverse_ptr->count_isotopes; i++) { + if (element_name == inverse_ptr->isotopes[i].elt_name) break; + } + if (i == inverse_ptr->count_isotopes) { + inverse_ptr->isotopes = (struct inv_isotope *) PHRQ_realloc(inverse_ptr->isotopes, (size_t) (inverse_ptr->count_isotopes + 1) * sizeof( struct inv_isotope)); + if (inverse_ptr->isotopes == NULL) malloc_error(); + inverse_ptr->isotopes[inverse_ptr->count_isotopes].isotope_number = isotope_number; + inverse_ptr->isotopes[inverse_ptr->count_isotopes].elt_name = element_name; + inverse_ptr->isotopes[inverse_ptr->count_isotopes].uncertainties = (double *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (inverse_ptr->isotopes[inverse_ptr->count_isotopes].uncertainties == NULL) malloc_error(); + inverse_ptr->count_isotopes++; + } +/* + * add redox state name to inv_ptr->i_u + */ + inverse_ptr->i_u = (struct inv_isotope *) PHRQ_realloc(inverse_ptr->i_u, (size_t) (inverse_ptr->count_i_u + 1) * sizeof( struct inv_isotope)); + if (inverse_ptr->i_u == NULL) malloc_error(); + inverse_ptr->i_u[inverse_ptr->count_i_u].elt_name = redox_name; + inverse_ptr->i_u[inverse_ptr->count_i_u].isotope_number = isotope_number; +/* + * Read isotope uncertainties + */ + inverse_ptr->i_u[inverse_ptr->count_i_u].uncertainties = read_list_doubles(&ptr1, &count); + inverse_ptr->i_u[inverse_ptr->count_i_u].count_uncertainties = count; + inverse_ptr->count_i_u++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_inv_phases (struct inverse *inverse_ptr, char *ptr) +/* ---------------------------------------------------------------------- */ +{ + int j, l; + int count_isotopes; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + char *ptr1; + struct isotope *isotopes; +/* + * Read phase name + */ + j = copy_token(token, &ptr, &l); + if (j == EMPTY) return(OK); + inverse_ptr->phases = (struct inv_phases *) PHRQ_realloc(inverse_ptr->phases, (size_t) (inverse_ptr->count_phases + 1) * sizeof( struct inv_phases)); + if (inverse_ptr->phases == NULL) malloc_error(); + inverse_ptr->phases[inverse_ptr->count_phases].name = string_hsave(token); +/* + * Read constraint, force, and isotopes + */ + inverse_ptr->phases[inverse_ptr->count_phases].constraint = EITHER; + inverse_ptr->phases[inverse_ptr->count_phases].force = FALSE; + count_isotopes = 0; + isotopes = (struct isotope *) PHRQ_malloc(sizeof(struct isotope)); + if (isotopes == NULL) malloc_error(); + + for (;;) { + j = copy_token(token, &ptr, &l); + if (j == EMPTY) break; + strcpy(token1, token); + str_tolower(token1); + if (token1[0] == 'p' ) { + inverse_ptr->phases[inverse_ptr->count_phases].constraint = PRECIPITATE; + } else if (token1[0] == 'd' ) { + inverse_ptr->phases[inverse_ptr->count_phases].constraint = DISSOLVE; + } else if (token[0] == 'f' ) { + inverse_ptr->phases[inverse_ptr->count_phases].force = TRUE; + } else if (j == DIGIT) { +/* + * read isotope data + */ + isotopes = (struct isotope *) PHRQ_realloc( isotopes , (size_t) (count_isotopes + 1) * sizeof (struct isotope)); + if (isotopes == NULL) malloc_error(); + ptr1 = token; + + /* isotope number */ + get_num(&ptr1, &(isotopes[count_isotopes].isotope_number)); + if (ptr1[0] == '\0' || isupper((int) ptr1[0]) == FALSE) { + sprintf(error_string, "Expecting element name: %s.", ptr1); + error_msg(error_string, CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + + /* element name */ + isotopes[count_isotopes].elt_name = string_hsave(ptr1); + + /* ratio */ + j = copy_token(token, &ptr, &l); + if (j != DIGIT ) { + error_msg("Expecting isotope ratio for phase.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + sscanf(token, SCANFORMAT, &(isotopes[count_isotopes].ratio)); + + /* read and store isotope ratio uncertainty */ + if (copy_token(token, &ptr, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for uncertainty in isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } + sscanf(token, SCANFORMAT, &(isotopes[count_isotopes].ratio_uncertainty)); + + count_isotopes++; + } else { + sprintf(error_string, "Unknown option for inverse modeling phase."); + warning_msg(error_string); + } + } + if (count_isotopes > 0) { + inverse_ptr->phases[inverse_ptr->count_phases].isotopes = isotopes; + inverse_ptr->phases[inverse_ptr->count_phases].count_isotopes = count_isotopes; + } else { + inverse_ptr->phases[inverse_ptr->count_phases].isotopes = NULL; + inverse_ptr->phases[inverse_ptr->count_phases].count_isotopes = 0; + isotopes = (struct isotope *) free_check_null(isotopes); + } + inverse_ptr->count_phases++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_kinetics (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads kinetics data + * + * 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 + * + */ +/* + * Read kinetics + */ + int i, j, k, l, count_comps, count_steps, count_list; + char *ptr; + char *description; + char token[MAX_LENGTH]; + int n; + int n_user, n_user_end; + struct kinetics *kinetics_ptr; + struct kinetics_comp *kinetics_comp_ptr; + LDBLE step, coef; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "tol", /* 0 */ + "m", /* 1 */ + "m0", /* 2 */ + "parms", /* 3 */ + "formula", /* 4 */ + "steps", /* 5 */ + "step_divide", /* 6 */ + "parameters", /* 7 */ + "runge-kutta", /* 8 */ + "runge_kutta", /* 9 */ + "rk", /* 10 */ + "bad_step_max", /* 11 */ + "cvode" /* 12 */ + }; + int count_opt_list = 13; + +/* + * Read kinetics number + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + +/* + * Find space for kinetics data + */ + kinetics_ptr = kinetics_search(n_user, &n, FALSE); + if (kinetics_ptr != NULL) { + kinetics_free(kinetics_ptr); + } else { + space ((void **) ((void *) &kinetics), count_kinetics, &max_kinetics, sizeof(struct kinetics)); + n = count_kinetics++; + } +/* + * Set use data to first read + */ + if (use.kinetics_in == FALSE) { + use.kinetics_in = TRUE; + use.n_kinetics_user = n_user; + } +/* + * Initialize + */ + kinetics_init(&(kinetics[n]), n_user, n_user_end, description); + free_check_null(description); + kinetics_ptr = &kinetics[n]; + + count_steps = 0; +/* + * Read kinetics data + */ + return_value = UNKNOWN; + kinetics_comp_ptr = NULL; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + switch (opt) { + case OPTION_EOF: /* end of file */ + return_value = EOF; + break; + case OPTION_KEYWORD: /* keyword */ + return_value = KEYWORD; + break; + case OPTION_DEFAULT: /* allocate space, read new name */ + count_comps = kinetics_ptr->count_comps++; + kinetics_ptr->comps = (struct kinetics_comp *) PHRQ_realloc(kinetics_ptr->comps, (size_t) (count_comps + 1) * sizeof(struct kinetics_comp)); + if (kinetics_ptr->comps == NULL) malloc_error(); + kinetics_ptr->comps[count_comps].moles = 0; + ptr = line; + copy_token (token, &ptr, &l); + kinetics_ptr->comps[count_comps].rate_name = string_hsave(token); +#ifdef SKIP + kinetics_ptr->comps[count_comps].formula = kinetics_ptr->comps[count_comps].rate_name; +#endif + kinetics_ptr->comps[count_comps].tol = 1e-8; + kinetics_ptr->comps[count_comps].m0 = -1.0; + kinetics_ptr->comps[count_comps].m = -1.0; + kinetics_ptr->comps[count_comps].count_c_params = 0; + + kinetics_comp_ptr = &kinetics_ptr->comps[count_comps]; + kinetics_comp_ptr->d_params = (double *) PHRQ_malloc(sizeof(LDBLE)); + if (kinetics_comp_ptr->d_params == NULL) malloc_error(); + kinetics_comp_ptr->count_d_params = 0; + + kinetics_comp_ptr->c_params = (char **) PHRQ_malloc(sizeof(char *)); + if (kinetics_comp_ptr->c_params == NULL) malloc_error(); + kinetics_comp_ptr->count_c_params = 0; + + kinetics_comp_ptr->count_list = 0; + kinetics_comp_ptr->list = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (kinetics_comp_ptr->list == NULL) malloc_error(); + break; + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in KINETICS keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* tolerance */ + if (kinetics_comp_ptr == NULL) { + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + input_error++; + } else { + if (copy_token (token, &next_char, &l) == DIGIT) { + kinetics_comp_ptr->tol = strtod(token, &ptr); + } else { + sprintf(error_string, "Expecting numerical value for tolerance."); + error_msg(error_string, CONTINUE); + input_error++; + } + } + break; + case 1: /* m */ + if (kinetics_comp_ptr == NULL) { + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + input_error++; + } else { + if (copy_token (token, &next_char, &l) == DIGIT) { + kinetics_comp_ptr->m = strtod(token, &ptr); + } else { + sprintf(error_string, "Expecting numerical value for moles of reactant."); + error_msg(error_string, CONTINUE); + input_error++; + } + } + break; + case 2: /* m0 */ + if (kinetics_comp_ptr == NULL) { + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + input_error++; + } else { + if (copy_token (token, &next_char, &l) == DIGIT) { + kinetics_comp_ptr->m0 = strtod(token, &ptr); + } else { + sprintf(error_string, "Expecting numerical value for initial moles of reactant."); + error_msg(error_string, CONTINUE); + input_error++; + } + } + break; + case 3: /* parms */ + case 7: /* parameters */ + if (kinetics_comp_ptr == NULL) { + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + input_error++; + } else { + while ((j = copy_token (token, &next_char, &l)) != EMPTY) { + /* + * Store a LDBLE parameter + */ + if (j == DIGIT) { + kinetics_comp_ptr->d_params = (double *) PHRQ_realloc(kinetics_comp_ptr->d_params, (size_t) (kinetics_comp_ptr->count_d_params + 1) * sizeof(LDBLE)); + if (kinetics_comp_ptr->d_params == NULL) malloc_error(); + kinetics_comp_ptr->d_params[kinetics_comp_ptr->count_d_params] = strtod(token, &ptr); + kinetics_comp_ptr->count_d_params++; + } else { + /* + * Store a character parameter + */ + kinetics_comp_ptr->c_params = (char **) PHRQ_realloc(kinetics_comp_ptr->c_params, (size_t) (kinetics_comp_ptr->count_c_params + 1) * sizeof(char *)); + if (kinetics_comp_ptr->c_params == NULL) malloc_error(); + kinetics_comp_ptr->c_params[kinetics_comp_ptr->count_c_params] = string_hsave(token); + kinetics_comp_ptr->count_c_params++; + } + } + } + break; + case 4: /* formula */ + if (kinetics_comp_ptr == NULL) { + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + input_error++; + } else { + /* + * Store reactant name, default coefficient + */ + ptr = next_char; + while (copy_token (token, &ptr, &l) != EMPTY) { + if ( isalpha((int) token[0]) || (token[0] == '(' ) || (token[0] == '[' )) { + count_list = kinetics_comp_ptr->count_list++; + kinetics_comp_ptr->list = (struct name_coef *) PHRQ_realloc(kinetics_comp_ptr->list, + (size_t) (count_list + 1) * sizeof(struct name_coef)); + if (kinetics_comp_ptr->list == NULL) malloc_error(); + kinetics_comp_ptr->list[count_list].name = string_hsave(token); + kinetics_comp_ptr->list[count_list].coef = 1.0; + } else { + /* + * Store relative coefficient + */ + j = sscanf(token, SCANFORMAT, &coef); + if (j == 1 ) { + count_list = kinetics_comp_ptr->count_list - 1; + kinetics_comp_ptr->list[count_list].coef = coef; + } else { + error_msg("Reading relative coefficient of reactant.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + } + } + break; + case 5: /* steps */ + /* + * Read one or more kinetics time increments + */ + while ( (j = copy_token (token, &next_char, &l)) == DIGIT ) { + /* Read next step increment(s) */ +/* multiple, equal timesteps 15 aug. 2005 */ + if (replace("*"," ",token) == TRUE) { + if (sscanf(token,"%d" SCANFORMAT, &k, &step) == 2) { + for (i = 0; i < k; i++) { + count_steps++; + kinetics_ptr->steps = (double *) PHRQ_realloc(kinetics_ptr->steps, (size_t) count_steps * sizeof(LDBLE)); + if (kinetics_ptr->steps == NULL) malloc_error(); + kinetics_ptr->steps[kinetics_ptr->count_steps] = step; + kinetics_ptr->count_steps = count_steps; + } + } else { + input_error++; + error_msg("Format error in multiple, equal KINETICS timesteps.\nCorrect is (for example): 20 4*10 2*5 3\n", CONTINUE); + } + } else { + step = strtod(token, &ptr); + count_steps++; + kinetics_ptr->steps = (double *) PHRQ_realloc(kinetics_ptr->steps, (size_t) count_steps * sizeof(LDBLE)); + if (kinetics_ptr->steps == NULL) malloc_error(); + kinetics_ptr->steps[kinetics_ptr->count_steps] = step; + kinetics_ptr->count_steps = count_steps; + } + } + if (j == EMPTY) break; + /* + * Read number of increments + */ + if (kinetics_ptr->count_steps != 1) { + error_msg("To define equal time increments, only one total time should be defined.", CONTINUE); + input_error++; + break; + } + do { + j = sscanf(token, "%d", &i); + if (j == 1 && i > 0 ) { + kinetics_ptr->count_steps = -i; + break; + } else if (j == 1 && i <= 0 ) { + error_msg("Expecting positive number for number of equal " + "time increments for kinetics.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + } while ( copy_token (token, &next_char, &l) != EMPTY ); + break; + case 6: /* step_divide */ + if (copy_token (token, &next_char, &l) == DIGIT) { + sscanf(token, SCANFORMAT, &kinetics_ptr->step_divide); + } else { + sprintf(error_string, "Expecting numerical value for step_divide."); + error_msg(error_string, CONTINUE); + input_error++; + } + break; + case 8: /* runge-kutta */ + case 9: /* runge_kutta */ + case 10: /* rk */ + j = copy_token (token, &next_char, &l); + if ( j == DIGIT) { + kinetics_ptr->rk = (int)strtod(token, &ptr); + } else if (j == EMPTY) { + } else { + sprintf(error_string, "Expecting order for Runge-Kutta method."); + error_msg(error_string, CONTINUE); + input_error++; + } + break; + case 11: /* bad_step_max */ + j = copy_token (token, &next_char, &l); + if ( j == DIGIT) { + kinetics_ptr->bad_step_max = (int)strtod(token, &ptr); + } else if (j == EMPTY) { + } else { + sprintf(error_string, "Expecting maximal bad steps number."); + error_msg(error_string, CONTINUE); + input_error++; + } + break; + case 12: /* cvode */ + kinetics[n].use_cvode = get_true_false(next_char, TRUE); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + +/* + * Default reactant + */ + for (i = 0; i < kinetics[n].count_comps; i++) { + if (kinetics[n].comps[i].count_list == 0) { + kinetics[n].comps[i].list[0].name = kinetics_ptr->comps[i].rate_name; + kinetics[n].comps[i].list[0].coef = 1; + kinetics[n].comps[i].count_list = 1; + } + } +/* + * Default 1 sec + */ + if (kinetics[n].count_steps == 0) { + kinetics[n].count_steps = 1; + kinetics[n].steps[0] = 1.0; + } +/* + * set defaults for moles + */ + for (i = 0; i < kinetics[n].count_comps; i++) { + if (kinetics[n].comps[i].m0 < 0) { + if (kinetics[n].comps[i].m < 0) { + kinetics[n].comps[i].m0 = 1; + } else { + kinetics[n].comps[i].m0 = kinetics[n].comps[i].m; + } + } + if (kinetics[n].comps[i].m < 0) { + kinetics[n].comps[i].m = kinetics[n].comps[i].m0; + } + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +LDBLE *read_list_doubles(char **ptr, int *count_doubles ) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads a list of LDBLE numbers until end of line is reached or + * a LDBLE can not be read from a token. + * + * Arguments: + * ptr entry: points to line to read from + * exit: points to next non-LDBLE token or end of line + * + * count_doubles exit: number of LDBLEs read + * + * Returns: + * pointer to a list of count_doubles LDBLEs. + */ + + LDBLE *LDBLE_list; + char token[MAX_LENGTH]; + LDBLE value; + char *ptr_save; + int l; + + LDBLE_list = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (LDBLE_list == NULL) malloc_error(); + *count_doubles = 0; + + ptr_save = *ptr; + while ( copy_token(token, ptr, &l) != EMPTY) { + if (sscanf(token,SCANFORMAT, &value) == 1) { + *count_doubles = *count_doubles + 1; + LDBLE_list = (LDBLE *) PHRQ_realloc(LDBLE_list, (size_t) (*count_doubles) * sizeof (LDBLE)); + if (LDBLE_list == NULL) malloc_error(); + LDBLE_list[ (*count_doubles) - 1] = value; + ptr_save = *ptr; + } else { + *ptr = ptr_save; + break; + } + } + return(LDBLE_list); +} +/* ---------------------------------------------------------------------- */ +int *read_list_ints (char **ptr, int *count_ints, int positive ) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads a list of int numbers until end of line is reached or + * an int can not be read from a token. + * + * Arguments: + * ptr entry: points to line to read from + * exit: points to next non-int token or end of line + * + * count_ints exit: number of LDBLEs read + * + * positive entry: if TRUE, expects to read only positive integers + * + * Returns: + * pointer to a list of count_ints ints. + */ + int *int_list; + char token[MAX_LENGTH]; + int value; + int l; + char *ptr_save; + + int_list = (int *) PHRQ_malloc(sizeof(int)); + if (int_list == NULL) malloc_error(); + *count_ints = 0; + + ptr_save = *ptr; + while ( copy_token(token, ptr, &l) != EMPTY) { + if (sscanf(token,"%d", &value) == 1) { + (*count_ints)++; + int_list = (int *) PHRQ_realloc(int_list, (size_t) (*count_ints) * sizeof (int)); + if (int_list == NULL) malloc_error(); + int_list[(*count_ints) - 1] = value; + if (value <= 0 && positive == TRUE) { + error_msg("Expected an integer greater than zero.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + ptr_save = *ptr; + } else { + *ptr = ptr_save; + break; + } + } + return(int_list); +} +/* ---------------------------------------------------------------------- */ +int *read_list_ints_range (char **ptr, int *count_ints, int positive, int *int_list ) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads a list of int numbers until end of line is reached or + * an int can not be read from a token. + * + * Arguments: + * ptr entry: points to line to read from + * exit: points to next non-int token or end of line + * + * count_ints entry: number of ints already in list + * + * positive entry: if TRUE, expects to read only positive integers + * + * Returns: + * pointer to a list of count_ints ints + */ + char token[MAX_LENGTH]; + int value, value1, value2; + int i, l; + char *ptr_save; + + if (int_list == NULL) { + int_list = (int *) PHRQ_malloc(sizeof(int)); + if (int_list == NULL) malloc_error(); + *count_ints = 0; + } + ptr_save = *ptr; + while ( copy_token(token, ptr, &l) != EMPTY) { + if (sscanf(token,"%d", &value) == 1) { + /* Read an integer */ + (*count_ints)++; + int_list = (int *) PHRQ_realloc(int_list, (size_t) (*count_ints) * sizeof (int)); + if (int_list == NULL) malloc_error(); + int_list[(*count_ints) - 1] = value; + if (value <= 0 && positive == TRUE) { + error_msg("Expected an integer greater than zero.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + /* Read range of integers */ + if (replace("-"," ",token) == TRUE) { + if (sscanf(token, "%d %d", &value1, &value2) != 2) { + error_msg("Expected an integer range n-m.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } else if (value2 < value1) { + error_msg("Expected an integer range n-m, with n <= m.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } else if (value2 <= 0 && positive == TRUE) { + error_msg("Expected an integer greater than zero.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } else { + for (i = value1 + 1; i <= value2; i++) { + (*count_ints)++; + int_list = (int *) PHRQ_realloc(int_list, (size_t) (*count_ints) * sizeof (int)); + if (int_list == NULL) malloc_error(); + int_list[(*count_ints) - 1] = i; + } + } + } + ptr_save = *ptr; + } else { + *ptr = ptr_save; + break; + } + } + return(int_list); +} +/* ---------------------------------------------------------------------- */ +int *read_list_t_f (char **ptr, int *count_ints ) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads a list of true and false until end of line is reached or + * until non- t or f is found + * + * Arguments: + * ptr entry: points to line to read from + * exit: points to next non-int token or end of line + * + * count_ints exit: number of LDBLEs read + * + * positive entry: if TRUE, expects to read only positive integers + * + * Returns: + * pointer to a list of count_ints ints. + */ + int *int_list; + char token[MAX_LENGTH]; + int value; + int l; + + int_list = (int *) PHRQ_malloc(sizeof(int)); + if (int_list == NULL) malloc_error(); + *count_ints = 0; + + while ( copy_token(token, ptr, &l) != EMPTY) { + str_tolower(token); + if (token[0] == 't') { + value = TRUE; + } else if (token[0] == 'f') { + value = FALSE; + } else { + error_msg("Expected TRUE or FALSE.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + (*count_ints)++; + int_list = (int *) PHRQ_realloc(int_list, (size_t) (*count_ints) * sizeof (int)); + if (int_list == NULL) malloc_error(); + int_list[(*count_ints) - 1] = value; + } + return(int_list); +} +/* ---------------------------------------------------------------------- */ +int read_log_k_only (char *ptr, LDBLE *log_k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read log k + */ + *log_k = 0.0; + replace("="," ",ptr); + if (sscanf(ptr,SCANFORMAT, log_k) < 1) { + input_error++; + error_msg("Expecting log k.", CONTINUE); + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_delta_h_only (char *ptr, LDBLE *delta_h, DELTA_H_UNIT *units) +/* ---------------------------------------------------------------------- */ +{ + int j, l, kilo, joul; + char token[MAX_LENGTH]; +/* + * Read delta H + */ + *delta_h = 0.0; + replace("="," ",ptr); + j = copy_token(token, &ptr, &l); + if (j == EMPTY) { + input_error++; + error_msg("Expecting numeric value for delta H.", CONTINUE); + return(ERROR); + } + if (sscanf(token,SCANFORMAT, delta_h) < 1) { + input_error++; + error_msg("Expecting numeric value for delta H.", CONTINUE); + return(ERROR); + } +/* + * Read delta H units + */ + j = copy_token(token, &ptr, &l); + *units = kjoules; + kilo = TRUE; + joul = TRUE; + if (j == EMPTY) { + return(OK); + } if (j == UPPER || j == LOWER) { + str_tolower(token); + if(strstr(token,"k") != token) { + /* convert to kilo */ + kilo = FALSE; + *delta_h /= 1000.; + } + if(strstr(token,"c") != NULL) { + /* convert to joules */ + *delta_h *= JOULES_PER_CALORIE; + joul = FALSE; + } + } + if (kilo == TRUE && joul == TRUE) { + *units = kjoules; + } else if (kilo == FALSE && joul == TRUE) { + *units = joules; + } else if (kilo == TRUE && joul == FALSE) { + *units = kcal; + } else if (kilo == FALSE && joul == FALSE) { + *units = cal; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_analytical_expression_only (char *ptr, LDBLE *log_k) +/* ---------------------------------------------------------------------- */ +{ + int j; +/* + * Read analytical expression + */ + for (j = 0; j < 5; j++) { + log_k[j] = 0.0; + } + j=sscanf(ptr,SCANFORMAT SCANFORMAT SCANFORMAT SCANFORMAT SCANFORMAT, &(log_k[0]), &(log_k[1]), &(log_k[2]), &(log_k[3]), + &(log_k[4])); + if (j < 1) { + input_error++; + error_msg("Expecting numeric values for analytical expression.", CONTINUE); + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_incremental_reactions(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Define flow only + * + * 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 j, l; + char *ptr; + char token[MAX_LENGTH]; + + ptr = line; + /* read keyword */ + copy_token(token, &ptr, &l); + + /* read true or false */ + incremental_reactions = get_true_false(ptr, TRUE); +/* + * find next keyword + */ + while ( (j = check_line("Subroutine Read", FALSE, TRUE, TRUE, FALSE)) != KEYWORD) { + /* empty, eof, keyword, print */ + if ( j == EOF) return(EOF); + sprintf(error_string,"Unknown input: %s", line); + error_msg(error_string, CONTINUE); + input_error++; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_master_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads master species data from data file or input file + */ + int j, i, l; + char *ptr, *ptr1; + LDBLE z; + struct element *elts_ptr; + struct species *s_ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + + elts_ptr = NULL; + for (;;) { + j=check_line ("Master species", FALSE, TRUE, TRUE, TRUE); + if (j == EOF || j == KEYWORD ) { + break; + } +/* + * Get element name with valence, allocate space, store + */ + ptr=line; +/* + * Get element name and save pointer to character string + */ + if ( copy_token(token, &ptr, &l) != UPPER && token[0] != '[' ) { + parse_error++; + error_msg ("Reading element for master species.", CONTINUE); + error_msg (line_save, CONTINUE); + continue; + } + /* + if (token[0] == '[') { + ptr1 = token; + get_elt(&ptr, element, &l); + strcpy(token, element); + } + */ + replace ("(+", "(", token); +/* + * Delete master if it exists + */ + master_delete(token); +/* + * Increase pointer array, if necessary, and malloc space + */ + if (count_master >= max_master) { + space ((void **) ((void *) &master), count_master+1, &max_master, sizeof(struct master *)); + } + master[count_master] = master_alloc(); +/* + * Set type to AQ + */ + master[count_master]->type = AQ; +/* + * Save element name + */ + master[count_master]->elt = element_store ( token ); +/* + * Save pointer to species data for master species + */ + if ( ( copy_token(token, &ptr, &l) != UPPER ) && + token[0] != '[' && + ( strcmp_nocase_arg1(token, "e-") != 0 ) ) { + parse_error++; + error_msg("Reading master species name.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } + + s_ptr=s_search (token); + if (s_ptr != NULL) { + master[count_master]->s = s_ptr; + } else { + ptr1=token; + get_token(&ptr1, token1, &z, &l); + master[count_master]->s = s_store(token1, z, FALSE); + } + +/* + * Read alkalinity for species + */ + copy_token(token, &ptr, &l); + i = sscanf(token,SCANFORMAT, &master[count_master]->alk); + if (i != 1) { + input_error++; + if (elts_ptr != NULL) { + sprintf(error_string, "Expected alkalinity for master species, %s, in master species input.", elts_ptr->name); + } else { + sprintf(error_string, "Expected alkalinity for master species in master species input."); + } + error_msg(error_string, CONTINUE); + continue; + } +/* + * Read default gfw for species + */ + i = copy_token(token, &ptr, &l); + if (i == DIGIT) { + sscanf(token,SCANFORMAT, &master[count_master]->gfw); + } else if (i == UPPER) { + master[count_master]->gfw_formula = string_hsave(token); + } else { + input_error++; + if (elts_ptr != NULL) { + sprintf(error_string, "Expected gram formula weight for master species, %s, in master species input.", elts_ptr->name); + } else { + sprintf(error_string, "Expected gram formula weight for master species in master species input."); + } + error_msg(error_string, CONTINUE); + continue; + } +/* + * MAKE LISTS OF PRIMARY AND SECONDARY MASTER SPECIES + */ + if ( strchr(master[count_master]->elt->name,'(') == NULL ) { + master[count_master]->primary=TRUE; + /* Read gram formula weight for primary */ + if ( strcmp(master[count_master]->elt->name,"E") != 0 ) { + elts_ptr = master[count_master]->elt; + i = copy_token(token, &ptr, &l); + if (i == DIGIT) { + sscanf(token,SCANFORMAT, &elts_ptr->gfw); + } else { + input_error++; + if (elts_ptr != NULL) { + sprintf(error_string,"Expected gram formula weight for element, %s.", elts_ptr->name); + } else { + sprintf(error_string,"Expected gram formula weight for element."); + } + + error_msg(error_string, CONTINUE); + continue; + } + } + } else { + master[count_master]->primary=FALSE; + } + count_master++; + if (count_master >= max_master) { + space ((void **) ((void *) &master), count_master, &max_master, + sizeof(struct master *)); + } + + } + return (j); +} +/* ---------------------------------------------------------------------- */ +int read_mix (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads mixing fractions + */ + int n, n_user, n_user_end; + int return_value; + int count_comps; + int n_solution; + LDBLE fraction; + int j, i, l; + char *ptr; + char token[MAX_LENGTH]; + char *description; + struct mix *mix_ptr; +/* + * Read mix number + */ + ptr = line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Update list of mixtures + */ + mix_ptr = mix_search(n_user, &n, FALSE); + if (mix_ptr != NULL) { + mix_free (&mix[n]); + } else { + n = count_mix++; + mix = (struct mix *) PHRQ_realloc(mix, (size_t) count_mix * sizeof (struct mix)); + if (mix == NULL) malloc_error(); + } +/* + * Set use data to first read + */ + if (use.mix_in == FALSE) { + use.mix_in = TRUE; + use.n_mix_user = n_user; + } +/* + * Defaults + */ + mix[n].description = description; + mix[n].n_user = n_user; + mix[n].n_user_end = n_user_end; + mix[n].comps = NULL; + count_comps = 0; +/* + * Read mixture data + */ + for (;;) { + return_value = check_line("Mixture data",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) { + break; + } + ptr=line; +/* + * Read n_user + */ + i = copy_token(token, &ptr, &l); + if (i == DIGIT) { + sscanf(token,"%d ", &n_solution); + } else { + input_error++; + error_msg("Expected a solution number in mix input.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } +/* + * Read fraction for solution + */ + copy_token(token, &ptr, &l); + j = sscanf(token, SCANFORMAT, &fraction); + if (j != 1 ) { + input_error++; + error_msg("Expected a mixing fraction.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } +/* + * Malloc space + */ + count_comps++; + if (mix[n].comps == NULL) { + mix[n].comps = (struct mix_comp *) PHRQ_malloc( (size_t) sizeof (struct mix_comp)); + } else { + mix[n].comps = (struct mix_comp *) PHRQ_realloc(mix[n].comps, + (size_t) count_comps * sizeof (struct mix_comp)); + } + if (mix[n].comps == NULL) malloc_error(); +/* + * Save data + */ + mix[n].comps[count_comps - 1].n_solution = n_solution; + mix[n].comps[count_comps - 1].fraction = fraction; + } + if (count_comps <= 0) { + input_error++; + error_msg("Must define at least one solution number and mixing fraction for MIX input.", CONTINUE); + } + mix[n].count_comps = count_comps; + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_number_description (char *ptr, int *n_user, + int *n_user_end, char **description) +/* ---------------------------------------------------------------------- */ +{ + int l, n; + char token[MAX_LENGTH]; + char *ptr1; +/* + * Read user number + */ + copy_token(token, &ptr, &l); + ptr1 = ptr; + if (copy_token (token, &ptr, &l) != DIGIT) { +/* + sprintf(error_string, "No number given with %s keyword, " + "%s 1 assumed.", str, str); + warning_msg(error_string); + */ + *n_user=1; + *n_user_end = 1; + } else if (strstr(token,"-") != NULL) { + replace("-"," ",token); + n = sscanf(token,"%d%d", n_user, n_user_end); + if (n != 2) { + if (next_keyword >= 0) { + sprintf(error_string, "Reading number range for %s.", + keyword[next_keyword].name); + } else { + sprintf(error_string, "Reading number range for keyword."); + } + error_msg(error_string, CONTINUE); + input_error++; + } + ptr1 = ptr; + } else { + sscanf(token,"%d", n_user); + *n_user_end = *n_user; + ptr1 = ptr; + } +/* + * Read description + */ + for ( ; isspace((int) ptr1[0]) ;ptr1++ ); + *description = string_duplicate ( ptr1 ); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_phases (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read data for phases, parse equations + */ + int j, i, l; + int association; + char *ptr; + char token[MAX_LENGTH]; + struct phase *phase_ptr; + struct elt_list *next_elt; + struct rxn_token *token_ptr; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "no_check", /* 0 */ + "check", /* 1 */ + "log_k", /* 2 */ + "logk", /* 3 */ + "delta_h", /* 4 */ + "deltah", /* 5 */ + "analytical_expression", /* 6 */ + "a_e", /* 7 */ + "ae", /* 8 */ + "add_logk", /* 9 */ + "add_log_k", /* 10 */ + "add_constant" /* 11 */ + }; + int count_opt_list = 12; + + association=FALSE; +/* + * Read eqn from file and call parser + */ + opt_save = OPTION_DEFAULT; + return_value = UNKNOWN; + phase_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 PHASES keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* no_check */ + if (phase_ptr == NULL) break; + phase_ptr->check_equation = FALSE; + break; + case 1: /* check */ + if (phase_ptr == NULL) break; + phase_ptr->check_equation = TRUE; + break; + case 2: /* log_k */ + case 3: /* logk */ + if (phase_ptr == NULL) break; + read_log_k_only(next_char, &phase_ptr->logk[0]); + opt_save = OPTION_DEFAULT; + break; + case 4: /* delta_h */ + case 5: /* deltah */ + if (phase_ptr == NULL) break; + read_delta_h_only(next_char, &phase_ptr->logk[1], &phase_ptr->original_units); + opt_save = OPTION_DEFAULT; + break; + case 6: /* analytical_expression */ + case 7: /* a_e */ + case 8: /* ae */ + if (phase_ptr == NULL) break; + read_analytical_expression_only(next_char, &(phase_ptr->logk[2])); + opt_save = OPTION_DEFAULT; + break; + case 9: /* add_logk */ + case 10: /* add_log_k */ + if (phase_ptr == NULL) break; + if (phase_ptr->count_add_logk == 0) { + phase_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (phase_ptr->add_logk == NULL) malloc_error(); + } else { + phase_ptr->add_logk = (struct name_coef *) PHRQ_realloc(phase_ptr->add_logk, (size_t) ((phase_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (phase_ptr->add_logk == NULL) malloc_error(); + } + /* read name */ + if (copy_token(token, &next_char, &i) == EMPTY) { + input_error++; + sprintf(error_string, "Expected the name of a NAMED_EXPRESSION."); + error_msg(error_string, CONTINUE); + break; + } + phase_ptr->add_logk[phase_ptr->count_add_logk].name = string_hsave(token); + /* read coef */ + i = sscanf(next_char,SCANFORMAT, &phase_ptr->add_logk[phase_ptr->count_add_logk].coef); + if (i <= 0) { + phase_ptr->add_logk[phase_ptr->count_add_logk].coef = 1; + } + phase_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case 11: /* add_constant */ + if (phase_ptr == NULL) break; + if (phase_ptr->count_add_logk == 0) { + phase_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (phase_ptr->add_logk == NULL) malloc_error(); + } else { + phase_ptr->add_logk = (struct name_coef *) PHRQ_realloc(phase_ptr->add_logk, (size_t) ((phase_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (phase_ptr->add_logk == NULL) malloc_error(); + } + i = sscanf(next_char,SCANFORMAT, &phase_ptr->add_logk[phase_ptr->count_add_logk].coef); + if (i <= 0) { + input_error++; + sprintf(error_string, "Expected the constant to add for log_K definition."); + error_msg(error_string, CONTINUE); + break; + } + /* set name */ + phase_ptr->add_logk[phase_ptr->count_add_logk].name = string_hsave("XconstantX"); + /* read coef */ + phase_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: +/* + * Get element name and save pointer to character string + */ + phase_ptr = NULL; + ptr=line; + copy_token(token, &ptr, &l); +/* + * Get and parse equation + */ + j=check_line ("Phase equation", FALSE, TRUE, TRUE, TRUE); + if (j == EOF || j == KEYWORD ) { + return_value = j; + break; + } + if ( parse_eq(line, &next_elt, association ) == ERROR) { + parse_error++; + error_msg("Parsing equation.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + } + phase_ptr = phase_store (token); +/* + * Get pointer to each species in the reaction, store new species if necessary + */ + phase_ptr->formula = string_hsave(trxn.token[0].name ); + for (i=1; inext_elt=next_elt; +/* + * Malloc space for phase reaction + */ + phase_ptr->rxn = rxn_alloc (count_trxn+1); +/* + * Copy reaction to reaction for phase, first token (token[0]) is not used + * except to check that coef of phase formula = 1.0 + */ + token_ptr=phase_ptr->rxn->token; + /* token_ptr[0].coef=0; */ + token_ptr[0].coef=trxn.token[0].coef; + token_ptr[0].s=trxn.token[1].s; + for (i=1; itype = SOLID; + opt_save = OPTION_DEFAULT; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_pure_phases(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads pure phase data + * + * 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 j, n, l, return_value; + int count_pure_phases; + int n_user, n_user_end; + char *ptr; + char *description; + char token[MAX_LENGTH]; + + ptr=line; +/* + * Read pp_assemblage number + */ + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Find pp_assemblage or realloc space for pp_assemblage + */ + + if (pp_assemblage_search(n_user, &n) != NULL) { + pp_assemblage_free (&pp_assemblage[n]); + } else { + n=count_pp_assemblage++; + space ((void **) ((void *) &pp_assemblage), count_pp_assemblage, &max_pp_assemblage, sizeof(struct pp_assemblage)); + } +/* + * Set use data to first read + */ + if (use.pp_assemblage_in == FALSE) { + use.pp_assemblage_in = TRUE; + use.n_pp_assemblage_user = n_user; + } + + pp_assemblage_init(&(pp_assemblage[n]), n_user, n_user_end, description); + free_check_null(description); +/* + * Read phases + */ + count_pure_phases = 0; + for (;;) { + return_value = check_line("Pure phase data",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) { + break; + } +/* + * Make space, set default + */ + count_pure_phases++; + pp_assemblage[n].pure_phases = (struct pure_phase *) PHRQ_realloc(pp_assemblage[n].pure_phases, (size_t) (count_pure_phases) * sizeof(struct pure_phase)); + if (pp_assemblage[n].pure_phases == NULL) malloc_error(); + pp_assemblage[n].pure_phases[count_pure_phases-1].si = 0.0; + pp_assemblage[n].pure_phases[count_pure_phases-1].add_formula = NULL; + pp_assemblage[n].pure_phases[count_pure_phases-1].moles = 10.0; + pp_assemblage[n].pure_phases[count_pure_phases-1].dissolve_only = FALSE; + pp_assemblage[n].pure_phases[count_pure_phases-1].delta = 0.0; +/* + * Read name + */ + ptr = line; + copy_token(token, &ptr, &l); + pp_assemblage[n].pure_phases[count_pure_phases-1].name = string_hsave(token); + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) continue; +/* + * Read saturation index + */ + j=sscanf(token,SCANFORMAT, &dummy); + pp_assemblage[n].pure_phases[count_pure_phases-1].si = (LDBLE) dummy; + if (j != 1 ) { + error_msg("Expected saturation index.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + continue; + } +/* + * Adding a reaction to the phase boundary + */ + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) continue; + if ( j == UPPER || j == LOWER) { + pp_assemblage[n].pure_phases[count_pure_phases-1].add_formula = string_hsave(token); + j = copy_token(token, &ptr, &l); + } +/* + * Read amount + */ + if ( j == EMPTY) continue; + j=sscanf(token,SCANFORMAT, &dummy); + pp_assemblage[n].pure_phases[count_pure_phases-1].moles = (LDBLE) dummy; + if (j != 1 ) { + error_msg("Expected amount of mineral.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + continue; + } + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) continue; + str_tolower(token); + if (strstr(token,"d") == token) { + pp_assemblage[n].pure_phases[count_pure_phases-1].dissolve_only = TRUE; + } else { + error_msg("Unexpected data at end of equilibrium-phase definition.", CONTINUE); + input_error++; + continue; + } + } + pp_assemblage[n].count_comps = count_pure_phases; +/* + * Sort phases by name (lowercase) + */ + qsort (pp_assemblage[n].pure_phases, + (size_t) count_pure_phases, + (size_t) sizeof(struct pure_phase), + pure_phase_compare); + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_reaction (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads reaction data + * + * 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 + * + */ +/* + * Read reaction + */ + int l; + char *ptr; + char *description; + char token[MAX_LENGTH]; + int n, return_value; + int n_user, n_user_end; + struct irrev *irrev_ptr; +/* + * Read reaction number + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + +/* + * Read reaction or realloc space for irrev reaction + */ + irrev_ptr = irrev_search(n_user, &n); + if (irrev_ptr != NULL) { + irrev_free(&irrev[n]); + } else { + n = count_irrev++; + irrev = (struct irrev *) PHRQ_realloc(irrev, (size_t) count_irrev * sizeof (struct irrev)); + if (irrev == NULL) malloc_error(); + } +/* + * Set use data to first read + */ + if (use.irrev_in == FALSE) { + use.irrev_in = TRUE; + use.n_irrev_user = n_user; + } +/* + * Defaults + */ + irrev[n].n_user = n_user; + irrev[n].n_user_end = n_user_end; + irrev[n].description = description; + irrev[n].steps = (double *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (irrev[n].steps == NULL) malloc_error(); + irrev[n].list = (struct name_coef *) PHRQ_malloc((size_t) sizeof(struct name_coef)); + if (irrev[n].list == NULL) malloc_error(); + irrev[n].count_steps = 0; + irrev[n].count_list = 0; + irrev[n].units = string_hsave("Mol"); + irrev[n].elts = NULL; +/* + * Read reaction data + */ + for (;;) { +/* + * Read line + */ + return_value = check_line("Pure phase data",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) { + break; + } + ptr = line; + copy_token(token, &ptr, &l); + if (isalpha((int) token[0]) || (token[0] == '(') || (token[0] == '[') ) { +/* + * Read reactant information + */ + read_reaction_reactants(&(irrev[n])); + } else { +/* + * Read steps information + */ + read_reaction_steps(&(irrev[n])); + } + } +/* + * Default 1 mol of reaction + */ + if (irrev[n].count_steps == 0) { + irrev[n].count_steps = 1; + irrev[n].steps[0] = 1.0; + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_reaction_reactants(struct irrev *irrev_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read reactants, may be a chemical formula or a pure_phase name + * followed by relative reaction coefficient, default 1.0. + * + */ + int j, l; + int count_list; + char token[MAX_LENGTH]; + LDBLE coef; + char *ptr; +/* + * Read one or more reactants + */ + ptr = line; + while (copy_token (token, &ptr, &l) != EMPTY) { +/* + * Store reactant name, default coefficient + */ + if ( isalpha((int) token[0]) || (token[0] == '(' ) || (token[0] == '[') ) { + irrev_ptr->count_list++; + count_list = irrev_ptr->count_list - 1; + irrev_ptr->list = (struct name_coef *) PHRQ_realloc(irrev_ptr->list, (size_t) (count_list + 1) * sizeof(struct name_coef)); + if (irrev_ptr->list == NULL) malloc_error(); + irrev_ptr->list[count_list].name = string_hsave(token); + irrev_ptr->list[count_list].coef = 1.0; +/* + * Store relative coefficient + */ + } else { + j = sscanf(token, SCANFORMAT, &coef); + if (j == 1 ) { + count_list = irrev_ptr->count_list - 1; + irrev_ptr->list[count_list].coef = coef; + } else { + error_msg("Reading relative coefficient of reactant.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_reaction_steps(struct irrev *irrev_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read amount(s) of irrev reactions in one of three forms: + * + * 6 millimoles in 6 steps or + * + * 1 2 3 4 5 6 millimoles or + * + * 6*1 millimoles + * INCREMENTAL_REACTIONS + */ + int i, j, l, n; + int count_steps; + char *ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + LDBLE step, value; + + ptr = line; + count_steps = irrev_ptr->count_steps; +/* + * Read one or more reaction increments + */ + for (;;) { + if ( copy_token (token, &ptr, &l) == EMPTY ) { + return(OK); + } +/* + * Read next step increment + */ +/* begin modif 29 july 2005... */ + if (replace("*"," ",token) == TRUE) { + if (sscanf(token,"%d" SCANFORMAT, &n, &value) == 2) { + for (i = 0; i < n; i++) { + count_steps++; + irrev_ptr->steps = (double *) PHRQ_realloc(irrev_ptr->steps, (size_t) count_steps * sizeof(LDBLE)); + if (irrev_ptr->steps == NULL) malloc_error(); + irrev_ptr->steps[irrev_ptr->count_steps] = value; + irrev_ptr->count_steps = count_steps; + } + } else { + input_error++; + error_msg("Format error in multiple, equal REACTION steps.\nCorrect is (for example): 0.2 4*0.1 2*0.5 0.3\n", CONTINUE); + } + } else { + j = sscanf(token, SCANFORMAT, &step); + if (j == 1 ) { + count_steps++; + irrev_ptr->steps = (double *) PHRQ_realloc(irrev_ptr->steps, (size_t) count_steps * sizeof(LDBLE)); + if (irrev_ptr->steps == NULL) malloc_error(); + irrev_ptr->steps[irrev_ptr->count_steps] = step; + irrev_ptr->count_steps = count_steps; + } else { + break; + } + } +/* ...end modif 29 july 2005 */ + } +/* + * Read units + */ + strcpy(token1, token); + strcat(token1,"/l"); + if (check_units(token1, FALSE, FALSE, NULL, FALSE) == OK) { + replace("/l", "", token1); + if (strstr(token1, "Mol") == NULL) { + sprintf(error_string, "Units of steps not in moles, %s.", token); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } else { + irrev_ptr->units = string_hsave(token1); + } + if ( copy_token (token, &ptr, &l) == EMPTY ) { + return(OK); + } + } +/* + * Read number of equal increments, store as negative integer + */ + if (count_steps != 1) { + error_msg("To define equal increments, only one reaction increment should be defined.", CONTINUE); + input_error++; + return(ERROR); + } + do { + j = sscanf(token, "%d", &i); + if (j == 1 && i > 0 ) { + irrev_ptr->count_steps = -i; + return(OK); + } else if (j == 1 && i <= 0 ) { + break; + } + } while ( copy_token (token, &ptr, &l) != EMPTY ); + + error_msg("Expecting positive number for number of equal " + "increments to add.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); +} +/* ---------------------------------------------------------------------- */ +int read_save (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution, mix, irreversible reaction, and pure phases to use + * in reaction calculation + */ + int i, l, n, n_user, n_user_end; + char *ptr; + char token[MAX_LENGTH]; +/* + * Read "save" + */ + ptr = line; + copy_token (token, &ptr, &l); +/* + * Read keyword + */ + copy_token (token, &ptr, &l); + check_key (token); + switch (next_keyword) { + case -1: /* Have not read line with keyword */ + case 0: /* End encountered */ + case 1: /* EOF encountered */ + case 2: /* Read aqueous model */ + case 3: /* Read master species */ + case 5: /* Phases */ + case 7: /* Reaction */ + case 8: /* Mix */ + case 9: /* Use */ + case 10: /* Save */ + case 11: + case 12: + case 14: + case 15: + case 17: + case 18: + case 21: + case 22: + case 23: + case 24: + case 25: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + input_error++; + error_msg("Expecting keyword solution, equilibrium_phases, exchange, surface, kinetics, gas_phase, or solid_solutions.", CONTINUE); + error_msg(line_save, CONTINUE); + check_line("End of save",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(ERROR); + } +/* + * Read number + */ + for (;;) { + i = copy_token (token, &ptr, &l); + if (i == DIGIT) { + replace("-"," ",token); + n = sscanf(token,"%d%d",&n_user, &n_user_end); + if (n == 1) { + n_user_end = n_user; + } + if (n_user < 0) { + error_msg("Number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + break; + } else if ( i == EMPTY ) { + sprintf(error_string, "No number given, 1 assumed."); + warning_msg(error_string); + n_user = 1; + n_user_end = 1; + break; + } } + switch (next_keyword) { + case 4: /* Solution */ + save.solution = TRUE; + save.n_solution_user = n_user; + save.n_solution_user_end = n_user_end; + break; + case 6: /* Pure phases */ + case 26: + case 27: + case 28: + case 29: + save.pp_assemblage = TRUE; + save.n_pp_assemblage_user = n_user; + save.n_pp_assemblage_user_end = n_user_end; + break; + case 13: /* exchange */ + save.exchange = TRUE; + save.n_exchange_user = n_user; + save.n_exchange_user_end = n_user_end; + break; + case 16: /* surface */ + save.surface = TRUE; + save.n_surface_user = n_user; + save.n_surface_user_end = n_user_end; + break; + case 19: /* gas_phase */ + save.gas_phase = TRUE; + save.n_gas_phase_user = n_user; + save.n_gas_phase_user_end = n_user_end; + break; + case 40: /* solid_solutions */ + case 41: /* solid_solution */ + save.s_s_assemblage = TRUE; + save.n_s_s_assemblage_user = n_user; + save.n_s_s_assemblage_user_end = n_user_end; + break; + } + check_line("End of save",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_selected_output (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read data for to output to flat file + */ + int value; + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "file", /* 0 */ + "totals", /* 1 */ + "molalities", /* 2 */ + "activities", /* 3 */ + "pure_phases", /* 4 */ + "si", /* 5 */ + "saturation_indices", /* 6 */ + "gases", /* 7 */ + "equilibrium_phases", /* 8 */ + "equilibria", /* 9 */ + "equilibrium", /* 10 */ + "pure", /* 11 */ + "inverse", /* 12 */ + "kinetic_reactants", /* 13 */ + "kinetics", /* 14 */ + "solid_solutions", /* 15 */ + "inverse_modeling", /* 16 */ + "reset", /* 17 */ + "simulation", /* 18 */ + "sim", /* 19 */ + "state", /* 20 */ + "solution", /* 21 */ + "soln", /* 22 */ + "distance", /* 23 */ + "dist", /* 24 */ + "time", /* 25 */ + "step", /* 26 */ + "reaction", /* 27 */ + "rxn", /* 28 */ + "temperature", /* 29 */ + "temp", /* 30 */ + "ph", /* 31 */ + "pe", /* 32 */ + "alkalinity", /* 33 */ + "alk", /* 34 */ + "ionic_strength", /* 35 */ + "mu", /* 36 */ + "water", /* 37 */ + "high_precision", /* 38 */ + "user_punch", /* 39 */ + "mol", /* 40 */ + "kin", /* 41 */ + "charge_balance", /* 42 */ + "percent_error", /* 43 */ + "selected_out", /* 44 */ + "selected_output", /* 45 */ + "isotopes", /* 46 */ + "calculate_values" /* 47 */ + }; + int count_opt_list = 48; + + int i, l; + char file_name[MAX_LENGTH], token[MAX_LENGTH]; + static int have_punch_name = FALSE; + + punch.in = TRUE; + punch.new_def = TRUE; + punch.count_totals = 0; + punch.count_molalities = 0; + punch.count_activities = 0; + punch.count_pure_phases = 0; + punch.count_si = 0; + punch.count_gases = 0; + punch.count_kinetics = 0; + punch.count_s_s = 0; +/* + * Read eqn from file and call parser + */ + opt_save = OPTION_ERROR; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + if (opt == OPTION_DEFAULT) { + opt = opt_save; + } + opt_save = opt; + switch (opt) { + case OPTION_EOF: /* end of file */ + return_value = EOF; + break; + case OPTION_KEYWORD: /* keyword */ + return_value = KEYWORD; + break; + case OPTION_DEFAULT: + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in SELECTED_OUTPUT keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* file name */ + /* copy_token(file_name, &next_char, &l); */ + string_trim(next_char); + strcpy(file_name, next_char); + have_punch_name = TRUE; + if (output_open(OUTPUT_PUNCH, file_name) != OK) { + sprintf(error_string, "Can't open file, %s.", file_name); + input_error++; + error_msg(error_string, CONTINUE); + } + opt_save = OPTION_ERROR; + break; + case 1: /* totals */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + if (i != UPPER && token[0] != '[') { + sprintf(error_string, "Expected element name to" + " begin with upper case letter."); + warning_msg(error_string); + } else { + punch.count_totals++; + punch.totals = (struct name_master *) PHRQ_realloc(punch.totals, (size_t) punch.count_totals * sizeof(struct name_master)); + if (punch.totals == NULL) malloc_error(); + punch.totals[punch.count_totals - 1].name = string_hsave(token); + } + } + break; + case 2: /* molalities */ + case 40: /* mol */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + if (i != UPPER && token[0] != '(' && (token[0] != '[')) { + sprintf(error_string, "Expected species name to" + " begin with upper case letter."); + warning_msg(error_string); + } else { + punch.count_molalities++; + punch.molalities = (struct name_species *) PHRQ_realloc(punch.molalities, (size_t) punch.count_molalities * sizeof(struct name_species)); + if (punch.molalities == NULL) malloc_error(); + punch.molalities[punch.count_molalities - 1].name = + string_hsave(token); + } + } + break; + case 3: /* activities */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + if (i != UPPER && token[0] != '(' && (token[0] != '[')) { + sprintf(error_string, "Expected species name to" + " begin with upper case letter."); + warning_msg(error_string); + } else { + punch.count_activities++; + punch.activities = (struct name_species *) PHRQ_realloc(punch.activities, (size_t) punch.count_activities * sizeof(struct name_species)); + if (punch.activities == NULL) malloc_error(); + punch.activities[punch.count_activities - 1].name = + string_hsave(token); + } + } + break; + case 4: /* pure_phases */ + case 8: /* equilibrium_phases */ + case 9: /* equilibria */ + case 10: /* equilibrium */ + case 11: /* pure */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_pure_phases++; + punch.pure_phases = (struct name_phase *) PHRQ_realloc(punch.pure_phases, (size_t) punch.count_pure_phases * sizeof(struct name_phase)); + if (punch.pure_phases == NULL) malloc_error(); + punch.pure_phases[punch.count_pure_phases - 1].name = string_hsave(token); + } + break; + case 5: /* si */ + case 6: /* saturation_index */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_si++; + punch.si = (struct name_phase *) PHRQ_realloc(punch.si, (size_t) punch.count_si * sizeof(struct name_phase)); + if (punch.si == NULL) malloc_error(); + punch.si[punch.count_si - 1].name = string_hsave(token); + } + break; + case 7: /* gases */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_gases++; + punch.gases = (struct name_phase *) PHRQ_realloc(punch.gases, (size_t) punch.count_gases * sizeof(struct name_phase)); + if (punch.gases == NULL) malloc_error(); + punch.gases[punch.count_gases - 1].name = string_hsave(token); + } + break; + case 12: /* inverse */ + case 16: /* inverse_modeling */ + punch.inverse = get_true_false(next_char, TRUE); + break; + case 13: /* kinetic_reactants */ + case 14: /* kinetics */ + case 41: /* kin */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_kinetics++; + punch.kinetics = (struct name_phase *) PHRQ_realloc(punch.kinetics, (size_t) punch.count_kinetics * sizeof(struct name_phase)); + if (punch.kinetics == NULL) malloc_error(); + punch.kinetics[punch.count_kinetics - 1].name = string_hsave(token); + } + break; + case 15: /* solid_solutions */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_s_s++; + punch.s_s = (struct name_phase *) PHRQ_realloc(punch.s_s, (size_t) punch.count_s_s * sizeof(struct name_phase)); + if (punch.s_s == NULL) malloc_error(); + punch.s_s[punch.count_s_s - 1].name = string_hsave(token); + } + break; + case 46: /* isotopes */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + if (i != UPPER && token[0] != '[') { + sprintf(error_string, "Expected element name to" + " begin with upper case letter."); + warning_msg(error_string); + } else { + punch.count_isotopes++; + punch.isotopes = (struct name_master *) PHRQ_realloc(punch.isotopes, (size_t) punch.count_isotopes * sizeof(struct name_master)); + if (punch.isotopes == NULL) malloc_error(); + punch.isotopes[punch.count_isotopes - 1].name = string_hsave(token); + } + } + break; + case 47: /* calculate_values */ + while( (i = copy_token(token, &next_char, &l)) != EMPTY) { + punch.count_calculate_values++; + punch.calculate_values = (struct name_master *) PHRQ_realloc(punch.calculate_values, (size_t) punch.count_calculate_values * sizeof(struct name_master)); + if (punch.calculate_values == NULL) malloc_error(); + punch.calculate_values[punch.count_calculate_values - 1].name = string_hsave(token); + } + break; + case 17: /* reset */ + value = get_true_false(next_char, TRUE); + punch.sim = value; + punch.state = value; + punch.soln = value; + punch.dist = value; + punch.time = value; + punch.step = value; + punch.rxn = value; + punch.temp = value; + punch.ph = value; + punch.pe = value; + punch.alk = value; + punch.mu = value; + punch.water = value; + punch.charge_balance = value; + punch.percent_error = value; + break; + case 18: /* simulation */ + case 19: /* sim */ + punch.sim = get_true_false(next_char, TRUE); + break; + case 20: /* state */ + punch.state = get_true_false(next_char, TRUE); + break; + case 21: /* solution */ + case 22: /* soln */ + punch.soln = get_true_false(next_char, TRUE); + break; + case 23: /* distance */ + case 24: /* dist */ + punch.dist = get_true_false(next_char, TRUE); + break; + case 25: /* time */ + punch.time = get_true_false(next_char, TRUE); + break; + case 26: /* step */ + punch.step = get_true_false(next_char, TRUE); + break; + case 27: /* reaction */ + case 28: /* rxn */ + punch.rxn = get_true_false(next_char, TRUE); + break; + case 29: /* temperature */ + case 30: /* temp */ + punch.temp = get_true_false(next_char, TRUE); + break; + case 31: /* ph */ + punch.ph = get_true_false(next_char, TRUE); + break; + case 32: /* pe */ + punch.pe = get_true_false(next_char, TRUE); + break; + case 33: /* alkalinity */ + case 34: /* alk */ + punch.alk = get_true_false(next_char, TRUE); + break; + case 35: /* ionic strength */ + case 36: /* mu */ + punch.mu = get_true_false(next_char, TRUE); + break; + case 37: /* water */ + punch.water = get_true_false(next_char, TRUE); + break; + case 38: /* high_precision */ + punch.high_precision = get_true_false(next_char, TRUE); + if (punch.high_precision == TRUE && convergence_tolerance > 1e-12) { + convergence_tolerance = 1e-12; + } + break; + case 39: /* user_punch */ + punch.user_punch = get_true_false(next_char, TRUE); + break; + case 42: /* charge_balance */ + punch.charge_balance = get_true_false(next_char, TRUE); + break; + case 43: /* percent_error */ + punch.percent_error = get_true_false(next_char, TRUE); + break; + case 44: /* selected_out */ + case 45: /* selected_output */ + pr.punch = get_true_false(next_char, TRUE); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + if (!have_punch_name) { + if (output_open(OUTPUT_PUNCH, "selected.out") != OK) { + sprintf(error_string, "Can't open file, %s.", "selected.out"); + input_error++; + error_msg(error_string, CONTINUE); + } + } + + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_solution(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution data + * + * 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 i, j, n, l; + int n_user, n_user_end; + int default_pe, alk; + int count_isotopes; + int max_mass_balance, count_mass_balance; + char *ptr, *ptr1; + char *description; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "temp", /* 0 */ + "temperature", /* 1 */ + "dens", /* 2 */ + "density", /* 3 */ + "units", /* 4 */ + "redox", /* 5 */ + "ph", /* 6 */ + "pe", /* 7 */ + "unit", /* 8 */ + "isotope", /* 9 */ + "water" /* 10 */ + + }; + int count_opt_list = 11; +/* + * Read solution number and description + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Malloc space for solution data + */ + if (solution_bsearch(n_user, &n, FALSE) != NULL) { + solution_free(solution[n]); + } else { + n=count_solution++; + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, sizeof (struct solution *) ); + } + } + solution[n] = solution_alloc(); + + solution[n]->n_user = n_user; + solution[n]->n_user_end = n_user_end; + if (use.solution_in == FALSE) { + use.solution_in = TRUE; + use.n_solution_user = n_user; + } + max_mass_balance=MAX_MASS_BALANCE; +/* + * Set default ph, temp, density, pe, units + */ + solution[n]->description = description; + solution[n]->tc=25.0; + solution[n]->ph=7.0; + solution[n]->density=1.0; + solution[n]->solution_pe = 4.0; + solution[n]->mass_water=1.0; + solution[n]->ah2o = 1.0; + solution[n]->mu = 1e-7; + solution[n]->cb = 0.0; + default_pe = 0; + solution[n]->units = string_hsave( "mMol/kgw" ); + solution[n]->totals[0].description=NULL; + count_mass_balance=0; + count_isotopes = 0; +/* + * Read concentration data + */ + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + if (opt == OPTION_DEFAULT) { + ptr = next_char; + if (copy_token(token, &ptr, &l) == DIGIT) { + opt = 9; + } + } + 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 SOLUTION keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* temperature */ + case 1: + if (sscanf(next_char,SCANFORMAT, &(solution[n]->tc)) != 1) { + solution[n]->tc = 25; + } + break; + case 2: /* density */ + case 3: + sscanf(next_char,SCANFORMAT, &(solution[n]->density)); + break; + case 4: /* units */ + case 8: /* unit */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (check_units (token, FALSE, FALSE, solution[n]->units, TRUE) == OK) { + solution[n]->units = string_hsave(token); + } else { + input_error++; + } + break; + case 5: /* redox */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (parse_couple(token) == OK) { + default_pe = pe_data_store (&(solution[n]->pe), token); + } else { + input_error++; + } + break; + case 6: /* ph */ + if ( read_conc(n, count_mass_balance, line) == ERROR ) { + input_error++; + break; + } + solution[n]->ph = solution[n]->totals[count_mass_balance].input_conc; + if (solution[n]->totals[count_mass_balance].equation_name == NULL ) { + break; + } + solution[n]->totals[count_mass_balance].description = string_hsave("H(1)"); + count_mass_balance++; + break; + case 7: /* pe */ + if ( read_conc(n, count_mass_balance, line) == ERROR ) { + input_error++; + break; + } + solution[n]->solution_pe = solution[n]->totals[count_mass_balance].input_conc; + if (solution[n]->totals[count_mass_balance].equation_name == NULL ) { + break; + } + solution[n]->totals[count_mass_balance].description = string_hsave("E"); + count_mass_balance++; + break; + case 9: /* isotope */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected isotope name to" + " begin with an isotopic number."); + error_msg(error_string, CONTINUE); + continue; + } + solution[n]->isotopes = (struct isotope *) PHRQ_realloc(solution[n]->isotopes, (size_t) (count_isotopes + 1) * sizeof(struct isotope)); + if (solution[n]->isotopes == NULL) malloc_error(); + + /* read and save element name */ + ptr1 = token; + get_num(&ptr1, &(solution[n]->isotopes[count_isotopes].isotope_number)); + if (ptr1[0] == '\0' || isupper((int) ptr1[0]) == FALSE) { + error_msg("Expecting element name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + solution[n]->isotopes[count_isotopes].elt_name = string_hsave(ptr1); + + /* read and store isotope ratio */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } + sscanf(token, SCANFORMAT, &(solution[n]->isotopes[count_isotopes].ratio)); + + solution[n]->isotopes[count_isotopes].ratio_uncertainty = NAN; + + /* read and store isotope ratio uncertainty */ + if ((j = copy_token(token, &next_char, &l)) != EMPTY) { + if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for uncertainty in isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } + sscanf(token, SCANFORMAT, &(solution[n]->isotopes[count_isotopes].ratio_uncertainty)); + } + count_isotopes++; + break; + case 10: /* water */ + j = copy_token (token, &next_char, &l); + if (j == EMPTY) { + solution[n]->mass_water=1.0; + } else if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for mass of water in solution."); + error_msg(error_string, CONTINUE); + } else { + sscanf(token, SCANFORMAT, &dummy); + solution[n]->mass_water = (LDBLE) dummy; + } + break; + case OPTION_DEFAULT: +/* + * Read concentration + */ + if ( read_conc(n, count_mass_balance, line) == ERROR ) { + input_error++; + break; + } + count_mass_balance++; + break; + } + if (count_mass_balance + 1 >= max_mass_balance) { + space ((void **) &(solution[n]->totals), count_mass_balance + 1, + &max_mass_balance, sizeof (struct conc)); + } + if (return_value == EOF || return_value == KEYWORD) break; + } +#ifdef SKIP +/* + * Sort totals by description + */ + qsort (solution[n]->totals, + (size_t) count_mass_balance, + (size_t) sizeof(struct conc), + conc_compare); +#endif +/* + * fix up default units and default pe + */ + for (i=0; i < count_mass_balance; i++) { + strcpy(token, solution[n]->totals[i].description); + str_tolower(token); + if (solution[n]->totals[i].units == NULL) { + solution[n]->totals[i].units = solution[n]->units; + } else { + alk = FALSE; + if (strstr(token, "alk") == token) alk = TRUE; + strcpy(token1, solution[n]->totals[i].units); + if (check_units (token1, alk, TRUE, solution[n]->units, TRUE) == ERROR ) { + input_error++; + } else { + solution[n]->totals[i].units = string_hsave(token1); + } + } + if (solution[n]->totals[i].n_pe < 0) { + solution[n]->totals[i].n_pe = default_pe; + } + } + solution[n]->default_pe = default_pe; +/* + * Mark end of solution + */ + solution[n]->totals[count_mass_balance].description = NULL; + solution[n]->count_isotopes = count_isotopes; +#ifdef SKIP + if (count_isotopes > 0) { + qsort (solution[n]->isotopes, + (size_t) count_isotopes, + (size_t) sizeof(struct isotope), + isotope_compare); + } else { + solution[n]->isotopes = free_check_null(solution[n]->isotopes); + } +#endif + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read data for aqueous species, parse equations + */ + int i; + int association; + struct species *s_ptr; + struct elt_list *next_elt; + char *ptr, token[MAX_LENGTH]; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "no_check", /* 0 */ + "check", /* 1 */ + "gamma", /* 2 */ + "mb", /* 3 */ + "mass_balance", /* 4 */ + "log_k", /* 5 */ + "logk", /* 6 */ + "delta_h", /* 7 */ + "deltah", /* 8 */ + "analytical_expression", /* 9 */ + "a_e", /* 10 */ + "ae", /* 11 */ + "mole_balance", /* 12 */ + "llnl_gamma", /* 13 */ + "co2_llnl_gamma", /* 14 */ + "activity_water", /* 15 */ + "add_logk", /* 16 */ + "add_log_k", /* 17 */ + "add_constant" /* 18 */ + }; + int count_opt_list = 19; + + association=TRUE; + s_ptr = NULL; +/* + * Read eqn from file and call parser + */ + 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: /* no_check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = FALSE; + break; + case 1: /* check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = TRUE; + break; + case 2: /* gamma data */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->gflag = 2; /* Wateq D-H */ + i = sscanf(next_char,SCANFORMAT SCANFORMAT, &s_ptr->dha, &s_ptr->dhb ); + if (i < 2) { + sprintf(error_string, "Expecting 2 activity-" + "coefficient parameters, a and b."); + warning_msg(error_string); + } + opt_save = OPTION_DEFAULT; + break; + case 3: /* mb */ + case 4: /* mass_balance */ + case 12: /* mole_balance */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + count_elts = 0; + paren_count =0; + copy_token(token, &next_char, &i); + s_ptr->mole_balance = string_hsave(token); + ptr = token; + get_secondary_in_species(&ptr, 1.0); + s_ptr->next_secondary = elt_list_save(); +/* debug + for (i = 0; i < count_elts; i++) { + output_msg(OUTPUT_MESSAGE,"%s\t%f\n", elt_list[i].elt->name, + elt_list[i].coef); + } + */ + opt_save = OPTION_DEFAULT; + break; + case 5: /* log_k */ + case 6: /* logk */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_log_k_only(next_char, &s_ptr->logk[0]); + opt_save = OPTION_DEFAULT; + break; + case 7: /* delta_h */ + case 8: /* deltah */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_delta_h_only(next_char, &s_ptr->logk[1], &s_ptr->original_units); + opt_save = OPTION_DEFAULT; + break; + case 9: /* analytical_expression */ + case 10: /* a_e */ + case 11: /* ae */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_analytical_expression_only(next_char, &(s_ptr->logk[2])); + opt_save = OPTION_DEFAULT; + break; + case 13: /* llnl_gamma */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->gflag = 7; /* llnl D-H */ + i = sscanf(next_char,SCANFORMAT, &s_ptr->dha); + if (i < 1) { + sprintf(error_string, "Expecting activity-coefficient parameter, a."); + warning_msg(error_string); + } + opt_save = OPTION_DEFAULT; + break; + case 14: /* co2_llnl_gamma */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->gflag = 8; /* llnl CO2 D-H */ + opt_save = OPTION_DEFAULT; + break; + case 15: /* activity water */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->gflag = 9; /* activity_water/55.5 for HDO, D2O, H2[O18], etc */ + opt_save = OPTION_DEFAULT; + break; + case 16: /* add_logk */ + case 17: /* add_log_k */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + /* read name */ + if (copy_token(token, &next_char, &i) == EMPTY) { + input_error++; + sprintf(error_string, "Expected the name of a NAMED_EXPRESSION."); + error_msg(error_string, CONTINUE); + break; + } + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave(token); + /* read coef */ + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + s_ptr->add_logk[s_ptr->count_add_logk].coef = 1; + } + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case 18: /* add_constant */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + input_error++; + sprintf(error_string, "Expected the constant to add for log_K definition."); + error_msg(error_string, CONTINUE); + break; + } + /* set name */ + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave("XconstantX"); + /* read coef */ + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: +/* + * Get space for species information and parse equation + */ + s_ptr = NULL; + if ( parse_eq(line, &next_elt, association ) == ERROR) { + parse_error++; + error_msg("Parsing equation.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + } +/* + * Get pointer to each species in the reaction, store new species if necessary + */ + trxn.token[0].s = s_store( trxn.token[0].name, trxn.token[0].z, TRUE); + for (i=1; inext_elt=next_elt; + trxn.token[0].s->next_secondary = NULL; + for ( ; next_elt->elt != NULL; next_elt++) { + if ( strcmp (next_elt->elt->name,"C") == 0 ) { + trxn.token[0].s->carbon = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"H") == 0 ) { + trxn.token[0].s->h = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"O") == 0 ) { + trxn.token[0].s->o = next_elt->coef; + } + } +/* + * Malloc space for species reaction + */ + trxn.token[0].s->rxn = rxn_alloc (count_trxn+1); +/* + * Copy reaction to reaction for species + */ + trxn_copy(trxn.token[0].s->rxn); + s_ptr=trxn.token[0].s; +/* + * Default gamma data + */ + s_ptr->dha = 0.0; + s_ptr->dhb = 0.0; + if (equal (s_ptr->z, 0.0, TOL) == TRUE) { + s_ptr->gflag = 0; /* Uncharged */ + s_ptr->dhb = 0.1; + } else { + s_ptr->gflag = 1; /* Davies */ + } +/* + * Set type for species + */ + if ( strcmp(trxn.token[0].s->name, "H+" ) == 0) { + s_hplus = trxn.token[0].s; + s_hplus->type = HPLUS; + } else if ( strcmp(trxn.token[0].s->name, "H3O+" ) == 0) { + s_h3oplus = trxn.token[0].s; + s_h3oplus->type = HPLUS; + } else if ( strcmp(trxn.token[0].s->name, "e-" ) == 0) { + s_eminus = trxn.token[0].s; + s_eminus->type = EMINUS; + s_eminus->gflag = 3; /* Always 1 */ + } else if ( strcmp(trxn.token[0].s->name, "H2O" ) == 0) { + s_h2o = trxn.token[0].s; + s_h2o->type = H2O; + s_h2o->gflag = 3; /* Always 1 */ + } else if ( strstr(trxn.token[0].s->name, "(s)" ) != NULL) { + trxn.token[0].s->type = SOLID; + } else if ( strcmp(trxn.token[0].s->name, "H2" ) == 0 ) { + trxn.token[0].s->type = AQ; + s_h2 = trxn.token[0].s; + } else if ( strcmp(trxn.token[0].s->name, "O2" ) == 0 ) { + trxn.token[0].s->type = AQ; + s_o2 = trxn.token[0].s; + } else { + trxn.token[0].s->type = AQ; + } + opt_save = OPTION_DEFAULT; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_use (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution, mix, irreversible reaction, and pure phases to use + * in reaction calculation + */ + int i, l, n_user, return_value; + char *ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH];; +/* + * Read "use" + */ + ptr = line; + copy_token (token, &ptr, &l); +/* + * Read keyword + */ + copy_token (token, &ptr, &l); + check_key (token); + switch (next_keyword) { + case -1: /* Have not read line with keyword */ + case 0: /* End encountered */ + case 1: /* EOF encountered */ + case 2: /* Read aqueous model */ + case 3: /* Read master species */ + case 5: + case 9: + case 10: + case 11: + case 12: + case 14: + case 15: + case 18: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 30: + case 31: + case 32: + case 34: + case 35: + case 38: + case 39: + input_error++; + error_msg("Expecting keyword solution, mix, kinetics, reaction, reaction_temperature, equilibrium_phases, exchange, surface, gas_phase, or solid_solutions.", CONTINUE); + error_msg(line_save, CONTINUE); + check_line("End of use",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(ERROR); + } +/* + * Read number + */ + strcpy(token1, token); + for (;;) { + i = copy_token (token, &ptr, &l); + if (i == DIGIT) { + sscanf(token,"%d",&n_user); + if (n_user < 0) { + error_msg("Number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + if (strstr(token,"-") != NULL) { + sprintf(error_string, "USE does not accept a range of numbers, %s.", token); + warning_msg(error_string); + sprintf(error_string, "Only %s %d will be used in the batch-reaction calculation.", token1, n_user); + warning_msg(error_string); + sprintf(error_string, "NOTE--USE is not needed for ADVECTION and TRANSPORT calculations."); + warning_msg(error_string); + + } + break; + } else if ( i == EMPTY ) { + sprintf(error_string, "No number given, 1 assumed."); + warning_msg(error_string); + n_user=1; + break; + } else if (token[0] == 'N' || token[0] == 'n') { + n_user = -2; + break; + } + } + switch (next_keyword) { + case 4: /* Solution */ + use.n_solution_user = n_user; + if (n_user >= 0 ) { + use.solution_in = TRUE; + } else { + use.solution_in = FALSE; + } + break; + case 6: /* Pure phases */ + case 26: + case 27: + case 28: + case 29: + use.n_pp_assemblage_user = n_user; + if (n_user >= 0 ) { + use.pp_assemblage_in = TRUE; + } else { + use.pp_assemblage_in = FALSE; + } + break; + case 7: /* Reaction */ + use.n_irrev_user = n_user; + if (n_user >= 0 ) { + use.irrev_in = TRUE; + } else { + use.irrev_in = FALSE; + } + break; + case 8: /* Mix */ + use.n_mix_user = n_user; + if (n_user >= 0 ) { + use.mix_in = TRUE; + } else { + use.mix_in = FALSE; + } + break; + case 13: /* Ex */ + use.n_exchange_user = n_user; + if (n_user >= 0 ) { + use.exchange_in = TRUE; + } else { + use.exchange_in = FALSE; + } + break; + case 16: /* Surface */ + use.n_surface_user = n_user; + if (n_user >= 0 ) { + use.surface_in = TRUE; + } else { + use.surface_in = FALSE; + } + break; + case 17: /* Temperature */ + use.n_temperature_user = n_user; + if (n_user >= 0 ) { + use.temperature_in = TRUE; + } else { + use.temperature_in = FALSE; + } + break; + case 19: /* Gas */ + use.n_gas_phase_user = n_user; + if (n_user >= 0 ) { + use.gas_phase_in = TRUE; + } else { + use.gas_phase_in = FALSE; + } + break; + case 33: /* Kinetics */ + use.n_kinetics_user = n_user; + if (n_user >= 0 ) { + use.kinetics_in = TRUE; + } else { + use.kinetics_in = FALSE; + } + break; + case 40: /* solid_solutions */ + case 41: /* solid_solution */ + use.n_s_s_assemblage_user = n_user; + if (n_user >= 0 ) { + use.s_s_assemblage_in = TRUE; + } else { + use.s_s_assemblage_in = FALSE; + } + break; + } + return_value = check_line("End of use",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_surface_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read data for surface species, parse equations + */ + int i; + int association; + char token[MAX_LENGTH]; + char *ptr; + LDBLE offset; + + struct species *s_ptr; + struct elt_list *next_elt; + struct rxn_token *token_ptr; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "no_check", /* 0 */ + "check", /* 1 */ + "mb", /* 2 */ + "mass_balance", /* 3 */ + "log_k", /* 4 */ + "logk", /* 5 */ + "delta_h", /* 6 */ + "deltah", /* 7 */ + "analytical_expression", /* 8 */ + "a_e", /* 9 */ + "ae", /* 10 */ + "mole_balance", /* 11 */ + "offset", /* 12 */ + "add_logk", /* 13 */ + "add_log_k", /* 14 */ + "add_constant" /* 15 */ + }; + int count_opt_list = 16; + + association=TRUE; +/* + * Read eqn from file and call parser + */ + opt_save = OPTION_DEFAULT; + return_value = UNKNOWN; + s_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 SURFACE_SPECIES keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* no_check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = FALSE; + break; + case 1: /* check */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + s_ptr->check_equation = TRUE; + break; + case 2: /* mb */ + case 3: /* mass_balance */ + case 11: /* mole_balance */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + count_elts = 0; + paren_count =0; + copy_token(token, &next_char, &i); + s_ptr->mole_balance = string_hsave(token); + ptr = token; + get_secondary_in_species(&ptr, 1.0); + s_ptr->next_secondary = elt_list_save(); +/* debug + for (i = 0; i < count_elts; i++) { + output_msg(OUTPUT_MESSAGE,"%s\t%f\n", elt_list[i].elt->name, + elt_list[i].coef); + } + */ + opt_save = OPTION_DEFAULT; + break; + case 4: /* log_k */ + case 5: /* logk */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_log_k_only(next_char, &s_ptr->logk[0]); + opt_save = OPTION_DEFAULT; + break; + case 6: /* delta_h */ + case 7: /* deltah */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_delta_h_only(next_char, &s_ptr->logk[1], &s_ptr->original_units); + opt_save = OPTION_DEFAULT; + break; + case 8: /* analytical_expression */ + case 9: /* a_e */ + case 10: /* ae */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_analytical_expression_only(next_char, &(s_ptr->logk[2])); + opt_save = OPTION_DEFAULT; + break; + case 12: /* offset */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (sscanf(next_char, SCANFORMAT, &offset) != 1) { + error_msg("No offset for log K given", STOP); + } + s_ptr->logk[0] += offset; + opt_save = OPTION_DEFAULT; + break; + case 13: /* add_logk */ + case 14: /* add_log_k */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + /* read name */ + if (copy_token(token, &next_char, &i) == EMPTY) { + input_error++; + sprintf(error_string, "Expected the name of a NAMED_EXPRESSION."); + error_msg(error_string, CONTINUE); + break; + } + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave(token); + /* read coef */ + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + s_ptr->add_logk[s_ptr->count_add_logk].coef = 1; + } + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case 15: /* add_constant */ + if (s_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + if (s_ptr->count_add_logk == 0) { + s_ptr->add_logk = (struct name_coef *) PHRQ_malloc(sizeof(struct name_coef)); + if (s_ptr->add_logk == NULL) malloc_error(); + } else { + s_ptr->add_logk = (struct name_coef *) PHRQ_realloc(s_ptr->add_logk, (size_t) ((s_ptr->count_add_logk + 1)* sizeof(struct name_coef))); + if (s_ptr->add_logk == NULL) malloc_error(); + } + i = sscanf(next_char,SCANFORMAT, &s_ptr->add_logk[s_ptr->count_add_logk].coef); + if (i <= 0) { + input_error++; + sprintf(error_string, "Expected the constant to add for log_K definition."); + error_msg(error_string, CONTINUE); + break; + } + /* set name */ + s_ptr->add_logk[s_ptr->count_add_logk].name = string_hsave("XconstantX"); + /* read coef */ + s_ptr->count_add_logk++; + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: +/* + * Get surface species information and parse equation + */ + s_ptr = NULL; + if ( parse_eq(line, &next_elt, association ) == ERROR) { + parse_error++; + error_msg("Parsing equation.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + } +/* + * Get pointer to each species in the reaction, store new species if necessary + */ + trxn.token[0].s = s_store(trxn.token[0].name, trxn.token[0].z, TRUE); + for (i=1; inext_elt=next_elt; + for ( ; next_elt->elt != NULL; next_elt++) { + if ( strcmp (next_elt->elt->name,"C") == 0 ) { + trxn.token[0].s->carbon = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"H") == 0 ) { + trxn.token[0].s->h = next_elt->coef; + } + if ( strcmp (next_elt->elt->name,"O") == 0 ) { + trxn.token[0].s->o = next_elt->coef; + } + } +/* + * Find coefficient of surface in rxn, store in equiv + */ + trxn.token[0].s->equiv = 0.0; + for (i=1; itype == SURF) { + trxn.token[0].s->equiv = trxn.token[i].coef; + } + } + if (trxn.token[0].s->equiv == 0.0) trxn.token[0].s->equiv = 1.0; +/* + * Malloc space for species reaction + */ + trxn.token[0].s->rxn = rxn_alloc (count_trxn+1); +/* + * Copy reaction to reaction for species + */ + token_ptr=trxn.token[0].s->rxn->token; + for (i=0; itype = SURF; + s_ptr=trxn.token[0].s; +/* + * Read gamma data + */ + s_ptr->gflag = 6; + s_ptr->dha = 0.0; + s_ptr->dhb = 0.0; + opt_save = OPTION_DEFAULT; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_surf(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads surface data + * + * 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 i, j, n, l; + int count_comps, count_charge; + int n_user, n_user_end; + LDBLE conc, area, grams /*, thickness , factor */; + char *ptr, *ptr1; + char *description; + char token[MAX_LENGTH], token1[MAX_LENGTH], name[MAX_LENGTH]; + struct surface *surface_ptr; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "equilibrate", /* 0 */ + "equil", /* 1 */ + "diff", /* 2 */ + "diffuse_layer", /* 3 */ + "no_edl", /* 4 */ + "no_electrostatic", /* 5 */ + "only_counter_ions", /* 6 */ + "donnan", /* 7 */ + "transport" /* 8 */ + }; + int count_opt_list = 9; +/* + * kin_surf is for Surfaces, related to kinetically reacting minerals + * they are defined if "sites" is followed by mineral name: + * Surf_wOH Manganite [equilibrium_phases or kinetics] 0.25 4000 + * ^Name mineral ^switch ^prop.factor ^m2/mol + */ +/* + * Read surface number and description + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Find space for surface data + */ + surface_ptr = surface_search(n_user, &n, FALSE); + if (surface_ptr != NULL) { + surface_free(&surface[n]); + } else { + n = count_surface++; + space ((void **) ((void *) &surface), count_surface, &max_surface, sizeof(struct surface)); + } +/* + * Initialize + */ + surface_init(&(surface[n]), n_user, n_user_end, description); + free_check_null(description); + + if (use.surface_in == FALSE) { + use.surface_in = TRUE; + use.n_surface_user = n_user; + } +/* + * Read surface data + */ + count_charge = 0; + count_comps = 0; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + 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 SURFACE keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* equilibrate */ + case 1: + for (;;) { + i = copy_token(token, &next_char, &l); + if (i == DIGIT) { + sscanf(token, "%d", &surface[n].n_solution); + surface[n].solution_equilibria = TRUE; + break; + } + if (i == EMPTY) { + error_msg("Expected a solution number with which to equilibrate surface.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + } + break; + case 2: /* diffuse_layer */ + case 3: + surface[n].thickness = 1e-8; + surface[n].diffuse_layer = TRUE; + for (;;) { + i = copy_token(token, &next_char, &l); + if (i == DIGIT) { + sscanf(token, SCANFORMAT, &surface[n].thickness); + break; + } else if (i != EMPTY) { + if (token[0] == 'D' || token[0] == 'd') { + surface[n].debye_units = 1.0; + j = copy_token(token1, &ptr, &l); + if (j == DIGIT) { + sscanf(token1, SCANFORMAT, &surface[n].debye_units); + break; + } else if (j != EMPTY) { + error_msg("Expected number of Debye units (1/k) for calculating diffuse layer thickness.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } else break; + } else { + error_msg("Expected D or d for Donnan calculations.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } + } else break; + } + break; + case 4: /* no electrostatic */ + case 5: + surface[n].edl = FALSE; + break; + case 6: + surface[n].only_counter_ions = TRUE; + break; + case 7: /* donnan for DL conc's */ + surface[n].donnan = TRUE; + break; + case 8: /* transport */ + surface[n].transport = TRUE; + break; + case OPTION_DEFAULT: +/* + * Read surface component + */ + ptr=line; + i = copy_token(token, &ptr, &l); + if (i != UPPER && token[0] != '[' ) { + error_msg("Expected surface name to begin with a capital letter.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } +/* + * Realloc space for new surface component + */ + surface[n].comps = (struct surface_comp *) PHRQ_realloc( surface[n].comps, (size_t) (count_comps + 1) * sizeof (struct surface_comp)); + if (surface[n].comps == NULL) malloc_error(); + surface[n].comps[count_comps].formula = string_hsave(token); + surface[n].comps[count_comps].moles = 0; + surface[n].comps[count_comps].cb = 0; + surface[n].comps[count_comps].phase_name = NULL; + surface[n].comps[count_comps].rate_name = NULL; + i = copy_token(token1, &ptr, &l); + if (i == DIGIT) { +/* + * Read surface concentration + */ + /* surface concentration is read directly */ + if ( sscanf(token1, SCANFORMAT, &conc) < 1) { + error_msg("Expected number of surface sites in moles.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } +#ifdef PHREEQCI_GUI + surface[n].comps[count_comps].moles = conc; +#endif +/* + * Read equilibrium phase name or kinetics rate name + */ + } else if (i != EMPTY) { + + /* surface conc. is related to mineral or kinetics */ + surface[n].comps[count_comps].phase_name = string_hsave(token1); + j = copy_token(token1, &ptr, &l); + + /* read optional 'equilibrium_phases' or 'kinetics' */ + if (j == DIGIT) { + surface[n].related_phases = TRUE; + } else { + if (token1[0] == 'K' || token1[0] == 'k') { + surface[n].comps[count_comps].rate_name = surface[n].comps[count_comps].phase_name; + surface[n].comps[count_comps].phase_name = NULL; + surface[n].related_rate = TRUE; + } else if (token1[0] == 'E' || token1[0] == 'e') { + surface[n].related_phases = TRUE; + surface[n].comps[count_comps].rate_name = NULL; + } else { + error_msg("Character string expected to be 'equilibrium_phase' or 'kinetics' to relate surface to mineral or kinetic reaction.\n", CONTINUE); + input_error++; + break; + } + j = copy_token(token1, &ptr, &l); + } + + /* read proportion */ + if (j != DIGIT) { + error_msg("Expected a coefficient to relate surface to mineral or kinetic reaction.\n", CONTINUE); + input_error++; + break; + } + sscanf(token1, SCANFORMAT, &surface[n].comps[count_comps].phase_proportion); + /* real conc must be defined in tidy_model */ + conc = 1.0; + } else { + error_msg("Expected concentration of surface, mineral name, or kinetic reaction name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + break; + } +/* + * Accumulate elements in elt_list + */ + count_elts = 0; + paren_count = 0; + ptr1 = token; + get_elts_in_species(&ptr1, conc); + surface[n].comps[count_comps].totals = elt_list_save(); +/* + * Search for charge structure + */ + ptr1 = token; + get_elt(&ptr1, name, &l); + ptr1 = strchr(name,'_'); + if (ptr1 != NULL) ptr1[0] = '\0'; + for (i = 0; i < count_charge; i++) { + if (strcmp(surface[n].charge[i].name, name) == 0) break; + } + if (i >= count_charge) { + surface[n].charge = (struct surface_charge *) PHRQ_realloc(surface[n].charge, (size_t) ( count_charge + 1) * sizeof(struct surface_charge)); + if (surface[n].charge == NULL) malloc_error(); + i = count_charge; + surface[n].charge[i].name = string_hsave(name); + if (surface[n].comps[count_comps].phase_name == NULL && surface[n].comps[count_comps].rate_name == NULL) { + surface[n].charge[i].specific_area = 600.0; + surface[n].charge[i].grams = 0.0; + } else { + surface[n].charge[i].specific_area = 0.0; + surface[n].charge[i].grams = 1.0; + } + surface[n].charge[i].mass_water = 0.0; + surface[n].charge[i].charge_balance = 0.0; + surface[n].charge[i].diffuse_layer_totals = NULL; + surface[n].charge[i].count_g = 0; + surface[n].charge[i].g = NULL; + surface[n].charge[i].psi_master = NULL; + count_charge++; + } + surface[n].comps[count_comps].charge = i; + count_comps++; +/* + * Read surface area (m2/g) + */ + copy_token(token1, &ptr, &l); + if (sscanf(token1, SCANFORMAT, &area) == 1) { + surface[n].charge[i].specific_area = area; + } else { + break; + } +/* + * Read grams of solid (g) + */ + copy_token(token1, &ptr, &l); + if (sscanf(token1, SCANFORMAT, &grams) == 1 ) { + surface[n].charge[i].grams = grams; + } + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + surface[n].count_comps = count_comps; + surface[n].count_charge = count_charge; +/* + * Make sure surface area is defined + */ + if (surface[n].edl == TRUE) { + for (i = 0; i < count_charge; i++) { + if (surface[n].charge[i].grams * surface[n].charge[i].specific_area <= 0) { + sprintf(error_string, "Surface area not defined for %s.\n", surface[n].charge[i].name); + error_msg(error_string, CONTINUE); + input_error++; + } + } + } else { + if (surface[n].diffuse_layer == TRUE) { + sprintf(error_string, "Diffuse_layer and no_edl are mutually exclusive options.\n"); + error_msg(error_string, CONTINUE); + input_error++; + } + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_surface_master_species (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads master species data from data file or input file + */ + int i, l, n, return_value; + char *ptr, *ptr1; + LDBLE z; + struct master *master_ptr; + struct species *s_ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + + for (;;) { + return_value = check_line ("Surface species equation", FALSE, TRUE, TRUE, TRUE); + if (return_value == EOF || return_value == KEYWORD ) break; +/* + * Get "element" name with valence, allocate space, store + */ + ptr=line; +/* + * Get element name and save pointer to character string + */ + if ( copy_token(token, &ptr, &l) != UPPER && token[0] != '[' ) { + parse_error++; + error_msg ("Reading element for master species.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } + /* + if (token[0] == '[') { + ptr1 = token; + get_elt(&ptr, element, &l); + strcpy(token, element); + } + */ + replace ("(+", "(", token); +/* + * Delete master if it exists + */ + master_delete(token); +/* + * Increase pointer array, if necessary, and malloc space + */ + if (count_master + 2 >= max_master) { + space ((void **) ((void *) &master), count_master+2, &max_master, sizeof(struct master *)); + } +/* + * Save values in master and species structure for surface sites + */ + master[count_master] = master_alloc(); + master[count_master]->type = SURF; + master[count_master]->elt = element_store ( token ); + + if ( copy_token(token, &ptr, &l) != UPPER && token[0] != '[' ) { + parse_error++; + error_msg("Reading surface master species name.", CONTINUE); + error_msg(line_save, CONTINUE); + continue; + } + s_ptr=s_search (token); + if (s_ptr != NULL) { + master[count_master]->s = s_ptr; + } else { + ptr1=token; + get_token(&ptr1, token1, &z, &l); + master[count_master]->s = s_store(token1, z, FALSE); + } + master[count_master]->primary=TRUE; + strcpy(token,master[count_master]->elt->name); + count_master++; +/* + * Save values in master and species structure for surface psi + */ + strcpy(token1, token); + replace ("_", " ", token1); + ptr1 = token1; + copy_token(token, &ptr1, &l); + strcat(token,"_psi"); + master_ptr=master_search (token, &n); + if (master_ptr == NULL) { + master[count_master] = master_alloc(); + master[count_master]->type = SURF_PSI; + master[count_master]->elt = element_store ( token ); + s_ptr=s_search (token); + if (s_ptr != NULL) { + master[count_master]->s = s_ptr; + } else { + master[count_master]->s = s_store(token, 0.0, FALSE); + } + count_elts = 0; + paren_count = 0; + ptr = token; + get_elts_in_species(&ptr, 1.0); + master[count_master]->s->next_elt = elt_list_save(); + + master[count_master]->s->type=SURF_PSI; + master[count_master]->primary=TRUE; + master[count_master]->s->rxn = rxn_alloc(3); +/* + * Define reaction for psi + */ + for( i = 0; i < 8; i++) { + master[count_master]->s->rxn->logk[i] = 0.0; + } + master[count_master]->s->rxn->token[0].s = master[count_master]->s; + master[count_master]->s->rxn->token[0].coef = -1.0; + master[count_master]->s->rxn->token[1].s = master[count_master]->s; + master[count_master]->s->rxn->token[1].coef = 1.0; + master[count_master]->s->rxn->token[2].s = NULL; + count_master++; + } + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int read_temperature (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads temperature data for reaction steps + * + * 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 + * + */ + char *ptr; + char *description; + int n, return_value; + int n_user, n_user_end; + struct temperature *temperature_ptr; +/* + * Read reaction number + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Read allocate space for temperature + */ + temperature_ptr = temperature_search(n_user, &n); + if (temperature_ptr != NULL) { + temperature_free(&temperature[n]); + } else { + n = count_temperature++; + temperature = (struct temperature *) PHRQ_realloc(temperature, (size_t) count_temperature * sizeof (struct temperature)); + if (temperature == NULL) malloc_error(); + } +/* + * Set use data to first read + */ + if (use.temperature_in == FALSE) { + use.temperature_in = TRUE; + use.n_temperature_user = n_user; + } +/* + * Defaults + */ + temperature[n].n_user = n_user; + temperature[n].n_user_end = n_user_end; + temperature[n].description = description; + temperature[n].t = (LDBLE *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (temperature[n].t == NULL) malloc_error(); + temperature[n].t[0] = 25.0; + temperature[n].count_t = 0; +/* + * Read temperature data + */ + for (;;) { + return_value = check_line("reaction_temperature",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; +/* + * Read steps information + */ + read_reaction_temps(&(temperature[n])); + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_reaction_temps(struct temperature *temperature_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read temperature one of two forms: + * + * (1) 25.0 30. 40. 50. 60. + * + * (2) 25.0 100.0 in 4 steps # (25 50 75 100) + * + */ + int i, j, l; + int count_t; + char *ptr; + char token[MAX_LENGTH]; + LDBLE step; + + ptr = line; + count_t = temperature_ptr->count_t; +/* + * Read one or more reaction increments + */ + for (;;) { + if ( copy_token (token, &ptr, &l) == EMPTY ) { + return(OK); + } +/* + * Read next step increment + */ + j = sscanf(token, SCANFORMAT, &step); + if (j == 1 ) { + count_t++; + temperature_ptr->t = (LDBLE *) PHRQ_realloc(temperature_ptr->t, (size_t) count_t * sizeof(LDBLE)); + if (temperature_ptr->t == NULL) malloc_error(); + temperature_ptr->t[temperature_ptr->count_t] = step; + temperature_ptr->count_t = count_t; + } else { + break; + } + } +/* + * Read number of equal increments, store as negative integer + */ + if (count_t != 2) { + error_msg("To define equal increments, exactly two temperatures should be defined.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + do { + j = sscanf(token, "%d", &i); + if (j == 1 && i > 0 ) { + temperature_ptr->count_t = -i; + return(OK); + } else if (j == 1 && i <= 0 ) { + break; + } + } while ( copy_token (token, &ptr, &l) != EMPTY ); + + error_msg("Expecting positive number for calculation of " + "temperature increments.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); +} +/* ---------------------------------------------------------------------- */ +int read_title (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads title for simulation + * + * 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 + * + */ + char *ptr, *ptr1; + int l, title_x_length, line_length; + int return_value; + char token[MAX_LENGTH]; +/* + * Read anything after keyword + */ + ptr=line; + copy_token(token, &ptr, &l); + ptr1 = ptr; + title_x = (char *) free_check_null(title_x); + if (copy_token(token, &ptr, &l) != EMPTY) { + title_x = string_duplicate(ptr1); + } else { + title_x = (char *) PHRQ_malloc(sizeof(char)); + if (title_x == NULL) malloc_error(); + title_x[0] = '\0'; + } + +/* + * Read additonal lines + */ + for (;;) { + return_value = check_line("title",TRUE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + if (return_value == EOF || return_value == KEYWORD ) break; +/* + * append line to title_x + */ + title_x_length = strlen(title_x); + line_length = strlen(line); + title_x = (char *) PHRQ_realloc(title_x, (size_t) (title_x_length + line_length + 2) * sizeof(char)); + if (title_x == NULL) malloc_error(); + if (title_x_length > 0) { + title_x[title_x_length] = '\n'; + title_x[title_x_length+1] = '\0'; + } + strcat(title_x, line); + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_advection (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads advection information + * + * 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 + * + */ +/* + * Read advection parameters: + * number of cells; + * number of shifts; + */ + char *ptr; + char *description; + int n_user, n_user_end, i; + + int count_punch, count_print; + int *punch_temp, *print_temp; + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "cells", /* 0 */ + "shifts", /* 1 */ + "print", /* 2 */ + "selected_output", /* 3 */ + "punch", /* 4 */ + "print_cells", /* 5 */ + "selected_cells", /* 6 */ + "time_step", /* 7 */ + "timest", /* 8 */ + "output", /* 9 */ + "output_frequency", /* 10 */ + "selected_output_frequency",/* 11 */ + "punch_frequency", /* 12 */ + "print_frequency", /* 13 */ + "punch_cells", /* 14 */ + "initial_time", /* 15 */ + "warning", /* 16 */ + "warnings" /* 17 */ + }; + int count_opt_list = 18; +/* + * Read advection number (not currently used) + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); +/* + * Set use data + */ + use.advect_in = TRUE; + count_ad_cells = 0; + count_ad_shifts = 0; + print_ad_modulus = 1; + punch_ad_modulus = 1; + count_punch = 0; + count_print = 0; + punch_temp = (int *) PHRQ_malloc(sizeof(int)); + if (punch_temp == NULL) malloc_error(); + print_temp = (int *) PHRQ_malloc(sizeof(int)); + if (print_temp == NULL) malloc_error(); +/* + * Read lines + */ + 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_DEFAULT: + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in ADVECTION keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* cells */ + sscanf(next_char, "%d", &count_ad_cells); + opt_save = OPTION_DEFAULT; + break; + case 1: /* shifts */ + sscanf(next_char, "%d", &count_ad_shifts); + opt_save = OPTION_DEFAULT; + break; + case 2: /* print */ + case 5: /* print_cells */ + print_temp = read_list_ints_range (&next_char, &count_print, TRUE, print_temp); +#ifdef SKIP + while (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &l); + print_temp = PHRQ_realloc(print_temp, (size_t) (count_print + 1) * sizeof(int)); + if (print_temp == NULL) malloc_error(); + print_temp[count_print] = l; + count_print++; + } +#endif + opt_save = 2; + break; + case 3: /* selected_output */ + case 11: /* selected_output_frequency */ + case 12: /* punch_frequency */ + sscanf(next_char, "%d", &punch_ad_modulus); + opt_save = OPTION_DEFAULT; + break; + case 4: /* punch */ + case 14: /* punch_cells */ + case 6: /* selected_cells */ + punch_temp = read_list_ints_range (&next_char, &count_punch, TRUE, punch_temp); +#ifdef SKIP + while (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &l); + punch_temp = PHRQ_realloc(punch_temp, (size_t) (count_punch + 1) * sizeof(int)); + if (punch_temp == NULL) malloc_error(); + punch_temp[count_punch] = l; + count_punch++; + } +#endif + opt_save = 4; + break; + case 7: /* time_step */ + case 8: /* timest */ + sscanf(next_char, SCANFORMAT, &advection_kin_time); + advection_kin_time_defined = TRUE; + opt_save = OPTION_DEFAULT; + break; + case 9: /* output */ + case 10: /* output_frequency */ + case 13: /* print_frequency */ + sscanf(next_char, "%d", &print_ad_modulus); + opt_save = OPTION_DEFAULT; + break; + case 15: /* initial_time */ + sscanf(next_char, SCANFORMAT, &initial_total_time); + opt_save = OPTION_DEFAULT; + break; + case 16: /* warning */ + case 17: /* warnings */ + advection_warnings = get_true_false(next_char, TRUE); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* + * Fill in data for punch + */ + advection_punch = (int *) PHRQ_realloc(advection_punch, (size_t) (count_ad_cells + 1) * sizeof(int)); + if (advection_punch == NULL) malloc_error(); + if (count_punch != 0) { + for (i=0; i count_ad_cells || punch_temp[i] < 1) { + sprintf(error_string,"Cell number for punch is out of range, %d. Request ignored.", punch_temp[i]); + warning_msg(error_string); + } else { + advection_punch[punch_temp[i]-1] = TRUE; + } + } + } else { + for (i=0; i count_ad_cells || print_temp[i] < 1) { + sprintf(error_string,"Cell number for print is out of range, %d. Request ignored.", print_temp[i]); + warning_msg(error_string); + } else { + advection_print[print_temp[i]-1] = TRUE; + } + } + } else { + for (i=0; idata))->keycount; + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int check_units (char *tot_units, int alkalinity, int check_compatibility, + const char *default_units, int print) +/* ---------------------------------------------------------------------- */ +{ +#define NUNITS (sizeof(units) / sizeof(char *)) +/* + * Check if legitimate units + * Input: + * tot_units character string to check, + * alkalinity TRUE if alkalinity, FALSE if any other total, + * check_compatibility TRUE check alk and default units, FALSE otherwise + * default_units character string of default units (check /L, /kg, etc) + * print TRUE print warning messages + * Output: + * tot_units standard form for unit + */ + int i, found; + char *end; + char string[MAX_LENGTH]; + const char *units[] = { + "Mol/l", /* 0 */ + "mMol/l", /* 1 */ + "uMol/l", /* 2 */ + "g/l", /* 3 */ + "mg/l", /* 4 */ + "ug/l", /* 5 */ + "Mol/kgs", /* 6 */ + "mMol/kgs", /* 7 */ + "uMol/kgs", /* 8 */ + "g/kgs", /* 9 = ppt */ + "mg/kgs", /* 10 = ppm */ + "ug/kgs", /* 11 = ppb */ + "Mol/kgw", /* 12 = mol/kg H2O */ + "mMol/kgw", /* 13 = mmol/kg H2O */ + "uMol/kgw", /* 14 = umol/kg H2O */ + "g/kgw", /* 15 = mol/kg H2O */ + "mg/kgw", /* 16 = mmol/kg H2O */ + "ug/kgw", /* 17 = umol/kg H2O */ + "eq/l", /* 18 */ + "meq/l", /* 19 */ + "ueq/l", /* 20 */ + "eq/kgs", /* 21 */ + "meq/kgs", /* 22 */ + "ueq/kgs", /* 23 */ + "eq/kgw", /* 24 */ + "meq/kgw", /* 25 */ + "ueq/kgw", /* 26 */ + }; + + squeeze_white (tot_units); + str_tolower(tot_units); + replace ("milli", "m", tot_units); + replace ("micro", "u", tot_units); + replace ("grams", "g", tot_units); + replace ("gram", "g", tot_units); + replace ("moles", "Mol", tot_units); + replace ("mole", "Mol", tot_units); + replace ("mol", "Mol", tot_units); + replace ("liter", "l", tot_units); + replace ("kgh", "kgw", tot_units); + replace ("ppt", "g/kgs", tot_units); + replace ("ppm", "mg/kgs",tot_units); + replace ("ppb", "ug/kgs",tot_units); + replace ("equivalents","eq", tot_units); + replace ("equivalent", "eq", tot_units); + replace ("equiv", "eq", tot_units); + + if ( (end=strstr(tot_units,"/l")) != NULL) { + *(end+2)='\0'; + } + if ( (end=strstr(tot_units,"/kgs")) != NULL) { + *(end+4)='\0'; + } + if ( (end=strstr(tot_units,"/kgw")) != NULL) { + *(end+4)='\0'; + } +/* + * Check if unit in list + */ + found = FALSE; + for (i=0; i < (int) NUNITS; i++) { + if (strcmp(tot_units, units[i]) == 0) { + found=TRUE; + break; + } + } + if (found == FALSE) { + if (print == TRUE) { + sprintf(error_string, "Unknown unit, %s.", tot_units); + error_msg(error_string, CONTINUE); + } + return (ERROR); + } + +/* + * Check if units are compatible with default_units + */ + if (check_compatibility == FALSE) return (OK); +/* + * Special cases for alkalinity + */ + if (alkalinity == TRUE && strstr(tot_units,"Mol") != NULL) { + if (print == TRUE) { + sprintf(error_string, "Alkalinity given in moles, assumed to be equivalents."); + warning_msg(error_string); + } + replace("Mol","eq",tot_units); + } + if (alkalinity == FALSE && strstr(tot_units,"eq") != NULL) { + if (print == TRUE) { + error_msg("Only alkalinity can be entered in equivalents.", CONTINUE); + } + return (ERROR); + } +/* + * See if default_units are compatible with tot_units + */ + if ( strstr(default_units,"/l") && strstr(tot_units,"/l")) return (OK); + if ( strstr(default_units,"/kgs") && strstr(tot_units,"/kgs")) return (OK); + if ( strstr(default_units,"/kgw") && strstr(tot_units,"/kgw")) return (OK); + + strcpy( string, default_units); + replace ("kgs","kg solution",string); + replace ("kgs","kg solution",tot_units); + replace ("kgw","kg water",string); + replace ("kgw","kg water",tot_units); + replace ("/l","/L",string); + replace ("Mol","mol",string); + replace ("/l","/L",tot_units); + replace ("Mol","mol",tot_units); + if (print == TRUE) { + sprintf(error_string, "Units for master species, %s, are not compatible with default units, %s.", tot_units, string); + error_msg(error_string, CONTINUE); + } + return (ERROR); +} +/* ---------------------------------------------------------------------- */ +int find_option(char *item, int *n, const char **list, int count_list, int exact) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compares a string value to match beginning letters of a list of options + * + * Arguments: + * item entry: pointer to string to compare + * n exit: item in list that was matched + * list entry: pointer to list of character values, assumed to + * be lower case + * count_list entry: number of character values in list + * + * Returns: + * OK item matched + * ERROR item not matched + * n -1 item not matched + * i position of match in list + */ + int i; + char token[MAX_LENGTH]; + + strcpy(token, item); + str_tolower(token); + for (i=0; i < count_list; i++) { + if (exact == TRUE) { + if (strcmp(list[i], token) == 0) { + *n = i; + return(OK); + } + } else { + if (strstr(list[i], token) == list[i]) { + *n = i; + return(OK); + } + } + } + *n = -1; + return(ERROR); +} +/* ---------------------------------------------------------------------- */ +int get_true_false(char *string, int default_value) +/* ---------------------------------------------------------------------- */ +{ +/* + * Returns true unless string starts with "F" or "f" + */ + int l; + char token[MAX_LENGTH]; + char *ptr; + + ptr = string; + + if (copy_token(token, &ptr, &l) == EMPTY) { + return(default_value); + } else { + if (token[0] == 'F' || token[0] == 'f') { + return(FALSE); + } + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int get_option (const char **opt_list, int count_opt_list, char **next_char) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read a line and check for options + */ + int j; + int opt_l, opt; + char *opt_ptr; + char option[MAX_LENGTH]; +/* + * Read line + */ + j = check_line ("get_option", FALSE, TRUE, TRUE, FALSE); + if (j == EOF) { + j = OPTION_EOF; + } else if (j == KEYWORD ) { + j = OPTION_KEYWORD; + } else if (j == OPTION) { + opt_ptr = line; + copy_token(option, &opt_ptr, &opt_l); + if (find_option(&(option[1]), &opt, opt_list, count_opt_list, FALSE) == OK) { + j = opt; + replace(option, opt_list[j], line_save); + replace(option, opt_list[j], line); + opt_ptr = line; + copy_token(option, &opt_ptr, &opt_l); + *next_char = opt_ptr; + if (pr.echo_input == TRUE) { + if(!reading_database()) output_msg(OUTPUT_MESSAGE, "\t%s\n", line_save); + } + } else { + if(!reading_database()) output_msg(OUTPUT_MESSAGE, "\t%s\n", line_save); + error_msg("Unknown option.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + j = OPTION_ERROR; + *next_char = line; + } + } else { + opt_ptr = line; + copy_token(option, &opt_ptr, &opt_l); + if (find_option(&(option[0]), &opt, opt_list, count_opt_list, TRUE) == OK) { + j = opt; + *next_char = opt_ptr; + } else { + j = OPTION_DEFAULT; + *next_char = line; + } + if (pr.echo_input == TRUE) { + if(!reading_database()) output_msg(OUTPUT_MESSAGE, "\t%s\n", line_save); + } + } + return (j); +} +/* ---------------------------------------------------------------------- */ +int read_rates (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads basic code with which to calculate rates + * + * 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 + * + */ + char *ptr; + int l, length, line_length, n; + int return_value, opt, opt_save; + char token[MAX_LENGTH]; + struct rate *rate_ptr; + char *description; + int n_user, n_user_end; + char *next_char; + const char *opt_list[] = { + "start", /* 0 */ + "end" /* 1 */ + }; + int count_opt_list = 2; +/* + * Read advection number (not currently used) + */ + n = -1; + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); + opt_save = OPTION_DEFAULT; +/* + * Read lines + */ + return_value = UNKNOWN; + rate_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 RATES 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 rate name */ + ptr = line; + copy_token(token, &ptr, &l); + rate_ptr = rate_search(token, &n); + if (rate_ptr == NULL) { + rates = (struct rate *) PHRQ_realloc(rates, (size_t) (count_rates + 1) * sizeof (struct rate)); + if (rates == NULL) malloc_error(); + rate_ptr = &rates[count_rates]; + count_rates++; + } else { + rate_free(rate_ptr); + } + rate_ptr->new_def = TRUE; + rate_ptr->commands = (char *) PHRQ_malloc(sizeof(char)); + if (rate_ptr->commands == NULL) malloc_error(); + rate_ptr->commands[0] = '\0'; + rate_ptr->name = string_hsave(token); + rate_ptr->linebase = NULL; + rate_ptr->varbase = NULL; + rate_ptr->loopbase = NULL; + opt_save = OPT_1; + break; + case OPT_1: /* read command */ + if (rate_ptr == NULL) { + input_error++; + sprintf(error_string, "No rate name has been defined."); + error_msg(error_string, CONTINUE); + opt_save = OPT_1; + break; + } + length = strlen(rate_ptr->commands); + line_length = strlen(line); + rate_ptr->commands = (char *) PHRQ_realloc(rate_ptr->commands, (size_t) (length + line_length + 2) * sizeof(char)); + if (rate_ptr->commands == NULL) malloc_error(); + rate_ptr->commands[length] = ';'; + rate_ptr->commands[length + 1] = '\0'; + strcat((rate_ptr->commands), line); + opt_save = OPT_1; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* output_msg(OUTPUT_MESSAGE, "%s", rates[0].commands); + */ return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_user_print (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads basic code with which to calculate rates + * + * 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 length, line_length; + int return_value, opt, opt_save; + 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; + 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 RATES keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* start */ + opt_save = OPTION_DEFAULT; + break; + case 1: /* end */ + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: /* read first command */ + rate_free(user_print); + user_print->new_def = TRUE; + user_print->commands = (char *) PHRQ_malloc(sizeof(char)); + if (user_print->commands == NULL) malloc_error(); + user_print->commands[0] = '\0'; + user_print->linebase = NULL; + user_print->varbase = NULL; + user_print->loopbase = NULL; + user_print->name = string_hsave("user defined Basic print routine"); + case OPT_1: /* read command */ + length = strlen(user_print->commands); + line_length = strlen(line); + user_print->commands = (char *) PHRQ_realloc(user_print->commands, (size_t) (length + line_length + 2) * sizeof(char)); + if (user_print->commands == NULL) malloc_error(); + user_print->commands[length] = ';'; + user_print->commands[length + 1] = '\0'; + strcat((user_print->commands), line); + opt_save = OPT_1; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* output_msg(OUTPUT_MESSAGE, "%s", rates[0].commands); + */ return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_user_punch (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads basic code with which to calculate rates + * + * 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, length, line_length; + int return_value, opt, opt_save; + char token[MAX_LENGTH]; + char *next_char; + const char *opt_list[] = { + "start", /* 0 */ + "end", /* 1 */ + "heading", /* 2 */ + "headings" /* 3 */ + }; + int count_opt_list = 4; + + opt_save = OPTION_DEFAULT; +/* + * Read lines + */ + user_punch_count_headings = 0; + 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 RATES keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* start */ + opt_save = OPTION_DEFAULT; + break; + case 1: /* end */ + opt_save = OPTION_DEFAULT; + break; + case 2: /* headings */ + case 3: /* heading*/ + while (copy_token(token, &next_char, &l) != EMPTY) { + user_punch_headings = (char **) PHRQ_realloc(user_punch_headings, (size_t) (user_punch_count_headings + 1) * sizeof(char *)); + if (user_punch_headings == NULL) malloc_error(); + user_punch_headings[user_punch_count_headings] = string_hsave(token); + user_punch_count_headings++; + } + break; + case OPTION_DEFAULT: /* read first command */ + rate_free(user_punch); + user_punch->new_def = TRUE; + user_punch->commands = (char *) PHRQ_malloc(sizeof(char)); + if (user_punch->commands == NULL) malloc_error(); + user_punch->commands[0] = '\0'; + user_punch->linebase = NULL; + user_punch->varbase = NULL; + user_punch->loopbase = NULL; + user_punch->name = string_hsave("user defined Basic punch routine"); + case OPT_1: /* read command */ + length = strlen(user_punch->commands); + line_length = strlen(line); + user_punch->commands = (char *) PHRQ_realloc(user_punch->commands, (size_t) (length + line_length + 2) * sizeof(char)); + if (user_punch->commands == NULL) malloc_error(); + user_punch->commands[length] = ';'; + user_punch->commands[length + 1] = '\0'; + strcat((user_punch->commands), line); + opt_save = OPT_1; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return(return_value); +} +#ifdef PHREEQ98 +/* ---------------------------------------------------------------------- */ +int read_user_graph (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads basic code with which to calculate rates + * + * 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, length, line_length; + int return_value, opt, opt_save; + char file_name[MAX_LENGTH]; + char token[MAX_LENGTH]; + char *next_char; + const char *opt_list[] = { + "start", /* 0 */ + "end", /* 1 */ + "heading", /* 2 */ + "headings", /* 3 */ + "chart_title", /* 4 */ + "axis_titles", /* 5 */ + "axis_scale", /* 6 */ + "initial_solutions", /* 7 */ + "plot_concentration_vs",/* 8 */ + "shifts_as_points", /* 9 */ + "grid_offset", /* 10 */ + "connect_simulations", /* 11 */ + "plot_csv_file" /* 12 */ + + }; + int count_opt_list = 13; + int i; + + opt_save = OPTION_DEFAULT; +/* + * Read lines + */ + user_graph_count_headings = 0; + 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 USER_GRAPH keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* start */ + opt_save = OPTION_DEFAULT; + break; + case 1: /* end */ + opt_save = OPTION_DEFAULT; + break; + case 2: /* headings */ + case 3: /* heading*/ + while (copy_token(token, &next_char, &l) != EMPTY) { + user_graph_headings = PHRQ_realloc(user_graph_headings, (size_t) (user_graph_count_headings + 1) * sizeof(char *)); + if (user_graph_headings == NULL) malloc_error(); + user_graph_headings[user_graph_count_headings] = string_hsave(token); + user_graph_count_headings++; + } + break; +/*Modifications of read_user_punch to change the chart's appearance */ + case 4: /* chart title */ + copy_title(token, &next_char, &l); + SetChartTitle(token); + break; + case 5: { /* axis titles */ + i = 0; + while (copy_title(token, &next_char, &l) != EMPTY) { + SetAxisTitles(token, i); + i++; + } + } + break; + case 6: { /* axis scales */ + char* axis = ""; + int j = 0; + copy_token(token, &next_char, &l); + str_tolower(token); + if (strstr(token, "x") == token) { + axis = "x"; + } else if (strstr(token, "y") == token) { + axis = "y"; + } else if (strstr(token, "s") == token) { + axis = "s"; + } else { + input_error++; + error_msg("Expected axis type.", CONTINUE); + } + while ((j < 4) && (i = copy_token(token, &next_char, &l)) != EMPTY) { + str_tolower(token); + if ((i == DIGIT) || (strstr(token, "auto") == token)) { + SetAxisScale(axis, j, token, FALSE); + } else { + input_error++; + error_msg("Expected numerical value or 'auto'.", CONTINUE); + } + j++; /* counter for categories */ + } + if (j == 4) SetAxisScale(axis, j, 0, get_true_false(next_char, FALSE)); + } + break; + case 7: + graph_initial_solutions = get_true_false(next_char, TRUE); + break; + case 8: + copy_token(token, &next_char, &l); + str_tolower(token); + if (strstr(token, "x") == token) { + chart_type = 0; + } else if (strstr(token, "t") == token) { + chart_type = 1; + } else { + input_error++; + error_msg("Expected simulation type.", CONTINUE); + } + break; + case 9: + shifts_as_points = get_true_false(next_char, TRUE); + if (shifts_as_points == TRUE) chart_type = 0; + else chart_type = 1; + break; + case 10: { + i = copy_token(token, &next_char, &l); + str_tolower(token); + if (i == DIGIT) sscanf(token, "%d", &RowOffset); + i = copy_token(token, &next_char, &l); + str_tolower(token); + if (i == DIGIT) sscanf(token, "%d", &ColumnOffset); + } + break; + case 11: + connect_simulations = get_true_false(next_char, TRUE); + break; + case 12: + string_trim(next_char); + strcpy(file_name, next_char); + if (!OpenCSVFile(file_name)) { + sprintf(error_string, "Can't open file, %s.", file_name); + input_error++; + error_msg(error_string, CONTINUE); + } + break; + /* End of modifications */ + case OPTION_DEFAULT: /* read first command */ + rate_free(user_graph); + user_graph->new_def = TRUE; + user_graph->commands = PHRQ_malloc(sizeof(char)); + if (user_graph->commands == NULL) malloc_error(); + user_graph->commands[0] = '\0'; + user_graph->linebase = NULL; + user_graph->varbase = NULL; + user_graph->loopbase = NULL; + user_graph->name = string_hsave("user defined Basic punch routine"); + case OPT_1: /* read command */ + length = strlen(user_graph->commands); + line_length = strlen(line); + user_graph->commands = PHRQ_realloc(user_graph->commands, (size_t) (length + line_length + 2) * sizeof(char)); + if (user_graph->commands == NULL) malloc_error(); + user_graph->commands[length] = ';'; + user_graph->commands[length + 1] = '\0'; + strcat((user_graph->commands), line); + opt_save = OPT_1; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + for (i = 0; i < user_graph_count_headings; i++) + GridHeadings(user_graph_headings[i], i); + return(return_value); +} +#endif +/* ---------------------------------------------------------------------- */ +int read_solid_solutions(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solid solution data + * + * 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 i, j, n, l; + int count_s_s, number_s_s, count_comps; + int n_user, n_user_end; + char *ptr; + char *description; + char token[MAX_LENGTH]; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "component", /* 0 */ + "comp", /* 1 */ + "parms", /* 2 */ + "gugg_nondimensional", /* 3 */ + "gugg_kj", /* 4 */ + "activity_coefficients", /* 5 */ + "distribution_coefficients", /* 6 */ + "miscibility_gap", /* 7 */ + "spinodal_gap", /* 8 */ + "critical_point", /* 9 */ + "alyotropic_point", /* 10 */ + "temp", /* 11 */ + "tempk", /* 12 */ + "tempc", /* 13 */ + "thompson", /* 14 */ + "margules", /* 15 */ + "comp1", /* 16 */ + "comp2" /* 17 */ + }; + int count_opt_list = 18; +/* + * Read s_s_assemblage number + */ + number_s_s = 0; + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); +/* + * Find old s_s_assemblage or alloc space for new s_s_assemblage + */ + if (s_s_assemblage_search(n_user, &n) != NULL) { + s_s_assemblage_free(&s_s_assemblage[n]); + } else { + n=count_s_s_assemblage; + space ((void **) ((void *) &s_s_assemblage), count_s_s_assemblage, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + count_s_s_assemblage++; + } +/* + * Initialize + */ + s_s_assemblage_init(&(s_s_assemblage[n]), n_user, n_user_end, description); + free_check_null(description); +/* + * Set use data to first read + */ + if (use.s_s_assemblage_in == FALSE) { + use.s_s_assemblage_in = TRUE; + use.n_s_s_assemblage_user = n_user; + } +/* + * Read solid solutions + */ + count_s_s = 0; + count_comps = 0; + return_value = UNKNOWN; + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + 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 SOLID_SOLUTIONS keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + +/* + * New component + */ + case 0: /* component */ + case 1: /* comp */ + count_comps=s_s_assemblage[n].s_s[number_s_s].count_comps++; + s_s_assemblage[n].s_s[number_s_s].comps = (struct s_s_comp *) PHRQ_realloc(s_s_assemblage[n].s_s[number_s_s].comps, (size_t) (count_comps+1) * sizeof(struct s_s_comp)); + if ( s_s_assemblage[n].s_s[number_s_s].comps == NULL) malloc_error(); + s_s_assemblage[n].s_s[number_s_s].comps[count_comps].initial_moles = 0; + s_s_assemblage[n].s_s[number_s_s].comps[count_comps].delta = 0; + /* + * Read phase name of component + */ + ptr = next_char; + copy_token(token, &ptr, &l); + s_s_assemblage[n].s_s[number_s_s].comps[count_comps].name = string_hsave(token); + /* + * Read moles of component + */ + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) { + s_s_assemblage[n].s_s[number_s_s].comps[count_comps].moles = NAN; + } else { + j=sscanf( token,SCANFORMAT, &dummy); + s_s_assemblage[n].s_s[number_s_s].comps[count_comps].moles = (LDBLE) dummy; + if (j != 1 ) { + error_msg("Expected moles of solid solution.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + break; + case 2: /* parms */ + case 3: /* gugg_nondimensional */ + /* + * Read parameters + */ + + ptr = next_char; + if (copy_token(token, &ptr, &l) != EMPTY) { + sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[0]) ); + } + if (copy_token(token, &ptr, &l) != EMPTY) { + sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[1]) ); + } + s_s_assemblage[n].s_s[number_s_s].input_case = 0; + break; + case 4: /* gugg_kj */ + ptr = next_char; + if (copy_token(token, &ptr, &l) != EMPTY) { + sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[0]) ); + } + if (copy_token(token, &ptr, &l) != EMPTY) { + sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[1]) ); + } + s_s_assemblage[n].s_s[number_s_s].input_case = 7; + break; + case 5: /* activity coefficients */ + ptr = next_char; + j = 0; + for (i = 0; i < 4; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 4) { + sprintf(error_string, "Expected 4 parameters to calculate a0 and a1 from two activity coefficients, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 1; + break; + case 6: /* distribution coefficients */ + ptr = next_char; + j = 0; + for (i = 0; i < 4; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 4) { + sprintf(error_string, "Expected 4 parameters to calculate a0 and a1 from two distribution coefficients, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 2; + break; + case 7: /* miscibility_gap */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected 2 miscibility gap fractions of component 2 to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 3; + break; + case 8: /* spinodal_gap */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected 2 spinodal gap fractions of component 2 to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 4; + break; + case 9: /* critical point */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected fraction of component 2 and critical temperature to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 5; + break; + case 10: /* alyotropic point */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected fraction of component 2 and sigma pi at alyotropic point to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 6; + break; + case 12: /* tempk */ + ptr = next_char; + j = 0; + if (copy_token(token, &ptr, &l) != EMPTY) { + j = sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].tk) ); + } + if (j != 1) { + sprintf(error_string, "Expected temperature (Kelvin) for parameters, assemblage %d, solid solution %s, using 298.15 K", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + warning_msg(error_string); + s_s_assemblage[n].s_s[number_s_s].tk = 298.15; + } + break; + case 11: /* temp */ + case 13: /* tempc */ + ptr = next_char; + j = 0; + if (copy_token(token, &ptr, &l) != EMPTY) { + j = sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].tk) ); + } + if (j != 1) { + sprintf(error_string, "Expected temperature (Celcius) for parameters, assemblage %d, solid solution %s, using 25 C", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + warning_msg(error_string); + s_s_assemblage[n].s_s[number_s_s].tk = 25.; + } + s_s_assemblage[n].s_s[number_s_s].tk += 273.15; + break; + case 14: /* Thompson and Waldbaum */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected Wg2 and Wg1 Thompson-Waldbaum parameters to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 8; + break; + case 15: /* Margules */ + ptr = next_char; + j = 0; + for (i = 0; i < 2; i++) { + if (copy_token(token, &ptr, &l) != EMPTY) { + j += sscanf( token,SCANFORMAT, &(s_s_assemblage[n].s_s[number_s_s].p[i]) ); + } + } + if (j != 2) { + sprintf(error_string, "Expected alpha2 and alpha3 Margules parameters to calculate a0 and a1, assemblage %d, solid solution %s", s_s_assemblage[n].n_user, s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + s_s_assemblage[n].s_s[number_s_s].input_case = 9; + break; + case 16: /* comp1 */ + if (count_comps < 2) { + s_s_assemblage[n].s_s[number_s_s].count_comps = 2; + count_comps = 2; + s_s_assemblage[n].s_s[number_s_s].comps = (struct s_s_comp *) PHRQ_realloc(s_s_assemblage[n].s_s[number_s_s].comps, (size_t) (count_comps) * sizeof(struct s_s_comp)); + if (s_s_assemblage[n].s_s[number_s_s].comps == NULL) malloc_error(); + } + /* + * Read phase name of component + */ + ptr = next_char; + copy_token(token, &ptr, &l); + s_s_assemblage[n].s_s[number_s_s].comps[0].name = string_hsave(token); + /* + * Read moles of component + */ + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) { + s_s_assemblage[n].s_s[number_s_s].comps[0].moles = NAN; + } else { + j=sscanf( token,SCANFORMAT, &dummy); + s_s_assemblage[n].s_s[number_s_s].comps[0].moles = (LDBLE) dummy; + if (j != 1 ) { + error_msg("Expected moles of solid solution.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + break; + case 17: /* comp2 */ + if (count_comps < 2) { + s_s_assemblage[n].s_s[number_s_s].count_comps = 2; + count_comps = 2; + s_s_assemblage[n].s_s[number_s_s].comps = (struct s_s_comp *) PHRQ_realloc(s_s_assemblage[n].s_s[number_s_s].comps, (size_t) (count_comps) * sizeof(struct s_s_comp)); + if (s_s_assemblage[n].s_s[number_s_s].comps == NULL) malloc_error(); + } + /* + * Read phase name of component + */ + ptr = next_char; + copy_token(token, &ptr, &l); + s_s_assemblage[n].s_s[number_s_s].comps[1].name = string_hsave(token); + /* + * Read moles of component + */ + if ( (j = copy_token(token, &ptr, &l)) == EMPTY) { + s_s_assemblage[n].s_s[number_s_s].comps[1].moles = NAN; + } else { + j=sscanf( token,SCANFORMAT, &dummy); + s_s_assemblage[n].s_s[number_s_s].comps[1].moles = (LDBLE) dummy; + if (j != 1 ) { + error_msg("Expected moles of solid solution.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + break; +/* + * New solid solution + */ + case OPTION_DEFAULT: + number_s_s = count_s_s++; + /* + * Make space, set default + */ + + /* realloc space for one s_s */ + s_s_assemblage[n].s_s = (struct s_s *) PHRQ_realloc(s_s_assemblage[n].s_s, (size_t) (count_s_s + 1) * sizeof(struct s_s)); + if (s_s_assemblage[n].s_s == NULL) malloc_error(); + + /* malloc space for one component */ + s_s_assemblage[n].s_s[number_s_s].comps = (struct s_s_comp *) PHRQ_malloc((size_t) sizeof(struct s_s_comp)); + if (s_s_assemblage[n].s_s[number_s_s].comps == NULL) malloc_error(); + count_comps = 0; + s_s_assemblage[n].s_s[number_s_s].count_comps = 0; + s_s_assemblage[n].s_s[number_s_s].input_case = 0; + s_s_assemblage[n].s_s[number_s_s].miscibility = FALSE; + s_s_assemblage[n].s_s[number_s_s].p[0] = 0.0; + s_s_assemblage[n].s_s[number_s_s].p[1] = 0.0; + s_s_assemblage[n].s_s[number_s_s].tk = 298.15; + /* + * Read solid solution name + */ + ptr = line; + copy_token(token, &ptr, &l); + s_s_assemblage[n].s_s[number_s_s].name = string_hsave(token); + s_s_assemblage[n].s_s[number_s_s].total_moles = NAN; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + for (i = 0; i < s_s_assemblage[n].count_s_s; i++) { + if (s_s_assemblage[n].s_s[i].p[0] != 0.0 || + s_s_assemblage[n].s_s[i].p[1] != 0.0) { + if (s_s_assemblage[n].s_s[number_s_s].count_comps != 2) { + sprintf(error_string, "Solid solution, %s, is nonideal. Must define exactly two components (-comp1 and -comp2).", s_s_assemblage[n].s_s[number_s_s].name); + error_msg(error_string, CONTINUE); + input_error++; + } + } + } +/* + * Sort components by name (lowercase) + */ + + s_s_assemblage[n].count_s_s = count_s_s; + qsort (s_s_assemblage[n].s_s, + (size_t) count_s_s, + (size_t) sizeof(struct s_s), + s_s_compare); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_llnl_aqueous_model_parameters(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads aqueous model parameters + * + * 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 + * + */ + extern int check_line_return; /* input.c */ + int i, count_alloc; + char token[MAX_LENGTH]; + + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "temperatures", /* 0 */ + "temperature", /* 1 */ + "temp", /* 2 */ + "adh", /* 3 */ + "debye_huckel_a", /* 4 */ + "dh_a", /* 5 */ + "bdh", /* 6 */ + "debye_huckel_b", /* 7 */ + "dh_b", /* 8 */ + "bdot", /* 9 */ + "b_dot", /* 10 */ + "c_co2", /* 11 */ + "co2_coefs" /* 12 */ + }; + int count_opt_list = 13; +/* + * Initialize + */ +/* + * Read aqueous model parameters + */ + return_value = UNKNOWN; + opt = get_option(opt_list, count_opt_list, &next_char); + for (;;) { + next_char = line; + if (opt >= 0) { + copy_token(token, &next_char , &i); + } + switch (opt) { + case OPTION_EOF: /* end of file */ + return_value = EOF; + break; + case OPTION_KEYWORD: /* keyword */ + return_value = KEYWORD; + break; + case OPTION_DEFAULT: + case OPTION_ERROR: + input_error++; + error_msg("Unknown input in LLNL_AQUEOUS_MODEL_PARAMETERS keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + +/* + * New component + */ + case 0: /* temperatures */ + case 1: /* temperature */ + case 2: /* temp */ + count_alloc = 1; + llnl_count_temp = 0; + i = read_lines_doubles(next_char, &(llnl_temp), &(llnl_count_temp), &(count_alloc), opt_list, count_opt_list, &opt); + /* + ptr = next_char; + llnl_temp = read_list_doubles(&ptr, &count); + llnl_count_temp = count; + */ + break; + case 3: /* adh */ + case 4: /* debye_huckel_a */ + case 5: /* dh_a */ + count_alloc = 1; + llnl_count_adh = 0; + i = read_lines_doubles(next_char, &(llnl_adh), &(llnl_count_adh), &(count_alloc), opt_list, count_opt_list, &opt); + /* + ptr = next_char; + llnl_adh = read_list_doubles(&ptr, &count); + llnl_count_adh = count; + */ + break; + case 6: /* bdh */ + case 7: /* debye_huckel_b */ + case 8: /* dh_b */ + count_alloc = 1; + llnl_count_bdh = 0; + i = read_lines_doubles(next_char, &(llnl_bdh), &(llnl_count_bdh), &(count_alloc), opt_list, count_opt_list, &opt); + /* + ptr = next_char; + llnl_bdh = read_list_doubles(&ptr, &count); + llnl_count_bdh = count; + */ + break; + case 9: /* bdot */ + case 10: /* b_dot */ + count_alloc = 1; + llnl_count_bdot = 0; + i = read_lines_doubles(next_char, &(llnl_bdot), &(llnl_count_bdot), &(count_alloc), opt_list, count_opt_list, &opt); + /* + ptr = next_char; + llnl_bdot = read_list_doubles(&ptr, &count); + llnl_count_bdot = count; + */ + break; + case 11: /* c_co2 */ + case 12: /* co2_coefs */ + count_alloc = 1; + llnl_count_co2_coefs = 0; + i = read_lines_doubles(next_char, &(llnl_co2_coefs), &(llnl_count_co2_coefs), &(count_alloc), opt_list, count_opt_list, &opt); + /* + ptr = next_char; + llnl_co2_coefs = read_list_doubles(&ptr, &count); + llnl_count_co2_coefs = count; + */ + break; + } + return_value = check_line_return; + if (return_value == EOF || return_value == KEYWORD) break; + } + /* check consistency */ + if ((llnl_count_temp <= 0) || + (llnl_count_temp != llnl_count_adh) || + (llnl_count_temp != llnl_count_bdh) || + (llnl_count_temp != llnl_count_bdot) ) { + error_msg("Must define equal number (>0) of temperatures, dh_a, dh_b, and bdot parameters\nin LLNL_AQUEOUS_MODEL", CONTINUE); + input_error++; + } + if (llnl_count_co2_coefs != 5) { + error_msg("Must define 5 CO2 activity coefficient parameters in LLNL_AQUEOUS_MODEL", CONTINUE); + input_error++; + } + for (i = 1; i < llnl_count_temp; i++) { + if (llnl_temp[i-1] > llnl_temp[i]) { + error_msg("Temperatures must be in ascending order in LLNL_AQUEOUS_MODEL", CONTINUE); + input_error++; + } + } + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_lines_doubles(char *next_char, LDBLE **d, int *count_d, int *count_alloc, const char **opt_list, int count_opt_list, int *opt) +/* ---------------------------------------------------------------------- */ + + { +/* + * Reads LDBLEs on line starting at next_char + * and on succeeding lines. Appends to d. + * Stops at KEYWORD, OPTION, and EOF + * + * Input Arguments: + * next_char points to line to read from + * d points to array of LDBLEs, must be malloced + * count_d number of elements in array + * count_alloc number of elements malloced + * + * Output Arguments: + * d points to array of LDBLEs, may have been + * realloced + * count_d updated number of elements in array + * count_alloc updated of elements malloced + * + * Returns: + * KEYWORD + * OPTION + * EOF + * ERROR if any errors reading LDBLEs + */ + + if (read_line_doubles(next_char, d, count_d, count_alloc) == ERROR) { + return(ERROR); + } + for(;;) { + *opt = get_option(opt_list, count_opt_list, &next_char); + if (*opt == OPTION_KEYWORD || *opt == OPTION_EOF || *opt ==OPTION_ERROR) { + break; + } else if (*opt >= 0) { + break; + } + next_char = line; + if (read_line_doubles(next_char, d, count_d, count_alloc) == ERROR) { + return(ERROR); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int read_line_doubles(char *next_char, LDBLE **d, int *count_d, int *count_alloc) +/* ---------------------------------------------------------------------- */ +{ + int i, j, l, n; + LDBLE value; + char token[MAX_LENGTH]; + + for (;;) { + j = copy_token(token, &next_char, &l); + if(j == EMPTY) { + break; + } + if (j != DIGIT) { + return(ERROR); + } + if (replace("*"," ",token) == TRUE) { + if (sscanf(token,"%d" SCANFORMAT, &n, &value) != 2) { + return(ERROR); + } + } else { + sscanf(token,SCANFORMAT, &value); + n = 1; + } + for (;;) { + if ((*count_d) + n > (*count_alloc)) { + *count_alloc *= 2; + *d = (LDBLE *) PHRQ_realloc(*d, (size_t) (*count_alloc) * sizeof(LDBLE)); + if (*d == NULL ) malloc_error(); + } else { + break; + } + } + for (i = 0; i < n; i++) { + (*d)[(*count_d) + i] = value; + } + *count_d += n; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int next_keyword_or_option(const char **opt_list, int count_opt_list) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads to next keyword or option or eof + * + * Returns: + * KEYWORD + * OPTION + * EOF + */ + int opt; + char *next_char; + + for(;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + if (opt == OPTION_EOF) { /* end of file */ + break; + } else if (opt == OPTION_KEYWORD) { /* keyword */ + break; + } else if (opt >= 0 && opt < count_opt_list) { + break; + } else { + error_msg("Expected a keyword or option.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + } + } + return(opt); +} +/* ---------------------------------------------------------------------- */ +int read_named_logk(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads K's that can be used to calculate K's for species + * + * 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 j, l; + int i, empty; + struct logk *logk_ptr; + char token[MAX_LENGTH]; + + int return_value, opt, opt_save; + char *next_char; + const char *opt_list[] = { + "log_k", /* 0 */ + "logk", /* 1 */ + "delta_h", /* 2 */ + "deltah", /* 3 */ + "analytical_expression", /* 4 */ + "a_e", /* 5 */ + "ae", /* 6 */ + "ln_alpha1000" /* 7 */ + }; + int count_opt_list = 8; + logk_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: /* log_k */ + case 1: /* logk */ + if (logk_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_log_k_only(next_char, &logk_ptr->log_k[0]); + opt_save = OPTION_DEFAULT; + break; + case 2: /* delta_h */ + case 3: /* deltah */ + if (logk_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_delta_h_only(next_char, &logk_ptr->log_k[1], &logk_ptr->original_units); + opt_save = OPTION_DEFAULT; + break; + case 4: /* analytical_expression */ + case 5: /* a_e */ + case 6: /* ae */ + if (logk_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + read_analytical_expression_only(next_char, &(logk_ptr->log_k[2])); + opt_save = OPTION_DEFAULT; + break; + case 7: /* ln_alpha1000 */ + if (logk_ptr == NULL) { + sprintf(error_string, "No reaction defined before option, %s.", opt_list[opt]); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + empty = TRUE; + for (i = 2; i < 7; i++) { + if (logk_ptr->log_k[i] != 0.0) { + empty = FALSE; + logk_ptr->log_k[i] = 0.0; + } + } + if (empty == FALSE) { + sprintf(error_string, "Analytical expression previously defined for %s in NAMED_EXPRESSIONS\nAnalytical expression will be overwritten.", logk_ptr->name); + warning_msg(error_string); + } + read_analytical_expression_only(next_char, &(logk_ptr->log_k[2])); + for (i = 2; i < 7; i++) { + logk_ptr->log_k[i] /= 1000.*LOG_10; + } + opt_save = OPTION_DEFAULT; + break; + case OPTION_DEFAULT: +/* + * Get space for logk information + */ + logk_ptr = NULL; + j = copy_token(token, &next_char, &l); + + logk_ptr = logk_store(token, TRUE); +/* + * Get pointer to each species in the reaction, store new species if necessary + */ + opt_save = OPTION_DEFAULT; + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_copy (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution, + * equilibrium_phases, + * exchange, + * surface, + * solid_solution, + * gas_phase, + * kinetics, + * mix, + * reaction, + * reaction_temperature + * + */ + int i, l, n, n_user, n_user_start, n_user_end, return_value; + char *ptr; + char token[MAX_LENGTH], token1[MAX_LENGTH];; +/* + * Read "copy" + */ + ptr = line; + copy_token (token, &ptr, &l); +/* + * Read keyword + */ + copy_token (token, &ptr, &l); + check_key (token); + switch (next_keyword) { + case -1: /* Have not read line with keyword */ + case 0: /* End encountered */ + case 1: /* EOF encountered */ + case 2: /* Read aqueous model */ + case 3: /* Read master species */ + case 5: + case 9: + case 10: + case 11: + case 12: + case 14: + case 15: + case 18: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 30: + case 31: + case 32: + case 34: + case 35: + case 38: + case 39: + input_error++; + error_msg("Expecting keyword solution, mix, kinetics, reaction, reaction_temperature, equilibrium_phases, exchange, surface, gas_phase, or solid_solutions.", CONTINUE); + error_msg(line_save, CONTINUE); + check_line("End of use",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(ERROR); + } +/* + * Read source index + */ + strcpy(token1, token); + i = copy_token (token, &ptr, &l); + if (i == DIGIT) { + sscanf(token,"%d",&n_user); + if (n_user < 0) { + error_msg("Source index number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + if (strstr(token,"-") != NULL) { + error_msg("COPY does not accept a range of numbers for source index", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + } else { + error_msg("Source index number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Read target index or range of indices + */ + i = copy_token (token, &ptr, &l); + if (i == DIGIT) { + replace("-"," ",token); + n = sscanf(token,"%d%d",&n_user_start, &n_user_end); + if (n == 1) { + n_user_end = n_user_start; + } + if (n_user_start < 0) { + error_msg("Target index number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + } else { + error_msg("Target index number must be a positive integer.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + + switch (next_keyword) { + case 4: /* Solution */ + copier_add(©_solution, n_user, n_user_start, n_user_end); + break; + case 6: /* Pure phases */ + case 26: + case 27: + case 28: + case 29: + copier_add(©_pp_assemblage, n_user, n_user_start, n_user_end); + break; + case 7: /* Reaction */ + copier_add(©_irrev, n_user, n_user_start, n_user_end); + break; + case 8: /* Mix */ + copier_add(©_mix, n_user, n_user_start, n_user_end); + break; + case 13: /* Ex */ + copier_add(©_exchange, n_user, n_user_start, n_user_end); + break; + case 16: /* Surface */ + copier_add(©_surface, n_user, n_user_start, n_user_end); + break; + case 17: /* Temperature */ + copier_add(©_temperature, n_user, n_user_start, n_user_end); + break; + case 19: /* Gas */ + copier_add(©_gas_phase, n_user, n_user_start, n_user_end); + break; + case 33: /* Kinetics */ + copier_add(©_kinetics, n_user, n_user_start, n_user_end); + break; + case 40: /* solid_solutions */ + case 41: /* solid_solution */ + copier_add(©_s_s_assemblage, n_user, n_user_start, n_user_end); + break; + } + return_value = check_line("End of COPY",FALSE,TRUE,TRUE,TRUE); + /* empty, eof, keyword, print */ + return(return_value); +} diff --git a/readtr.cpp b/readtr.cpp new file mode 100644 index 00000000..c29afb06 --- /dev/null +++ b/readtr.cpp @@ -0,0 +1,1121 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: readtr.c 430 2005-08-22 22:53:26Z dlpark $"; + +static int read_line_LDBLEs(char *next_char, LDBLE **d, int *count_d, int *count_alloc); + +#define OPTION_EOF -1 +#define OPTION_KEYWORD -2 +#define OPTION_ERROR -3 +#define OPTION_DEFAULT -4 +#define OPTION_DEFAULT2 -5 + +/* ---------------------------------------------------------------------- */ +int read_transport (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads advection and column information + * + * 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 + * + */ + char *ptr; + int i, j, l; + int old_cells, max; + int count_length, count_disp, count_punch, count_print; + int count_length_alloc, count_disp_alloc; + char token[MAX_LENGTH]; + char *description; + int n_user, n_user_end; + LDBLE *length, *disp; + int *punch_temp, *print_temp; + int return_value, opt, opt_save; + char *next_char, *next_char_save; + char file_name[MAX_LENGTH]; + + const char *opt_list[] = { + "cells", /* 0 */ + "shifts", /* 1 */ + "print", /* 2 */ + "selected_output", /* 3 */ + "bcond", /* 4 */ + "timest", /* 5 */ + "diffc", /* 6 */ + "tempr", /* 7 */ + "length", /* 8 */ + "disp", /* 9 */ + "punch", /* 10 */ + "stagnant", /* 11 */ + "bc", /* 12 */ + "boundary_conditions", /* 13 */ + "time_step", /* 14 */ + "temp_retardation_factor", /* 15 */ + "diffusion_coefficient", /* 16 */ + "dispersivity", /* 17 */ + "direction", /* 18 */ + "temperature_retardation_factor", /* 19 */ + "print_cells", /* 20 */ + "selected_cells", /* 21 */ + "flow_direction", /* 22 */ + "flow", /* 23 */ + "lengths", /* 24 */ + "dispersivities", /* 25 */ + "dump", /* 26 */ + "output", /* 27 */ + "output_frequency", /* 28 */ + "selected_output_frequency",/* 29 */ + "punch_cells", /* 30 */ + "dump_frequency", /* 31 */ + "dump_restart", /* 32 */ + "punch_frequency", /* 33 */ + "print_frequency", /* 34 */ + "correct_disp", /* 35 */ + "initial_time", /* 36 */ + "warning", /* 37 */ + "warnings", /* 38 */ + "thermal_diffusion" /* 39 */ + }; + int count_opt_list = 40; + if (svnid == NULL) fprintf(stderr," "); + + + strcpy(file_name, "phreeqc.dmp"); +/* + * Initialize + */ + simul_tr++; + if (simul_tr == 1) { + correct_disp = FALSE; + old_cells = 0; + } else { + old_cells = count_cells; + } + count_length = count_disp = count_punch = count_print = 0; + length = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (length == NULL) malloc_error(); + disp = (LDBLE *) PHRQ_malloc(sizeof(LDBLE)); + if (disp == NULL) malloc_error(); + punch_temp = (int *) PHRQ_malloc(sizeof(int)); + if (punch_temp == NULL) malloc_error(); + print_temp = (int *) PHRQ_malloc(sizeof(int)); + if (print_temp == NULL) malloc_error(); + count_length_alloc = count_disp_alloc = 1; + transport_start = 1; +/* + * Read transport number (not currently used) + */ + ptr=line; + read_number_description (ptr, &n_user, &n_user_end, &description); + description = (char *) free_check_null(description); +/* + * Set use data to last read + */ + use.trans_in = TRUE; + +/* + * Read lines + */ + 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: + case OPTION_DEFAULT: + input_error++; + error_msg("Unknown input in TRANSPORT keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* cells */ + sscanf(next_char, "%d", &count_cells); + opt_save = OPTION_DEFAULT; + break; + case 1: /* shifts */ + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &count_shifts); + } else { + warning_msg("Expected the number of shifts. One shift is assumed."); + count_shifts = 1; + } + j = copy_token(token, &next_char, &l); + if (j != EMPTY) { + if (j == DIGIT) { + sscanf(token, "%d", &ishift); + } else { + input_error++; + error_msg("Expected shift direction, -1, 0, 1. Use -direction instead.", CONTINUE); + ishift = 1; + } + } + opt_save = OPTION_DEFAULT; + break; + case 2: /* print */ + case 20: /* print_cells */ + print_temp = read_list_ints_range (&next_char, &count_print, TRUE, print_temp); +#ifdef SKIP + while (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &l); + print_temp = PHRQ_realloc(print_temp, (size_t) (count_print + 1) * sizeof(LDBLE)); + if (print_temp == NULL) malloc_error(); + print_temp[count_print] = l; + count_print++; + } +#endif + opt_save = 2; + break; + case 3: /* selected_output */ + case 29: /* selected_output_frequency */ + case 33: /* punch_frequency */ + sscanf(next_char, "%d", &punch_modulus); + opt_save = OPTION_DEFAULT; + break; + case 4: /* bcond */ + case 12: /* bc */ + case 13: /* boundary_conditions */ + /* first cell boundary condition */ + i = copy_token(token, &next_char, &l); + str_tolower(token); + if (i == DIGIT) { + sscanf(token, "%d", &bcon_first); + if (bcon_first < 1 || bcon_first > 3) { + input_error++; + error_msg("Expected boundary condition to be 'constant' (1), 'closed' (2) , or 'flux' (3).", CONTINUE); + } + } else if (i == EMPTY) { + bcon_first = 3; + } else if (strstr(token, "co") == token) { + bcon_first = 1; + } else if (strstr(token, "cl") == token) { + bcon_first = 2; + } else if (strstr(token, "f") == token) { + bcon_first = 3; + } else { + input_error++; + error_msg("Expected boundary condition to be 'constant', 'closed', or 'flux'.", CONTINUE); + } + + /* last cell boundary condition */ + i = copy_token(token, &next_char, &l); + str_tolower(token); + if (i == DIGIT) { + sscanf(token, "%d", &bcon_last); + if (bcon_last < 1 || bcon_last > 3) { + input_error++; + error_msg("Expected boundary condition to be 'constant' (1), 'closed' (2) , or 'flux' (3).", CONTINUE); + } + } else if (i == EMPTY) { + bcon_last = 3; + } else if (strstr(token, "co") == token) { + bcon_last = 1; + } else if (strstr(token, "cl") == token) { + bcon_last = 2; + } else if (strstr(token, "f") == token) { + bcon_last = 3; + } else { + input_error++; + error_msg("Expected boundary condition to be 'constant', 'closed', or 'flux'.", CONTINUE); + } + opt_save = OPTION_DEFAULT; + break; + case 5: /* timest */ + case 14: /* time_step */ + sscanf(next_char, SCANFORMAT, ×t); + opt_save = OPTION_DEFAULT; + break; + case 6: /* diffc */ + case 16: /* diffusion_coefficient */ + sscanf(next_char, SCANFORMAT, &diffc); + opt_save = OPTION_DEFAULT; + break; + case 7: /* tempr */ + case 15: /* temp_retardation_factor */ + case 19: /* temperature_retardation_factor */ + case 39: /* thermal_diffusion */ + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, SCANFORMAT, &tempr); + } + if (tempr < 1) { + tempr = 1; + warning_msg("Temperature retardation factor < 1 is not possible.\n" + "Temperature retardation factor = 1 assumed."); + } + j = copy_token(token, &next_char, &l); + if (j == DIGIT) { + sscanf(token, SCANFORMAT, &heat_diffc); + } + opt_save = OPTION_DEFAULT; + break; + case 8: /* length */ + case 24: /* lengths */ + if (read_line_LDBLEs(next_char, &length, &count_length, &count_length_alloc) == ERROR) { + input_error++; + error_msg("Reading lengths in TRANSPORT keyword.\n", CONTINUE); + } + opt_save = 8; + break; + case 9: /* disp */ + case 17: /* dispersivity */ + case 25: /* dispersivities */ + if (read_line_LDBLEs(next_char, &disp, &count_disp, &count_disp_alloc) == ERROR) { + input_error++; + error_msg("Reading dispersivities in TRANSPORT keyword.\n", CONTINUE); + } + opt_save = 9; + break; + case 10: /* punch */ + case 21: /* selected_cells */ + case 30: /* punch_cells */ + punch_temp = read_list_ints_range (&next_char, &count_punch, TRUE, punch_temp); +#ifdef SKIP + while (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &l); + punch_temp = PHRQ_realloc(punch_temp, (size_t) (count_punch + 1) * sizeof(LDBLE)); + if (punch_temp == NULL) malloc_error(); + punch_temp[count_punch] = l; + count_punch++; + } +#endif + opt_save = 10; + break; + case 11: /* stagnant */ +/* !!!!! sscanf(next_char, "%d", &count_stag); + */ + if (copy_token(token, &next_char, &l) != EMPTY) { + + /* exchange factor */ + if (sscanf(token, "%d", &(stag_data->count_stag)) != 1) { + input_error++; + sprintf(error_string,"Expecting number of stagnant layers."); + error_msg(error_string, CONTINUE); + break; + } + + /* exchange factor */ + j = copy_token(token, &next_char, &l); + if (j != EMPTY) { + if (sscanf(token, SCANFORMAT, &(stag_data->exch_f)) != 1) { + input_error++; + sprintf(error_string,"Expecting exchange factor for stagnant layers."); + error_msg(error_string, CONTINUE); + break; + } + copy_token(token, &next_char, &l); + if (sscanf(token, SCANFORMAT, &(stag_data->th_m)) != 1) { + input_error++; + sprintf(error_string,"Expecting porosity in the mobile zone."); + error_msg(error_string, CONTINUE); + break; + } + copy_token(token, &next_char, &l); + if (sscanf(token, SCANFORMAT, &(stag_data->th_im)) != 1) { + input_error++; + sprintf(error_string,"Expecting porosity in the immobile zone."); + error_msg(error_string, CONTINUE); + break; + } + } + } + opt_save = OPTION_DEFAULT; + break; + case 18: /* direction */ + case 22: /* flow_direction */ + case 23: /* flow */ + copy_token(token, &next_char, &l); + str_tolower(token); + if (strstr(token, "f") == token) { + ishift = 1; + } else if (strstr(token, "b") == token) { + ishift = -1; + } else if (strstr(token, "d") == token) { + ishift = 0; + } else if (strstr(token, "n") == token) { + ishift = 0; + } else { + input_error++; + error_msg("Expected flow direction to be 'forward', 'back', or 'no_flow'.", CONTINUE); + } + opt_save = OPTION_DEFAULT; + break; + case 26: /* dump */ + dump_in = TRUE; + next_char_save = next_char; + if (copy_token(file_name, &next_char, &l) == EMPTY) { + strcpy(file_name, "phreeqc.dmp"); + } else { + string_trim(next_char_save); + strcpy(file_name, next_char_save); + } +#ifdef SKIP + + /* Can not define dump_modulus an transport_start here */ + + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &dump_modulus); + } + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &transport_start); + } +#endif + opt_save = OPTION_DEFAULT; + break; + case 27: /* output */ + case 28: /* output_frequency */ + case 34: /* print_frequency */ + sscanf(next_char, "%d", &print_modulus); + opt_save = OPTION_DEFAULT; + break; + case 31: /* dump_frequency */ + dump_in = TRUE; + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &dump_modulus); + } else { + warning_msg("Expected integer value for dump_frequency."); + dump_modulus = 0; + } + opt_save = OPTION_DEFAULT; + break; + case 32: /* dump_restart */ + dump_in = TRUE; + if (copy_token(token, &next_char, &l) == DIGIT) { + sscanf(token, "%d", &transport_start); + } else { + warning_msg("Expected shift number to start calculations, 1 will be used."); + transport_start = 1; + } + opt_save = OPTION_DEFAULT; + break; + case 35: /* correct_dispersion */ + correct_disp = get_true_false(next_char, TRUE); + opt_save = OPTION_DEFAULT; + break; + case 36: /* initial_time */ + sscanf(next_char, SCANFORMAT, &initial_total_time); + opt_save = OPTION_DEFAULT; + break; + case 37: /* warning */ + case 38: /* warnings */ + transport_warnings = get_true_false(next_char, TRUE); + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* + * Determine number of cells + */ + max = count_cells; + if (count_length > max) max = count_length; + if (count_disp > max) max = count_disp; + if (max > count_cells) { + if (max == count_length) { + sprintf(token,"Number of cells is increased to number of 'lengths' %d.", count_length); + warning_msg(token); + } else { + sprintf(token,"Number of cells is increased to number of dispersivities %d.", count_disp); + warning_msg(token); + } + } +/* + * Allocate space for cell_data + */ + cell_data = (struct cell_data *)PHRQ_realloc(cell_data, (size_t)(max * (1 + stag_data->count_stag) + 1)*sizeof(struct cell_data)); + if (cell_data == NULL) malloc_error(); +/* + * Fill in data for lengths + */ + if (count_length == 0) { + if (old_cells < max) { + sprintf(error_string,"No cell-lengths were read; length = 1 m assumed."); + warning_msg(error_string); + for (i = 0; i < max; i++) cell_data[i].length = 1.0; + } + } else { + for (i = 0; i < count_length; i++) { + cell_data[i].length = length[i]; + } + if (max > count_length) { + sprintf(error_string,"Cell-lengths were read for %d cells. Last value is used till cell %d.", count_length, max); + warning_msg(error_string); + for (i = count_length - 1; i < max; i++) { + cell_data[i].length = length[count_length - 1]; + } + } + } + cell_data[0].mid_cell_x = cell_data[0].length / 2; + for (i = 1; i < max; i++) { + cell_data[i].mid_cell_x = cell_data[i-1].mid_cell_x + + (cell_data[i-1].length + cell_data[i].length)/2; + } + cell_data[max].mid_cell_x = cell_data[max-1].mid_cell_x + cell_data[max-1].length; +/* + * Fill in data for dispersivities + */ + if (count_disp == 0) { + if (old_cells < max) { + sprintf(error_string,"No dispersivities were read; disp = 0 assumed."); + warning_msg(error_string); + for (i = 0; i < max; i++) cell_data[i].disp = 0.0; + } + } else { + for (i = 0; i < count_disp; i++) { + cell_data[i].disp = disp[i]; + } + if (max > count_disp) { + sprintf(error_string,"Dispersivities were read for %d cells. Last value is used till cell %d.", count_disp, max); + warning_msg(error_string); + for (i = count_disp - 1; i < max; i++) { + cell_data[i].disp = disp[count_disp - 1]; + } + } + } + + count_cells = max; + +/* + * Account for stagnant cells + */ + if (stag_data->count_stag > 0) { + max = count_cells * (1 + stag_data->count_stag) + 1; + for (i = 0; i < count_cells; i++) { + for (l = 1; l <= stag_data->count_stag; l++) { + cell_data [ i+1+l*count_cells ] .mid_cell_x = cell_data[i].mid_cell_x; + } + } + } +/* + * Fill in data for punch + */ + if (count_punch != 0) { + for (i=0; i max || punch_temp[i] < 1) { + sprintf(error_string,"Cell number for punch is out of range, %d. Request ignored.", punch_temp[i]); + warning_msg(error_string); + } else { + cell_data[punch_temp[i]-1].punch = TRUE; + } + } + } else if (simul_tr == 1) { + for (i=0; i max || print_temp[i] < 1) { + sprintf(error_string,"Cell number for print is out of range, %d. Request ignored.", print_temp[i]); + warning_msg(error_string); + } else { + cell_data[print_temp[i]-1].print = TRUE; + } + } + } else if (simul_tr == 1) { + for (i=0; i count_shifts) { + input_error++; + sprintf(error_string,"Starting shift for transport, %d, is greater than number of shifts, %d.", transport_start, count_shifts); + error_msg(error_string, CONTINUE); + } + } +/* + * Check boundary conditions + */ + if ((ishift != 0) && ((bcon_first == 2) || (bcon_last == 2))) { + warning_msg("Boundary condition = 'closed' not possible with advective transport.\n\t Boundary condition = 'flux' assumed."); + if (bcon_first == 2) bcon_first =3; + if (bcon_last == 2) bcon_last =3; + } +/* + * Retain data from previous run + */ + if (simul_tr > 1) { + if ((count_length == 0) && (count_disp == 0)) { + dup_print("Column data retained from former run", TRUE); + } + } +/* + * Check heat_diffc + */ + if (heat_diffc < 0) { + heat_diffc = diffc; + } else if (stag_data->count_stag == 1) { + if (stag_data->exch_f > 0) { + if (diffc <= 0 && heat_diffc > 0) { + input_error++; + sprintf(error_string,"Must enter diffusion coefficient (-diffc) when modeling thermal diffusion."); + error_msg(error_string, CONTINUE); + } else if (heat_diffc > diffc) { + sprintf(error_string,"Thermal diffusion is calculated assuming exchange factor was for\n\t effective (non-thermal) diffusion coefficient = %e.", (double) diffc); + warning_msg(error_string); + } + } else { + if (heat_diffc > diffc) { + input_error++; + sprintf(error_string,"Must enter value for mobile/stagnant exchange factor when modeling thermal diffusion."); + error_msg(error_string, CONTINUE); + } + } + } else if (stag_data->count_stag > 1 && heat_diffc > diffc) { + input_error++; + sprintf(error_string,"Only one stagant layer permitted (-stag) when modeling thermal diffusion."); + error_msg(error_string, CONTINUE); + } + +/* + * free storage for length, disp, punch + */ + length = (LDBLE *) free_check_null(length); + disp = (LDBLE *) free_check_null(disp); + punch_temp = (int *) free_check_null(punch_temp); + print_temp = (int *) free_check_null(print_temp); + + if (dump_in == TRUE) { + if(output_open(OUTPUT_DUMP, file_name) != OK) { + sprintf(error_string, "Can't open file, %s.", file_name); + error_msg(error_string, CONTINUE); + input_error++; + } + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int read_line_LDBLEs(char *next_char, LDBLE **d, int *count_d, int *count_alloc) +/* ---------------------------------------------------------------------- */ +{ + int i, j, l, n; + LDBLE value; + char token[MAX_LENGTH]; + + for (;;) { + j = copy_token(token, &next_char, &l); + if(j == EMPTY) { + break; + } + if (j != DIGIT) { + return(ERROR); + } + if (replace("*"," ",token) == TRUE) { + if (sscanf(token,"%d" SCANFORMAT, &n, &value) != 2) { + return(ERROR); + } + } else { + sscanf(token,SCANFORMAT, &value); + n = 1; + } + for (;;) { + if ((*count_d) + n > (*count_alloc)) { + *count_alloc *= 2; + *d = (LDBLE *) PHRQ_realloc(*d, (size_t) (*count_alloc) * sizeof(LDBLE)); + if (*d == NULL ) malloc_error(); + } else { + break; + } + } + for (i = 0; i < n; i++) { + (*d)[(*count_d) + i] = value; + } + *count_d += n; + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int dump(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * dumps solution compositions to file + */ + + int i, j, k, l; + + if (dump_in == FALSE || pr.dump == FALSE) return(OK); + output_rewind(OUTPUT_DUMP); + output_msg(OUTPUT_DUMP, "# Dumpfile\n# Transport simulation %d. Shift %d.\n#\n", simul_tr, transport_step); + + for (k = 0; k <= 1 + (1 + stag_data->count_stag) * count_cells; k++) { + dump_reaction(k); + dump_kinetics(k); + output_msg(OUTPUT_DUMP, "END\n"); + dump_solution(k); + dump_pp_assemblage(k); + dump_exchange(k); + dump_surface(k); + dump_gas_phase(k); + dump_s_s_assemblage(k); + output_msg(OUTPUT_DUMP, "END\n"); + } + + output_msg(OUTPUT_DUMP, "KNOBS\n"); + output_msg(OUTPUT_DUMP, "\t-iter%15d\n", itmax); + output_msg(OUTPUT_DUMP, "\t-tol %15.3e\n", (double) ineq_tol); + output_msg(OUTPUT_DUMP, "\t-step%15.3e\n", (double) step_size); + output_msg(OUTPUT_DUMP, "\t-pe_s%15.3e\n", (double) pe_step_size); + output_msg(OUTPUT_DUMP, "\t-diag "); + if (diagonal_scale == TRUE) output_msg(OUTPUT_DUMP, "true\n"); + else output_msg(OUTPUT_DUMP, "false\n"); + + output_msg(OUTPUT_DUMP, "SELECTED_OUTPUT\n"); + output_msg(OUTPUT_DUMP, "\t-file %-15s\n", "sel_o$$$.prn"); + if (punch.count_totals != 0) { + output_msg(OUTPUT_DUMP, "\t-tot "); + for (i = 0; i < punch.count_totals; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.totals[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_molalities != 0) { + output_msg(OUTPUT_DUMP, "\t-mol "); + for (i = 0; i < punch.count_molalities; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.molalities[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_activities != 0) { + output_msg(OUTPUT_DUMP, "\t-act "); + for (i = 0; i < punch.count_activities; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.activities[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_pure_phases != 0) { + output_msg(OUTPUT_DUMP, "\t-equ "); + for (i = 0; i < punch.count_pure_phases; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.pure_phases[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_si != 0) { + output_msg(OUTPUT_DUMP, "\t-si "); + for (i = 0; i < punch.count_si; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.si[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_gases != 0) { + output_msg(OUTPUT_DUMP, "\t-gas "); + for (i = 0; i < punch.count_gases; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.gases[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_s_s != 0) { + output_msg(OUTPUT_DUMP, "\t-solid_solutions "); + for (i = 0; i < punch.count_s_s; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.s_s[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + if (punch.count_kinetics != 0) { + output_msg(OUTPUT_DUMP, "\t-kin "); + for (i = 0; i < punch.count_kinetics; i++) { + output_msg(OUTPUT_DUMP, " %s", punch.kinetics[i].name); + } + output_msg(OUTPUT_DUMP, "\n"); + } + output_msg(OUTPUT_DUMP, "TRANSPORT\n"); + output_msg(OUTPUT_DUMP, "\t-cells %6d\n", count_cells); + output_msg(OUTPUT_DUMP, "\t-shifts%6d%6d\n", count_shifts, ishift); + output_msg(OUTPUT_DUMP, "\t-output_frequency %6d\n", print_modulus); + output_msg(OUTPUT_DUMP, "\t-selected_output_frequency %6d\n", punch_modulus); + output_msg(OUTPUT_DUMP, "\t-bcon %6d%6d\n", bcon_first, bcon_last); + output_msg(OUTPUT_DUMP, "\t-timest %13.5e\n", (double) timest); + output_msg(OUTPUT_DUMP, "\t-diffc %13.5e\n", (double) diffc); + output_msg(OUTPUT_DUMP, "\t-tempr %13.5e\n", (double) tempr); + if (correct_disp == TRUE) { + output_msg(OUTPUT_DUMP, "\t-correct_disp %s\n", "True"); + } else { + output_msg(OUTPUT_DUMP, "\t-correct_disp %s\n", "False"); + } + output_msg(OUTPUT_DUMP, "\t-length\n"); + for (i = 0; i < count_cells; i++) { + output_msg(OUTPUT_DUMP, "%12.3e", (double) cell_data[i].length); + if (i > 0 && (i % 8 ) == 0) output_msg(OUTPUT_DUMP, "\n"); + } + output_msg(OUTPUT_DUMP, "\n"); + output_msg(OUTPUT_DUMP, "\t-disp\n"); + for (i = 0; i < count_cells; i++) { + output_msg(OUTPUT_DUMP, "%12.3e", (double) cell_data[i].disp); + if (i > 0 && (i % 8 ) == 0) output_msg(OUTPUT_DUMP, "\n"); + } + output_msg(OUTPUT_DUMP, "\n"); + output_msg(OUTPUT_DUMP, "\t-punch_cells"); + if (stag_data->count_stag > 0) j = 1 + (1 + stag_data->count_stag) * count_cells; + else j = count_cells; + l = 0; + for (i = 0; i < j; i++) { + if (cell_data[i].punch != TRUE) continue; + output_msg(OUTPUT_DUMP, " %d", i+1); + l++; + if ((l % 20) == 0) output_msg(OUTPUT_DUMP, "\n"); + } + output_msg(OUTPUT_DUMP, "\n"); + output_msg(OUTPUT_DUMP, "\t-print_cells"); + if (stag_data->count_stag > 0) j = 1 + (1 + stag_data->count_stag) * count_cells; + else j = count_cells; + l = 0; + for (i = 0; i < j; i++) { + if (cell_data[i].print != TRUE) continue; + output_msg(OUTPUT_DUMP, " %d", i+1); + l++; + if ((l % 20) == 0) output_msg(OUTPUT_DUMP, "\n"); + } + output_msg(OUTPUT_DUMP, "\n"); + output_msg(OUTPUT_DUMP, "\t-dump $$$.dmp\n"); + output_msg(OUTPUT_DUMP, "\t-dump_frequency %d\n", dump_modulus); + output_msg(OUTPUT_DUMP, "\t-dump_restart %d\n", transport_step + 1); + + output_msg(OUTPUT_DUMP, "END\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_exchange(int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print moles of each exchange species + */ + int i, j, n; + struct exchange *exchange_ptr; + + exchange_ptr = exchange_bsearch(k, &n); + if ( exchange_ptr == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "EXCHANGE %d\n", k); +#ifdef SKIP + for (i = 0; i < exchange[n].count_comps; i++) { + output_msg(OUTPUT_DUMP, "\t%-15s", exchange[n].comps[i].formula); + if (exchange[n].comps[i].phase_name != NULL) { + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e\n", + exchange[n].comps[i].phase_name, + exchange[n].comps[i].phase_proportion); + } else { + for (j = 0; exchange[n].comps[i].totals[j].elt != NULL; j++) { + if (strcmp(exchange_ptr->comps[i].totals[j].elt->name, exchange[n].comps[i].formula) == NULL) { + output_msg(OUTPUT_DUMP, "%15.6e\n", exchange[n].comps[i].totals[j].coef); + } + } + } + } +#endif + for (i = 0; i < exchange[n].count_comps; i++) { + if (exchange[n].comps[i].phase_name != NULL) { + output_msg(OUTPUT_DUMP, "\t%-15s", exchange[n].comps[i].formula); + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e\n", + exchange[n].comps[i].phase_name, + (double) exchange[n].comps[i].phase_proportion); + } else { + for (j = 0; exchange[n].comps[i].totals[j].elt != NULL; j++) { +/* if (exchange_ptr->comps[i].totals[j].elt->master->type != EX) continue; */ + output_msg(OUTPUT_DUMP, "\t%-15s", exchange[n].comps[i].totals[j].elt->name); + output_msg(OUTPUT_DUMP, "%15.6e", (double) exchange[n].comps[i].totals[j].coef); + + if (exchange[n].comps[i].rate_name != NULL) { + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e", exchange[n].comps[i].rate_name, (double) exchange[n].comps[i].phase_proportion); + } +#ifdef SKIP + for (l = 0; l < count_kin_exch; l++) { + if (strcmp_nocase(kin_exch[l].exch_name, exchange[n].comps[i].totals[j].elt->name) != 0) continue; + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e", kin_exch[l].phase_name, kin_exch[l].phase_proportion); + } +#endif + output_msg(OUTPUT_DUMP, "\n"); + } + } + } + output_msg(OUTPUT_DUMP, "\t-equil %d\n", k); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_pp_assemblage(int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints saturation indices and masses of pure_phases in pp_assemblage + */ + int j, n; + + if (pp_assemblage_search(k, &n) == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "EQUILIBRIUM_PHASES %d\n", k); + for (j = 0; j < pp_assemblage[n].count_comps; j++) { + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e", + pp_assemblage[n].pure_phases[j].name, + (double) pp_assemblage[n].pure_phases[j].si); + + if (pp_assemblage[n].pure_phases[j].add_formula == NULL) { + output_msg(OUTPUT_DUMP, "%15.6e", + (double) pp_assemblage[n].pure_phases[j].moles); + } else { + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e", + pp_assemblage[n].pure_phases[j].add_formula, + (double) pp_assemblage[n].pure_phases[j].moles); + } + output_msg(OUTPUT_DUMP, "\n"); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_reaction (int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps reaction data + */ + int i; + struct irrev *irrev_ptr; + + if ((irrev_ptr = irrev_search(k, &i)) == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "REACTION %d\n", k); + for (i = 0; i < irrev_ptr->count_list; i++) { + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e\n", + irrev_ptr->list[i].name, + (double) irrev_ptr->list[i].coef); + } + if (irrev_ptr->count_steps >= 1) { + for (i = 0; i < irrev_ptr->count_steps; i++) + output_msg(OUTPUT_DUMP, "%15.6e", (double) irrev_ptr->steps[i]); + } else { + output_msg(OUTPUT_DUMP, "\t%15.6e in %d step", + (double) irrev_ptr->steps[0], + - irrev_ptr->count_steps); + } + output_msg(OUTPUT_DUMP, "\n"); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_surface(int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Print moles of each surface master species + */ + int i, j, l, n; + struct surface *surface_ptr; + + if ((surface_ptr = surface_bsearch(k, &n)) == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "SURFACE %d\n", k); + for (i = 0; i < surface[n].count_comps; i++) { + for (j = 0; surface[n].comps[i].totals[j].elt != NULL; j++) { + if (surface_ptr->comps[i].totals[j].elt->master->type != SURF) continue; + output_msg(OUTPUT_DUMP, "\t%-13s", surface[n].comps[i].totals[j].elt->name); + + if (surface[n].comps[i].phase_name != NULL) { + output_msg(OUTPUT_DUMP, "\t%-13s equi %13.5e", + surface[n].comps[i].phase_name, + (double) surface[n].comps[i].phase_proportion); + } else if (surface[n].comps[i].rate_name != NULL) { + output_msg(OUTPUT_DUMP, "\t%-13s kine %13.5e", + surface[n].comps[i].rate_name, + (double) surface[n].comps[i].phase_proportion); + } else { + output_msg(OUTPUT_DUMP, "\t%13.5e", (double) surface[n].comps[i].totals[j].coef); +#ifdef SKIP + for (l = 0; l < count_kin_surf; l++) { + if (strcmp_nocase(kin_surf[l].surf_name, surface[n].comps[i].totals[j].elt->name) != 0) continue; + output_msg(OUTPUT_DUMP, "\t%-13s %13.5e", kin_surf[l].phase_name, kin_surf[l].phase_proportion); + } +#endif + } + if (surface[n].edl == TRUE) { + l = surface[n].comps[i].charge; + output_msg(OUTPUT_DUMP, " %13.5e", (double) surface[n].charge[l].specific_area); + if (surface[n].comps[i].phase_name == NULL && surface[n].comps[i].rate_name == NULL) { + output_msg(OUTPUT_DUMP, " %13.5e\n", (double) surface[n].charge[l].grams); + } else output_msg(OUTPUT_DUMP, "\n"); + } else output_msg(OUTPUT_DUMP, "\n"); + } + } + if (surface[n].diffuse_layer == TRUE) { + output_msg(OUTPUT_DUMP, "\t-diffuse\t%13.5e\n", (double) surface[n].thickness); + } else if (surface[n].edl == FALSE) { + output_msg(OUTPUT_DUMP, "\t-no_edl\n"); + } + + + output_msg(OUTPUT_DUMP, "\t-equil %d\n", k); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_gas_phase(int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps gas phase data + */ + int i, n; + LDBLE lp; + struct rxn_token *rxn_ptr; + struct gas_phase *gas_phase_ptr; + + if ((gas_phase_ptr = gas_phase_bsearch(k, &n)) == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "GAS_PHASE %d\n", k); + output_msg(OUTPUT_DUMP, "\t-pressure%15.6e\n", (double) gas_phase[n].total_p); + output_msg(OUTPUT_DUMP, "\t-volume%15.6e\n", (double) gas_phase[n].volume); + output_msg(OUTPUT_DUMP, "\t-temperature%15.6e\n", (double) gas_phase[n].temperature); + for (i = 0; i < gas_phase[n].count_comps; i++) { +/* + * Calculate partial pressure + */ + lp=-gas_phase_ptr->comps[i].phase->lk; + if (use.gas_phase_ptr->comps[i].phase->rxn_x != NULL) { + for (rxn_ptr = use.gas_phase_ptr->comps[i].phase->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { + lp += rxn_ptr->s->la * rxn_ptr->coef; + } + } else { + lp = -99.9; + } + output_msg(OUTPUT_DUMP, "\t%-15s%15.6e\n", + gas_phase[n].comps[i].name, + (double) lp); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_s_s_assemblage(int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps solid solution data + */ + int i, j, n; + struct s_s_assemblage *s_s_assemblage_ptr; + + s_s_assemblage_ptr = s_s_assemblage_bsearch(k, &n); + if (s_s_assemblage_ptr == NULL) return(OK); + + output_msg(OUTPUT_DUMP, "SOLID_SOLUTIONS %d\n", k); + for (i = 0; i < s_s_assemblage[n].count_s_s; i++) { + output_msg(OUTPUT_DUMP, "\t%-15s\n", s_s_assemblage[n].s_s[i].name); + for (j = 0; j < s_s_assemblage[n].s_s[i].count_comps; j++) { + output_msg(OUTPUT_DUMP, "\t\t-comp\t%-15s%15.6e\n", + s_s_assemblage[n].s_s[i].comps[j].name, + (double) s_s_assemblage[n].s_s[i].comps[j].moles); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_kinetics (int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps kinetics data + */ + int i, j, n; + struct kinetics *kinetics_ptr; + struct kinetics_comp *kinetics_comp_ptr; + + if ((kinetics_ptr = kinetics_search(k, &n, FALSE)) == NULL) return(OK); + output_msg(OUTPUT_DUMP, "KINETICS %d\n", k); + for (i = 0; i < kinetics[n].count_comps; i++) { + output_msg(OUTPUT_DUMP, "%-15s\n", kinetics_ptr->comps[i].rate_name); + + kinetics_comp_ptr = &kinetics_ptr->comps[i]; + output_msg(OUTPUT_DUMP, "\t-formula "); + for (j = 0; j < kinetics_comp_ptr->count_list; j++) { + output_msg(OUTPUT_DUMP, " %s %12.3e", kinetics_comp_ptr->list[j].name, (double) kinetics_comp_ptr->list[j].coef); + } + output_msg(OUTPUT_DUMP, "\n"); + + output_msg(OUTPUT_DUMP, "\t-tol %15.2e\n", (double) kinetics_ptr->comps[i].tol); + output_msg(OUTPUT_DUMP, "\t-m0 %15.6e\n", (double) kinetics_ptr->comps[i].m0); + output_msg(OUTPUT_DUMP, "\t-m %15.6e\n", (double) kinetics_ptr->comps[i].m); + + if (kinetics_comp_ptr->count_d_params != 0) { + output_msg(OUTPUT_DUMP, "\t-parm"); + for (j = 0; j < kinetics_comp_ptr->count_d_params; j++) { + output_msg(OUTPUT_DUMP, "%15.6e", (double) kinetics_comp_ptr->d_params[j]); + } + output_msg(OUTPUT_DUMP, "\n"); + } + +/* not dumped: kinetics_comp_ptr->count_c_params = 0 */ + } + output_msg(OUTPUT_DUMP, "\t-step_divide %15.6e\n", (double) kinetics[n].step_divide); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_solution (int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps solution data + */ + int i, j; + struct solution *solution_ptr; + + solution_ptr = solution_bsearch(k, &j, TRUE); + if (solution_ptr != NULL) { + output_msg(OUTPUT_DUMP, "SOLUTION %d\n", k); + output_msg(OUTPUT_DUMP, "\tunits mol/kgw\n"); + output_msg(OUTPUT_DUMP, "\ttemp %5.1f\n", (double) solution_ptr->tc); + output_msg(OUTPUT_DUMP, "\tpH %9.5f\n", (double) solution_ptr->ph); + output_msg(OUTPUT_DUMP, "\tpe %9.5f\n", (double) solution_ptr->solution_pe); + output_msg(OUTPUT_DUMP, "\twater %9.5f\n", (double) solution_ptr->mass_water); + for (i = 0; solution_ptr->totals[i].description != NULL; i++) { + /* + * write out totals... + */ + output_msg(OUTPUT_DUMP, "\t%-6s", solution_ptr->totals[i].description); + output_msg(OUTPUT_DUMP, " %13.5e\n", (double) (solution_ptr->totals[i].moles/solution_ptr->mass_water)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int dump_mix (int k) +/* ---------------------------------------------------------------------- */ +{ +/* + * Dumps solution data + */ + int j; + struct mix *mix_ptr; + + mix_ptr = mix_bsearch(k, &j); + if (mix_ptr == NULL) return(ERROR); + for (j = 0; j < mix_ptr->count_comps; j++) { + dump_solution(mix_ptr->comps[j].n_solution); + } + output_msg(OUTPUT_DUMP, "MIX %d\n", k); + for (j = 0; j < mix_ptr->count_comps; j++) { + output_msg(OUTPUT_DUMP, "\t5%d\t%13.5e\n", mix_ptr->comps[j].n_solution, (double) mix_ptr->comps[j].fraction); + } + return(OK); +} diff --git a/revisions b/revisions new file mode 100644 index 00000000..821702ef --- /dev/null +++ b/revisions @@ -0,0 +1,1401 @@ +------------------------------------------------------------ +Features not documented in WRIR 99-4259. +------------------------------------------------------------ + + svn 675: + Added PRINT option to print the species that contribute + to alkalinity. Alkalinity distribution is printed in + the output file following the distribution of species. + Default at program startup is false. + + PRINT + -alkalinity true + +------------------------------------------------------------ +Version 2.12: +------------------------------------------------------------ + +* Made aqueous activity coefficients the default activity + coefficients for exchange species when using the + Pitzer formulation. New option in EXCHANGE is + -pitzer_exchange_gammas T/F, default is true; + defining "false" sets exchange activity coefficients + to 1.0. Option has no effect for ion-association + model (non-Pitzer). + + +* Added multiplier format to REACTION steps and KINETICS steps, + which simplifies definition of multiple equal reaction increments. + + This definition: + + INCREMENTAL_REACTIONS true + REACTION + H2O 1 + -36 3*-4 2*-.25 -0.19 4*-0.1 3*-0.05 moles + + is equivalent to this definition: + + INCREMENTAL_REACTIONS true + REACTION + H2O 1 + -36 -4 -4 -4 -.25 -.25 -0.19 -0.1 -0.1 -0.1 + -0.1 -0.05 -0.05 -0.05 moles + + + +* Added Pitzer activity formulation. Use pitzer.dat database + to invoke the Pitzer model. Should have same capabilities + as ion-association model except explicit diffuse layer + calculation is not implemented with the Pitzer model. + New keyword is PITZER with following options: + + PITZER + -MacInnes T/F # uses MacInnes assumption or unscaled for + # individual activities and activity coefficients + -B0 + Na+ Cl- 0.0765 -777.03 -4.4706 0.008946 -3.3158E-6 + -B1 + Na+ Cl- 0.2664 0 0 6.1608E-5 1.0715E-6 + -B2 + Mg+2 SO4-2 -37.23 0 0 -0.253 + -C0 + Na+ Cl- 0.00127 33.317 0.09421 -4.655E-5 + -THETA + K+ Na+ -0.012 + -LAMDA + Na+ CO2 0.1 + -ZETA + H+ Cl- B(OH)3 -0.0102 + -PSI + Na+ K+ Cl- -0.0018 + + A five-term expression for temperature dependence is available + for all Pitzer parameter values: + P = A0 + A1*(1/TK - 1/TR) + A2log(TK/TR) + A3/(TK-TR) + + A4*(TK*TK - TR*TR), + where TK is Kelvin and TR is 298.15. + +* Cl1mp is a new multiple precision version of routine cl1, + a simplex-based optimization routine. Cl1mp was develeped + by using the Gnu Multiple Precision package (gmp). + Calculations are carried out to about 30 significant + digits. Cl1mp may help in some situations where roundoff + errors are a problem, but it is still possible that roundoff + errors will cause cl1mp to fail to find a solution to an + optimization problem. The mp version has the following + options in INVERSE_MODELING: + + -multiple_precision T/F--causes the mp version + to be used in inverse modeling calculations. + -mp_tolerance 1e-12--tolerance for mp version of + cl1. As in cl1, numbers less than the + tolerance are considered to be zero. + 1e-12 is the default. + -censor_mp 1e-20--as calculations occur in the + linear equation array, elements less + than this value are set to zero. Default + is 1e-20. A value of 0.0 causes no + censoring to occur. + +------------------------------------------------------------ +Version 2.11: +------------------------------------------------------------ + +* A new database, minteq.v4.dat, has been translated from + version 4.02 of MINTEQA2 and is included in all + distributions. The database minteq.dat from earlier + version of MINTEQA2 has been slightly revised and is + also included. + +------------------------------------------------------------ +Version 2.10: +------------------------------------------------------------ + + No new features. + +------------------------------------------------------------ +Version 2.9: +------------------------------------------------------------ +* Added new keyword COPY that allows a data entity + to be copied from one index to a new index + or to a range of indicies. Format is + + COPY keyword index index_start[-index_end] + + where keyword may be SOLUTION + EQUILIBRIUM_PHASES + EXCHANGE + GAS_PHASE + KINETICS + MIX + REACTION + REACTION_TEMPERATURE + SOLID_SOLUTION + SURFACE + +* Added new Basic functions + b$ = PAD(a$, 20) pads a$ to a total of 20 characters + with spaces and stores result in b$. PAD returns + a copy of a$ if a$ is more than 20 characters. + i = INSTR(a$, b$) sets i to the character position of + string b$ in a$, 0 in not found. + b$ = LTRIM(a$) trims white space from beginning of + string a$ and stores result in b$. + b$ = RTRIM(a$) trims white space from end of string + a$ and stores result in b$. + b$ = TRIM(a$) trims white space from beginning and + end of string a$ and stores result in b$. + + +* Added new Basic function SYS that calculates the to + total amount of an element in all phases (solution, + equilibrium_phases, surfaces, exchangers, solid solutions, + and gas phase). KINETIC reactions are not included. + The function has two forms: (1) one element name as an + argument (variable names are user specified) + + 10 t = SYS("As") + + the function will return the total arsenic in the system. + (2) 5 argumens + + 10 t = SYS("As", count_species, names$, types$, moles) + + will return the total arsenic in the system to tot; count_species-- + the number of species that contain arsenic, including + solution, equilibrium_phases, surfaces, exchangers, solid solutions, + and gas phase species; names$--a character array that has the + name of each species; type$--a character array that specifies the + type of phase for the species, aq, equi, surf, ex, s_s, gas, diff. + Diff refers to the amount of the element in the diffuse layer of + a surface when the explicit diffuse layer calculation is used; + moles--an array containing the number of moles of the element in + the species. The sum of moles(i) is equal to tot. + + SYS has several special arguments for the form + SYS("arg", count, names$, types$, values) + arg is one of the options listed below. + count is a single numeric value and is the number of elements + in the following arrays. + name$ is an array of string values. + type$ is an array of string values. + values is an array of numeric values. + + Values of arg: + + elt_name returns total number of moles of element in system. + count is the number of species for the element in + the system, including aqueous, exchange, surface, + equilibrium_phase, solid solution component, and + gas phase "species". + Arrays are filled for each "species"; values are moles. + "elements" returns total number of moles of dissolved elements other + than H and O. + count is number of elements, valence states, + exchangers, and surfaces. + Arrays are filled for each element and valence state, + type is "dis"; exchanger, type is "ex", + and surface, type is "surf". Values are moles. + "phases" returns maximum saturation index of all phases. + count is number of phases in system. + Arrays are filled for each phase; values are + saturation indexes. + "aq" returns sum of moles of all aqueous species. + count is number of aqueous species in system. + Arrays are filled with each aqueous species; + values are moles. + "ex" returns sum of moles of all exchange species. + count is number of exchange species in system. + Arrays are filled with each exchange species; + values are moles. + "surf" returns sum of moles of all surface species. + count is number of surface species in system. + Arrays are filled with each surface species; + values are moles. + "s_s" returns sum of moles of all solid solution components. + count is number of solid solution components in system. + Arrays are filled with each solid solution component; + values are moles. + "gas" returns sum of moles of all gas components. + count is number of gas components in system. + Arrays are filled with each gas component; + values are moles. + +* Added new Basic function, DESCRIPTION, that has the value + defined for the description field of the SOLUTION keyword line. + +* Added alternative ordinary differential equation solver + called CVODE, a set of C routines from the Lawrence + Livermore National Labs. CVODE is part of the SUNDIALS + package. CVODE is used in place of the Runge Kutta method + when "-cvode true" is used within a KINETICS data block. + + KINETICS + -cvode true + +------------------------------------------------------------ +Version 2.8: +------------------------------------------------------------ + + No new features. + +------------------------------------------------------------ +Version 2.7: +------------------------------------------------------------ +Changed format of selected output file: + Removed quotations surrounding strings in headings. + Removed quotations surrounding strings in state variable. + All fields are 12 or 20 places depending on + -high_precision. + Headings are not truncated even if longer than + specified precision. + For isotopes, missing value is -9999.9 + Selected output is updated each simulation. + If a species or phase is defined + subsequent to the simulation where SELECTED_OUTPUT + was defined it will appear in the selected output + file in the simulation in which it is defined and + in subsequent simulations. + +Added strings for each file, which can be extracted from the + executable file with the "ident" command. + +Fixed null pointer for isotope_ratios if Basic routine + was undefined. + +Fixed problem in C++ if structure name is same as member name. + logk member of logk structure was renamed to log_k. + +Added identifier -add_constant to PHASES, EXCHANGE_SPECIES, + SOLUTION_SPECIES, and SURFACE_SPECIES. + + -add_constant -0.301 + + log K is augmented by the specified constant. + + +Theory and implementation of isotopes in PHREEQC is documented in: + +Thorstenson, D.C., and Parkhurst, D.L., 2002, Calculation of +individual isotope equilibrium constants for implementation in +geochemical models: U.S. Geological Survey Water-Resources +Investigations Report 02-4172, 129 p. + +Added KEYWORDS: + +ISOTOPES + Element + -isotope isotope_name units standard_ratio + -total_is_major T/F (OPTION IS DISABLED!!) + +CALCULATE_VALUES + Name + -start + Basic statements, must have SAVE + -end + +ISOTOPE_RATIOS (for printing) + Name=Calculate_values_name Isotope_name + +ISOTOPE_ALPHAS (for printing) + Name=Calculate_values_name Named_logk=named_expression_name + +Basic functions: + calc_value("calc_value_name") evaluates a definition of CALCULATE_VALUES + lk_named("name") log10(K) of definition in NAMED_EXPRESSIONS + lk_phase("name") log10(K) of definition in PHASES + lk_species("name") log10(K) of definition in (SOLUTION, EXCHANGE, SURFACE)_SPECIES + sum_gas("template","element") Sum of element in gases with specified template + template="{C,[13C],[14C]}{O,[18O]}2" includes all CO2 gases + sum_species("template","element") Sum of element in aqueous, exchange, and surface species with + specified template + sum_s_s("s_s_name","element") Sum of element in a specified solid solution + +PRINT keyword: + -initial_isotopes T/F + -isotope_ratios T/F + -isotope_alphas T/F + -censor_species 1e-8 # omit species from Distribution of Species if less than + # relative minimum of an element or element redox state + # total concentration + +SELECTED_OUTPUT keyword: + -calculate_values name1 name2 ... + -isotopes minor_isotope1 minor_isotope2 .... + +Added functions LK_SPECIES, LK_NAMED, LK_PHASE for Basic + interpreter. LK_SPECIES("CaHCO3+") returns the + log k for the association reaction for the ion pair + CaHCO3+ at the current temperature. The log K is + for the reaction as defined in the database or + input file. Similarly, + LK_NAMED("Log_alpha_18O_CO2(aq)/CO2(g)") returns the + value for the log K at the current temperature using + expressions defined in NAMED_LOG_K data block; + LK_PHASE("Calcite") returns the value of log K + for calcite at the current temperature for the + dissociation reaction defined in the database or + input file. Values are "log10" values. +Example for Basic program: + 10 PRINT "Log10 KCalcite: ", LK_PHASE("Calcite") + 20 PRINT "Log10 KCaHCO3+: ", LK_SPECIES("CaHCO3+") + 30 PRINT " 1000ln(alpha): ", LK_NAMED("Log_alpha_18O_CO2(aq)/CO2(g)")*LOG(10)*1000 + +NAMED_EXPRESSION--New keyword data block. + + This data block was implemented to facilitate isotopic + calculations. It allows analytical expressions that + are functions of temperature to be defined. The purpose + is to separate the fractionation factors from the log + K, so that the fractionation factor or its temperature + dependence can be easily modified. The named expression + can be added to a log K for a species or phase by the + -add_logk identifier in SOLUTION_SPECIES + EXCHANGE_SPECIES, SURFACE_SPECIES, or PHASES data + block. Log K, Delta H, and analytical expressions for a + log K can be defined with identifiers -log_k, -delta_h, + and -analytical_expression as described in SOLUTION_SPECIES + in WRIR 99-4259. Fractionation factors are often defined + as 1000*ln(alpha). The identifier -ln_alpha1000 can be used + to enter data in this form. The analytical expression is the + same as defined in SOLUTION_SPECIES, but the result of the + expression is converted to log10(alpha) by dividing by + 1000*ln(10) before it is summed into log K values. + +NAMED_EXPRESSIONS + Log_K_calcite # CaCO3 + 2H3O+ = Ca+2 + 3H2O + CO2 + log_k 8.201 + delta_h -8.035 kcal + -analytic 292.29 0.015455 -24146.841 -94.16451 2248628.9 + + Log_alpha_18O_CO2(aq)/Calcite + -ln_alpha1000 3.8498 0.0 10.611e3 0.0 -1.8034e6 + + Log_alpha_13C_CO2(aq)/Calcite + -ln_alpha1000 2.72 0.0 0.0 0.0 -1.1877e6 + +------------------------------------------------------------ +Added identifier -add_logk to SOLUTION_SPECIES + EXCHANGE_SPECIES, SURFACE_SPECIES, and PHASES data + block. + + Allows a named expression to be added to the definition + of the log K for a species or phase. In the following + example, the log K for the phase Ca[14C][18O]3 is summed from + four parts, one defined with the log_k identifier and the + other three parts from expressions defined in NAMED_EXPRESSIONS. + The named expression is multiplied by the coefficient at the + end of the line before it is summed into the log K. A missing + coefficient is 1.0 by default. + +PHASES + Ca[13C][18O]3 + Ca[13C][18O]3 + 3CO2 + 2H3O+ = Ca+2 + 3H2O + 3CO[18O] + [13C]O2 + log_k 0.903089986991 # 3*log10(2) + -add_logk Log_K_calcite 1.0 + -add_logk Log_alpha_13C_CO2(aq)/Calcite 1.0 + -add_logk Log_alpha_18O_CO2(aq)/Calcite 3.0 + + +SOLUTION keyword: + At present, can only define isotopes in the units defined in ISOTOPES. + +------------------------------------------------------------ +Version 2.6: +------------------------------------------------------------ + + No new features. + +------------------------------------------------------------ +Version 2.5: +------------------------------------------------------------ +Added the capability to use square brackets to define an + "element" name. The brackets act like quotation marks + in that any character string can be used within the + brackets as an element name. For example, [Fe3], [13C], + and [N5] are now legal "element" names. All element + names without brackets must begin with a capital letter, + followed by zero or more lower case letters and underscores. + +Added identifier -activity_water for a species in SOLUTION_SPECIES + data block. This identifier has been added for future updates + that will allow isotopic calculations. It is intended to be + used only for isotopic variations of H2O, like D2O or + H2[O18]. It forces the activity coefficient for the + species to be activity(water)/55.5. This effectively sets + the activity of the species to the mole fraction in + solution. + +Added identifier -bad_step_max to KINETICS data block. + An integer following -bad_step_max gives the maximum number + of times a rate integration may fail before execution of the + program is terminated. Default is 500. + +------------------------------------------------------------ +Version 2.4: +------------------------------------------------------------ + +------------------------------------------------------------ +Added identifier -warnings to PRINT keyword. + + An integer following -warnings gives the maximum number + of warnings to print into the output file. A negative + number allows all warnings to be printed. + + Example: -warnings 20 + +------------------------------------------------------------ +Changed the results of the function CELL_NO in Basic programs. + + Function cell_no in Basic now prints a number equivalent + to -solution in SELECTED_OUTPUT data block. It gives the + solution number for initial solution calculations and the + solution being used in batch reaction calculations. + Result is the same as previous versions for ADVECTION or + TRANSPORT calculations. + +------------------------------------------------------------ +Version 2.3: +------------------------------------------------------------ +DATABASE--New keyword data block + + It must be the first keyword in the input file. + The character string following the keyword is + the pathname for the database file to be used + in the calculation. The file that is specified + takes precedence over any default database + name, including environmental variable + PHREEQC_DATABASE and command line arguments. + +LLNL_AQUEOUS_MODEL_PARAMETERS--New keyword data block + + Added new keyword to make aqueous model similar to + EQ3/6 and Geochemists Workbench when using + llnl.dat as the database file. Values + of Debye-Huckel a and b and bdot (ionic strength + coefficient) are read at fixed temperatures. + Linear interpolation occurs between temperatures. + + New options for SOLUTION_SPECIES are + -llnl_gamma a , where a is the ion-size parameter. + -co2_llnl_gamma , indicates the temperature dependent + function for the bdot term given in + -co2_coefs of LLNL_AQUEOUS_MODEL_PARAMETERS + will be used. Applies to uncharged + species only. + +LLNL_AQUEOUS_MODEL_PARAMETERS +-temperatures + 0.0100 25.0000 60.0000 100.0000 + 150.0000 200.0000 250.0000 300.0000 +#debye huckel a (adh) +-dh_a + 0.4939 0.5114 0.5465 0.5995 + 0.6855 0.7994 0.9593 1.2180 +#debye huckel b (bdh) +-dh_b + 0.3253 0.3288 0.3346 0.3421 + 0.3525 0.3639 0.3766 0.3925 +-bdot + 0.0394 0.0410 0.0438 0.0460 + 0.0470 0.0470 0.0340 0.0000 +#cco2 (coefficients for the Drummond (1981) polynomial) +-co2_coefs + -1.0312 0.0012806 + 255.9 0.4445 + -0.001606 + +------------------------------------------------------------ +Added function SURF to Basic. + + SURF("element", "surface") gives the amount of element + sorbed on "surface". "surface" should be the surface + name, not the surface-site name (that is, no underscore). + +------------------------------------------------------------ +Allow decimals in definition of secondary master species. + + Some redox states do not average to integers, + for convenience in identifying them, decimal numbers + may be used within the parentheses that define the + redox state, example S(0.3) could be used in the + MASTER_SPECIES data block for the valence state of + aqueous species S6-2. + +------------------------------------------------------------ +Eliminate echo of input file in PRINT data block. + + -echo_input T/F turns echoing on and off. + Default is true, initial value is true. + +------------------------------------------------------------ +Added option for an equilibrium-phase to dissolve only. + "dis" is added at the end of a line defining an equilibrium- + phase. No data fields may be omitted. Should not + be used when adding an alternative reaction. + Example: + EQUILIBRIUM_PHASES + Dolomite 0.0 0.001 dis + +------------------------------------------------------------ +Version 2.2: +------------------------------------------------------------ +Added function EDL to Basic. + EDL("element", "surface") gives the amount of + element in the diffuse layer for "surface", not + including sorbed species. "surface" should be + the surface name, not the surface-site name + (that is, no underscore). + + Special values for "element" include: + "charge" - gives surface charge, equivalents. + "sigma" - surface charge density, C/m**2. + "psi" - potential at the surface, Volts. + "water" - mass of water in the diffuse layer, kg. + +------------------------------------------------------------ +End of Features not documented in WRIR 99-4259. +------------------------------------------------------------ + +------------------------------------------------------------ +Revisions and bug fixes +------------------------------------------------------------ + svn 675: + Added PRINT option to print the species that contribute + to alkalinity. Alkalinity distribution is printed in + the output file following the distribution of species. + Default at program startup is false. + + PRINT + -alkalinity true + + svn 655: + IAP and log K printed in Phase assemblage data + block were calculated from reactions rewritten to + new master species. Now the original data base + reaction is used to calculate IAP and log K. + Also fixed check that ensured all elements of + phase in are in solution before SI is calculated. + + svn 631: + Fixed bug with alternate formula for equilibrium phase, + nothing happened if all other equations were satisfied + at beginning of reaction calculation. + + svn 603: + Link gmp library statically. + + svn 601: + Fixed statement on multiprecision. + + svn 581: + Fixed bug in PhreeqcI that did not reinitialize + Chebyschev parameters leading to incorrect results + with Pitzer activity coefficients. Results were + correct on first run, but erroneous on subsequent + runs. + + Added statement to identify multiprecision or + standard solver for inverse modeling. + + svn 578: + + Distribution changes. Fixed names in README file. + Modified Makefile to use specified version. Split + Linux and source distribution procedure. + +Version 2.12 Date: Wed September 28, 2005 + + Executables and output files for Sun operating systems + are no longer provided. + + Limited log activities of master species to be greater + than the smallest machine precision exponential number. + Avoids a matherr exception and allows trial of additional + parameter sets to attempt to solve the system of + equations. + + Made aqueous activity coefficients the default activity + coefficients for exchange species when using the + Pitzer formulation. New option in EXCHANGE is + -pitzer_exchange_gammas T/F, default is true; + defining "false" sets exchange activity coefficients + to 1.0. Option has no effect for ion-association + model (non-Pitzer). + + Edited phreeqc.dat to add -gamma expression for + CdX2 and PbX2. + + Replaced O2(g) log K in phreeqc.dat and wateq4f.dat + with data from llnl.dat, which appears to be better. + + Added multiplier format to REACTION increments, which + simplifies definition of multiple equal reaction increments. + + REACTION + H2O 1 + -36 3*-4 2*-.25 -0.19 4*-0.1 3*-0.05 moles + + Added Pitzer activity formulation. Use pizer.dat database + to invoke the Pitzer model. Should have same capabilities + as ion-association model except explicit diffuse layer + calculation is not implemented with the Pitzer model. + + + Fixed bug in surface sites related to mineral and exchange + sites related to mineral. Did not have complete logic to + handle redox valence states in formula for species. + + Modified to remove non standard usage of va_list. + + Removed exchange master species from SYS("ex",..) + list of species. This species is fictive and should + not be included in the list. + + Changed -redox in SOLUTION so that if one of the + redox states of a couple is not defined, then + redox defaults to pe. + + Fixed buffer overrun in PhreeqcI with SOLUTION_SPREAD, + caused segmenatation fault with lines greater than + 500 characters. + + Added bigger string for some error messages to avoid + access violation in cvode. + + Changed output_msg to warning_msg for combinations + of convergence parameters so that message would + be controlled by -warnings identifier. + + Carriage returns are now stripped from Basic program + statements. Switching files from Windows to Unix sometimes + leaves extra carriage returns at the ends of lines, which + caused a syntax error for some Basic commands. + + Two bugs were fixed in inverse modeling. (1) Potential + models are now checked for all equality and inequality + constraints. Previously some constraints were not checked. + (2) One loop of cl1 did not include the last row when + checking for the pivot element. Also printing of headers + was slightly modified for inverse modeling. + + A new multiple precision version of cl1 was develeped by + using the Gnu Multiple Precision package (gmp). Calculations + are carried out to about 30 significant digits. The mp + version may help in some situations where roundoff errors are + a problem, but it is still possible that roundoff errors will + cause cl1mp to fail to find a solution to the optimization + problem. The mp version has the following options in + INVERSE_MODELING: + -multiple_precision T/F--causes the mp version + to be used in inverse modeling calculations. + -mp_tolerance 1e-12--tolerance for mp version of + cl1. As in cl1, numbers less than the + tolerance are considered to be zero. + 1e-12 is the default. + -censor_mp 1e-20--as calculations occur in the + linear equation array, elements less + than this value are set to zero. Default + is 1e-20. A value of 0.0 causes no + censoring to occur. + +Version 2.11 Date: Mon February 7, 2005 + + Fixed error in selected output file with mixing reaction. + MIX number was written to two columns, should be one. + + Fixed memory leak with PAD function. + + New database minteq.v4.dat has been translated from version + 4.02 of MINTEQA2. An older version of the MINTEQA2 database is + retained in file minteq.dat. + + Switched version control to subversion. Simplified, + reorganized makefiles. + + Fixed bug with PRINT; -warnings n. Use of this option + generally eliminated all warning messages instead of + all messages after the nth. Default number of warning + messages printed in now 100 per simulation. + + Fixed memory leaks in cvode that caused phreeqci to crash. + Now uses PHRQ_malloc in case of other memory leaks. Also + fixed potential memory error with PAD Basic function. + + Saturation index phases that included water had wrong + value if distribution of species, exchange, or surface + not written also. + + Fixed error message in cvode, if max iterations exceeded + the error caused a segmentation fault. + + Made printing of parameter combination message a warning + message so that it could be turned off. + +Version 2.10 Date: Tue November 2, 2004 + + Rearranged i/o for PHREEQC and reorganized driver + subroutine. The object of these changes is to make + the program more functional as a module for other + programs (PHAST) and eventually to produce a callable + C and Fortran module. + + Fixed a problem with surface related to a phase, when + phase was not part of system (for example, Fe(OH)3a when + there is no iron in system. + + Added convergence parameter set that requires mineral + transfers to produce positive concentrations in the + event that negative concentrations have been produced in + the prior Newton-Raphson iteration. (Fluorite example). + + Fixed bug with kinetics formulas; did not account for + stoichiometric coefficient correctly when using + phase names. Generalized to allow multiple phase + names in the -formula definition. + +Version 2.9 Date: Wed September 15, 2004 + + In inverse modeling, program terminates if sum of initial + solutions and phases is > 32. + + Fixed bug with isotopes. Log activity estimate after initial + solution calculation was inf under some conditions. An initial + surface calculation failed when using D. + + Changed saturation index print out to use reaction and log K + defined in PHASES definition. Previously, reaction could be + rewritten to predominant redox species. + + Fixed incorrect print of elapsed time for kinetics in advection. + + Added phrqproto.h prototype file and phrqtype.h for + switching compilation to long double. + + Fixed incorrect printout of kinetics delta moles with + advection. + + Added convergence parameter set that skips mineral + equations for first 5 iterations. + + Added entity_exists for module. + + Tried to fix bug with mix index incorrect (-2) for + mixing with kinetics. + + Added new keyword COPY that allows a data entity + to be copied from one index to a new index + or to a range of indicies. Format is + + COPY keyword index index_start[-index_end] + + where keyword is one of the following: + SOLUTION + EQUILIBRIUM_PHASES + EXCHANGE + GAS_PHASE + KINETICS + MIX + REACTION + REACTION_TEMPERATURE + SOLID_SOLUTION + SURFACE + + Numerical method had a bug with ionic strength, if + mass of water was not approximately 1. Routine + revise_guesses did not divide by the mass of + water. Also changed check in routine molalities + to check by molality, not moles. + + Fixed a null pointer when surface was related to a + mineral and mineral was not in database. + + Added new Basic functions + i = INSTR(a$, b$) sets i to the character position of + string b$ in a$, 0 in not found. + b$ = LTRIM(a$) trims white space from beginning of + string a$ and stores result in b$. + b$ = RTRIM(a$) trims white space from end of string + a$ and stores result in b$. + b$ = LTRIM(a$) trims white space from beginning and + end of string a$ and stores result in b$. + + Added new Basic function SYS that calculates the to + total amount of an element in all phases (solution, + equilibrium_phases, surfaces, exchangers, solid solutions, + and gas phase). KINETIC reactions are not included. + The function has two forms: (1) one element name as an + argument (variable names are user specified) + + 10 t = SYS("As") + + the function will return the total arsenic in the system. + (2) 5 argumens + + 10 t = SYS("As", count_species, names$, types$, moles) + + will return the total arsenic in the system to tot; count_species-- + the number of species that contain arsenic, including + solution, equilibrium_phases, surfaces, exchangers, solid solutions, + and gas phase species; names$--a character array that has the + name of each species; type$--a character array that specifies the + type of phase for the species, aq, equi, surf, ex, s_s, gas, diff. + Diff refers to the amount of the element in the diffuse layer of + a surface when the explicit diffuse layer calculation is used; + moles--an array containing the number of moles of the element in + the species. The sum of moles(i) is equal to tot. + + SYS has several special arguments for the form + SYS("arg", count, names$, types$, values) + arg is one of the options listed below. + count is a single numeric value and is the number of elements + in the following arrays. + name$ is an array of string values. + type$ is an array of string values. + values is an array of numeric values. + + Values of arg: + + elt_name returns total number of moles of element in system. + count is the number of species for the element in + the system, including aqueous, exchange, surface, + equilibrium_phase, solid solution component, and + gas phase "species". + Arrays are filled for each "species"; values are moles. + "elements" returns total number of moles of all elements, + valence states, exchangers, and surfaces. + count is number of elements, valence states, + exchangers, and surfaces. + Arrays are filled for each element, valence state, + exchanger, and surface; values are moles. + "phases" returns maximum saturation index of all phases. + count is number of phases in system. + Arrays are filled for each phase; values are + saturation indexes. + "aq" returns sum of moles of all aqueous species. + count is number of aqueous species in system. + Arrays are filled with each aqueous species; + values are moles. + "ex" returns sum of moles of all exchange species. + count is number of exchange species in system. + Arrays are filled with each exchange species; + values are moles. + "surf" returns sum of moles of all surface species. + count is number of surface species in system. + Arrays are filled with each surface species; + values are moles. + "surf" returns sum of moles of all solid solution components. + count is number of solid solution components in system. + Arrays are filled with each solid solution component; + values are moles. + "gas" returns sum of moles of all gas components. + count is number of gas components in system. + Arrays are filled with each gas component; + values are moles. + + Added new Basic function, DESCRIPTION, that has the value + defined for the description field of the SOLUTION keyword line. + + Added alternative ordinary differential equation solver + called CVODE, a set of C routines from the Lawrence + Livermore National Labs. CVODE is part of the SUNDIALS + package. CVODE is used in place of the Runge Kutta method + when "-cvode true" is used within a KINETICS data block. + + KINETICS + -cvode true + + Fixed error in SOLUTION_SPREAD, defining -redox + did not set the default redox for the solutions + that were defined; pe was always used as default. + + Modified code to allocate space differently for + pp_assemblage, exchange, surface, gas_phase, + kinetics, and s_s_assemblage. Enough space is allocated + at beginning of distribute_initial_conditions. + May speed up phast initialization and make better + use of available memory. + + Changed gfw of water to 18 if isotopes of water are + included. Solvent is [1H]2[16O]. + + Fixed a bug in surface integration where order of ions + in the list of g's was incorrect. + + Pyrite rate was not 0 if supersaturated in phreeqc.dat + and wateq4f.dat + + Segmentation error if a surface species was not + defined with an equation that contained another surface + species. In this case, the surface master species + had been redefined to be an aqueous species (SOLUTION_SPECIES). + +Version 2.8 Date: Tue April 15, 2003 + + Updated arsenic data in wateq4f.dat to be consistent with + Archer and Nordstrom (2002). + + Revised Basic interpreter to allow lines of any length + and character strings of any length. + + Renumbering basic statement that included the function + SURF in PhreeqcI caused SURF to be omitted and generated + a syntax error. SURF and other functions had not been + implemented in PhreeqcI. + + Fixed a bug in the Basic Interpreter. If elements of + a dimensioned variable (character or number) were used on + both sides of an equation, the result was erroneously + stored in the last element of the variable used on the + right-hand side instead of the element specified on the + left-hand side. + + Using comma in some fields caused an infinite loop. + + Fixed bug with SOLUTION_SPREAD, Phreeqc was not + calculating solution numbers for solution_spread + solutions without solution numbers. + + Fixed bug with stagnant zone calculations. If solutions + not defined for stagnant cells, PhreeqcI crashed. + + Added new state for calculations, PHAST. Previously + phast used the state TRANSPORT, which caused some + erroneous results with temperature when TRANSPORT was + used in the PHREEQC part of the calculation. + + Trying to define dump file in TRANSPORT caused a file + opening error. Fixed logic so now can open a file + and the name can include blanks. + +Version 2.7 Date: Fri February 14, 2003 + + Initialized gfw in elements structure. + + Fixed bug where "time" would be wrong for initial + solution calculation. Needed to initialize + rate variables for PhreeqcI. + + Added print of simulation number to error file for + phreeqci + + Limited printing of cell numbers to output file in advection + calculations. Cell numbers only printed if results + for cell are going to be printed. + + PhreeqcI captured status messages for kinetics, which + made a very large error file in some cases and + a long wait to view the output file in PhreeqcI. + Now PhreeqcI does not capture these intermediate + status messages. + + Removed old code related to redirecting error file + + + Corrected error in transport where wrong time step was used + for integration. + + Changes to speed up transport algorithm. + + Allow file names with spaces in selected_output file name and + dump_file name. + + Modifications to work with RC1 phast log file. + + Allow any characters in square brackets for element name. + - and + and perhaps others caused problems before. + + Fixed log molality of water in species printout, was + equal to log activity of water. Also fixed + basic function for LM. + + Changed solid solution prints to print 0 if solid solution + is not present. + + Fixed bug if no rate name was defined before options + in RATES. + + Fixed warning on Mac compilation in fpunchf. + + Fixed bug if isotopes were used but H and O isotopes + were not defined. + + Fixed bug where special initial solution calculations + were done at later calculation stages. + Needed to set initial_solution_isotopes = FALSE; + + Fixed problem in C++ if structure name is same as member name. + logk member of logk structure was renamed to log_k. + + Added identifier -add_constant to PHASES, EXCHANGE_SPECIES, + SOLUTION_SPECIES, and SURFACE_SPECIES. + + -add_constant -0.301 + + log K is augmented by the specified constant. + + + Added punch_isotopes and punch_calculate_values to allow + printing isotope ratios and any CALCULATE_VALUES result. + + Added KEYWORDS: + + ISOTOPES + Element + -isotope isotope_name units standard_ratio + -total_is_major T/F (OPTION IS DISABLED!!) + + CALCULATE_VALUES + Name + -start + Basic statements, must have SAVE + -end + + ISOTOPE_RATIOS (for printing) + Name=Calculate_values_name Isotope_name + + ISOTOPE_ALPHAS (for printing) + Name=Calculate_values_name Named_logk=named_expression_name + + Basic functions: + calc_value("calc_value_name") evaluates a definition of CALCULATE_VALUES + lk_named("name") log10(K) of definition in NAMED_EXPRESSIONS + lk_phase("name") log10(K) of definition in PHASES + lk_species("name") log10(K) of definition in (SOLUTION, EXCHANGE, SURFACE)_SPECIES + sum_gas("template","element") Sum of element in gases with specified template + template="{C,[13C],[14C]}{O,[18O]}2" includes all CO2 gases + sum_species("template","element") Sum of element in aqueous, exchange, and surface species with + specified template + sum_s_s("s_s_name","element") Sum of element in a specified solid solution + + PRINT keyword: + -initial_isotopes T/F + -isotope_ratios T/F + -isotope_alphas T/F + -censor_species 1e-8 # Omits print of species if less than relative criterion + + SELECTED_OUTPUT keyword: + -calculate_values name1 name2 ... + -isotopes minor_isotope1 minor_isotope2 .... + + Added functions LK_SPECIES, LK_NAMED, LK_PHASE for Basic + interpreter. LK_SPECIES("CaHCO3+") returns the + log k for the association reaction for the ion pair + CaHCO3+ at the current temperature. The log K is + for the reaction as defined in the database or + input file. Similarly, + LK_NAMED("Log_alpha_18O_CO2(aq)/CO2(g)") returns the + value for the log K at the current temperature using + expressions defined in NAMED_LOG_K data block; + LK_PHASE("Calcite") returns the value of log K + for calcite at the current temperature for the + dissociation reaction defined in the database or + input file. Values are "log10" values. + Example for Basic program: + + 10 PRINT "Log10 KCalcite: ", LK_PHASE("Calcite") + 20 PRINT "Log10 KCaHCO3+: ", LK_SPECIES("CaHCO3+") + 30 PRINT " 1000ln(alpha): ", LK_NAMED("Log_alpha_18O_CO2(aq)/CO2(g)")*LOG(10)*1000 + + Added NAMED_EXPRESSIONS data block. This data block was + implemented to facilitate isotopic calculations. + It allows analytical expressions that are functions + of temperature to be defined. The purpose is to + separate the fractionation factors from the log K, + so that the fractionation factor or its temperature + dependence can be easily modified. The named + expression can be added to a log K for a species + or phase by the -add_logk identifier in SOLUTION_SPECIES + EXCHANGE_SPECIES, SURFACE_SPECIES, or PHASES data + block. + +Version 2.6 Date: Mon April 22, 2002 + + PhreeqcI released. + + All selected_output is routed through a single routine. + + Allow "_" inside square brackets, [A_bcd]. + + Fixed bug match_elts_in_species, check for "e-" was wrong. + + Modified minteq.dat to put CuS4S5-3, Cu(S4)2-3 in + in Cu(1) mole balance equations instead of + Cu(2). Before the change, the program would + not converge if Cu(2) were defined in an + initial solution. + + Made revisions hopefully to improve SOLID_SOLUTIONS + convergence with small numbers of moles of + solids. + + Made changes related to dump file and PhreeqcI. + + Iterations now sums iterations in all kinetics calculations + + Fixed bug with LA("H2O"), which was returning natural log + of activity of water. + + +Version 2.5 Date: Mon October 1, 2001 + In llnl.dat, fixed sign errors in RRE (rare earth elements) + for some redox reactions and removed some redundant + species, generally ReeO2- was retained and Ree(OH)4- + was removed. + + Added the capability to use square brackets to define an + "element" name. The brackets act like quotation marks + in that any character string can be used within the + brackets as an element name. This was introduced to + simplify expansion of the model to isotopic species. + [13C], [14C], and [18O] are legal element names. + + Added identifier -activity_water for a species in + SOLUTION_SPECIES data block. This identifier has been + added for future updates that will allow isotopic + calculations. It is intended to be used only for + isotopic variations of H2O, like D2O or H2[O18]. It + forces the activity coefficient for the species to be + activity(water)/55.5. This effectively sets the activity + of the species to the mole fraction in solution. + + Fixed bug in checking solid solutions for presence or + absence of elements in the system. Programming + error caused segmentation fault if an error + was detected under certain conditions. + + Changed return value of MOL to be molality of water + if argument is "H2O". Also changed return value + of LA to be activity of water if argument is + "H2O". + + Diffuse layer calculation was incorrect if aqueous phase did not + have 1 kilogram of water. Eq. 74 of manual has molality, + but code used moles. The code was corrected by adding + the mass of water to the formulation. + + Stagnant zones with first-order exchange approximation (1 stagnant + cell, exchange factor, and porosities defined) did not work + correctly if mobile and immobile cells did not have equal + volumes of water. The mixing factors were revised to account + for the masses of water in the stagnant and mobile zones. + + A fatal error was erroneously detected if the database file + had a DATABASE data block. DATABASE data block is + now ignored while reading the database file. + + Added identifier -bad_step_max to KINETICS data block. + An integer following -bad_step_max gives the maximum number + of times a rate integration may fail before execution of the + program is terminated. Default is 500. + +Version 2.4.2: Date: Fri June 15, 2001 + Fixed spreadsheet bug. Program was not ignoring columns + that could not be identified as either element + names or allowed data (ph, pe, number, description, + etc). Also, the program failed if a spreadsheet solution + number was negative. + +Version 2.4.1: Date: Mon June 4, 2001 + Fixed spreadsheet bugs with isotopes. + +Version 2.4: Date: Fri June 1, 2001 + + Added structure for spreadsheet for use by PhreeqcI. + + Isotope value initialized incorrectly if only an -uncertainty was + defined in SOLUTION_SPREAD. + + Fixed segmentation violation when primary and secondary master + species were defined improperly. + + Corrected enthalpies of reaction in llnl.dat. Previous release had + erroneously had enthalpies of formation in -delta_H + parameter; the values should be enthalpies of reaction. + Enthalpies of reaction were calculated from the + enthalpies of formation and these values are now included + in the -delta_H parameter. This change will have very + little impact on calculations because the analytical + expression has precedence over -delta_H in calculating + temperature dependence of log K, and nearly all species + and minerals have an analytical expression or lack both + an analytical expression and an enthalpy of reaction. + + Corrected bugs in punch of solid solution components that caused + both selected output and output file errors: moles + were incorrect in selected output, and total moles and + mole fraction were incorrect in output file. + + Added surface complexation constants for Fe+2; two complexes for + weak sites and one complex for strong sites. phreeqc.dat + and wateq4f.dat modified. + + Comment for units of parameters for calcite rate equation was + wrong. Rate equation now uses cm^2/L for area parameter. + Previously the correct units would have been 1/decimeter. + phreeqc.dat and wateq4f.dat modified. + + Fixed a bug when rates were equal within tolerance, but negative + concentrations occurred because of small initial + concentrations. + + Added -warnings to PRINT keyword for specification of maximum + number of warnings to print. Negative number allows + all warnings to be printed. + + Function CELL_NO in Basic now prints a number equivalent to + -solution in SELECTED_OUTPUT data block. This does not + change printing for ADVECTION or TRANSPORT calculations. + + Kinetics time is halved for advective part of reaction in + transport; time incorrectly accounted for before. + + -punch_ identifiers printed -1 instead of the correct solution + number for batch-reaction calculations. + + -high_precision is no longer reset to false with every + SELECTED_OUTPUT data block. + + SELECTED_OUTPUT file name stored for use by PhreeqcI. + + Alkalinity for NH3 corrected to 1.0 in llnl.dat. + + Fixed bug with USER_PRINT of kinetics. Did not find correct + kinetics information in some cases. + + Fixed bug in default values for SOLUTION_SPREAD. Cannot use phase + name and SI for pH or pe, and bug did not allow PHREEQC + to run. Now PHREEQC runs, but warns that this is not + allowed. + +Version 2.3: Date: Tue January 2, 2001 + + Added new keyword DATABASE. It must be the first keyword in + the input file. The character string following the + keyword is the pathname for the database file to + be used in the calculation. The file that is + specified takes precedence over any default + database name, including environmental variable + PHREEQC_DATABASE and command line arguments. + + Fixed bug in SOLUTION_SPREAD. If first heading in + the spread-sheet input was an identifier--pH, + pe, units, etc--then the headings were interpreted + as an identifier and bad things happened. + + Added new keyword to make aqueous model similar to + LLNL and Geochemists Workbench when using + llnl.dat as the database file. Values + of Debye-Huckel a and b and bdot (ionic strength + coefficient) are read at fixed temperatures. + Linear interpolation occurs between temperatures. + + New options for SOLUTION_SPECIES are + -llnl_gamma a , where a is the ion-size parameter. + -co2_llnl_gamma , indicates the temperature dependent + function for the bdot term given in + -co2_coefs of LLNL_AQUEOUS_MODEL_PARAMETERS + will be used. Applies to uncharged + species only. + +LLNL_AQUEOUS_MODEL_PARAMETERS +-temperatures + 0.0100 25.0000 60.0000 100.0000 + 150.0000 200.0000 250.0000 300.0000 +#debye huckel a (adh) +-dh_a + 0.4939 0.5114 0.5465 0.5995 + 0.6855 0.7994 0.9593 1.2180 +#debye huckel b (bdh) +-dh_b + 0.3253 0.3288 0.3346 0.3421 + 0.3525 0.3639 0.3766 0.3925 +-bdot + 0.0394 0.0410 0.0438 0.0460 + 0.0470 0.0470 0.0340 0.0000 +#cco2 (coefficients for the Drummond (1981) polynomial) +-co2_coefs + -1.0312 0.0012806 + 255.9 0.4445 + -0.001606 + + + Fixed bug in basic interpreter. A number like "..524" would + cause an infinite loop. + + Added function SURF to Basic. + SURF("element", "surface") gives the amount of + element sorbed on "surface". "surface" + should be the surface name, not the + surface-site name (that is, no underscore). + + Fixed option to "runge_kutta" from "runge-kutta" to match + documentation for KINETICS. + + Fixed UO2+2 and Mn+2 reaction stoichiometry for Hfo surface complexation + in wateq4f.dat. + + Added option for an equilibrium-phase to dissolve only. + "dis" is added at the end of a line defining an equilibrium- + phase. No data fields may be omitted. Should not + be used when adding an alternative reaction. + Example: + EQUILIBRIUM_PHASES + Dolomite 0.0 0.001 dis + R-K integration failed when only the final rate generated + negative concentrations. + Allow decimals in definition of secondary master species, for + example S(0.3). + Fixed bug if description was more than about 85 characters; + now allows about 400 characters. + Fixed bug for surface/exchange sites related to phases. Was + checking internal copies of surfaces/exchange with negative + numbers. + Fixed bug in quick prep that did not set the correct pointer + for gas phases. + Fixed segmentation fault that occurred if all elements for + phase-boundary mineral were not in the solution. + Only applied to a phase used to define concentration + in an initial solution calculation. + Added option to eliminate echo of input file in PRINT + data block. -echo_input T/F turns echoing on + and off. Default is on. + + +Release 2.2: Date: Wed March 1, 2000 + + Fixed bug in MIX if no solutions are defined. + Changed printout for surface. + Only gives net surface charge for diffuse layer + calculation. + Prints correct value for the surface charge and + surface charge density for diffuse-layer + calculation. + + Added function EDL to Basic. + EDL("element", "surface") gives the amount of + element in the diffuse layer for "surface". + not including sorbed species. "surface" should + be the surface name, not the surface-site name + (that is, no underscore). + + Special values for "element" include: + "charge" - gives surface charge, equivalents. + "sigma" - surface charge density, C/m**2. + "psi" - potential at the surface, Volts. + "water" - mass of water in the diffuse layer, kg. + Changed distribution to be more consistent with other USGS + water-resources applications. + +Release 2.1: Date: Wed January 19, 2000 + + Added additional #ifdef's for PhreeqcI. + Fixed problem with formats for USER_PUNCH and + others with Microsoft C++ 3 digit + exponents. + +Initial Release 2.0: Date: Wed December 15, 1999 + +Version: C_54 = Version 2.0 + diff --git a/smalldense.cpp b/smalldense.cpp new file mode 100644 index 00000000..4116703f --- /dev/null +++ b/smalldense.cpp @@ -0,0 +1,243 @@ +/******************************************************************* + * * + * File : smalldense.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for a generic DENSE linear * + * solver package, intended for small dense matrices. * + * * + *******************************************************************/ + +#include +#include +#include "smalldense.h" +#include "sundialstypes.h" +#include "sundialsmath.h" +#include "output.h" +#include "phqalloc.h" +/* WARNING don't include any headers below here */ +#define malloc PHRQ_malloc +static char const svnid[] = "$Id: smalldense.c 663 2005-11-16 00:46:04Z dlpark $"; + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + + +/* Implementation */ + + +realtype **denalloc(integertype n) +{ + integertype j; + realtype **a; + + if (n <= 0) return(NULL); + + a = (realtype **) malloc(n * sizeof(realtype *)); + if (a == NULL) return(NULL); + + a[0] = (realtype *) malloc(n * n * sizeof(realtype)); + if (a[0] == NULL) { + free(a); + return(NULL); + } + + for (j=1; j < n; j++) a[j] = a[0] + j * n; + + return(a); +} + +integertype *denallocpiv(integertype n) +{ + if (n <= 0) return(NULL); + + return((integertype *) malloc(n * sizeof(integertype))); +} + +integertype gefa(realtype **a, integertype n, integertype *p) +{ + integertype i, j, k, l; + realtype *col_j, *col_k, *diag_k; + realtype temp, mult, a_kj; + booleantype swap; + + /* k = elimination step number */ + + for (k=0; k < n-1; k++, p++) { + + col_k = a[k]; + diag_k = col_k + k; + + /* find l = pivot row number */ + + l=k; + for (i=k+1; i < n; i++) + if (ABS(col_k[i]) > ABS(col_k[l])) l=i; + *p = l; + + /* check for zero pivot element */ + + if (col_k[l] == ZERO) return(k+1); + + /* swap a(l,k) and a(k,k) if necessary */ + + /*if ( (swap = (l != k) )) {*/ + swap = (l != k); + if (swap) { + temp = col_k[l]; + col_k[l] = *diag_k; + *diag_k = temp; + } + + /* Scale the elements below the diagonal in */ + /* column k by -1.0 / a(k,k). After the above swap, */ + /* a(k,k) holds the pivot element. This scaling */ + /* stores the pivot row multipliers -a(i,k)/a(k,k) */ + /* in a(i,k), i=k+1, ..., n-1. */ + + mult = -ONE / (*diag_k); + for(i=k+1; i < n; i++) + col_k[i] *= mult; + + /* row_i = row_i - [a(i,k)/a(k,k)] row_k, i=k+1, ..., n-1 */ + /* row k is the pivot row after swapping with row l. */ + /* The computation is done one column at a time, */ + /* column j=k+1, ..., n-1. */ + + for (j=k+1; j < n; j++) { + + col_j = a[j]; + a_kj = col_j[l]; + + /* Swap the elements a(k,j) and a(k,l) if l!=k. */ + + if (swap) { + col_j[l] = col_j[k]; + col_j[k] = a_kj; + } + + /* a(i,j) = a(i,j) - [a(i,k)/a(k,k)]*a(k,j) */ + /* a_kj = a(k,j), col_k[i] = - a(i,k)/a(k,k) */ + + if (a_kj != ZERO) { + for (i=k+1; i < n; i++) + col_j[i] += a_kj * col_k[i]; + } + } + } + + /* set the last pivot row to be n-1 and check for a zero pivot */ + + *p = n-1; + if (a[n-1][n-1] == ZERO) return(n); + + /* return 0 to indicate success */ + + return(0); +} + +void gesl(realtype **a, integertype n, integertype *p, realtype *b) +{ + integertype k, l, i; + realtype mult, *col_k; + + /* Solve Ly = Pb, store solution y in b */ + + for (k=0; k < n-1; k++) { + l = p[k]; + mult = b[l]; + if (l != k) { + b[l] = b[k]; + b[k] = mult; + } + col_k = a[k]; + for (i=k+1; i < n; i++) + b[i] += mult*col_k[i]; + } + + /* Solve Ux = y, store solution x in b */ + + for (k=n-1; k >= 0; k--) { + col_k = a[k]; + b[k] /= col_k[k]; + mult = -b[k]; + for (i=0; i < k; i++) + b[i] += mult*col_k[i]; + } +} + +void denzero(realtype **a, integertype n) +{ + integertype i, j; + realtype *col_j; + + for (j=0; j < n; j++) { + col_j = a[j]; + for (i=0; i < n; i++) + col_j[i] = ZERO; + } +} + +void dencopy(realtype **a, realtype **b, integertype n) +{ + integertype i, j; + realtype *a_col_j, *b_col_j; + + for (j=0; j < n; j++) { + a_col_j = a[j]; + b_col_j = b[j]; + for (i=0; i < n; i++) + b_col_j[i] = a_col_j[i]; + } + +} + +void denscale(realtype c, realtype **a, integertype n) +{ + integertype i, j; + realtype *col_j; + + for (j=0; j < n; j++) { + col_j = a[j]; + for (i=0; i < n; i++) + col_j[i] *= c; + } +} + +void denaddI(realtype **a, integertype n) +{ + integertype i; + + for (i=0; i < n; i++) a[i][i] += ONE; +} + +void denfreepiv(integertype *p) +{ + free(p); +} + +void denfree(realtype **a) +{ + free(a[0]); + free(a); +} + +void denprint(realtype **a, integertype n) +{ + integertype i, j; + + printf("\n"); + for (i=0; i < n; i++) { + for (j=0; j < n; j++) { + printf("%10g", (double) a[j][i]); + } + printf("\n"); + } + printf("\n"); +} diff --git a/smalldense.h b/smalldense.h new file mode 100644 index 00000000..bffcc85c --- /dev/null +++ b/smalldense.h @@ -0,0 +1,224 @@ +/******************************************************************* + * * + * File : smalldense.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the header file for a generic DENSE linear solver * + * package, intended for small dense matrices. These routines * + * use the type realtype** for dense matrix arguments. * + * * + * These routines begin with "den" (except for the factor and * + * solve routines which are called gefa and gesl, respectively). * + * The underlying matrix storage is described in the * + * documentation for denalloc. * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidsmalldense[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _smalldense_h +#define _smalldense_h + +#include "sundialstypes.h" + + +/****************************************************************** + * * + * Function : denalloc * + * Usage : realtype **a; * + * a = denalloc(n); * + * if (a == NULL) ... memory request failed * + *----------------------------------------------------------------* + * denalloc(n) allocates storage for an n by n dense matrix. It * + * returns a pointer to the newly allocated storage if * + * successful. If the memory request cannot be satisfied, then * + * denalloc returns NULL. The underlying type of the dense matrix * + * returned is realtype **. If we allocate a dense matrix * + * realtype **a by a = denalloc(n), then a[j][i] references the * + * (i,j)th element of the matrix a, 0 <= i,j <= n-1, and a[j] is * + * a pointer to the first element in the jth column of a. * + * The location a[0] contains a pointer to n^2 contiguous * + * locations which contain the elements of a. * + * * + ******************************************************************/ + +realtype **denalloc(integertype n); + + +/****************************************************************** + * * + * Function : denallocpiv * + * Usage : integertype *pivot; * + * pivot = denallocpiv(n); * + * if (pivot == NULL) ... memory request failed * + *----------------------------------------------------------------* + * denallocpiv(n) allocates an array of n integertype. It returns * + * a pointer to the first element in the array if successful. * + * It returns NULL if the memory request could not be satisfied. * + * * + ******************************************************************/ + +integertype *denallocpiv(integertype n); + + +/****************************************************************** + * * + * Function : gefa * + * Usage : integertype ier; * + * ier = gefa(a,n,p); * + * if (ier > 0) ... zero element encountered during * + * the factorization * + *----------------------------------------------------------------* + * gefa(a,n,p) factors the n by n dense matrix a. It overwrites * + * the elements of a with its LU factors and keeps track of the * + * pivot rows chosen in the pivot array p. * + * * + * A successful LU factorization leaves the matrix a and the * + * pivot array p with the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., n-1. * + * * + * (2) If the unique LU factorization of a is given by Pa = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of a * + * (including its diagonal) contains U and the strictly lower * + * triangular part of a contains the multipliers, I-L. * + * * + * gefa returns 0 if successful. Otherwise it encountered a zero * + * diagonal element during the factorization. In this case it * + * returns the column index (numbered from one) at which it * + * encountered the zero. * + * * + ******************************************************************/ + +integertype gefa(realtype **a, integertype n, integertype *p); + + +/****************************************************************** + * * + * Function : gesl * + * Usage : realtype *b; * + * ier = gefa(a,n,p); * + * if (ier == 0) gesl(a,n,p,b); * + *----------------------------------------------------------------* + * gesl(a,n,p,b) solves the n by n linear system ax = b. It * + * assumes that a has been LU factored and the pivot array p has * + * been set by a successful call to gefa(a,n,p). The solution x * + * is written into the b array. * + * * + ******************************************************************/ + +void gesl(realtype **a, integertype n, integertype *p, realtype *b); + + +/****************************************************************** + * * + * Function : denzero * + * Usage : denzero(a,n); * + *----------------------------------------------------------------* + * denzero(a,n) sets all the elements of the n by n dense matrix * + * a to be 0.0. * + * * + ******************************************************************/ + +void denzero(realtype **a, integertype n); + + +/****************************************************************** + * * + * Function : dencopy * + * Usage : dencopy(a,b,n); * + *----------------------------------------------------------------* + * dencopy(a,b,n) copies the n by n dense matrix a into the * + * n by n dense matrix b. * + * * + ******************************************************************/ + +void dencopy(realtype **a, realtype **b, integertype n); + + +/****************************************************************** + * * + * Function : denscale * + * Usage : denscale(c,a,n); * + *----------------------------------------------------------------* + * denscale(c,a,n) scales every element in the n by n dense * + * matrix a by c. * + * * + ******************************************************************/ + +void denscale(realtype c, realtype **a, integertype n); + + +/****************************************************************** + * * + * Function : denaddI * + * Usage : denaddI(a,n); * + *----------------------------------------------------------------* + * denaddI(a,n) increments the n by n dense matrix a by the * + * identity matrix. * + * * + ******************************************************************/ + +void denaddI(realtype **a, integertype n); + + +/****************************************************************** + * * + * Function : denfreepiv * + * Usage : denfreepiv(p); * + *----------------------------------------------------------------* + * denfreepiv(p) frees the pivot array p allocated by * + * denallocpiv. * + * * + ******************************************************************/ + +void denfreepiv(integertype *p); + + +/****************************************************************** + * * + * Function : denfree * + * Usage : denfree(a); * + *----------------------------------------------------------------* + * denfree(a) frees the dense matrix a allocated by denalloc. * + * * + ******************************************************************/ + +void denfree(realtype **a); + + +/****************************************************************** + * * + * Function : denprint * + * Usage : denprint(a,n); * + *----------------------------------------------------------------* + * denprint(a,n) prints the n by n dense matrix a to standard * + * output as it would normally appear on paper. It is intended as * + * a debugging tool with small values of n. The elements are * + * printed using the %g option. A blank line is printed before * + * and after the matrix. * + * * + ******************************************************************/ + +void denprint(realtype **a, integertype n); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/spread.cpp b/spread.cpp new file mode 100644 index 00000000..61fdc15c --- /dev/null +++ b/spread.cpp @@ -0,0 +1,1069 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: spread.c 187 2005-03-16 19:54:17Z charlton $"; + +#define STATIC static + +#define STRING 11 +#define NUMBER 12 +#define MIXED 13 +#define EOL 14 + +#define OPTION_EOF -1 +#define OPTION_KEYWORD -2 +#define OPTION_ERROR -3 +#define OPTION_DEFAULT -4 +#define OPT_1 -5 + +static int copy_token_tab(char *token_ptr, char **ptr, int *length); +static int get_option_string (const char **opt_list, int count_opt_list, char **next_char); +static int spread_row_free(struct spread_row *spread_row_ptr); +static int spread_row_to_solution(struct spread_row *heading, struct spread_row *units, struct spread_row *data, struct defaults defaults); +static struct spread_row *string_to_spread_row(char *string); +#ifdef PHREEQCI_GUI +static void add_row(struct spread_row *spread_row_ptr); +static void copy_defaults(struct defaults *dest_ptr, struct defaults *src_ptr); +void free_spread(void); +static struct spread_row *copy_row(struct spread_row *spread_row_ptr); +#endif + +/* ---------------------------------------------------------------------- */ +int read_solution_spread(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution data + * + * 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 + * + */ + struct spread_row *heading, *row_ptr, *units; + int i, j, l, j1, num, count; + int strings, numbers; + int spread_lines; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + char *ptr; + struct defaults defaults = { + 25, + 1, + "mmol/kgw", + "pe", + 7, + 4, + 1, + 1, + iso_defaults, + }; + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "temp", /* 0 */ + "temperature", /* 1 */ + "dens", /* 2 */ + "density", /* 3 */ + "units", /* 4 */ + "redox", /* 5 */ + "ph", /* 6 */ + "pe", /* 7 */ + "unit", /* 8 */ + "isotope", /* 9 */ + "water", /* 10 */ + "isotope_uncertainty", /* 11 */ + "uncertainty", /* 12 */ + "uncertainties" /* 13 */ + }; + int count_opt_list = 14; + if (svnid == NULL) fprintf(stderr," "); + + heading = NULL; + units = NULL; + defaults.count_iso = count_iso_defaults; + defaults.iso = (struct iso *) PHRQ_malloc((size_t) defaults.count_iso * sizeof(struct iso)); + if (defaults.iso == NULL) malloc_error(); + memcpy(defaults.iso, iso_defaults, (size_t) defaults.count_iso * sizeof(struct iso)); + return_value = UNKNOWN; + spread_lines = 0; +/* + * Loop on solutions + */ + for (;;) { + opt = get_option(opt_list, count_opt_list, &next_char); + if (spread_lines == 0 && opt != OPTION_DEFAULT) { + row_ptr = string_to_spread_row(line); + count = 0; + ptr = line; + numbers = 0; + strings = 0; + while ( ((j = copy_token(token, &ptr, &l)) != EMPTY)) { + count++; + if (j == UPPER || j == LOWER) strings++; + if (j == DIGIT) numbers++; + } +#ifdef SKIP + for (i = 0; i < row_ptr->count; i++) { + if (row_ptr->type_vector[i] == STRING) { + strings++; + } else if (row_ptr->type_vector[i] == NUMBER) { + numbers++; + } + } +#endif + /* + * Is 2nd token all number + */ + ptr = line; + copy_token(token, &ptr, &l); + j = copy_token(token, &ptr, &l); + num = FALSE; + if (j == DIGIT) { + strtod(token, &ptr); + j1 = copy_token(token1, &ptr, &l); + if (j1 != EMPTY) { + num = FALSE; + } else { + num = TRUE; + } + } + + /* + * Starts with hyphen + */ + ptr = line; + copy_token(token, &ptr, &l); + if (token[0] == '-') { + opt = opt; + } else { + switch (opt) { + case 0: /* temp */ + case 1: /* temperature */ + case 2: /* dens */ + case 3: /* density */ + case 10: /* water */ + if (count == 2 && num == TRUE) { + opt = opt; + } else { + opt = OPTION_DEFAULT; + } + break; + case 6: /* ph */ + case 7: /* pe */ + if ((count == 2 || count == 3 || count == 4) && num == TRUE) { + opt = opt; + } else { + opt = OPTION_DEFAULT; + } + break; + case 5: /* redox */ + case 4: /* units */ + case 8: /* unit */ + if (count == 2) { + opt = opt; + } else { + opt = OPTION_DEFAULT; + } + break; + case 9: /* isotope */ + if (row_ptr->count > 4) { + opt = OPTION_DEFAULT; + } else { + opt = opt; + } + break; + case 11: /* isotope_uncertainty */ + case 12: /* uncertainty */ + case 13: /* uncertainties */ + if (row_ptr->count > 3) { + opt = OPTION_DEFAULT; + } else { + opt = opt; + } + break; + } + } + spread_row_free(row_ptr); + } + if (opt == OPTION_DEFAULT) { + if (spread_lines == 0) { + opt = 100; + } + spread_lines++; + } + 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 SOLUTION keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case OPTION_DEFAULT: /* solution definition */ + row_ptr = string_to_spread_row(line); + if (spread_lines == 2) { + numbers = 0; + strings = 0; + for (i = 0; i < heading->count; i++) { + if (row_ptr->type_vector[i] == STRING) { + strings++; + } else if (row_ptr->type_vector[i] == NUMBER) { + numbers++; + } +#ifdef SKIP + if (row_ptr->type_vector[i] == STRING && + (strcmp_nocase(heading->char_vector[i],"units") != 0) && + (strcmp_nocase(heading->char_vector[i],"unit") != 0) && + (strcmp_nocase(heading->char_vector[i],"description") != 0) && + (strcmp_nocase(heading->char_vector[i],"desc") != 0) && + (strcmp_nocase(heading->char_vector[i],"descriptor") != 0) && + (strcmp_nocase(heading->char_vector[i],"redox") != 0) ) { + break; + } +#endif + } +#ifdef SKIP + if (i < heading->count) { + units = row_ptr; + break; + } +#endif + if (numbers == 0) { + units = row_ptr; + break; + } + } + spread_row_to_solution(heading, units, row_ptr, defaults); +#ifdef PHREEQCI_GUI + add_row(row_ptr); +#endif + spread_row_free(row_ptr); + break; + case 0: /* temperature */ + case 1: + sscanf(next_char,SCANFORMAT, &(defaults.temp)); + break; + case 2: /* density */ + case 3: + sscanf(next_char,SCANFORMAT, &(defaults.density)); + break; + case 4: /* units */ + case 8: /* unit */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (check_units (token, FALSE, FALSE, NULL, TRUE) == OK) { + defaults.units = string_hsave(token); + } else { + input_error++; + } + break; + case 5: /* redox */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (parse_couple(token) == OK) { + defaults.redox = string_hsave(token); + } else { + input_error++; + } + break; + case 6: /* ph */ + copy_token (token, &next_char, &l); + sscanf(token,SCANFORMAT, &(defaults.ph)); + if (copy_token (token, &next_char, &l) != EMPTY) { + warning_msg("Not possible to use phase name or saturation index in definition of default pH in SOLUTION_SPREAD."); + } + break; + case 7: /* pe */ + copy_token (token, &next_char, &l); + sscanf(token,SCANFORMAT, &(defaults.pe)); + if (copy_token (token, &next_char, &l) != EMPTY) { + warning_msg("Not possible to use phase name or saturation index in definition of default pe in SOLUTION_SPREAD."); + } + break; + case 11: /* isotope_uncertainty */ + case 12: /* uncertainty */ + case 13: /* uncertainties */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected isotope name to" + " begin with an isotopic number."); + error_msg(error_string, CONTINUE); + continue; + } + for (i = 0; i < defaults.count_iso; i++) { + if (strcmp(token, defaults.iso[i].name) == 0) { + break; + } + } + if (i == defaults.count_iso) { + defaults.iso = (struct iso *) PHRQ_realloc(defaults.iso, (size_t) (i+1) * sizeof(struct iso)); + if (defaults.iso == NULL) malloc_error(); + defaults.iso[i].name = string_duplicate(token); + defaults.iso[i].value = NAN; + defaults.iso[i].uncertainty = NAN; + defaults.count_iso++; + } + + /* read and store isotope ratio uncertainty */ + if ( (j = copy_token(token, &next_char, &l)) != EMPTY) { + if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for uncertainty in isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } else { + sscanf(token, SCANFORMAT, &(defaults.iso[i].uncertainty)); + } + } else { + defaults.iso[i].uncertainty = NAN; + } + break; + case 10: /* water */ + j = copy_token (token, &next_char, &l); + if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for mass of water in solution."); + error_msg(error_string, CONTINUE); + } else { + sscanf(token, SCANFORMAT, &(defaults.water)); + } + break; + case 9: /* isotope */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected isotope name to" + " begin with an isotopic number."); + error_msg(error_string, CONTINUE); + continue; + } + for (i = 0; i < defaults.count_iso; i++) { + if (strcmp(token, defaults.iso[i].name) == 0) { + break; + } + } + if (i == defaults.count_iso) { + defaults.iso = (struct iso *) PHRQ_realloc(defaults.iso, (size_t) (i+1) * sizeof(struct iso)); + if (defaults.iso == NULL) malloc_error(); + defaults.iso[i].name = string_duplicate(token); + defaults.iso[i].value = NAN; + defaults.iso[i].uncertainty = NAN; + defaults.count_iso++; + } + /* read and store isotope ratio */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for default isotope ratio."); + error_msg(error_string, CONTINUE); + break; + } + sscanf(token, SCANFORMAT, &(defaults.iso[i].value)); + /* read and store isotope ratio uncertainty */ + if ( (j = copy_token(token, &next_char, &l)) != EMPTY) { + if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for uncertainty in isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } else { + sscanf(token, SCANFORMAT, &(defaults.iso[i].uncertainty)); + } + } + break; + case 100: /* read headings */ + heading = string_to_spread_row(line); + for (i = 0; i < heading->count; i++) { + while(replace(" ", "", heading->char_vector[i]) == TRUE); + while(replace(",", "_", heading->char_vector[i]) == TRUE); + } + + break; + } + if (return_value == EOF || return_value == KEYWORD) break; + } +#ifdef PHREEQCI_GUI + if (heading) g_spread_sheet.heading = copy_row(heading); + if (units) g_spread_sheet.units = copy_row(units); + copy_defaults(&g_spread_sheet.defaults, &defaults); +#endif + spread_row_free(heading); + spread_row_free(units); + /* free non-default iso names */ + for (i = count_iso_defaults; i < defaults.count_iso; i++) { + defaults.iso[i].name = (char *) free_check_null(defaults.iso[i].name); + } + defaults.iso = (struct iso *) free_check_null(defaults.iso); + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int spread_row_to_solution(struct spread_row *heading, struct spread_row *units, + struct spread_row *data, struct defaults defaults) +/* ---------------------------------------------------------------------- */ +{ + int i, j, n, l, next_keyword_save; + int n_user, n_user_end; + int default_pe, alk; + int count_isotopes; + int max_mass_balance, count_mass_balance; + char *ptr, *ptr1; + char *description; + char token[MAX_LENGTH], token1[MAX_LENGTH]; + char string[2*MAX_LENGTH]; + LDBLE dummy; + + int return_value, opt; + char *next_char; + const char *opt_list[] = { + "temp", /* 0 */ + "temperature", /* 1 */ + "dens", /* 2 */ + "density", /* 3 */ + "units", /* 4 */ + "redox", /* 5 */ + "ph", /* 6 */ + "pe", /* 7 */ + "unit", /* 8 */ + "isotope", /* 9 */ + "water", /* 10 */ + "description", /* 11 */ + "desc", /* 12 */ + "descriptor" /* 13 */ + + }; + int count_opt_list = 14; + +/* + * look for solution number + */ + n_user = -1; + n_user_end = -1; + description = string_duplicate(""); + for (i = 0; i < heading->count; i++) { + if (strcmp_nocase(heading->char_vector[i], "number") == 0) { + break; + } + } + if (i == heading->count || data->type_vector[i] == EMPTY || data->count <= i) { + n_user = -1; +#ifdef SKIP + for (i = 0; i < count_solution; i++) { + if (n_user <= solution[i]->n_user) { + n_user = solution[i]->n_user + 1; + } + } +#endif + } else if (data->type_vector[i] == STRING) { + input_error++; + sprintf(error_string,"Expected solution number or number range in 'number' column, found: %s.", data->char_vector[i]); + error_msg(error_string, CONTINUE); + } else { + strcpy(string, "solution_s "); + strcat(string, data->char_vector[i]); + ptr = string; + description = (char *) free_check_null(description); + next_keyword_save = next_keyword; + next_keyword = 42; + read_number_description (ptr, &n_user, &n_user_end, &description); + next_keyword = next_keyword_save; + } +/* + * set up solution + */ + + if (n_user >= 0 && solution_bsearch(n_user, &n, FALSE) != NULL) { + solution_free(solution[n]); + } else { + n=count_solution++; + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, sizeof (struct solution *) ); + } + } + solution[n] = solution_alloc(); + + solution[n]->n_user = n_user; + solution[n]->n_user_end = n_user_end; + if (use.solution_in == FALSE) { + use.solution_in = TRUE; + use.n_solution_user = n_user; + } + max_mass_balance=MAX_MASS_BALANCE; +/* + * Set default ph, temp, density, pe, units + */ + solution[n]->description = description; + solution[n]->tc=defaults.temp; + solution[n]->ph=defaults.ph; + solution[n]->density=defaults.density; + solution[n]->solution_pe = defaults.pe; + solution[n]->mass_water=defaults.water; + solution[n]->ah2o = 1.0; + solution[n]->mu = 1e-7; + solution[n]->cb = 0.0; + default_pe = 0; + solution[n]->units = defaults.units; + solution[n]->totals[0].description=NULL; + count_mass_balance=0; + count_isotopes = 0; + default_pe = pe_data_store (&(solution[n]->pe), defaults.redox); +/* + * Read concentration data + */ + return_value = UNKNOWN; + for (i = 0; i < heading->count; i++) { + if (strcmp_nocase(heading->char_vector[i], "number") == 0) continue; + if (strcmp_nocase(heading->char_vector[i], "uncertainty") == 0) continue; + if (strcmp_nocase(heading->char_vector[i], "uncertainties") == 0) continue; + if (strcmp_nocase(heading->char_vector[i], "isotope_uncertainty") == 0) continue; + /* + * Copy in element name + */ + if (heading->type_vector[i] == EMPTY) continue; + strcpy(string, heading->char_vector[i]); + strcat(string, " "); + /* + * Copy in concentration data + */ + if (i >= data->count || data->type_vector[i] == EMPTY) continue; + strcat(string, data->char_vector[i]); + strcat(string, " "); + /* + * Copy in concentration data + */ + if (units != NULL && i < units->count && units->type_vector[i] != EMPTY) { + strcat(string, units->char_vector[i]); + } +/* + * Parse string just like read_solution input + */ + next_char = string; + opt = get_option_string(opt_list, count_opt_list, &next_char); + if (opt == OPTION_DEFAULT && heading->type_vector[i] == NUMBER) { + opt = 9; + } + 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 SOLUTION keyword.", CONTINUE); + error_msg(line_save, CONTINUE); + break; + case 0: /* temperature */ + case 1: + sscanf(next_char,SCANFORMAT, &(solution[n]->tc)); + break; + case 2: /* density */ + case 3: + sscanf(next_char,SCANFORMAT, &(solution[n]->density)); + break; + case 4: /* units */ + case 8: /* unit */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (check_units (token, FALSE, FALSE, solution[n]->units, TRUE) == OK) { + solution[n]->units = string_hsave(token); + } else { + input_error++; + } + break; + case 5: /* redox */ + if (copy_token (token, &next_char, &l) == EMPTY) break; + if (parse_couple(token) == OK) { + default_pe = pe_data_store (&(solution[n]->pe), token); + } else { + input_error++; + } + break; + case 6: /* ph */ + next_char = string; + if ( read_conc(n, count_mass_balance, next_char) == ERROR ) { + input_error++; + break; + } + solution[n]->ph = solution[n]->totals[count_mass_balance].input_conc; + if (solution[n]->totals[count_mass_balance].equation_name == NULL ) { + break; + } + solution[n]->totals[count_mass_balance].description = string_hsave("H(1)"); + count_mass_balance++; + break; + case 7: /* pe */ + next_char = string; + if ( read_conc(n, count_mass_balance, next_char) == ERROR ) { + input_error++; + break; + } + solution[n]->solution_pe = solution[n]->totals[count_mass_balance].input_conc; + if (solution[n]->totals[count_mass_balance].equation_name == NULL ) { + break; + } + solution[n]->totals[count_mass_balance].description = string_hsave("E"); + count_mass_balance++; + break; + case 9: /* isotope */ + next_char = string; + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected isotope name to" + " begin with an isotopic number."); + error_msg(error_string, CONTINUE); + continue; + } + solution[n]->isotopes = (struct isotope *) PHRQ_realloc(solution[n]->isotopes, (size_t) (count_isotopes + 1) * sizeof(struct isotope)); + if (solution[n]->isotopes == NULL) malloc_error(); + /* read and save element name */ + ptr1 = token; + get_num(&ptr1, &(solution[n]->isotopes[count_isotopes].isotope_number)); + if (ptr1[0] == '\0' || isupper((int) ptr1[0]) == FALSE) { + error_msg("Expecting element name.", CONTINUE); + error_msg(line_save, CONTINUE); + input_error++; + return(ERROR); + } + solution[n]->isotopes[count_isotopes].elt_name = string_hsave(ptr1); + + /* read and store isotope ratio */ + if (copy_token(token, &next_char, &l) != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for isotope ratio."); + error_msg(error_string, CONTINUE); + continue; + } + sscanf(token, SCANFORMAT, &(solution[n]->isotopes[count_isotopes].ratio)); + + /* read and store isotope ratio uncertainty */ + /* first choice is next column */ + if ((i + 1) < heading->count && + (strcmp_nocase(heading->char_vector[i+1], "uncertainty") == 0 || + strcmp_nocase(heading->char_vector[i+1], "isotope_uncertainty") == 0 || + strcmp_nocase(heading->char_vector[i+1], "uncertainties") == 0) && + (i + 1) < data->count && + data->type_vector[i+1] == NUMBER) { + solution[n]->isotopes[count_isotopes].ratio_uncertainty = data->d_vector[i+1]; + } else { + next_char = string; + copy_token (token, &next_char, &l); + for (j = 0; j < defaults.count_iso; j++) { + if (strcmp(token, defaults.iso[j].name) == 0) { + solution[n]->isotopes[count_isotopes].ratio_uncertainty = defaults.iso[j].uncertainty; + break; + } + } + if (j == defaults.count_iso) { + solution[n]->isotopes[count_isotopes].ratio_uncertainty = NAN; + } + } + count_isotopes++; + break; + case 10: /* water */ + j = copy_token (token, &next_char, &l); + if (j == EMPTY) { + solution[n]->mass_water=1.0; + } else if (j != DIGIT) { + input_error++; + sprintf(error_string, "Expected numeric value for mass of water in solution."); + error_msg(error_string, CONTINUE); + } else { + sscanf(token, SCANFORMAT, &dummy); + solution[n]->mass_water = (LDBLE) dummy; + } + break; + case 11: /* description */ + case 12: /* desc */ + case 13: /* descriptor */ + solution[n]->description = (char *) free_check_null(solution[n]->description); + solution[n]->description = string_duplicate(next_char); + break; + case OPTION_DEFAULT: +/* + * Read concentration + */ + next_char = string; + if (copy_token (token, &next_char, &l) == LOWER) continue; + next_char = string; + if ( read_conc(n, count_mass_balance, next_char) == ERROR ) { +#ifdef SKIP + input_error++; + break; +#endif + } + count_mass_balance++; + break; + } + if (count_mass_balance + 1 >= max_mass_balance) { + space ((void **) &(solution[n]->totals), count_mass_balance + 1, + &max_mass_balance, sizeof (struct conc)); + } + if (return_value == EOF || return_value == KEYWORD) break; + } +/* + * Sort totals by description + */ + qsort (solution[n]->totals, + (size_t) count_mass_balance, + (size_t) sizeof(struct conc), + conc_compare); +/* + * fix up default units and default pe + */ + for (i=0; i < count_mass_balance; i++) { + strcpy(token, solution[n]->totals[i].description); + str_tolower(token); + if (solution[n]->totals[i].units == NULL) { + solution[n]->totals[i].units = solution[n]->units; + } else { + alk = FALSE; + if (strstr(token, "alk") == token) alk = TRUE; + strcpy(token1, solution[n]->totals[i].units); + if (check_units (token1, alk, TRUE, solution[n]->units, TRUE) == ERROR ) { + input_error++; + } else { + solution[n]->totals[i].units = string_hsave(token1); + } + } + if (solution[n]->totals[i].n_pe < 0) { + solution[n]->totals[i].n_pe = default_pe; + } + } + solution[n]->default_pe = default_pe; +/* + * Mark end of solution + */ + solution[n]->totals[count_mass_balance].description = NULL; + solution[n]->count_isotopes = count_isotopes; + if (count_isotopes > 0) { + qsort (solution[n]->isotopes, + (size_t) count_isotopes, + (size_t) sizeof(struct isotope), + isotope_compare); + } else { + solution[n]->isotopes = (struct isotope *) free_check_null(solution[n]->isotopes); + } + return(return_value); +} + +/* ---------------------------------------------------------------------- */ +struct spread_row *string_to_spread_row(char *string) +/* ---------------------------------------------------------------------- */ +{ + int j, l; + int length = 10; + char token[MAX_LENGTH]; + char *ptr; + struct spread_row *spread_row_ptr; +/* + * Allocate space + */ + spread_row_ptr = (struct spread_row *) PHRQ_malloc((size_t) sizeof(struct spread_row)); + if (spread_row_ptr == NULL) malloc_error(); + spread_row_ptr->char_vector = (char **) PHRQ_malloc((size_t) length * sizeof(char *)); + if (spread_row_ptr->char_vector == NULL) malloc_error(); + spread_row_ptr->d_vector = (LDBLE *) PHRQ_malloc((size_t) length * sizeof(LDBLE)); + if (spread_row_ptr->d_vector == NULL) malloc_error(); + spread_row_ptr->type_vector = (int *) PHRQ_malloc((size_t) length * sizeof(int)); + if (spread_row_ptr->type_vector == NULL) malloc_error(); + spread_row_ptr->count = 0; + spread_row_ptr->empty = 0; + spread_row_ptr->string = 0; + spread_row_ptr->number = 0; + ptr = string; +/* + * Split by tabs, reallocate space + */ + for (;;) { + if (spread_row_ptr->count + 1 > length) { + length *= 2; + + spread_row_ptr->char_vector = (char **) PHRQ_realloc(spread_row_ptr->char_vector, (size_t) length * sizeof(char *)); + if (spread_row_ptr->char_vector == NULL) malloc_error(); + + spread_row_ptr->d_vector = (LDBLE *) PHRQ_realloc(spread_row_ptr->d_vector, (size_t) length * sizeof(LDBLE)); + if (spread_row_ptr->d_vector == NULL) malloc_error(); + + spread_row_ptr->type_vector = (int *) PHRQ_realloc(spread_row_ptr->type_vector, (size_t) length * sizeof(int)); + if (spread_row_ptr->type_vector == NULL) malloc_error(); + } + j = copy_token_tab(token, &ptr, &l); + if (j == EOL) break; + spread_row_ptr->char_vector[spread_row_ptr->count] = string_duplicate(token); + spread_row_ptr->d_vector[spread_row_ptr->count] = NAN; + if (j == EMPTY || l == 0) { + spread_row_ptr->empty++; + spread_row_ptr->type_vector[spread_row_ptr->count] = EMPTY; + } else if (j == UPPER || j == LOWER) { + spread_row_ptr->string++; + spread_row_ptr->type_vector[spread_row_ptr->count] = STRING; + } else if (j == DIGIT) { + spread_row_ptr->number++; + spread_row_ptr->d_vector[spread_row_ptr->count] = strtod(token, NULL); + spread_row_ptr->type_vector[spread_row_ptr->count] = NUMBER; + } + spread_row_ptr->count++; + } +/* + * Clean up and return + */ + if (spread_row_ptr->count == 0) { + spread_row_ptr->char_vector = (char **) free_check_null(spread_row_ptr->char_vector); + spread_row_ptr->d_vector = (LDBLE *) free_check_null(spread_row_ptr->d_vector); + spread_row_ptr->type_vector = (int *) free_check_null(spread_row_ptr->type_vector); + } else { + spread_row_ptr->char_vector = (char **) PHRQ_realloc(spread_row_ptr->char_vector, (size_t) spread_row_ptr->count * sizeof(char *)); + if (spread_row_ptr->char_vector == NULL) malloc_error(); + spread_row_ptr->d_vector = (LDBLE *) PHRQ_realloc(spread_row_ptr->d_vector, (size_t) spread_row_ptr->count * sizeof(LDBLE)); + if (spread_row_ptr->d_vector == NULL) malloc_error(); + spread_row_ptr->type_vector = (int *) PHRQ_realloc(spread_row_ptr->type_vector, (size_t) spread_row_ptr->count * sizeof(int)); + if (spread_row_ptr->type_vector == NULL) malloc_error(); + + } + return (spread_row_ptr); +} +/* ---------------------------------------------------------------------- */ +int spread_row_free(struct spread_row *spread_row_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; + + if (spread_row_ptr == NULL) return(OK); + for (i = 0; i< spread_row_ptr->count; i++) { + spread_row_ptr->char_vector[i] = (char *) free_check_null(spread_row_ptr->char_vector[i]); + } + + spread_row_ptr->char_vector = (char **) free_check_null(spread_row_ptr->char_vector); + spread_row_ptr->d_vector = (double *) free_check_null(spread_row_ptr->d_vector); + spread_row_ptr->type_vector = (int *) free_check_null(spread_row_ptr->type_vector); + spread_row_ptr = (struct spread_row *) free_check_null(spread_row_ptr); + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int copy_token_tab(char *token_ptr, char **ptr, int *length) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies from **ptr to *token_ptr until first tab is encountered. + * + * Arguments: + * *token_ptr output, place to store token + * + * **ptr input, character string to read token from + * output, next position after token + * + * length output, length of token + * + * Returns: + * UPPER, + * LOWER, + * DIGIT, + * EMPTY, + * EOL, + * UNKNOWN. + */ + int i, j, return_value; + char c; +/* + * Strip leading spaces + */ + while ( (c=**ptr) == ' ' ) (*ptr)++; +/* + * Check what we have + */ + if ( isupper((int) c) ) { + return_value=UPPER; + } else if ( islower((int) c) ) { + return_value=LOWER; + } else if ( isdigit((int) c) || c=='.' || c=='-') { + return_value=DIGIT; + } else if ( c == '\0') { + return_value=EOL; + return(return_value); + } else if ( c == '\t') { + return_value=EMPTY; + } else { + return_value=UNKNOWN; + } +/* + * Begin copying to token + */ + i=0; +#ifdef SKIP + while ( (c=**ptr) != '\t' && + c != '\0' ) { + token_ptr[i]=c; + (*ptr)++; + i++; + } +#endif + for (;;) { + c=**ptr; + if (c == '\t') { + (*ptr)++; + break; + } else if (c =='\0') { + break; + } else { + token_ptr[i]=c; + (*ptr)++; + i++; + } + } + token_ptr[i]='\0'; + *length=i; +/* + * Strip trailing spaces + */ + for (j = i-1; j >= 0; j--) { + if (j != ' ') break; + } + if (j != i-1) { + token_ptr[j+1]='\0'; + *length=j+1; + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +static int get_option_string (const char **opt_list, int count_opt_list, char **next_char) +/* ---------------------------------------------------------------------- */ +{ +/* + * Read a line and check for options + */ + int j; + int opt_l, opt; + char *opt_ptr; + char option[MAX_LENGTH]; + + opt_ptr = *next_char; + if (opt_ptr[0] == '-') { + opt_ptr++; + copy_token(option, &opt_ptr, &opt_l); + if (find_option(&(option[1]), &opt, opt_list, count_opt_list, FALSE) == OK) { + j = opt; + *next_char = opt_ptr; + } else { + error_msg("Unknown option.", CONTINUE); + error_msg(*next_char, CONTINUE); + input_error++; + j = OPTION_ERROR; + } + } else { + copy_token(option, &opt_ptr, &opt_l); + if (find_option(&(option[0]), &opt, opt_list, count_opt_list, TRUE) == OK) { + j = opt; + *next_char = opt_ptr; + } else { + j = OPTION_DEFAULT; + } + } + return (j); +} +#ifdef PHREEQCI_GUI +/* ---------------------------------------------------------------------- */ +void free_spread(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + spread_row_free(g_spread_sheet.heading); + spread_row_free(g_spread_sheet.units); + for (i = 0; i < g_spread_sheet.count_rows; i++) + { + spread_row_free(g_spread_sheet.rows[i]); + } + g_spread_sheet.rows = free_check_null(g_spread_sheet.rows); + + for (i = 0; i < g_spread_sheet.defaults.count_iso; i++) + { + g_spread_sheet.defaults.iso[i].name = free_check_null(g_spread_sheet.defaults.iso[i].name); + } + g_spread_sheet.defaults.iso = free_check_null(g_spread_sheet.defaults.iso); + + g_spread_sheet.defaults.redox = free_check_null(g_spread_sheet.defaults.redox); + g_spread_sheet.defaults.units = free_check_null(g_spread_sheet.defaults.units); +} +/* ---------------------------------------------------------------------- */ +void add_row(struct spread_row *spread_row_ptr) +/* ---------------------------------------------------------------------- */ +{ + g_spread_sheet.rows = (struct spread_row **) PHRQ_realloc(g_spread_sheet.rows, sizeof(struct spread_row*) * (g_spread_sheet.count_rows + 1)); + if (g_spread_sheet.rows == NULL) + { + malloc_error(); + } + else + { + g_spread_sheet.rows[g_spread_sheet.count_rows++] = copy_row(spread_row_ptr); + } +} +/* ---------------------------------------------------------------------- */ +struct spread_row *copy_row(struct spread_row *spread_row_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct spread_row *new_spread_row_ptr; +/* + * Allocate space + */ + new_spread_row_ptr = (struct spread_row *) PHRQ_malloc((size_t) sizeof(struct spread_row)); + if (new_spread_row_ptr == NULL) malloc_error(); + new_spread_row_ptr->char_vector = (char **) PHRQ_malloc((size_t) spread_row_ptr->count * sizeof(char *)); + if (new_spread_row_ptr->char_vector == NULL) malloc_error(); + new_spread_row_ptr->d_vector = (LDBLE *) PHRQ_malloc((size_t) spread_row_ptr->count * sizeof(LDBLE)); + if (new_spread_row_ptr->d_vector == NULL) malloc_error(); + new_spread_row_ptr->type_vector = (int *) PHRQ_malloc((size_t) spread_row_ptr->count * sizeof(int)); + if (new_spread_row_ptr->type_vector == NULL) malloc_error(); + + for (i = 0; i < spread_row_ptr->count; i++) + { + new_spread_row_ptr->char_vector[i] = string_duplicate(spread_row_ptr->char_vector[i]); + new_spread_row_ptr->d_vector[i] = spread_row_ptr->d_vector[i]; + new_spread_row_ptr->type_vector[i] = spread_row_ptr->type_vector[i]; + } + new_spread_row_ptr->count = spread_row_ptr->count; + new_spread_row_ptr->empty = spread_row_ptr->empty; + new_spread_row_ptr->number = spread_row_ptr->number; + new_spread_row_ptr->string = spread_row_ptr->string; + + return new_spread_row_ptr; +} +/* ---------------------------------------------------------------------- */ +void copy_defaults(struct defaults *dest_ptr, struct defaults *src_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; + dest_ptr->count_iso = src_ptr->count_iso; + dest_ptr->density = src_ptr->density; + dest_ptr->iso = (struct iso*)PHRQ_malloc(sizeof(struct iso) * src_ptr->count_iso); + if (dest_ptr->iso == NULL) + { + malloc_error(); + } + else + { + for (i = 0; i < src_ptr->count_iso; i++) + { + dest_ptr->iso[i] = src_ptr->iso[i]; + dest_ptr->iso[i].name = string_duplicate(src_ptr->iso[i].name); + } + } + + dest_ptr->pe = src_ptr->pe; + dest_ptr->ph = src_ptr->ph; + dest_ptr->redox = string_duplicate(src_ptr->redox); + dest_ptr->temp = src_ptr->temp; + dest_ptr->units = string_duplicate(src_ptr->units); + dest_ptr->water = src_ptr->water; +} + +#endif diff --git a/step.cpp b/step.cpp new file mode 100644 index 00000000..1f60ae1d --- /dev/null +++ b/step.cpp @@ -0,0 +1,1028 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: step.c 406 2005-07-27 15:39:12Z dlpark $"; + +static int check_pp_assemblage (struct pp_assemblage *pp_assemblage_ptr); +static int gas_phase_check (struct gas_phase *gas_phase_ptr); +static int pp_assemblage_check (struct pp_assemblage *pp_assemblage_ptr); +static int reaction_calc(struct irrev *irrev_ptr); +static int solution_check (void); +static int s_s_assemblage_check (struct s_s_assemblage *s_s_assemblage_ptr); + +/* ---------------------------------------------------------------------- */ +int step(LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ +/* + * zero global solution, add solution or mixture, add exchange, + * add surface, add gas phase, add solid solutions, + * set temperature, and add reaction. + * Ensure all elements + * included in any of these are present in small amounts. + * Save result as n_user -1. + */ + LDBLE difftemp; + int step_number; + struct pp_assemblage *pp_assemblage_save = NULL; + struct s_s_assemblage *s_s_assemblage_save = NULL; + + if (svnid == NULL) fprintf(stderr," "); + +/* + * Zero out global solution data + */ + + xsolution_zero(); +/* + * Set reaction to zero + */ + step_x = 0.0; + step_number = reaction_step; +/* + * Mixing or solution + */ + if (use.mix_ptr != NULL) { + add_mix(use.mix_ptr); + } else if ( use.solution_ptr != NULL ) { + add_solution(use.solution_ptr, 1.0, 1.0); + } else { + input_error++; + error_msg("Neither mixing nor an initial solution have " + "been defined in reaction step.", STOP); + } +/* + * Reaction + */ + if(use.irrev_ptr != NULL) { + add_reaction(use.irrev_ptr, step_number, step_fraction); + } +/* + * Kinetics + */ + if(use.kinetics_ptr != NULL) { + add_kinetics(use.kinetics_ptr); + /* + master_ptr =master_bsearch("S(6)"); + output_msg(OUTPUT_MESSAGE,"Added kinetics, S(6) %e\n", master_ptr->total); + master_ptr =master_bsearch("S"); + output_msg(OUTPUT_MESSAGE,"Added kinetics, S %e\n", master_ptr->total); + */ + } +/* + * Exchange + */ + if (use.exchange_ptr != NULL) { + add_exchange(use.exchange_ptr); + } +/* + * Surface + */ + if (use.surface_ptr != NULL) { + add_surface(use.surface_ptr); + } +/* + * Gases + */ + if(use.gas_phase_ptr != NULL) { + add_gas_phase(use.gas_phase_ptr); + } +/* + * Temperature + */ + if(use.temperature_ptr != NULL) { + add_temperature(use.temperature_ptr, step_number); + } + if ((state == TRANSPORT) && (transport_step != 0) && + (cell > 0) && (cell != count_cells+1)) { + difftemp = tc_x - cell_data[cell-1].temp; + cell_data[cell-1].temp += difftemp/tempr; + tc_x = cell_data[cell-1].temp; + } +/* + * Pure phases and solid solutions are added to avoid + * zero or negative concentrations + */ +/* + * Pure phases + */ + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_save = (struct pp_assemblage *) PHRQ_malloc(sizeof(struct pp_assemblage)); + if (pp_assemblage_save == NULL) malloc_error(); + pp_assemblage_copy(use.pp_assemblage_ptr, pp_assemblage_save, use.pp_assemblage_ptr->n_user); + add_pp_assemblage (use.pp_assemblage_ptr); + } +/* + * Solid solutions + */ + if(use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_save = (struct s_s_assemblage *) PHRQ_malloc(sizeof(struct s_s_assemblage)); + if (s_s_assemblage_save == NULL) malloc_error(); + s_s_assemblage_copy(use.s_s_assemblage_ptr, s_s_assemblage_save, use.s_s_assemblage_ptr->n_user); + add_s_s_assemblage(use.s_s_assemblage_ptr); + } +/* + * Check that elements are available for gas components, + * pure phases, and solid solutions + */ + if(use.gas_phase_ptr != NULL) { + gas_phase_check(use.gas_phase_ptr); + } + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_check (use.pp_assemblage_ptr); + } + if(use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_check(use.s_s_assemblage_ptr); + } +/* + * Check that element moles are >= zero + */ + if (solution_check() == MASS_BALANCE) { + /* reset moles and deltas */ + if (use.pp_assemblage_ptr != NULL) { + pp_assemblage_free(use.pp_assemblage_ptr); + pp_assemblage_copy(pp_assemblage_save, use.pp_assemblage_ptr, use.pp_assemblage_ptr->n_user); + pp_assemblage_free(pp_assemblage_save); + pp_assemblage_save = (struct pp_assemblage *) free_check_null(pp_assemblage_save); + } + if (use.s_s_assemblage_ptr != NULL) { + s_s_assemblage_free(use.s_s_assemblage_ptr); + s_s_assemblage_copy(s_s_assemblage_save, use.s_s_assemblage_ptr, use.s_s_assemblage_ptr->n_user); + s_s_assemblage_free(s_s_assemblage_save); + s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(s_s_assemblage_save); + } + return(MASS_BALANCE); + } +/* + * Copy global into solution n_user = -1 + */ + xsolution_save(-1); + step_save_surf(-1); + step_save_exch(-1); +/* + * Clean up temporary space + */ + if (pp_assemblage_save != NULL) { + pp_assemblage_free(pp_assemblage_save); + pp_assemblage_save = (struct pp_assemblage *) free_check_null(pp_assemblage_save); + } + if (s_s_assemblage_save != NULL) { + s_s_assemblage_free(s_s_assemblage_save); + s_s_assemblage_save = (struct s_s_assemblage *) free_check_null(s_s_assemblage_save); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int xsolution_zero (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Zero out _x variables, master->totals, and species->la + */ + int i; +/* + * Zero totals in master structures + */ + new_x = FALSE; + + tc_x = 0.0; + ph_x = 0.0; + solution_pe_x = 0.0; + mu_x = 0.0; + ah2o_x = 0.0; + density_x = 0.0; + total_h_x = 0.0; + total_o_x = 0.0; + cb_x = 0.0; + mass_water_aq_x = 0.0; + units_x = moles_per_kilogram_string; + + for (i=0; i < count_master; i++) { + master[i]->total = 0.0; + master[i]->total_primary = 0.0; + master[i]->s->la = 0.0; + } + if (pitzer_model == TRUE) { + for (i=0; i < count_s; i++) { + s[i]->lg = 0.0; + } + } +/* + * Copy pe data (not sure this will be used + */ +/* + pe_data_free (pe_x); + pe_x = pe_data_alloc(); + */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_solution (struct solution *solution_ptr, LDBLE extensive, LDBLE intensive) +/* ---------------------------------------------------------------------- */ +{ +/* + * Accumulate solution data in master->totals and _x variables. + * + * extensive is multiplication factor for solution + * intensive is fraction of all multiplication factors for all solutions + */ + int i; + struct master *master_ptr; + struct species *species_ptr; +/* + * Add solution to global variables + */ + tc_x += solution_ptr->tc * intensive; + ph_x += solution_ptr->ph * intensive; + solution_pe_x += solution_ptr->solution_pe * intensive; + mu_x += solution_ptr->mu * intensive; + ah2o_x += solution_ptr->ah2o * intensive; + density_x += solution_ptr->density * intensive; + + total_h_x += solution_ptr->total_h * extensive; + total_o_x += solution_ptr->total_o * extensive; + cb_x += solution_ptr->cb * extensive; + mass_water_aq_x += solution_ptr->mass_water * extensive; +/* + * Copy totals data into primary master species + */ + for (i=0; solution_ptr->totals[i].description != NULL; i++) { + master_ptr = master_bsearch_primary(solution_ptr->totals[i].description); + master_ptr->total += solution_ptr->totals[i].moles * extensive; + } +/* + * Accumulate initial guesses for activities + */ + /*for (i=0; solution_ptr->master_activity[i].description != NULL; i++) {*/ + for (i=0; i < solution_ptr->count_master_activity; i++) { + if (solution_ptr->master_activity[i].description != NULL) { + master_ptr = master_bsearch(solution_ptr->master_activity[i].description); + if (master_ptr != NULL) { + master_ptr->s->la += solution_ptr->master_activity[i].la * intensive; + } + } + } +/* + * Accumulate initial guesses for log gamma + */ + if (pitzer_model == TRUE) { + for (i=0; i < solution_ptr->count_species_gamma ; i++) { + species_ptr = s_search(solution_ptr->species_gamma[i].description); + if (species_ptr != NULL) { + species_ptr->lg += solution_ptr->species_gamma[i].la * intensive; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_exchange (struct exchange *exchange_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Accumulate exchange data in master->totals and _x variables. + */ + int i, j; + struct master *master_ptr; + + if (exchange_ptr == NULL) return(OK); +/* + * Add element concentrations on exchanger to master species totals + */ + for (i = 0; i < exchange_ptr->count_comps; i++) { + for (j = 0; exchange_ptr->comps[i].totals[j].elt != NULL; j++) { + master_ptr = exchange_ptr->comps[i].totals[j].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += exchange_ptr->comps[i].totals[j].coef; + } else if (master_ptr->s == s_h2o) { + total_o_x += exchange_ptr->comps[i].totals[j].coef; + } else { + master_ptr->total += exchange_ptr->comps[i].totals[j].coef; + } + } + } + if (exchange_ptr->new_def == TRUE) { + for (i = 0; i < count_master; i++) { + if (master[i]->type == EX && master[i]->total > 0) { + master[i]->s->la = log10(0.1 * master[i]->total); + } + } + } else { + for (i = 0; i < exchange_ptr->count_comps; i++) { + exchange_ptr->comps[i].master->s->la = exchange_ptr->comps[i].la; + cb_x += exchange_ptr->comps[i].charge_balance; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_surface (struct surface *surface_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Accumulate surface data in master->totals and _x variables. + */ + int i, j; + struct master *master_ptr; + + if (surface_ptr == NULL) return(OK); +/* + * Add element concentrations on surface to master species totals + */ + diffuse_layer_x = surface_ptr->diffuse_layer; + for (i = 0; i < surface_ptr->count_comps; i++) { + if(surface_ptr->edl == FALSE) { + cb_x += surface_ptr->comps[i].cb; + } + if (surface_ptr->new_def == FALSE) { + surface_ptr->comps[i].master->s->la = surface_ptr->comps[i].la; + } +/* + * Add surface and specifically sorbed elements + */ + for (j = 0; surface_ptr->comps[i].totals[j].elt != NULL; j++) { + master_ptr = surface_ptr->comps[i].totals[j].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += surface_ptr->comps[i].totals[j].coef; + } else if (master_ptr->s == s_h2o) { + total_o_x += surface_ptr->comps[i].totals[j].coef; + } else { + master_ptr->total += surface_ptr->comps[i].totals[j].coef; + } + } + } + if (surface_ptr->edl == FALSE) return(OK); + for (i = 0; i < surface_ptr->count_charge; i++) { + if (surface_ptr->edl == TRUE) { + cb_x += surface_ptr->charge[i].charge_balance; + } + if (surface_ptr->new_def == FALSE) { + surface_ptr->charge[i].psi_master->s->la = surface_ptr->charge[i].la_psi; + } +/* + * Add diffuse layer elements (including water in Debye layer) + */ + if (surface_ptr->diffuse_layer == TRUE && surface_ptr->new_def == FALSE) { + for (j = 0; surface_ptr->charge[i].diffuse_layer_totals[j].elt != NULL; j++) { + master_ptr = surface_ptr->charge[i].diffuse_layer_totals[j].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += surface_ptr->charge[i].diffuse_layer_totals[j].coef; + } else if (master_ptr->s == s_h2o) { + total_o_x += surface_ptr->charge[i].diffuse_layer_totals[j].coef; + } else { + master_ptr->total += surface_ptr->charge[i].diffuse_layer_totals[j].coef; + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_mix (struct mix *mix_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * calls add_solution to accumulate all data in master->totals + * and other variables. + */ + int i; + int n; + LDBLE sum_fractions, intensive, extensive; + struct solution *solution_ptr; + int count_positive; + LDBLE sum_positive; + + if (mix_ptr == NULL) return(OK); + if (mix_ptr->count_comps <= 0) return(OK); + sum_fractions = 0.0; + sum_positive = 0.0; + count_positive = 0; + for (i = 0; i < mix_ptr->count_comps; i++) { + sum_fractions += mix_ptr->comps[i].fraction; + if (mix_ptr->comps[i].fraction > 0) { + sum_positive += mix_ptr->comps[i].fraction; + count_positive++; + } + } + for (i = 0; i < mix_ptr->count_comps; i++) { + solution_ptr = solution_bsearch (mix_ptr->comps[i].n_solution, &n, TRUE); + if (solution_ptr == NULL) { + input_error++; + continue; + } + extensive = mix_ptr->comps[i].fraction; + intensive = extensive / sum_fractions; + if (count_positive < mix_ptr->count_comps) { + if (mix_ptr->comps[i].fraction > 0) { + intensive = extensive / sum_positive; + } else { + intensive = 0; + } + } + add_solution(solution_ptr, extensive, intensive); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_pp_assemblage (struct pp_assemblage *pp_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Add a small amount of each phase if necessary to insure + * all elements exist in solution. + */ + int i, j; + LDBLE amount_to_add, total; + char token[MAX_LENGTH]; + char *ptr; + struct pure_phase *pure_phase_ptr; + struct master *master_ptr; + + if (check_pp_assemblage(pp_assemblage_ptr) == OK) return(OK); +/* + * Go through list and generate list of elements and + * coefficient of elements in reaction + */ + count_elts = 0; + paren_count = 0; +/* + * Check that all elements are in solution for phases with greater than zero mass + */ + pure_phase_ptr = pp_assemblage_ptr->pure_phases; + for (j = 0; j < pp_assemblage_ptr->count_comps; j++) { + count_elts = 0; + paren_count = 0; + amount_to_add = 0.0; + pure_phase_ptr[j].delta = 0.0; + if (pure_phase_ptr[j].add_formula != NULL) { + strcpy(token, pure_phase_ptr[j].add_formula); + ptr = &(token[0]); + get_elts_in_species (&ptr, 1.0); + } else { + strcpy(token, pure_phase_ptr[j].phase->formula); + add_elt_list(pure_phase_ptr[j].phase->next_elt, 1.0); + } + if (pure_phase_ptr[j].moles > 0.0) { + for (i = 0; i < count_elts; i++) { + master_ptr = elt_list[i].elt->primary; + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } else if (master_ptr->total > MIN_TOTAL) { + continue; + } else { + total = (-master_ptr->total + 1e-10) / elt_list[i].coef; + if (amount_to_add < total) { + amount_to_add = total; + } + } + } + if (pure_phase_ptr[j].moles < amount_to_add) { + amount_to_add = pure_phase_ptr[j].moles; + } + } + if (amount_to_add > 0.0) { + pure_phase_ptr[j].moles -= amount_to_add; + pure_phase_ptr[j].delta = amount_to_add; +/* + * Add reaction to totals + */ + for (i = 0; i < count_elts; i++) { + master_ptr = elt_list[i].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += elt_list[i].coef * amount_to_add; + } else if (master_ptr->s == s_h2o) { + total_o_x += elt_list[i].coef * amount_to_add; + } else { + master_ptr->total += elt_list[i].coef * amount_to_add; + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int check_pp_assemblage (struct pp_assemblage *pp_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check list of all elements in pure_phase assemblage to see + * if all are in model. Return true if all are present, + * Return false if one or more is missing. + */ + int j; + struct master *master_ptr; + for (j = 0; pp_assemblage_ptr->next_elt[j].elt != NULL; j++) { + master_ptr = pp_assemblage_ptr->next_elt[j].elt->primary; + if (master_ptr->s == s_h2o || master_ptr->s == s_hplus) continue; + if (master_ptr->total > MIN_TOTAL) continue; + return(FALSE); + } + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int add_reaction (struct irrev *irrev_ptr, int step_number, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ +/* + * Add irreversible reaction + */ + int i; + char c; + struct master *master_ptr; +/* + * Calculate and save reaction + */ +/* !!!!! with kinetics reaction, coeff's may change + * and reaction_calc must be called .... + */ + if (irrev_ptr->elts == NULL ) { + if (reaction_calc(irrev_ptr) == ERROR) { + return(ERROR); + } + } +/* + * Step size + */ + if (incremental_reactions == FALSE) { + if (irrev_ptr->count_steps > 0) { + if (step_number > irrev_ptr->count_steps) { + step_x = irrev_ptr->steps[irrev_ptr->count_steps - 1]; + } else { + step_x = irrev_ptr->steps[step_number - 1]; + } + } else if (irrev_ptr->count_steps < 0) { + if (step_number > -irrev_ptr->count_steps) { + step_x = irrev_ptr->steps[0]; + } else { + step_x = irrev_ptr->steps[0] * + ( (LDBLE) step_number ) / ( (LDBLE) (-irrev_ptr->count_steps)); + } + } else { + step_x = 0.0; + } + } else { + /* Incremental reactions */ + if (irrev_ptr->count_steps > 0) { + if (step_number > irrev_ptr->count_steps) { + step_x = irrev_ptr->steps[irrev_ptr->count_steps - 1]; + } else { + step_x = irrev_ptr->steps[step_number - 1]; + } + } else if (irrev_ptr->count_steps < 0) { + if (step_number > -irrev_ptr->count_steps) { + step_x = 0; + } else { + step_x = irrev_ptr->steps[0] / ( (LDBLE) (-irrev_ptr->count_steps)); + } + } else { + step_x = 0.0; + } + } +/* + * Convert units + */ + c = irrev_ptr->units[0]; + if (c == 'm') { + step_x *= 1e-3; + } else if (c == 'u') { + step_x *= 1e-6; + } else if (c == 'n') { + step_x *= 1e-9; + } +/* + * Add reaction to totals + */ + for (i = 0; irrev_ptr->elts[i].elt != NULL; i++) { + master_ptr = irrev_ptr->elts[i].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += irrev_ptr->elts[i].coef * step_x * step_fraction; + } else if (master_ptr->s == s_h2o) { + total_o_x += irrev_ptr->elts[i].coef * step_x * step_fraction; + } else { + master_ptr->total += irrev_ptr->elts[i].coef * step_x * step_fraction; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int reaction_calc(struct irrev *irrev_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through irreversible reaction initially to + * determine a list of elements and amounts in + * the reaction. + */ + int i, j, return_value; + LDBLE coef; + char token[MAX_LENGTH]; + char *ptr; + struct phase *phase_ptr; +/* + * Go through list and generate list of elements and + * coefficient of elements in reaction + */ + return_value = OK; + count_elts = 0; + paren_count = 0; + + for (i=0; i < irrev_ptr->count_list; i++) { + coef = irrev_ptr->list[i].coef; + strcpy(token, irrev_ptr->list[i].name); + phase_ptr = phase_bsearch(token, &j, FALSE); +/* + * Reactant is a pure phase, copy formula into token + */ + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, coef); + } else { + ptr = &(token[0]); + get_elts_in_species (&ptr, coef); + } + } +/* + * Check that all elements are in database + */ + for (i = 0; i < count_elts; i++) { + if (elt_list[i].elt->master == NULL) { + sprintf(error_string, "Element or phase not defined in database, %s.", elt_list[i].elt->name); + error_msg(error_string, CONTINUE); + input_error++; + return_value = ERROR; + } + } + irrev_ptr->elts = elt_list_save(); + + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int add_temperature (struct temperature *temperature_ptr, int step_number) +/* ---------------------------------------------------------------------- */ +{ +/* + * Determine temperature of reaction step, if reaction_temperature + * information is present. + */ + int denom; + LDBLE tc_temp; +/* + * Find temperature + */ + if (temperature_ptr == NULL) return(ERROR); + if (temperature_ptr->count_t > 0) { + if (step_number > temperature_ptr->count_t) { + tc_temp = temperature_ptr->t[temperature_ptr->count_t - 1]; + } else { + tc_temp = temperature_ptr->t[step_number - 1]; + } + } else if (temperature_ptr->count_t < 0) { + if (step_number > -temperature_ptr->count_t) { + tc_temp = temperature_ptr->t[1]; + } else { + if (-temperature_ptr->count_t <= 1) { + denom = 1; + } else { + denom = -temperature_ptr->count_t - 1; + } + tc_temp = temperature_ptr->t[0] + (temperature_ptr->t[1] - temperature_ptr->t[0]) * + ( (LDBLE) (step_number - 1) ) / ( (LDBLE) denom ); + } + } else { + tc_temp = 25.0; + } + tc_x = tc_temp; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_gas_phase (struct gas_phase *gas_phase_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Accumulate gas data in master->totals and _x variables. + */ + int i; + + struct gas_comp *gas_comp_ptr; + struct master *master_ptr; + + if (gas_phase_ptr == NULL) return(OK); + gas_comp_ptr = gas_phase_ptr->comps; +/* + * calculate reaction + */ + count_elts = 0; + paren_count = 0; + for (i = 0; i < gas_phase_ptr->count_comps; i++) { + add_elt_list(gas_comp_ptr[i].phase->next_elt, gas_comp_ptr[i].moles); + } +/* + * Sort elements in reaction and combine + */ + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } +/* + * Add gas elements to totals + */ + for (i = 0; i < count_elts; i++) { + master_ptr = elt_list[i].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += elt_list[i].coef; + } else if (master_ptr->s == s_h2o) { + total_o_x += elt_list[i].coef; + } else { + master_ptr->total += elt_list[i].coef; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_s_s_assemblage (struct s_s_assemblage *s_s_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Accumulate solid_solution data in master->totals and _x variables. + */ + int i, j, k; + LDBLE amount_to_add, total; + struct s_s *s_s_ptr; + struct master *master_ptr; + char token[MAX_LENGTH]; + char *ptr; + + if (s_s_assemblage_ptr == NULL) return(OK); + count_elts = 0; + paren_count = 0; +/* + * Check that all elements are in solution for phases with greater than zero mass + */ + for (i = 0; i < s_s_assemblage_ptr->count_s_s; i++) { + count_elts = 0; + paren_count = 0; + s_s_ptr = &(s_s_assemblage_ptr->s_s[i]); + for (j = 0; j < s_s_ptr->count_comps; j++) { + amount_to_add = 0.0; + s_s_ptr->comps[j].delta = 0.0; + if (s_s_ptr->comps[j].moles > 0.0) { + strcpy(token, s_s_ptr->comps[j].phase->formula); + ptr = &(token[0]); + get_elts_in_species (&ptr, 1.0); + for (k = 0; k < count_elts; k++) { + master_ptr = elt_list[k].elt->primary; + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } else if (master_ptr->total > MIN_TOTAL) { + continue; + } else { + total = (-master_ptr->total + 1e-10) / elt_list[k].coef; + if (amount_to_add < total) { + amount_to_add = total; + } + } + } + } + if (s_s_ptr->comps[j].moles < amount_to_add) { + amount_to_add = s_s_ptr->comps[j].moles; + } + if (amount_to_add > 0.0) { + s_s_ptr->comps[j].moles -= amount_to_add; + s_s_ptr->comps[j].delta = amount_to_add; +/* + * Add reaction to totals + */ + for (k = 0; k < count_elts; k++) { + master_ptr = elt_list[k].elt->primary; + if (master_ptr->s == s_hplus) { + total_h_x += elt_list[k].coef * amount_to_add; + } else if (master_ptr->s == s_h2o) { + total_o_x += elt_list[k].coef * amount_to_add; + } else { + master_ptr->total += elt_list[k].coef * amount_to_add; + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_kinetics (struct kinetics *kinetics_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Add kinetic reaction + */ + int i; + struct master *master_ptr; +/* + * Add reaction to totals + */ + if (kinetics_ptr->totals == NULL) return(OK); + for (i = 0; kinetics_ptr->totals[i].elt != NULL; i++) { + master_ptr = kinetics_ptr->totals[i].elt->primary; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Element %s in kinetic reaction not found in database.", kinetics_ptr->totals[i].elt->name); + error_msg(error_string, STOP); + } + if (master_ptr->s == s_hplus) { + total_h_x += kinetics_ptr->totals[i].coef; + } else if (master_ptr->s == s_h2o) { + total_o_x += kinetics_ptr->totals[i].coef; + } else { + master_ptr->total += kinetics_ptr->totals[i].coef; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_check (struct gas_phase *gas_phase_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check for missing elements + */ + int i, j; + + struct gas_comp *gas_comp_ptr; + struct master *master_ptr; + + if (gas_phase_ptr == NULL) return(OK); + gas_comp_ptr = gas_phase_ptr->comps; +/* + * Check that all elements are in solution for phases with zero mass + */ + for (i = 0; i < gas_phase_ptr->count_comps; i++) { + count_elts = 0; + paren_count = 0; + if (gas_comp_ptr[i].moles <= 0.0) { + add_elt_list(gas_comp_ptr[i].phase->next_elt, 1.0); + for (j = 0; j < count_elts; j++) { + master_ptr = elt_list[j].elt->primary; + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } else if (master_ptr->total > MIN_TOTAL) { + continue; + } else { + if (state != ADVECTION && state != TRANSPORT && state != PHAST ) { + sprintf(error_string, "Element %s is contained in gas %s (which has 0.0 mass),\nbut is not in solution or other phases.", elt_list[j].elt->name, gas_comp_ptr[i].phase->name); + warning_msg(error_string); + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_check (struct pp_assemblage *pp_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check for missing elements + */ + int i, j, k; + char token[MAX_LENGTH]; + char *ptr; + struct pure_phase *pure_phase_ptr; + struct master *master_ptr; + + if (check_pp_assemblage(pp_assemblage_ptr) == OK) return(OK); +/* + * Check that all elements are in solution for phases with zero mass + */ + pure_phase_ptr = pp_assemblage_ptr->pure_phases; + for (j = 0; j < pp_assemblage_ptr->count_comps; j++) { + count_elts = 0; + paren_count = 0; + if (pure_phase_ptr[j].moles <= 0.0) { + pure_phase_ptr[j].delta = 0.0; + if (pure_phase_ptr[j].add_formula != NULL) { + strcpy(token, pure_phase_ptr[j].add_formula); + ptr = &(token[0]); + get_elts_in_species (&ptr, 1.0); + } else { + strcpy(token, pure_phase_ptr[j].phase->formula); + add_elt_list(pure_phase_ptr[j].phase->next_elt, 1.0); + } + for (i = 0; i < count_elts; i++) { + master_ptr = elt_list[i].elt->primary; + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } else if (master_ptr->total > MIN_TOTAL) { + continue; + } else { + if (state != ADVECTION && state != TRANSPORT && state != PHAST) { + sprintf(error_string, "Element %s is contained in %s (which has 0.0 mass)," + "\t\nbut is not in solution or other phases.", elt_list[i].elt->name, pure_phase_ptr[j].phase->name); + warning_msg(error_string); + } +/* + * Make la's of all master species for the element small, so SI will be small + * and no mass transfer will be calculated + */ + for (k = 0; k < count_master; k++) { + if (master[k]->elt->primary == master_ptr) { + master[k]->s->la = -9999.999; + } + } + } + } + } + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_check (struct s_s_assemblage *s_s_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check for missing elements + */ + int i, j, k, l; + struct master *master_ptr; + + if (s_s_assemblage_ptr == NULL) return(OK); +/* + * Check that all elements are in solution for phases with zero mass + */ + for (i = 0; i < s_s_assemblage_ptr->count_s_s; i++) { + for (j = 0; j < s_s_assemblage_ptr->s_s[i].count_comps; j++) { + count_elts = 0; + paren_count = 0; + if (s_s_assemblage_ptr->s_s[i].comps[j].moles <= 0.0) { + add_elt_list(s_s_assemblage_ptr->s_s[i].comps[j].phase->next_elt, 1.0); + for (l = 0; l < count_elts; l++) { + master_ptr = elt_list[l].elt->primary; + if (master_ptr->s == s_hplus) { + continue; + } else if (master_ptr->s == s_h2o) { + continue; + } else if (master_ptr->total > MIN_TOTAL) { + continue; + } else { + if (state != ADVECTION && state != TRANSPORT && state != PHAST ) { + sprintf(error_string, "Element %s is contained in solid solution %s (which has 0.0 mass),\nbut is not in solution or other phases.", elt_list[l].elt->name, s_s_assemblage_ptr->s_s[i].comps[j].phase->name); + warning_msg(error_string); + } + } + /* + * Make la's of all master species for the element small, + * so SI will be small + * and no mass transfer will be calculated + */ + for (k = 0; k < count_master; k++) { + if (master[k]->elt->primary == master_ptr) { + master[k]->s->la = -9999.999; + } + } + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solution_check (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check for missing elements + */ + int i; + struct master *master_ptr; + +/* + * Check that all elements are in solution for phases with zero mass + */ + for (i =0; i < count_master; i++) { + master_ptr = master[i]; + if (master_ptr->total >= 0.0) continue; + if (master_ptr->total > -MIN_TOTAL) { + master_ptr->total = 0; + continue; + } + if (master_ptr->s == s_eminus || master_ptr->s == s_h2o || master_ptr->s == s_hplus || master_ptr->s == s_h3oplus) { + master_ptr->total = 0; + continue; + } + sprintf(error_string, "Element %s has negative moles in solution, %e. \n\tErroneous mole balance occurs as moles are added to produce zero moles.\n\tUsually caused by KINETICS, REACTION, or diffuse layer calculation.\n\tMay be due to large time steps in early part of KINETICS simulation or negative concentrations in the diffuse layer.", master_ptr->elt->name, (double) master_ptr->total); + warning_msg(error_string); + return(MASS_BALANCE); + } + return(OK); +} diff --git a/structures.cpp b/structures.cpp new file mode 100644 index 00000000..eab00142 --- /dev/null +++ b/structures.cpp @@ -0,0 +1,6059 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: structures.c 715 2006-01-18 01:26:29Z dlpark $"; + +static int exchange_compare_int(const void *ptr1, const void *ptr2); +static int gas_phase_compare_int(const void *ptr1, const void *ptr2); + +static int inverse_compare(const void *ptr1, const void *ptr2); +static int inverse_free (struct inverse *inverse_ptr); + +static int irrev_compare (const void *ptr1, const void *ptr2); +static int irrev_compare_int(const void *ptr1, const void *ptr2); +static int irrev_sort(void); + +static int kinetics_compare_int(const void *ptr1, const void *ptr2); + +static int logk_init(struct logk *logk_ptr); + +static int master_compare_string (const void *ptr1, const void *ptr2); +static int master_free(struct master *master_ptr); + +#if defined(PHREEQCI_GUI) +int mix_compare (const void *ptr1, const void *ptr2); +#else +static int mix_compare (const void *ptr1, const void *ptr2); +#endif +static int mix_compare_int(const void *ptr1, const void *ptr2); + +static struct phase *phase_alloc(void); +static int phase_compare_string (const void *ptr1, const void *ptr2); +static int phase_free(struct phase *phase_ptr); +static int phase_init(struct phase *phase_ptr); + +static int pp_assemblage_compare_int(const void *ptr1, const void *ptr2); + +static int rate_compare (const void *ptr1, const void *ptr2); +static int rate_compare_string (const void *ptr1, const void *ptr2); + +static struct species *s_alloc(void); +static int s_free (struct species *s_ptr); +static int s_init(struct species *s_ptr); + +static int s_s_assemblage_compare_int(const void *ptr1, const void *ptr2); + +static int solution_compare(const void *ptr1, const void *ptr2); +static int solution_compare_int(const void *ptr1, const void *ptr2); +static struct solution *solution_copy(struct solution *solution_old_ptr, int n_user_new); + +static int species_list_compare (const void *ptr1, const void *ptr2); + +static int surface_compare_int(const void *ptr1, const void *ptr2); + +static int temperature_compare (const void *ptr1, const void *ptr2); +static int temperature_compare_int(const void *ptr1, const void *ptr2); + +static int rxn_token_temp_compare(const void *ptr1, const void *ptr2); +static int trxn_multiply (LDBLE coef); + +#ifdef PHREEQCI_GUI +extern void free_spread(void); +#endif +#if defined(USE_MPI) && defined(HDF5_CREATE) && defined(MERGE_FILES) +extern void MergeFinalize(void); +#endif + +/* ---------------------------------------------------------------------- */ +int clean_up(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free all allocated memory, except strings + */ + int i, j; + if (svnid == NULL) fprintf(stderr," "); + + description_x = (char *) free_check_null(description_x); + isotopes_x = (struct isotope *) free_check_null(isotopes_x); + moles_per_kilogram_string = (char *) free_check_null(moles_per_kilogram_string); + pe_string = (char *) free_check_null(pe_string); +/* model */ + last_model.exchange = (struct master **) free_check_null(last_model.exchange); + last_model.gas_phase = (struct phase **) free_check_null(last_model.gas_phase); + last_model.pp_assemblage = (struct phase **) free_check_null(last_model.pp_assemblage); + last_model.s_s_assemblage = (char **) free_check_null(last_model.s_s_assemblage); + last_model.add_formula = (char **) free_check_null(last_model.add_formula); + last_model.si = (double *) free_check_null(last_model.si); + last_model.surface_comp = (struct master **) free_check_null(last_model.surface_comp); + last_model.surface_charge = (struct master **) free_check_null(last_model.surface_charge); + + /* model */ + free_model_allocs(); + +/* species */ + + for (j=0; jname, element_ptr2->name)); */ + return(strcmp(element_ptr1->name, element_ptr2->name)); + +} +/* ---------------------------------------------------------------------- */ +struct element *element_store (char *element) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "element" in the hash table for elements. + * + * If found, pointer to the appropriate element structure is returned. + * + * If the string is not found, a new entry is made at the end of + * the elements array (position count_elements) and count_elements is + * incremented. A new entry is made in the hash table. Pointer to + * the new structure is returned. + * + * Arguments: + * element input, character string to be located or stored. + * + * Returns: + * The address of an elt structure that contains the element data. + */ + int n; + struct element *elts_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + item.key = element; + item.data = NULL; + found_item = hsearch_multi(elements_hash_table, item, FIND); + if (found_item != NULL) { + elts_ptr = (struct element *) (found_item->data); + return (elts_ptr); + } +/* + * Save new elt structure and return pointer to it + */ + /* make sure there is space in elements */ + elements[count_elements] = (struct element *) PHRQ_malloc((size_t) sizeof(struct element)); + if (elements[count_elements] == NULL) malloc_error(); + /* set name pointer in elements structure */ + elements[count_elements]->name=string_hsave( element ); + /* set return value */ + elements[count_elements]->master = NULL; + elements[count_elements]->primary = NULL; + elements[count_elements]->gfw = 0.0; + n = count_elements++; + if (count_elements >= max_elements) { + space ((void **) ((void *) &elements), count_elements, &max_elements, sizeof(struct element *)); + } +/* + * Update hash table + */ + item.key = elements[n]->name; + item.data = (void *) elements[n]; + found_item = hsearch_multi(elements_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in element_store."); + error_msg(error_string, CONTINUE); + } + return (elements[n]); +} +/* ********************************************************************** + * + * Routines related to structure "elt_list" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +int elt_list_combine(void) +/* ---------------------------------------------------------------------- */ +/* + * Function goes through the list of elements pointed to by elt_list + * and combines the coefficients of elements that are the same. + * Assumes elt_list has been sorted by element name. + */ +{ + int i, j; + + if (count_elts < 1 ) { + output_msg(OUTPUT_MESSAGE, "elt_list_combine: How did this happen?\n"); + return(ERROR); + } + if (count_elts == 1 ) { + return(OK); + } + j=0; + for ( i=1; i < count_elts; i++) { + if ( elt_list[i].elt == elt_list[j].elt ) { + elt_list[j].coef += elt_list[i].coef; + } else { + j++; + if ( i != j ) { + elt_list[j].elt=elt_list[i].elt; + elt_list[j].coef=elt_list[i].coef; + } + } + } + count_elts=j+1; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int elt_list_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct elt_list *a, *b; + + a=(const struct elt_list *) ptr1; + b=(const struct elt_list *) ptr2; + return( strncmp( a->elt->name, b->elt->name, MAX_LENGTH)); +} +/* ---------------------------------------------------------------------- */ +struct elt_list *elt_list_dup(struct elt_list *elt_list_ptr_old) +/* ---------------------------------------------------------------------- */ +{ +/* + * Duplicates the elt_list structure pointed to by elt_list_ptr_old. + */ + int i, count_totals; + struct elt_list *elt_list_ptr_new; +/* + * Count totals data and copy + */ + if (elt_list_ptr_old == NULL) return (NULL); + for (i = 0; elt_list_ptr_old[i].elt != NULL; i++); + count_totals = i; +/* + * Malloc space and store element data + */ + elt_list_ptr_new = (struct elt_list *) PHRQ_malloc( (size_t) (count_totals + 1) + * sizeof(struct elt_list)); + if (elt_list_ptr_new == NULL ) malloc_error(); + memcpy(elt_list_ptr_new, elt_list_ptr_old, + (size_t) (count_totals + 1) * sizeof(struct elt_list)); + return (elt_list_ptr_new); +} +/* ---------------------------------------------------------------------- */ +int elt_list_print(struct elt_list *elt_list_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Duplicates the elt_list structure pointed to by elt_list_ptr_old. + */ + int i; +/* + * Debug print for element list + */ + if (elt_list_ptr == NULL) return (ERROR); + output_msg(OUTPUT_MESSAGE, "Elt_list\n"); + for (i = 0; elt_list_ptr[i].elt != NULL; i++) { + output_msg(OUTPUT_MESSAGE, "\t%s\t%e\n", elt_list_ptr[i].elt->name, (double) elt_list_ptr[i].coef); + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int elt_list_print0(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Duplicates the elt_list structure pointed to by elt_list_ptr_old. + */ + int i; +/* + * Debug print for element list + */ + output_msg(OUTPUT_STDERR, "Elt_list\n"); + for (i = 0; i < count_elts; i++) { + output_msg(OUTPUT_STDERR, "\t%s\t%e\n", elt_list[i].elt->name, (double) elt_list[i].coef); + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +struct elt_list *elt_list_save(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Takes data from work space elt_list, allocates a new elt_list structure, + * copies data from work space to new structure, and returns pointer to + * new structure. + */ + int j; + struct elt_list *elt_list_ptr; +/* + * Sort elements in reaction and combine + */ + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } +/* + * Malloc space and store element data + */ + elt_list_ptr=(struct elt_list *) PHRQ_malloc((size_t) (count_elts + 1)*sizeof(struct elt_list)); + if (elt_list_ptr == NULL ) malloc_error(); + for ( j=0; j < count_elts; j++ ) { + elt_list_ptr[j].elt=elt_list[j].elt; + elt_list_ptr[j].coef=elt_list[j].coef; + } + elt_list_ptr[count_elts].elt=NULL; + return (elt_list_ptr); +} +/* ********************************************************************** + * + * Routines related to structure "exchange" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct exchange *exchange_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct exchange *exchange_ptr; + exchange_ptr = (struct exchange *) PHRQ_malloc(sizeof (struct exchange)); + if (exchange_ptr == NULL) malloc_error(); + exchange_ptr->description = NULL; + exchange_ptr->count_comps = 0; + exchange_ptr->comps = NULL; + return ( exchange_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct exchange *exchange_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search exchange to find if user exchange number k exists. + * Exchange is assumed to be in sort order by user number. + */ + void *void_ptr; + if (count_exchange == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) exchange, + (size_t) count_exchange, + (size_t) sizeof(struct exchange), + exchange_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct exchange *) void_ptr - exchange); + return ( (struct exchange *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int exchange_comp_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct exch_comp *exch_comp_ptr1, *exch_comp_ptr2; + exch_comp_ptr1 = (const struct exch_comp *) ptr1; + exch_comp_ptr2 = (const struct exch_comp *) ptr2; + return(strcmp_nocase(exch_comp_ptr1->master->elt->name, exch_comp_ptr2->master->elt->name)); +} +/* ---------------------------------------------------------------------- */ +int exchange_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct exchange *exchange_ptr1, *exchange_ptr2; + exchange_ptr1 = (const struct exchange *) ptr1; + exchange_ptr2 = (const struct exchange *) ptr2; + if (exchange_ptr1->n_user > exchange_ptr2->n_user) return(1); + if (exchange_ptr1->n_user < exchange_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int exchange_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare exchange user numbers + */ + const int *nptr1; + const struct exchange *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct exchange *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int exchange_copy(struct exchange *exchange_old_ptr, + struct exchange *exchange_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies exchange data from exchange_old_ptr to new location, exchange_new_ptr. + * Space for the exchange_new_ptr structure must already be malloced. + * Space for exchange components is malloced here. + */ + int count_comps, i; + char token[MAX_LENGTH]; +/* + * Store data for structure exchange + */ + memcpy(exchange_new_ptr, exchange_old_ptr, sizeof(struct exchange)); + exchange_new_ptr->n_user = n_user_new; + exchange_new_ptr->n_user_end = n_user_new; + count_comps = exchange_old_ptr->count_comps; + exchange_new_ptr->new_def = exchange_old_ptr->new_def; + exchange_new_ptr->solution_equilibria = FALSE; + exchange_new_ptr->n_solution = -2; + exchange_new_ptr->count_comps = count_comps; + sprintf(token, "Exchanger defined in simulation %d.", simulation); + exchange_new_ptr->description = string_duplicate(token); +/* + * Count exchange components and allocate space + */ + exchange_new_ptr->comps = (struct exch_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct exch_comp)); + if (exchange_new_ptr->comps == NULL) malloc_error(); +/* + * Write exch_comp structure for each exchange component + */ + memcpy(exchange_new_ptr->comps, exchange_old_ptr->comps, + (size_t) (count_comps) * sizeof (struct exch_comp)); + for ( i = 0; i < count_comps; i++) { + exchange_new_ptr->comps[i].totals = elt_list_dup(exchange_old_ptr->comps[i].totals); + exchange_new_ptr->comps[i].formula_totals = elt_list_dup(exchange_old_ptr->comps[i].formula_totals); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an exchange definition from position n to position count_exchange. + * New exchange structure is given user number n_user. + */ + space ((void **) ((void *) &exchange), count_exchange, &max_exchange, sizeof(struct exchange)); + exchange_copy(&exchange[n], &exchange[count_exchange], n_user); + count_exchange++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array exchange. + */ +{ + int i; + int n_old; + struct exchange *exchange_ptr_old; +/* + * Find n_user_old in structure array + */ + exchange_ptr_old = exchange_bsearch(n_user_old, &n_old); + if (exchange_ptr_old != NULL) { + /* + * Delete exchange + */ + exchange_free(&exchange[n_old]); + + for(i = n_old + 1; i < count_exchange; i++) { + memcpy( (void *) &exchange[i - 1], (void *) &exchange[i], + (size_t) sizeof (struct exchange) ); + } + count_exchange--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies exchange[n_user_old] to old n_user_new space if + * found or to exchange[count_exchange] if not found. + * Exchange array may not be in sort order after the copy. + */ + int sort; + int n_old, n_new; + struct exchange *exchange_ptr_old, *exchange_ptr_new; +/* + * Find n_user_old in structure array exchange + */ + if (n_user_old == n_user_new) return(OK); + exchange_ptr_old = exchange_bsearch(n_user_old, &n_old); + if (exchange_ptr_old == NULL) { + sprintf(error_string, "Exchange %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array exchange or make new space + */ + sort = FALSE; + exchange_ptr_new = exchange_bsearch(n_user_new, &n_new); + if (exchange_ptr_new != NULL) { + exchange_free(exchange_ptr_new); + } else { + space ((void **) ((void *) &exchange), count_exchange, &max_exchange, sizeof(struct exchange)); + if (n_user_new < exchange[count_exchange-1].n_user) sort = TRUE; + n_new = count_exchange++; + } +/* + * Copy data + */ + exchange_copy(&exchange[n_old], &exchange[n_new], n_user_new); + if (sort == TRUE) exchange_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_free (struct exchange *exchange_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees all data associated with exchange structure. + */ + int i; + if (exchange_ptr == NULL) return(ERROR); +/* + * Free space allocated for exchange structure + */ + exchange_ptr->description = (char *) free_check_null (exchange_ptr->description); + for (i=0; i < exchange_ptr->count_comps; i++) { + exchange_ptr->comps[i].totals = (struct elt_list *) free_check_null (exchange_ptr->comps[i].totals); + exchange_ptr->comps[i].formula_totals = (struct elt_list *) free_check_null (exchange_ptr->comps[i].formula_totals); + } + exchange_ptr->comps = (struct exch_comp *) free_check_null (exchange_ptr->comps); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_init (struct exchange *exchange_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees all data associated with exchange structure. + */ + + if (exchange_ptr == NULL) return(ERROR); + exchange_ptr->n_user = n_user; + exchange_ptr->n_user_end = n_user_end; + exchange_ptr->new_def = TRUE; + exchange_ptr->description = string_duplicate(description); + exchange_ptr->solution_equilibria = FALSE; + exchange_ptr->n_solution = 0; + exchange_ptr->count_comps = 0; + exchange_ptr->comps = (struct exch_comp *) PHRQ_malloc(sizeof (struct exch_comp)); + if (exchange_ptr->comps == NULL) malloc_error(); + exchange_ptr->related_phases = FALSE; + exchange_ptr->related_rate = FALSE; + exchange_ptr->pitzer_exchange_gammas = TRUE; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int exchange_ptr_to_user(struct exchange *exchange_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies exchange_old_ptr to old n_user_new space if + * found or to exchange[count_exchange] if not found. + * Exchange array may not be in sort order after the copy. + */ + int sort; + int n_new; + struct exchange *exchange_ptr_new; +/* + * Find n_user_old in structure array exchange + */ + if (exchange_ptr_old == NULL) { + sprintf(error_string, "Exchange ptr is NULL"); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array exchange or make new space + */ + sort = FALSE; + exchange_ptr_new = exchange_bsearch(n_user_new, &n_new); + if (exchange_ptr_new == exchange_ptr_old) return(OK); + if (exchange_ptr_new != NULL) { + exchange_free(exchange_ptr_new); + } else { + space ((void **) ((void *) &exchange), count_exchange, &max_exchange, sizeof(struct exchange)); + if (n_user_new < exchange[count_exchange-1].n_user) sort = TRUE; + n_new = count_exchange++; + } +/* + * Copy data + */ + exchange_copy(exchange_ptr_old, &exchange[n_new], n_user_new); + if (sort == TRUE) exchange_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct exchange *exchange_replicate(struct exchange *exchange_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct exchange *exchange_ptr; + exchange_ptr = exchange_alloc(); + exchange_copy(exchange_old_ptr, exchange_ptr, n_user_new); + return (exchange_ptr); +} +/* ---------------------------------------------------------------------- */ +struct exchange *exchange_search(int n_user, int *n, int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Does linear search for user number n_user. + * Returns pointer to exchange structure and position number, n, + * in exchange array if found. + * Returns NULL if not found. + */ + int i; + for (i = 0; i < count_exchange; i++) { + if (n_user == exchange[i].n_user) { + break; + } + } + if (i >= count_exchange) { + if ( print == TRUE) { + sprintf(error_string, "Exchange %d not found.", n_user); + error_msg(error_string, CONTINUE); + } + *n = -999; + return(NULL); + } + *n = i; + return(&exchange[i]); +} +/* ---------------------------------------------------------------------- */ +int exchange_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of exchange structures + */ + if (count_exchange > 0) { + qsort (exchange, (size_t) count_exchange, (size_t) sizeof(struct exchange), + exchange_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "gas" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +int gas_comp_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct gas_comp *gas_comp_ptr1, *gas_comp_ptr2; + gas_comp_ptr1 = (const struct gas_comp *) ptr1; + gas_comp_ptr2 = (const struct gas_comp *) ptr2; + return(strcmp_nocase(gas_comp_ptr1->name, gas_comp_ptr2->name)); + +} +/* ---------------------------------------------------------------------- */ +struct gas_phase *gas_phase_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct gas_phase *gas_phase_ptr; + gas_phase_ptr = (struct gas_phase *) PHRQ_malloc(sizeof (struct gas_phase)); + if (gas_phase_ptr == NULL) malloc_error(); + gas_phase_ptr->description = NULL; + gas_phase_ptr->count_comps = 0; + gas_phase_ptr->comps = NULL; + return ( gas_phase_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct gas_phase *gas_phase_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search gas_phase to find if user gas_phase number k exists. + * Assumes array gas_phase is in sort order. + */ + void *void_ptr; + if (count_gas_phase == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) gas_phase, + (size_t) count_gas_phase, + (size_t) sizeof(struct gas_phase), + gas_phase_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct gas_phase *) void_ptr - gas_phase); + return ( (struct gas_phase *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct gas_phase *gas_phase_ptr1, *gas_phase_ptr2; + gas_phase_ptr1 = (const struct gas_phase *) ptr1; + gas_phase_ptr2 = (const struct gas_phase *) ptr2; + if (gas_phase_ptr1->n_user > gas_phase_ptr2->n_user) return(1); + if (gas_phase_ptr1->n_user < gas_phase_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int gas_phase_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare gas phase user numbers + */ + const int *nptr1; + const struct gas_phase *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct gas_phase *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_copy(struct gas_phase *gas_phase_old_ptr, + struct gas_phase *gas_phase_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies gas_phase structure from gas_phase_old_ptr to new location gas_phase_new_ptr. + * Space for a gas_phase structure must already be malloced + * Space for gas_phase components is alloced here. + */ + int count_comps; + char token[MAX_LENGTH]; +/* + * Store data for structure gas + */ + memcpy(gas_phase_new_ptr, gas_phase_old_ptr, (size_t) sizeof(struct gas_phase)); + count_comps = gas_phase_old_ptr->count_comps; + gas_phase_new_ptr->n_user = n_user_new; + gas_phase_new_ptr->n_user_end = n_user_new; + gas_phase_new_ptr->new_def = FALSE; + sprintf(token, "Gas defined in simulation %d.", simulation); + gas_phase_new_ptr->description = string_duplicate(token); +/* + * Allocate space for gas components + */ + gas_phase_new_ptr->comps = (struct gas_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct gas_comp)); + if (gas_phase_new_ptr->comps == NULL) malloc_error(); +/* + * Write gas_comp structure for each gas component + */ + memcpy(gas_phase_new_ptr->comps, gas_phase_old_ptr->comps, + (size_t) (count_comps) * sizeof (struct gas_comp)); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an gas_phase definition to position count_gas_phase. + */ + space ((void **) ((void *) &gas_phase), count_gas_phase, &max_gas_phase, sizeof(struct gas_phase)); + gas_phase_copy(&gas_phase[n], &gas_phase[count_gas_phase], n_user); + count_gas_phase++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array gas_phase. + */ +{ + int i; + int n_old; + struct gas_phase *gas_phase_ptr_old; +/* + * Find n_user_old in structure array + */ + gas_phase_ptr_old = gas_phase_bsearch(n_user_old, &n_old); + if (gas_phase_ptr_old != NULL) { + /* + * Delete gas_phase + */ + gas_phase_free(&gas_phase[n_old]); + + for(i = n_old + 1; i < count_gas_phase; i++) { + memcpy( (void *) &gas_phase[i - 1], (void *) &gas_phase[i], + (size_t) sizeof (struct gas_phase) ); + } + count_gas_phase--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies gas_phase[n_user_old] to old n_user_new space if + * found or to gas_phase[count_gas_phase] if not found. + * Gas_Phase array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + struct gas_phase *gas_phase_ptr_old, *gas_phase_ptr_new; +/* + * Find n_user_old in structure array gas_phase + */ + if (n_user_old == n_user_new) return(OK); + gas_phase_ptr_old = gas_phase_bsearch(n_user_old, &n_old); + if (gas_phase_ptr_old == NULL) { + sprintf(error_string, "Gas_Phase %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array gas_phase or make new space + */ + sort = FALSE; + gas_phase_ptr_new = gas_phase_bsearch(n_user_new, &n_new); + if (gas_phase_ptr_new != NULL) { + gas_phase_free (&gas_phase[n_new]); +#ifdef SKIP + gas_phase[n_new].comps = free_check_null (gas_phase[n_new].comps); +#endif + } else { + space ((void **) ((void *) &gas_phase), count_gas_phase, &max_gas_phase, sizeof(struct gas_phase)); + if (n_user_new < gas_phase[count_gas_phase-1].n_user) sort = TRUE; + n_new = count_gas_phase++; + } +/* + * Copy data + */ + gas_phase_copy(&gas_phase[n_old], &gas_phase[n_new], n_user_new); + if (sort == TRUE) gas_phase_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_free (struct gas_phase *gas_phase_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees space associated with gas_phase_ptr. + */ + if (gas_phase_ptr == NULL) return(ERROR); +/* + * Free space allocated for gas_phase structure + */ + gas_phase_ptr->description = (char *) free_check_null (gas_phase_ptr->description); + gas_phase_ptr->comps = (struct gas_comp *) free_check_null (gas_phase_ptr->comps); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_init (struct gas_phase *gas_phase_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees space associated with gas_phase_ptr. + */ + if (gas_phase_ptr == NULL) return(ERROR); + gas_phase_ptr->n_user = n_user; + gas_phase_ptr->n_user_end = n_user_end; + gas_phase_ptr->description = string_duplicate(description); + gas_phase_ptr->new_def = TRUE; + gas_phase_ptr->solution_equilibria = FALSE; + gas_phase_ptr->n_solution = 0; + gas_phase_ptr->type = PRESSURE; + gas_phase_ptr->total_p = 1.0; + gas_phase_ptr->total_moles = 0.0; + gas_phase_ptr->volume = 1.0; + gas_phase_ptr->temperature = 298.15; + gas_phase_ptr->count_comps = 0; + gas_phase_ptr->comps = (struct gas_comp *) PHRQ_malloc((size_t) sizeof(struct gas_comp)); + if (gas_phase_ptr->comps == NULL) malloc_error(); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_ptr_to_user(struct gas_phase *gas_phase_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies gas_phase_ptr_old to old n_user_new space if + * found or to gas_phase[count_gas_phase] if not found. + * Gas_Phase array may not be in sort order after the copy. + */ + int n_new, sort; + struct gas_phase *gas_phase_ptr_new; +/* + * Find n_user_old in structure array gas_phase + */ + if (gas_phase_ptr_old == NULL) { + sprintf(error_string, "Gas_Phase pointer is NULL."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array gas_phase or make new space + */ + sort = FALSE; + gas_phase_ptr_new = gas_phase_bsearch(n_user_new, &n_new); + if (gas_phase_ptr_new == gas_phase_ptr_old) return(OK); + if (gas_phase_ptr_new != NULL) { + gas_phase_free (&gas_phase[n_new]); +#ifdef SKIP + gas_phase[n_new].comps = free_check_null (gas_phase[n_new].comps); +#endif + } else { + space ((void **) ((void *) &gas_phase), count_gas_phase, &max_gas_phase, sizeof(struct gas_phase)); + if (n_user_new < gas_phase[count_gas_phase-1].n_user) sort = TRUE; + n_new = count_gas_phase++; + } +/* + * Copy data + */ + gas_phase_copy(gas_phase_ptr_old, &gas_phase[n_new], n_user_new); + if (sort == TRUE) gas_phase_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct gas_phase *gas_phase_replicate(struct gas_phase *gas_phase_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct gas_phase *gas_phase_ptr; + gas_phase_ptr = gas_phase_alloc(); + gas_phase_copy(gas_phase_old_ptr, gas_phase_ptr, n_user_new); + return (gas_phase_ptr); +} +/* ---------------------------------------------------------------------- */ +struct gas_phase *gas_phase_search (int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "gas_phase" for user number n_user + * + * Arguments: + * n_user input, user number + * n output, position in gas_phase + * + * Returns: + * if found, the address of the gas_phase element + * if not found, NULL + * + */ + int i; + for (i=0; i < count_gas_phase; i++) { + if ( gas_phase[i].n_user == n_user) { + *n = i; + return (&(gas_phase[i])); + } + } +/* + * Gas_phase not found + */ + return (NULL); +} +/* ---------------------------------------------------------------------- */ +int gas_phase_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of gas_phase structures + */ + if (count_gas_phase > 0) { + qsort (gas_phase, (size_t) count_gas_phase, (size_t) sizeof(struct gas_phase), + gas_phase_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "inverse" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct inverse *inverse_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space for a new inverse structure at position count_inverse. + * Initializes structure. + * arguments + * input: none + * output: pointer to an inverse structure + * return: OK + */ +{ + struct inverse *inverse_ptr; + + count_inverse++; + inverse = (struct inverse *) PHRQ_realloc(inverse, (size_t) count_inverse * sizeof(struct inverse)); + if (inverse == NULL) malloc_error(); + inverse_ptr = &(inverse[count_inverse-1]); +/* + * Initialize variables + */ + inverse_ptr->description = NULL; + inverse_ptr->count_uncertainties = 0; + inverse_ptr->count_solns = 0; + inverse_ptr->count_elts = 0; + inverse_ptr->count_isotopes = 0; + inverse_ptr->count_i_u = 0; + inverse_ptr->count_phases = 0; + inverse_ptr->count_force_solns = 0; +/* + * allocate space for pointers in structure to NULL + */ + + inverse_ptr->uncertainties = (double *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (inverse_ptr->uncertainties == NULL) malloc_error(); + + inverse_ptr->ph_uncertainties = (double *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (inverse_ptr->ph_uncertainties == NULL) malloc_error(); + +#ifdef SKIP + inverse_ptr->alk_uncertainties = PHRQ_malloc((size_t) sizeof(LDBLE)); + if (inverse_ptr->alk_uncertainties == NULL) malloc_error(); +#endif + + inverse_ptr->force_solns = (int *) PHRQ_malloc((size_t) sizeof(int)); + if (inverse_ptr->force_solns == NULL) malloc_error(); + + inverse_ptr->dalk_dph = NULL; + inverse_ptr->dalk_dc = NULL; + + + inverse_ptr->solns = NULL; + + inverse_ptr->elts = (struct inv_elts *) PHRQ_malloc((size_t) sizeof(struct inv_elts)); + if (inverse_ptr->elts == NULL) malloc_error(); + inverse_ptr->elts[0].name = NULL; + inverse_ptr->elts[0].uncertainties = NULL; + + inverse_ptr->isotopes = (struct inv_isotope *) PHRQ_malloc((size_t) sizeof(struct inv_isotope)); + if (inverse_ptr->isotopes == NULL) malloc_error(); + inverse_ptr->isotopes[0].isotope_name = NULL; + inverse_ptr->isotopes[0].isotope_number = 0; + inverse_ptr->isotopes[0].elt_name = NULL; + + inverse_ptr->i_u = (struct inv_isotope *) PHRQ_malloc((size_t) sizeof(struct inv_isotope)); + if (inverse_ptr->i_u == NULL) malloc_error(); + inverse_ptr->i_u[0].isotope_name = NULL; + inverse_ptr->i_u[0].isotope_number = 0; + inverse_ptr->i_u[0].elt_name = NULL; + + inverse_ptr->phases = (struct inv_phases *) PHRQ_malloc((size_t) sizeof(struct inv_phases)); + if (inverse_ptr->phases == NULL) malloc_error(); + + return(inverse_ptr); +} +/* ---------------------------------------------------------------------- */ +int inverse_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare inverse values for n_user + */ + const struct inverse *nptr1; + const struct inverse *nptr2; + + nptr1= (const struct inverse *) ptr1; + nptr2= (const struct inverse *) ptr2; + if (nptr1->n_user > nptr2->n_user) return(1); + if (nptr1->n_user < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int inverse_delete(int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Deletes inverse i from list (i is not user number), + * Frees memory allocated to inverse struct + * Input: i, number of inverse struct to delete + * Return: OK + */ + int j; + + inverse_free ( &(inverse[i]) ); + for (j=i; j < (count_inverse - 1); j++) { + memcpy ( (void *) &(inverse[j]), (void *) &(inverse[j+1]), + (size_t) sizeof (struct inverse)); + } + count_inverse--; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int inverse_free (struct inverse *inverse_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free all memory for an inverse structure. + */ + int i; + + inverse_ptr->description = (char *) free_check_null (inverse_ptr->description); +/* Free solns */ + inverse_ptr->solns = (int *) free_check_null (inverse_ptr->solns); + +/* Free uncertainties */ + inverse_ptr->uncertainties = (double *) free_check_null (inverse_ptr->uncertainties); + inverse_ptr->ph_uncertainties = (double *) free_check_null (inverse_ptr->ph_uncertainties); +#ifdef SKIP + inverse_ptr->alk_uncertainties = (double *) free_check_null (inverse_ptr->alk_uncertainties); +#endif + +/* Free force_solns */ + inverse_ptr->force_solns = (int *) free_check_null (inverse_ptr->force_solns); + +/* Free elts */ + for (i = 0; i < inverse_ptr->count_elts; i++) { + inverse_ptr->elts[i].uncertainties = (double *) free_check_null (inverse_ptr->elts[i].uncertainties); + }; + inverse_ptr->elts = (struct inv_elts *) free_check_null (inverse_ptr->elts); + +/* Free isotopes */ + for (i = 0; i < inverse_ptr->count_isotopes; i++) { + inverse_ptr->isotopes[i].uncertainties = (double *) free_check_null (inverse_ptr->isotopes[i].uncertainties); + }; + inverse_ptr->isotopes = (struct inv_isotope *) free_check_null (inverse_ptr->isotopes); + + for (i = 0; i < inverse_ptr->count_i_u; i++) { + inverse_ptr->i_u[i].uncertainties = (double *) free_check_null (inverse_ptr->i_u[i].uncertainties); + }; + inverse_ptr->i_u = (struct inv_isotope *) free_check_null (inverse_ptr->i_u); + +/* Free phases */ + for (i = 0; i < inverse_ptr->count_phases; i++) { + inverse_ptr->phases[i].isotopes = (struct isotope *) free_check_null(inverse_ptr->phases[i].isotopes); + } + inverse_ptr->phases = (struct inv_phases *) free_check_null (inverse_ptr->phases); + +/* Free carbon derivatives */ + inverse_ptr->dalk_dph = (LDBLE *) free_check_null(inverse_ptr->dalk_dph); + inverse_ptr->dalk_dc = (LDBLE *) free_check_null(inverse_ptr->dalk_dc); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int inverse_isotope_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + int i; + const struct inv_isotope *iso_ptr1, *iso_ptr2; + + iso_ptr1 = (const struct inv_isotope *) ptr1; + iso_ptr2 = (const struct inv_isotope *) ptr2; + i = strcmp_nocase(iso_ptr1->elt_name, iso_ptr2->elt_name); + if (i != 0) return(i); + if (iso_ptr1->isotope_number < iso_ptr2->isotope_number) { + return(-1); + } else if (iso_ptr1->isotope_number > iso_ptr2->isotope_number) { + return(1); + } + return(0); +} + +/* ---------------------------------------------------------------------- */ +struct inverse *inverse_search (int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "inverse" for user number n_user. + * + * Arguments: + * n_user input, user number + * n output, position in inverse + * + * Returns: + * if found, the address of the inverse element + * if not found, NULL + * + */ + int i; + for (i=0; i < count_inverse; i++) { + if ( inverse[i].n_user == n_user) { + *n = i; + return (&(inverse[i])); + } + } +/* + * An inverse structure with n_user was not found + */ + return (NULL); +} +/* ---------------------------------------------------------------------- */ +int inverse_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of inverse structures + */ + if (count_inverse > 0) { + qsort (inverse, (size_t) count_inverse, (size_t) sizeof(struct inverse), + inverse_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "irrev" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct irrev *irrev_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Search irrev to find if user irrev number k exists. + * Uses binary search, assumes array irrev is in sort order. + */ + void *void_ptr; + if (count_irrev == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) irrev, + (size_t) count_irrev, + (size_t) sizeof(struct irrev), + irrev_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct irrev *) void_ptr - irrev); + return ( (struct irrev *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int irrev_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct irrev *irrev_ptr1, *irrev_ptr2; + irrev_ptr1 = (const struct irrev *) ptr1; + irrev_ptr2 = (const struct irrev *) ptr2; + if (irrev_ptr1->n_user > irrev_ptr2->n_user) return(1); + if (irrev_ptr1->n_user < irrev_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int irrev_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare irrev user numbers + */ + const int *nptr1; + const struct irrev *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct irrev *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int irrev_copy(struct irrev *irrev_old_ptr, struct irrev *irrev_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies irrev structure from irrev_old_ptr to new location irrev_new_ptr. + * Space for a irrev structure must already be malloced + * Space for irrev components is alloced here. + */ + int count_list, count_steps; + char token[MAX_LENGTH]; +/* + * Store data for structure gas + */ + memcpy(irrev_new_ptr, irrev_old_ptr, (size_t) sizeof(struct irrev)); + irrev_new_ptr->n_user = n_user_new; + irrev_new_ptr->n_user_end = n_user_new; + sprintf(token, "Reaction defined in simulation %d.", simulation); + irrev_new_ptr->description = string_duplicate(token); + count_list = irrev_old_ptr->count_list; + count_steps = irrev_old_ptr->count_steps; +/* + * Allocate space + */ + irrev_new_ptr->list = (struct name_coef *) PHRQ_malloc((size_t) (count_list) * sizeof (struct name_coef)); + if (irrev_new_ptr->list == NULL) malloc_error(); + memcpy(irrev_new_ptr->list, irrev_old_ptr->list, (size_t) (count_list) * sizeof (struct name_coef)); + if (count_steps < 0) count_steps = 1; + irrev_new_ptr->steps = (LDBLE *) PHRQ_malloc((size_t) (count_steps) * sizeof (LDBLE)); + if (irrev_new_ptr->steps == NULL) malloc_error(); + memcpy(irrev_new_ptr->steps, irrev_old_ptr->steps, (size_t) (count_steps) * sizeof (LDBLE)); + + if (irrev_old_ptr->elts != NULL) { + irrev_new_ptr->elts = elt_list_dup(irrev_old_ptr->elts); + } else { + irrev_new_ptr->elts = NULL; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int irrev_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Finds irrev structure with user number n_user_old, + * copies data to irrev structure with user number n_user_new. + * If n_user_new already exists, it is overwritten and sort order + * is maintained. + * If n_user_new does not exist, a new structure is allocated; sort + * order may not be preserved. + */ + int n_old, n_new, sort; + char token[MAX_LENGTH]; + int count_steps, count_list; + struct irrev *irrev_ptr_old, *irrev_ptr_new; +/* + * Find n_user_old in structure array irrev_assemblage or make new space + */ + if (n_user_old == n_user_new) return(OK); + irrev_ptr_old = irrev_bsearch(n_user_old, &n_old); + if (irrev_ptr_old == NULL) { + sprintf(error_string, "Irreversible reaction %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_old in structure array irrev or make new space + */ + sort = FALSE; + irrev_ptr_new = irrev_bsearch(n_user_new, &n_new); + if (irrev_ptr_new != NULL) { + irrev_free(irrev_ptr_new); + } else { + irrev = (struct irrev *) PHRQ_realloc( irrev, (size_t) (count_irrev + 1) * sizeof (struct irrev)); + if (irrev == NULL) malloc_error(); + if (n_user_new < irrev[count_irrev-1].n_user) sort = TRUE; + n_new = count_irrev++; + } +/* + * Store data for structure irrev + */ + count_steps = irrev[n_old].count_steps; + irrev[n_new].n_user = n_user_new; + irrev[n_new].n_user_end = n_user_new; + sprintf(token, "Irreversible reaction defined in simulation %d.", simulation); + irrev[n_new].description = string_duplicate(token); + irrev[n_new].units = irrev[n_old].units; + irrev[n_new].count_steps = count_steps; + count_list = irrev[n_old].count_list; + irrev[n_new].count_list = irrev[n_old].count_list; +/* + * Allocate space + */ + irrev[n_new].list = (struct name_coef *) PHRQ_malloc((size_t) (count_list) * sizeof (struct name_coef)); + if (irrev[n_new].list == NULL) malloc_error(); + memcpy(irrev[n_new].list, irrev[n_old].list, + (size_t) (count_list) * sizeof (struct name_coef)); + + if (count_steps < 0) count_steps = 1; + irrev[n_new].steps = (LDBLE *) PHRQ_malloc((size_t) (count_steps) * sizeof (LDBLE)); + if (irrev[n_new].steps == NULL) malloc_error(); + memcpy(irrev[n_new].steps, irrev[n_old].steps, + (size_t) (count_steps) * sizeof (LDBLE)); + + if (irrev[n_old].elts != NULL) { + irrev[n_new].elts = elt_list_dup(irrev[n_old].elts); + } else { + irrev[n_new].elts = NULL; + } + if (sort == TRUE) irrev_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int irrev_free (struct irrev *irrev_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free memory pointed to by an irrev structure. + */ + if (irrev_ptr == NULL) return(ERROR); +/* + * Free space allocated for irrev structure + */ + irrev_ptr->description = (char *) free_check_null (irrev_ptr->description); + irrev_ptr->list = (struct name_coef *) free_check_null (irrev_ptr->list); + irrev_ptr->elts = (struct elt_list *) free_check_null (irrev_ptr->elts); + irrev_ptr->steps = (LDBLE *) free_check_null (irrev_ptr->steps); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct irrev *irrev_search(int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Linear search for irrev user number n_user. + * If found, n is position in irrev array and pointer to irrev structure + * is returned + * If not found, NULL is returned. + */ + int i; + for (i = 0; i < count_irrev; i++) { + if (n_user == irrev[i].n_user) { + break; + } + } + if (i >= count_irrev) { + *n = -999; + return(NULL); + } + *n = i; + return(&irrev[i]); +} +/* ---------------------------------------------------------------------- */ +int irrev_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of irrev structures + */ + if (count_irrev > 0) { + qsort (irrev, (size_t) count_irrev, (size_t) sizeof(struct irrev), + irrev_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "kinetics" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct kinetics *kinetics_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct kinetics *kinetics_ptr; + kinetics_ptr = (struct kinetics *) PHRQ_malloc(sizeof (struct kinetics)); + if (kinetics_ptr == NULL) malloc_error(); + kinetics_ptr->description = NULL; + kinetics_ptr->count_comps = 0; + kinetics_ptr->comps = NULL; + kinetics_ptr->count_steps = 0; + kinetics_ptr->steps = NULL; + /*kinetics_ptr->units = NULL;*/ + kinetics_ptr->totals = NULL; + return ( kinetics_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct kinetics *kinetics_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search kinetics to find if user kinetics number k exists. + * Kinetics is assumed to be in sort order by user number. + */ + void *void_ptr; + if (count_kinetics == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) kinetics, + (size_t) count_kinetics, + (size_t) sizeof(struct kinetics), + kinetics_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct kinetics *) void_ptr - kinetics); + return ( (struct kinetics *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int kinetics_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct kinetics *kinetics_ptr1, *kinetics_ptr2; + kinetics_ptr1 = (const struct kinetics *) ptr1; + kinetics_ptr2 = (const struct kinetics *) ptr2; + if (kinetics_ptr1->n_user > kinetics_ptr2->n_user) return(1); + if (kinetics_ptr1->n_user < kinetics_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int kinetics_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare kinetics user numbers + */ + const int *nptr1; + const struct kinetics *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct kinetics *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int kinetics_copy(struct kinetics *kinetics_old_ptr, + struct kinetics *kinetics_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies kinetics data from kinetics_old_ptr to new location, kinetics_new_ptr. + * Space for the kinetics_new_ptr structure must already be malloced. + * Space for kinetics components is malloced here. + */ + char token[MAX_LENGTH]; + int count_steps, i; +/* + * copy old to new + */ + memcpy(kinetics_new_ptr, kinetics_old_ptr, sizeof (struct kinetics)); +/* + * Store data for structure kinetics + */ + kinetics_new_ptr->n_user = n_user_new; + kinetics_new_ptr->n_user_end = n_user_new; + sprintf(token, "Kinetics defined in simulation %d.", simulation); + kinetics_new_ptr->description = string_duplicate(token); + kinetics_new_ptr->totals = NULL; + kinetics_new_ptr->totals = elt_list_dup(kinetics_old_ptr->totals); +/* + * Copy time steps + */ + if (kinetics_new_ptr->count_steps > 0) { + count_steps = kinetics_new_ptr->count_steps; + } else if (kinetics_new_ptr->count_steps < 0) { + count_steps = 1; + } else { + count_steps = 0; + } + if (count_steps > 0) { + kinetics_new_ptr->steps = (LDBLE *) PHRQ_malloc((size_t) (count_steps * sizeof (LDBLE))); + if (kinetics_new_ptr->steps == NULL) malloc_error(); + memcpy(kinetics_new_ptr->steps, kinetics_old_ptr->steps, (size_t) count_steps * sizeof (LDBLE)); + } +/* + * Copy kinetic components + */ + if (kinetics_new_ptr->count_comps > 0) { + kinetics_new_ptr->comps = (struct kinetics_comp *) PHRQ_malloc((size_t) kinetics_old_ptr->count_comps * sizeof (struct kinetics_comp)); + if (kinetics_new_ptr->comps == NULL) malloc_error(); + } else { + kinetics_new_ptr->comps = NULL; + } + for (i = 0; i < kinetics_old_ptr->count_comps; i++) { + kinetics_comp_duplicate(&kinetics_new_ptr->comps[i], &kinetics_old_ptr->comps[i]); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_comp_duplicate(struct kinetics_comp *kinetics_comp_new_ptr, struct kinetics_comp *kinetics_comp_old_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies kinetics comp data from kinetics_comp_old_ptr to new location + * Space for the new structure must already be allocated + */ + memcpy(kinetics_comp_new_ptr, kinetics_comp_old_ptr, sizeof (struct kinetics_comp)); +/* + * Kinetics character parameters + */ + if (kinetics_comp_new_ptr->count_c_params > 0) { + kinetics_comp_new_ptr->c_params = (char **) PHRQ_malloc((size_t) (kinetics_comp_old_ptr->count_c_params) * sizeof (char *)); + if (kinetics_comp_new_ptr->c_params == NULL) malloc_error(); + memcpy(kinetics_comp_new_ptr->c_params, kinetics_comp_old_ptr->c_params, (size_t) (kinetics_comp_old_ptr->count_c_params) * sizeof (char *)); + } else { + kinetics_comp_new_ptr->c_params = NULL; + } +/* + * Kinetics LDBLE parameters + */ + if (kinetics_comp_new_ptr->count_d_params > 0) { + kinetics_comp_new_ptr->d_params = (LDBLE *) PHRQ_malloc((size_t) (kinetics_comp_old_ptr->count_d_params) * sizeof (LDBLE)); + if (kinetics_comp_new_ptr->d_params == NULL) malloc_error(); + memcpy(kinetics_comp_new_ptr->d_params, kinetics_comp_old_ptr->d_params, (size_t) (kinetics_comp_old_ptr->count_d_params) * sizeof (LDBLE)); + } else { + kinetics_comp_new_ptr->d_params = (LDBLE *) PHRQ_malloc((size_t) sizeof (LDBLE)); + } +/* + * Kinetics list of formulae + */ + if (kinetics_comp_new_ptr->count_list > 0) { + kinetics_comp_new_ptr->list = (struct name_coef *) PHRQ_malloc((size_t) (kinetics_comp_old_ptr->count_list) * sizeof (struct name_coef)); + if (kinetics_comp_new_ptr->list == NULL) malloc_error(); + memcpy(kinetics_comp_new_ptr->list, kinetics_comp_old_ptr->list, (size_t) (kinetics_comp_old_ptr->count_list) * sizeof (struct name_coef)); + } else { + kinetics_comp_new_ptr->d_params = NULL; + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int kinetics_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an kinetics definition from position n to position count_kinetics. + * New kinetics structure is given user number n_user. + */ + space ((void **) ((void *) &kinetics), count_kinetics, &max_kinetics, sizeof(struct kinetics)); + kinetics_copy(&kinetics[n], &kinetics[count_kinetics], n_user); + count_kinetics++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array kinetics. + */ +{ + int i; + int n_old; + struct kinetics *kinetics_ptr_old; +/* + * Find n_user_old in structure array + */ + kinetics_ptr_old = kinetics_bsearch(n_user_old, &n_old); + if (kinetics_ptr_old != NULL) { + /* + * Delete kinetics + */ + kinetics_free(&kinetics[n_old]); + + for(i = n_old + 1; i < count_kinetics; i++) { + memcpy( (void *) &kinetics[i - 1], (void *) &kinetics[i], + (size_t) sizeof (struct kinetics) ); + } + count_kinetics--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies kinetics[n_user_old] to old n_user_new space if + * found or to kinetics[count_kinetics] if not found. + * Kinetics array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + struct kinetics *kinetics_ptr_old, *kinetics_ptr_new; +/* + * Find n_user_old in structure array kinetics + */ + if (n_user_old == n_user_new) return(OK); + kinetics_ptr_old = kinetics_bsearch(n_user_old, &n_old); + if (kinetics_ptr_old == NULL) { + sprintf(error_string, "Kinetics %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array kinetics or make new space + */ + sort = FALSE; + kinetics_ptr_new = kinetics_bsearch(n_user_new, &n_new); + if (kinetics_ptr_new != NULL) { + kinetics_free(kinetics_ptr_new); + } else { + space ((void **) ((void *) &kinetics), count_kinetics, &max_kinetics, sizeof(struct kinetics)); + if (n_user_new < kinetics[count_kinetics-1].n_user) sort = TRUE; + n_new = count_kinetics++; + } +/* + * Copy data + */ + kinetics_copy(&kinetics[n_old], &kinetics[n_new], n_user_new); + if (sort == TRUE) kinetics_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_free (struct kinetics *kinetics_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Frees all data associated with kinetics structure. + */ + if (kinetics_ptr == NULL) return(ERROR); +/* + * Free space allocated for kinetics structure + */ + for (i = 0; i < kinetics_ptr->count_comps; i++) { + kinetics_ptr->comps[i].c_params = (char **) free_check_null (kinetics_ptr->comps[i].c_params); + kinetics_ptr->comps[i].d_params = (LDBLE *) free_check_null (kinetics_ptr->comps[i].d_params); + kinetics_ptr->comps[i].list = (struct name_coef *) free_check_null (kinetics_ptr->comps[i].list); + } + kinetics_ptr->description = (char *) free_check_null (kinetics_ptr->description); + kinetics_ptr->steps = (LDBLE *) free_check_null (kinetics_ptr->steps); + kinetics_ptr->comps = (struct kinetics_comp *) free_check_null (kinetics_ptr->comps); + kinetics_ptr->totals = (struct elt_list *) free_check_null (kinetics_ptr->totals); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_init (struct kinetics *kinetics_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ + if (kinetics_ptr == NULL) return(ERROR); + kinetics_ptr->n_user = n_user; + kinetics_ptr->n_user_end = n_user_end; + kinetics_ptr->description = string_duplicate(description); + kinetics_ptr->count_comps = 0; + kinetics_ptr->comps = (struct kinetics_comp *) PHRQ_malloc((size_t) sizeof(struct kinetics_comp)); + if (kinetics_ptr->comps == NULL) malloc_error(); + kinetics_ptr->count_steps = 0; + kinetics_ptr->steps = (LDBLE *) PHRQ_malloc((size_t) sizeof(LDBLE)); + if (kinetics_ptr->steps == NULL) malloc_error(); + kinetics_ptr->step_divide = 1.0; + /*kinetics_ptr->units = string_hsave("sec");*/ + kinetics_ptr->totals = NULL; + kinetics_ptr->rk = 3; + kinetics_ptr->bad_step_max = 500; + kinetics_ptr->use_cvode = FALSE; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int kinetics_ptr_to_user(struct kinetics *kinetics_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies kinetics_ptr_old to old n_user_new space if + * found or to kinetics[count_kinetics] if not found. + * Kinetics array may not be in sort order after the copy. + */ + int n_new, sort; + struct kinetics *kinetics_ptr_new; +/* + * Find n_user_old in structure array kinetics + */ + if (kinetics_ptr_old == NULL) { + sprintf(error_string, "Kinetics pointer is NULL."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array kinetics or make new space + */ + sort = FALSE; + kinetics_ptr_new = kinetics_bsearch(n_user_new, &n_new); + if (kinetics_ptr_new == kinetics_ptr_old) return(OK); + if (kinetics_ptr_new != NULL) { + kinetics_free(kinetics_ptr_new); + } else { + space ((void **) ((void *) &kinetics), count_kinetics, &max_kinetics, sizeof(struct kinetics)); + if (n_user_new < kinetics[count_kinetics-1].n_user) sort = TRUE; + n_new = count_kinetics++; + } +/* + * Copy data + */ + kinetics_copy(kinetics_ptr_old, &kinetics[n_new], n_user_new); + if (sort == TRUE) kinetics_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct kinetics *kinetics_replicate(struct kinetics *kinetics_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct kinetics *kinetics_ptr; + kinetics_ptr = kinetics_alloc(); + kinetics_copy(kinetics_old_ptr, kinetics_ptr, n_user_new); + return (kinetics_ptr); +} +/* ---------------------------------------------------------------------- */ +struct kinetics *kinetics_search(int n_user, int *n, int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Does linear search for user number n_user. + * Returns pointer to kinetics structure and position number, n, + * in kinetics array if found. + * Returns NULL if not found. + */ + int i; + for (i = 0; i < count_kinetics; i++) { + if (n_user == kinetics[i].n_user) { + break; + } + } + if (i >= count_kinetics) { + if ( print == TRUE) { + sprintf(error_string, "Kinetics %d not found.", n_user); + error_msg(error_string, CONTINUE); + } + *n = -999; + return(NULL); + } + *n = i; + return(&kinetics[i]); +} +/* ---------------------------------------------------------------------- */ +int kinetics_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of kinetics structures + */ + if (count_kinetics > 0) { + qsort (kinetics, (size_t) count_kinetics, (size_t) sizeof(struct kinetics), + kinetics_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "master" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct master *master_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a master structure and initializes the space. + * arguments: void + * return: pointer to a master structure + */ +{ + struct master *ptr; + ptr=(struct master *) PHRQ_malloc(sizeof(struct master)); + if (ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL + */ + ptr->in=FALSE; + ptr->type=0; + ptr->primary=FALSE; + ptr->coef=0.0; + ptr->total=0.0; + ptr->elt=NULL; + ptr->alk = 0.0; + ptr->gfw = 0.0; + ptr->gfw_formula=NULL; + ptr->unknown=NULL; + ptr->s=NULL; + ptr->rxn_primary=NULL; + ptr->rxn_secondary=NULL; + ptr->pe_rxn=NULL; + ptr->minor_isotope = FALSE; + + return(ptr); +} +/* ---------------------------------------------------------------------- */ +int master_delete(char *ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Delete master species: Free memory of master species structure, free + * the structure, and remove from array master. + * + * Input + * ptr character string with name of element or valence state + * Returns + * TRUE if master species was deleted. + * FALSE if master species was not found. + */ + int j, n; + + if (master_search(ptr, &n) == NULL) return(FALSE); + master_free (master[n]); + for (j=n; j < (count_master - 1); j++) { + master[j] = master[j+1]; + } + count_master--; + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int master_free(struct master *master_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free memory pointed to by master species pointer, master_ptr. + * Frees master_ptr itself. + */ + if (master_ptr == NULL) return(ERROR); + rxn_free (master_ptr->rxn_primary); + rxn_free (master_ptr->rxn_secondary); + master_ptr = (struct master *) free_check_null (master_ptr); + return(OK); +} + +/* ---------------------------------------------------------------------- */ +struct master *master_bsearch (const char *ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Uses binary search. Assumes master is in sort order. + * Find master species for string (*ptr) containing name of element or valence state. + * + * Input: ptr pointer to string containing element name + * + * Return: pointer to master structure containing name ptr or NULL. + */ + void *void_ptr; + if (count_master == 0) { + return(NULL); + } + void_ptr = bsearch ((const char *) ptr, + (char *) master, + (unsigned) count_master, + sizeof(struct master *), + master_compare_string); + if (void_ptr == NULL) { + return(NULL); + } else { + return (* (struct master **) void_ptr); + } +} +/* ---------------------------------------------------------------------- */ +int master_compare_string (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const char *string_ptr; + const struct master *master_ptr; + + string_ptr = (const char *) ptr1; + master_ptr = * (const struct master **) ptr2; + return(strcmp_nocase(string_ptr, master_ptr->elt->name)); +} +/* ---------------------------------------------------------------------- */ +int master_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct master *master_ptr1, *master_ptr2; + master_ptr1 = * (const struct master **) ptr1; + master_ptr2 = * (const struct master **) ptr2; + return(strcmp_nocase(master_ptr1->elt->name, master_ptr2->elt->name)); +} +/* ---------------------------------------------------------------------- */ +struct master *master_bsearch_primary (char *ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Find primary master species for first element in the string, ptr. + * Uses binary search. Assumes master is in sort order. + */ + int l; + char *ptr1; + char elt[MAX_LENGTH]; + struct master *master_ptr_primary; +/* + * Find element name + */ + ptr1=ptr; + get_elt(&ptr1, elt, &l); +/* + * Search master species list + */ + master_ptr_primary=master_bsearch(elt); + if (master_ptr_primary == NULL ) { + input_error++; + sprintf(error_string, "Could not find primary master species for %s.", ptr); + error_msg(error_string, CONTINUE); + } + return(master_ptr_primary); +} +/* ---------------------------------------------------------------------- */ +struct master *master_search (char *ptr, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Linear search of master to find master species in string, ptr. + * Returns pointer if found. n contains position in array master. + * Returns NULL if not found. + */ + int i; + struct master *master_ptr; +/* + * Search master species list + */ + *n = -999; + for (i = 0; i < count_master; i++) { + if (strcmp(ptr, master[i]->elt->name) == 0) { + *n = i; + master_ptr = master[i]; + return(master_ptr); + } + } + return(NULL); +} +/* ********************************************************************** + * + * Routines related to structure "mix" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct mix *mix_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Search mix to find if user mix number k exists. + * Uses binary search, assumes array mix is in sort order. + */ + void *void_ptr; + if (count_mix == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) mix, + (size_t) count_mix, + (size_t) sizeof(struct mix), + mix_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct mix *) void_ptr - mix); + return ( (struct mix *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int mix_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct mix *mix_ptr1, *mix_ptr2; + mix_ptr1 = (const struct mix *) ptr1; + mix_ptr2 = (const struct mix *) ptr2; + if (mix_ptr1->n_user > mix_ptr2->n_user) return(1); + if (mix_ptr1->n_user < mix_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int mix_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare mix user numbers + */ + const int *nptr1; + const struct mix *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct mix *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int mix_copy(struct mix *mix_old_ptr, + struct mix *mix_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies mix data from mix_old_ptr to new location, mix_new_ptr. + * Space for the mix_new_ptr structure must already be malloced. + * Space for mix components is malloced here. + */ + char token[MAX_LENGTH]; +/* + * Copy old to new + */ + memcpy(mix_new_ptr, mix_old_ptr, sizeof (struct mix)); +/* + * Store data for structure mix + */ + mix_new_ptr->n_user = n_user_new; + mix_new_ptr->n_user_end = n_user_new; + sprintf(token, "Mix defined in simulation %d.", simulation); + mix_new_ptr->description = string_duplicate(token); +/* + * Count mix components and allocate space + */ + mix_new_ptr->comps = (struct mix_comp *) PHRQ_malloc((size_t) (mix_old_ptr->count_comps) * sizeof (struct mix_comp)); + if (mix_new_ptr->comps == NULL) malloc_error(); + memcpy(mix_new_ptr->comps, mix_old_ptr->comps, + (size_t) (mix_old_ptr->count_comps) * sizeof (struct mix_comp)); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mix_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies mix[n_user_old] to old n_user_new space if + * found or to mix[count_mix] if not found. + * Mix array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + char token[MAX_LENGTH]; + int count_comps; + struct mix *mix_ptr_old, *mix_ptr_new; +/* + * Find n_user_old in structure array mix or make new space + */ + if (n_user_old == n_user_new) return(OK); + mix_ptr_old = mix_bsearch(n_user_old, &n_old); + if (mix_ptr_old == NULL) { + sprintf(error_string, "Mix %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_old in structure array mix or make new space + */ + sort = FALSE; + mix_ptr_new = mix_bsearch(n_user_new, &n_new); + if (mix_ptr_new != NULL) { + mix_free (&(mix[n_new])); + } else { + mix = (struct mix *) PHRQ_realloc( mix, (size_t) (count_mix + 1) *sizeof (struct mix)); + if (mix == NULL) malloc_error(); + if (n_user_new < mix[count_mix - 1].n_user) sort = TRUE; + n_new = count_mix++; + } +/* + * Store data for structure mix + */ + memcpy(&mix[n_new], &mix[n_old], sizeof(struct mix)); + count_comps = mix[n_old].count_comps; + mix[n_new].n_user = n_user_new; + mix[n_new].n_user_end = n_user_new; + sprintf(token, "Mix defined in simulation %d.", simulation); + mix[n_new].description = string_duplicate(token); +/* + * Count mix components and allocate space + */ + mix[n_new].comps = (struct mix_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct mix_comp)); + if (mix[n_new].comps == NULL) malloc_error(); +/* + * Write mix_comp structure for each mix component + */ + memcpy(mix[n_new].comps, mix[n_old].comps, + (size_t) (count_comps) * sizeof (struct mix_comp)); + if (sort == TRUE) mix_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int mix_free (struct mix *mix_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free space allocated for mixture structure. + */ + if (mix_ptr == NULL) return(ERROR); + + mix_ptr->description = (char *) free_check_null (mix_ptr->description); + mix_ptr->comps = (struct mix_comp *) free_check_null (mix_ptr->comps); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct mix *mix_search(int n_user, int *n, int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Linear search of mix array for user number n_user. + * Returns pointer to mix structure if found, n is set to position in mix array. + * Returns NULL if not found. + */ + int i; + for (i = 0; i < count_mix; i++) { + if (n_user == mix[i].n_user) { + break; + } + } + if (i >= count_mix) { + if ( print == TRUE) { + sprintf(error_string, "Mix %d not found.", n_user); + error_msg(error_string, CONTINUE); + } + *n = -999; + return(NULL); + } + *n = i; + return(&mix[i]); +} +/* ---------------------------------------------------------------------- */ +int mix_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of mix structures + */ + if (count_mix > 0) { + qsort (mix, (size_t) count_mix, (size_t) sizeof(struct mix), + mix_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "pe_data" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct pe_data *pe_data_alloc(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Allocate and initialize an array of struct pe_data + */ + struct pe_data *pe_data_ptr; + char token[MAX_LENGTH]; + + pe_data_ptr = (struct pe_data *) PHRQ_malloc( (size_t) (2 * sizeof (struct pe_data))); + if (pe_data_ptr == NULL) malloc_error(); + pe_data_ptr[0].name = pe_string; + if (s_eminus != NULL && s_eminus->rxn != NULL) { + pe_data_ptr[0].rxn = rxn_dup(s_eminus->rxn); + } else { + pe_data_ptr[0].rxn = rxn_alloc(3); + if (pe_data_ptr[0].rxn == NULL) malloc_error(); + strcpy(token,"e-"); + s_eminus = s_store(token, -1.0, FALSE); + pe_data_ptr[0].rxn->token[0].s = s_eminus; + pe_data_ptr[0].rxn->token[0].coef = -1.0; + pe_data_ptr[0].rxn->token[1].s = s_eminus; + pe_data_ptr[0].rxn->token[1].coef = -1.0; + pe_data_ptr[0].rxn->token[2].s = NULL; + } + pe_data_ptr[1].name = NULL; + pe_data_ptr[1].rxn = NULL; + + return (pe_data_ptr); +} +/* ---------------------------------------------------------------------- */ +struct pe_data *pe_data_dup (struct pe_data *pe_ptr_old) +/* ---------------------------------------------------------------------- */ +{ +/* + * Allocate space and copy data from pe_ptr_old into the new space. + * Returns pointer to new space. + */ + int i, count_pe; + struct pe_data *pe_ptr_new; +/* + * Count pe data and copy into new structure + */ + if (pe_ptr_old == NULL) return(ERROR); + for (i = 0; pe_ptr_old[i].name != NULL; i++); + count_pe = i + 1; + pe_ptr_new = (struct pe_data *) PHRQ_malloc( (size_t) count_pe * sizeof(struct pe_data)); + if (pe_ptr_new == NULL) malloc_error(); + memcpy ( (void *) pe_ptr_new, (void *) pe_ptr_old, (size_t) count_pe * sizeof(struct pe_data) ); + for (i = 0; i < count_pe - 1; i++) { + pe_ptr_new[i].rxn = rxn_dup(pe_ptr_old[i].rxn); + } + pe_ptr_new[count_pe - 1].rxn = NULL; + return(pe_ptr_new); +} +/* ---------------------------------------------------------------------- */ +int pe_data_free (struct pe_data *pe_data_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees all data for pe_data_ptr, including pe_data_ptr. + */ + int i; + + if ( pe_data_ptr == NULL ) return(ERROR); + for (i=0; pe_data_ptr[i].name != NULL; i++) { + rxn_free(pe_data_ptr[i].rxn); + } + pe_data_ptr = (struct pe_data *) free_check_null (pe_data_ptr); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pe_data_store (struct pe_data **pe, const char *token) +/* ---------------------------------------------------------------------- */ +{ +/* + * Find pe name in current list of pe_data structures + * or allocate new pe_data structure + */ + int i; + struct pe_data *pe_data_ptr; +/* + * Search for pe in list + */ + pe_data_ptr = *pe; + for (i=0; pe_data_ptr[i].name != NULL; i++) { + if (strcmp (token, pe_data_ptr[i].name ) == 0 ) { + return (i); + } + } +/* + * Save new struct pe_data in array + */ + *pe = (struct pe_data *) PHRQ_realloc( (void *) *pe, (size_t) (i+2) * sizeof(struct pe_data)); + if (*pe == NULL) malloc_error(); + pe_data_ptr = *pe; + pe_data_ptr[i].name = string_hsave ( token ); + pe_data_ptr[i].rxn = NULL; + pe_data_ptr[i + 1].name = NULL; + return ( i ); +} + +/* ********************************************************************** + * + * Routines related to structure "phases" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct phase *phase_alloc(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Allocates space to a phase structure and initializes + * arguments: void + * return: pointer to new phase structure + */ + struct phase *phase_ptr; +/* + * Allocate space + */ + phase_ptr=(struct phase *) PHRQ_malloc(sizeof(struct phase)); + if (phase_ptr == NULL) malloc_error(); +/* + * Initialize space + */ + phase_init(phase_ptr); + return(phase_ptr); +} +/* ---------------------------------------------------------------------- */ +int phase_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compares names of phases for sort + */ + const struct phase *phase_ptr1, *phase_ptr2; + phase_ptr1 = * (const struct phase **) ptr1; + phase_ptr2 = * (const struct phase **) ptr2; + return(strcmp_nocase(phase_ptr1->name, phase_ptr2->name)); +} +/* ---------------------------------------------------------------------- */ +int phase_compare_string (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const char *char_ptr; + const struct phase *phase_ptr; + char_ptr = (const char *) ptr1; + phase_ptr = * (const struct phase **) ptr2; + return(strcmp_nocase(char_ptr, phase_ptr->name)); +} +/* ---------------------------------------------------------------------- */ +int phase_delete(int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Deletes phase i from list, phases + * Frees memory allocated to phase[i] and renumbers phases to remove number i. + * Input: i, number of phase + * Return: OK + */ + int j; + + phase_free(phases[i]); + phases[i] = (struct phase *) free_check_null(phases[i]); + for (j=i; j < (count_phases - 1); j++) { + phases[j]=phases[j+1]; + } + count_phases--; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int phase_free(struct phase *phase_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees memory allocated within phase[i], does not free phase structure + * Input: i, number of phase + * Return: OK + */ + if (phase_ptr == NULL) return(ERROR); + phase_ptr->next_elt = (struct elt_list *) free_check_null (phase_ptr->next_elt); + phase_ptr->next_sys_total = (struct elt_list *) free_check_null (phase_ptr->next_sys_total); + rxn_free (phase_ptr->rxn); + rxn_free (phase_ptr->rxn_s); + rxn_free (phase_ptr->rxn_x); + phase_ptr->add_logk = (struct name_coef *) free_check_null (phase_ptr->add_logk); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct phase *phase_bsearch (char *ptr, int *j, int print) +/* ---------------------------------------------------------------------- */ +{ +/* Binary search the structure array "phases" for a name that is equal to + * ptr. Assumes array phases is in sort order. + * + * Arguments: + * name input, a character string to be located in phases. + * j index number in array phases. + * + * Returns: + * if found, pointer to phase structure. + * if not found, NULL + * + */ + void *void_ptr; + + void_ptr = NULL; + if (count_phases > 0) { + void_ptr = (void *) + bsearch ( (char *) ptr, + (char *) phases, + (size_t) count_phases, + (size_t) sizeof(struct phase *), + phase_compare_string); + } + if (void_ptr == NULL && print == TRUE) { + sprintf(error_string, "Could not find phase in list, %s.", ptr); + error_msg(error_string, CONTINUE); + } + + if (void_ptr == NULL) { + *j = -1; + return(NULL); + } + + *j = (int) ((struct phase **) void_ptr - phases); + return (* (struct phase **) void_ptr); +} +/* ---------------------------------------------------------------------- */ +static int phase_init(struct phase *phase_ptr) +/* ---------------------------------------------------------------------- */ +/* + * set pointers in phase structure to NULL + */ +{ + int i; + + phase_ptr->name=NULL; + phase_ptr->formula=NULL; + phase_ptr->in = FALSE; + phase_ptr->lk = 0.0; + for (i = 0; i < 8; i++) phase_ptr->logk[i]=0.0; + phase_ptr->type = SOLID; + phase_ptr->check_equation = TRUE; + phase_ptr->next_elt = NULL; + phase_ptr->next_sys_total = NULL; + phase_ptr->rxn = NULL; + phase_ptr->rxn_s = NULL; + phase_ptr->rxn_x = NULL; + phase_ptr->add_logk = NULL; + phase_ptr->count_add_logk = 0; + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct phase *phase_store (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for phases. + * + * If found, pointer to the appropriate phase structure is returned. + * + * If the string is not found, a new entry is made at the end of + * the phases array (position count_phases) and count_phases is + * incremented. A new entry is made in the hash table. Pointer to + * the new structure is returned. + * + * Arguments: + * name input, character string to be located or stored. + * + * Returns: + * The address of a phase structure that contains the phase data. + * If phase existed, it is reinitialized. The structure returned + * contains only the name of the phase. + */ + int n; + struct phase *phase_ptr; + ENTRY item, *found_item; + char token[MAX_LENGTH]; + char *ptr; +/* + * Search list + */ + + strcpy(token, name); + str_tolower(token); + ptr = string_hsave(token); + + item.key = ptr; + item.data = NULL; + found_item = hsearch_multi(phases_hash_table, item, FIND); + if (found_item != NULL) { + phase_ptr = (struct phase *) (found_item->data); + phase_free (phase_ptr); + phase_init (phase_ptr); + phase_ptr->name = string_hsave( name ); + return (phase_ptr); + } +/* + * Make new phase structure and return pointer to it + */ + /* make sure there is space in phases */ + n = count_phases++; + if (count_phases >= max_phases) { + space ((void **) ((void *) &phases), count_phases, &max_phases, sizeof(struct phase *)); + } + phases[n]=phase_alloc(); + /* set name in phase structure */ + phases[n]->name = string_hsave( name ); +/* + * Update hash table + */ + item.key = ptr; + item.data = (void *) phases[n]; + found_item = hsearch_multi(phases_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in phase_store."); + error_msg(error_string, CONTINUE); + } + + return (phases[n]); +} +#ifdef SKIP +/* ---------------------------------------------------------------------- */ +struct phase *phase_search (char *ptr, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Linear search of phases to find phase with name in ptr. + * Returns pointer if found. n contains position in array master. + * Returns NULL if not found. + */ + int i; + struct phase *phase_ptr; +/* + * Search phases list + */ + *n = -999; + for (i = 0; i < count_phases; i++) { + if (strcmp_nocase(ptr, phases[i]->name) == 0) { + *n = i; + phase_ptr = phases[i]; + return(phase_ptr); + } + } + return(NULL); +} +/* ---------------------------------------------------------------------- */ +struct phase *phase_store (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for phases. + * + * If found, pointer to the appropriate phase structure is returned. + * + * If the string is not found, a new entry is made at the end of + * the phases array (position count_phases) and count_phases is + * incremented. A new entry is made in the hash table. Pointer to + * the new structure is returned. + * + * Arguments: + * name input, character string to be located or stored. + * + * Returns: + * The address of a phase structure that contains the phase data. + * If phase existed, it is reinitialized. The structure returned + * contains only the name of the phase. + */ + int n; + struct phase *phase_ptr; +/* + * Search list + */ + phase_ptr = phase_search(name, &n); + if (phase_ptr != NULL) { + phase_free (phase_ptr); + phase_init (phase_ptr); + phase_ptr->name = string_hsave( name ); + return (phase_ptr); + } +/* + * Make new phase structure and return pointer to it + */ + /* make sure there is space in phases */ + n = count_phases++; + if (count_phases >= max_phases) { + space ((void **) &phases, count_phases, &max_phases, sizeof(struct phase *)); + } + phases[n]=phase_alloc(); + /* set name in phase structure */ + phases[n]->name = string_hsave( name ); + return (phases[n]); +} +#endif +/* ********************************************************************** + * + * Routines related to structure "pp_assemblage" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct pp_assemblage *pp_assemblage_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct pp_assemblage *pp_assemblage_ptr; + pp_assemblage_ptr = (struct pp_assemblage *) PHRQ_malloc(sizeof (struct pp_assemblage)); + if (pp_assemblage_ptr == NULL) malloc_error(); + pp_assemblage_ptr->description = NULL; + pp_assemblage_ptr->next_elt = NULL; + pp_assemblage_ptr->count_comps = 0; + pp_assemblage_ptr->pure_phases = NULL; + return ( pp_assemblage_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct pp_assemblage *pp_assemblage_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search of array pp_assemblage to find user number k. + * Assumes pp_assemblage is in sort order. + * + * Input: k, user number to find. + * + * Output: n, position in array pp_assemblage for user number k. + * + * Return: pointer to pp_assemblage structure for user number k, if found. + * NULL if not found. + */ + void *void_ptr; + if (count_pp_assemblage == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) pp_assemblage, + (size_t) count_pp_assemblage, + (size_t) sizeof(struct pp_assemblage), + pp_assemblage_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct pp_assemblage *) void_ptr - pp_assemblage); + return ( (struct pp_assemblage *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct pp_assemblage *pp_assemblage_ptr1, *pp_assemblage_ptr2; + pp_assemblage_ptr1 = (const struct pp_assemblage *) ptr1; + pp_assemblage_ptr2 = (const struct pp_assemblage *) ptr2; + if (pp_assemblage_ptr1->n_user > pp_assemblage_ptr2->n_user) return(1); + if (pp_assemblage_ptr1->n_user < pp_assemblage_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int pp_assemblage_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare pp_assemblage user numbers + */ + const int *nptr1; + const struct pp_assemblage *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct pp_assemblage *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_copy(struct pp_assemblage *pp_assemblage_old_ptr, + struct pp_assemblage *pp_assemblage_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies pp_assemblage data from pp_assemblage_old_ptr to pp_assemblage_new_ptr. + * Space for a pp_assemblage_new_ptr must already be malloced. + * Space for list of pure phases in assemblage is malloced here. + */ + int count_comps; + char token[MAX_LENGTH]; +/* + * Store data for structure pp_assemblage + */ + pp_assemblage_new_ptr->n_user = n_user_new; + pp_assemblage_new_ptr->n_user_end = n_user_new; + pp_assemblage_new_ptr->new_def = pp_assemblage_old_ptr->new_def; + sprintf(token, "Pp_Assemblage defined in simulation %d.", simulation); + pp_assemblage_new_ptr->description = string_duplicate(token); + pp_assemblage_new_ptr->next_elt = elt_list_dup(pp_assemblage_old_ptr->next_elt); +/* + * Count pure phases + */ + count_comps = pp_assemblage_old_ptr->count_comps; + pp_assemblage_new_ptr->count_comps = count_comps; +/* + * Malloc space and copy + */ + pp_assemblage_new_ptr->pure_phases = (struct pure_phase *) PHRQ_malloc( (size_t) count_comps * sizeof(struct pure_phase)); + if (pp_assemblage_new_ptr->pure_phases == NULL) malloc_error(); + + memcpy( (void *) pp_assemblage_new_ptr->pure_phases, + (void *) pp_assemblage_old_ptr->pure_phases, + (size_t) count_comps * sizeof(struct pure_phase) ); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an pp_assemblage definition from position n + * to position count_pp_assemblage. + */ + space ((void **) ((void *) &pp_assemblage), count_pp_assemblage, &max_pp_assemblage, sizeof(struct pp_assemblage)); + pp_assemblage_copy(&pp_assemblage[n], &pp_assemblage[count_pp_assemblage], n_user); + count_pp_assemblage++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies pp_assemblage[n_user_old] to old n_user_new space if + * found or to pp_assemblage[count_pp_assemblage] if not found. + * Pp_Assemblage array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + struct pp_assemblage *pp_assemblage_ptr_old, *pp_assemblage_ptr_new; +/* + * Find n_user_old in structure array pp_assemblage + */ + if (n_user_old == n_user_new) return(OK); + pp_assemblage_ptr_old = pp_assemblage_bsearch(n_user_old, &n_old); + if (pp_assemblage_ptr_old == NULL) { + sprintf(error_string, "Pp_Assemblage %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array pp_assemblage or make new space + */ + sort = FALSE; + pp_assemblage_ptr_new = pp_assemblage_bsearch(n_user_new, &n_new); + if (pp_assemblage_ptr_new != NULL) { + pp_assemblage_free(pp_assemblage_ptr_new); + } else { + space ((void **) ((void *) &pp_assemblage), count_pp_assemblage, &max_pp_assemblage, sizeof(struct pp_assemblage)); + if (n_user_new < pp_assemblage[count_pp_assemblage-1].n_user) sort = TRUE; + n_new = count_pp_assemblage++; + } +/* + * Copy data + */ + pp_assemblage_copy(&pp_assemblage[n_old], &pp_assemblage[n_new], n_user_new); + if (sort == TRUE) pp_assemblage_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array pp_assemblage. + */ +{ + int i; + int n_old; + struct pp_assemblage *pp_assemblage_ptr_old; +/* + * Find n_user_old in structure array + */ + pp_assemblage_ptr_old = pp_assemblage_bsearch(n_user_old, &n_old); + if (pp_assemblage_ptr_old != NULL) { + /* + * Delete pp_assemblage + */ + pp_assemblage_free(&pp_assemblage[n_old]); + + for(i = n_old + 1; i < count_pp_assemblage; i++) { + memcpy( (void *) &pp_assemblage[i - 1], (void *) &pp_assemblage[i], + (size_t) sizeof (struct pp_assemblage) ); + } + count_pp_assemblage--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_free (struct pp_assemblage *pp_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free space allocated for pp_assemblage structure + */ + if (pp_assemblage_ptr == NULL) return(ERROR); + + pp_assemblage_ptr->description = (char *) free_check_null (pp_assemblage_ptr->description); + pp_assemblage_ptr->next_elt = (struct elt_list *) free_check_null (pp_assemblage_ptr->next_elt); + pp_assemblage_ptr->pure_phases = (struct pure_phase *) free_check_null (pp_assemblage_ptr->pure_phases); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_init (struct pp_assemblage *pp_assemblage_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ +/* + * Provides initial values for a new pp_assemblage + * arguments: + * n position in array pp_assemblage + * n_user user number for pp_assemblage + * return: OK + */ + pp_assemblage_ptr->n_user = n_user; + pp_assemblage_ptr->n_user_end = n_user_end; + pp_assemblage_ptr->new_def = TRUE; + pp_assemblage_ptr->description = string_duplicate(description); + + pp_assemblage_ptr->next_elt = NULL; + pp_assemblage_ptr->count_comps = 0; + pp_assemblage_ptr->pure_phases = (struct pure_phase *) PHRQ_malloc((size_t) sizeof(struct pure_phase)); + if (pp_assemblage_ptr->pure_phases == NULL) malloc_error(); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_ptr_to_user(struct pp_assemblage *pp_assemblage_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies pp_assemblage_ptr_old to old n_user_new space if + * found or to pp_assemblage[count_pp_assemblage] if not found. + * Pp_Assemblage array may not be in sort order after the copy. + */ + int n_new, sort; + struct pp_assemblage *pp_assemblage_ptr_new; +/* + * Find n_user_old in structure array pp_assemblage + */ + if (pp_assemblage_ptr_old == NULL) { + sprintf(error_string, "Pp_Assemblage pointer is NULL."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array pp_assemblage or make new space + */ + sort = FALSE; + pp_assemblage_ptr_new = pp_assemblage_bsearch(n_user_new, &n_new); + if (pp_assemblage_ptr_new == pp_assemblage_ptr_old) return(OK); + if (pp_assemblage_ptr_new != NULL) { + pp_assemblage_free(pp_assemblage_ptr_new); + } else { + space ((void **) ((void *) &pp_assemblage), count_pp_assemblage, &max_pp_assemblage, sizeof(struct pp_assemblage)); + if (n_user_new < pp_assemblage[count_pp_assemblage-1].n_user) sort = TRUE; + n_new = count_pp_assemblage++; + } +/* + * Copy data + */ + pp_assemblage_copy(pp_assemblage_ptr_old, &pp_assemblage[n_new], n_user_new); + if (sort == TRUE) pp_assemblage_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct pp_assemblage *pp_assemblage_replicate(struct pp_assemblage *pp_assemblage_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct pp_assemblage *pp_assemblage_ptr; + pp_assemblage_ptr = pp_assemblage_alloc(); + pp_assemblage_copy(pp_assemblage_old_ptr, pp_assemblage_ptr, n_user_new); + return (pp_assemblage_ptr); +} +/* ---------------------------------------------------------------------- */ +struct pp_assemblage *pp_assemblage_search (int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "pp_assemblage" for user number n_user. + * + * Arguments: + * n_user input, user number + * n output, position in pp_assemblage + * + * Returns: + * if found, the address of the pp_assemblage element + * if not found, NULL + */ + int i; + for (i=0; i < count_pp_assemblage; i++) { + if ( pp_assemblage[i].n_user == n_user) { + *n = i; + return (&(pp_assemblage[i])); + } + } +/* + * Pp_Assemblage not found + */ + return (NULL); +} +/* ---------------------------------------------------------------------- */ +int pp_assemblage_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of pp_assemblage structures + */ + if (count_pp_assemblage > 0) { + qsort (pp_assemblage, (size_t) count_pp_assemblage, (size_t) sizeof(struct pp_assemblage), + pp_assemblage_compare); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int pure_phase_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct pure_phase *pure_phase_ptr1, *pure_phase_ptr2; + pure_phase_ptr1 = (const struct pure_phase *) ptr1; + pure_phase_ptr2 = (const struct pure_phase *) ptr2; + return(strcmp_nocase(pure_phase_ptr1->name, pure_phase_ptr2->name)); + +} +/* ********************************************************************** + * + * Routines related to structure "rates" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct rate *rate_bsearch (char *ptr, int *j) +/* ---------------------------------------------------------------------- */ +{ +/* Binary search the structure array "rates" for a name that is equal to + * ptr. Assumes array rates is in sort order. + * + * Arguments: + * name input, a character string to be located in rates. + * j index number in array rates. + * + * Returns: + * if found, pointer to rate structure. + * if not found, NULL + * + */ + void *void_ptr; + + if (count_rates == 0) { + *j = -1; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) ptr, + (char *) rates, + (size_t) count_rates, + (size_t) sizeof(struct rate *), + rate_compare_string); + + if (void_ptr == NULL) { + *j = -1; + return(NULL); + } + + *j = (int) ((struct rate *) void_ptr - rates); + return ((struct rate *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int rate_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compares names of rates for sort + */ + const struct rate *rate_ptr1, *rate_ptr2; + rate_ptr1 = * (const struct rate **) ptr1; + rate_ptr2 = * (const struct rate **) ptr2; + return(strcmp_nocase(rate_ptr1->name, rate_ptr2->name)); +} +/* ---------------------------------------------------------------------- */ +int rate_compare_string (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const char *char_ptr; + const struct rate *rate_ptr; + char_ptr = (const char *) ptr1; + rate_ptr = * (const struct rate **) ptr2; + return(strcmp_nocase(char_ptr, rate_ptr->name)); +} +/* ---------------------------------------------------------------------- */ +int rate_free(struct rate *rate_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees memory allocated within rate[i], does not free rate structure + * Input: i, number of rate + * Return: OK + */ + char cmd[] = "new; quit"; + + if (rate_ptr == NULL) return(ERROR); + rate_ptr->commands = (char *) free_check_null(rate_ptr->commands); + basic_run(cmd, rate_ptr->linebase, rate_ptr->varbase, rate_ptr->loopbase); + rate_ptr->linebase = NULL; + rate_ptr->varbase = NULL; + rate_ptr->loopbase = NULL; + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct rate *rate_search (char *name, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "rates" for name. + * + * Arguments: + * name input, name of rate + * n output, position in rates + * + * Returns: + * if found, the address of the pp_assemblage element + * if not found, NULL + */ + int i; + *n = -1; + for (i=0; i < count_rates; i++) { + if ( strcmp_nocase(rates[i].name, name) == 0) { + *n = i; + return (&(rates[i])); + } + } +/* + * rate name not found + */ + return (NULL); +} +/* ---------------------------------------------------------------------- */ +int rate_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of rate structures + */ + if (count_rates > 0) { + qsort (rates, (size_t) count_rates, (size_t) sizeof(struct rate), + rate_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "reaction", balanced chemical reactions + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct reaction *rxn_alloc(int ntokens) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Allocates space to a rxn structure + * input: ntokens, number of tokens in reaction + * return: pointer to a species structure + */ + struct reaction *rxn_ptr; +/* + * Malloc reaction structure + */ + rxn_ptr=(struct reaction *) PHRQ_malloc(sizeof(struct reaction)); + if (rxn_ptr == NULL) malloc_error(); +/* + * zero log k data + */ + for (i = 0; i < 7; i++) { + rxn_ptr->logk[i] = 0.0; + } +/* + * Malloc rxn_token structure + */ + rxn_ptr->token = (struct rxn_token *) PHRQ_malloc((size_t) ntokens*sizeof(struct rxn_token)); + if (rxn_ptr->token == NULL) malloc_error(); + return(rxn_ptr); +} +/* ---------------------------------------------------------------------- */ +struct reaction *rxn_dup(struct reaction *rxn_ptr_old) +/* ---------------------------------------------------------------------- */ +{ +/* + * mallocs space for a reaction and copies the reaction + * input: rxn_ptr_old, pointer to a reaction structure to copy + * + * Return: rxn_ptr_new, pointer to duplicated structure to copy + */ + int i; + struct reaction *rxn_ptr_new; + + if (rxn_ptr_old == NULL) return(NULL); + for (i = 0; rxn_ptr_old->token[i].s != NULL; i++); + + rxn_ptr_new = rxn_alloc( i + 1); +/* + * Copy logk data + */ + memcpy (rxn_ptr_new->logk, rxn_ptr_old->logk, (size_t) 7 * sizeof (LDBLE)); +/* + * Copy tokens + */ + memcpy (rxn_ptr_new->token, rxn_ptr_old->token, (size_t) (i + 1) * sizeof (struct rxn_token)); + + return(rxn_ptr_new); +} +/* ---------------------------------------------------------------------- */ +LDBLE rxn_find_coef(struct reaction *r_ptr, const char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Finds coefficient of token in reaction. + * input: r_ptr, pointer to a reaction structure + * str, string to find as reaction token + * + * Return: 0.0, if token not found + * coefficient of token, if found. + */ + struct rxn_token *r_token; + LDBLE coef; + + r_token=r_ptr->token + 1; + coef=0.0; + while (r_token->s != NULL) { + if (strcmp(r_token->s->name, str) == 0) { + coef=r_token->coef; + break; + } + r_token++; + } + return(coef); +} +/* ---------------------------------------------------------------------- */ +int rxn_free(struct reaction *rxn_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees space allocated for a reaction structure + * input: rxn_ptr, pointer to reaction structure + * return: ERROR, if pointer is NULL + * OK, otherwise. + */ + if (rxn_ptr == NULL) return(ERROR); + rxn_ptr->token = (struct rxn_token *) free_check_null (rxn_ptr->token); + rxn_ptr = (struct reaction *) free_check_null (rxn_ptr); + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "species" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct species *s_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a species structure, initializes + * arguments: void + * return: pointer to a species structure + */ +{ + struct species *s_ptr; + s_ptr=(struct species *) PHRQ_malloc(sizeof(struct species)); + if (s_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + s_init(s_ptr); + + return(s_ptr); +} +/* ---------------------------------------------------------------------- */ +int s_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct species *s_ptr1, *s_ptr2; + s_ptr1 = * (const struct species **) ptr1; + s_ptr2 = * (const struct species **) ptr2; + return(strcmp(s_ptr1->name, s_ptr2->name)); + +} +/* ---------------------------------------------------------------------- */ +int s_delete (int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Delete species i: free memory and renumber array of pointers, s. + */ + int j; + + s_free (s[i]); + s[i] = (struct species *) free_check_null(s[i]); + for (j=i; j < (count_s - 1); j++) { + s[j]=s[j+1]; + } + count_s--; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_free (struct species *s_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free space allocated for species structure, s_ptr. Does not free s_ptr. + */ + if (s_ptr == NULL) return(ERROR); + s_ptr->next_elt = (struct elt_list *) free_check_null (s_ptr->next_elt); + s_ptr->next_secondary = (struct elt_list *) free_check_null (s_ptr->next_secondary); + s_ptr->next_sys_total = (struct elt_list *) free_check_null (s_ptr->next_sys_total); + s_ptr->add_logk = (struct name_coef *) free_check_null(s_ptr->add_logk); + rxn_free (s_ptr->rxn); + rxn_free (s_ptr->rxn_s); + rxn_free (s_ptr->rxn_x); + s_ptr->diff_layer = (struct species_diff_layer *) free_check_null (s_ptr->diff_layer); + return(OK); +} +/* ---------------------------------------------------------------------- */ +static int s_init(struct species *s_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a species structure + */ +{ + int i; +/* + * set pointers in structure to NULL + */ + s_ptr->name=NULL; + s_ptr->mole_balance=NULL; + s_ptr->primary=NULL; + s_ptr->secondary=NULL; + s_ptr->next_elt=NULL; + s_ptr->next_secondary=NULL; + s_ptr->next_sys_total=NULL; + s_ptr->rxn=NULL; + s_ptr->rxn_s=NULL; + s_ptr->rxn_x=NULL; + s_ptr->diff_layer = NULL; +/* + * set varibles = 0 + */ + s_ptr->in = FALSE; + s_ptr->gfw = 0.0; + s_ptr->z = 0.0; + s_ptr->alk = 0.0; + s_ptr->carbon = 0.0; + s_ptr->co2 = 0.0; + s_ptr->h = 0.0; + s_ptr->o = 0.0; + s_ptr->dha = 0.0; + s_ptr->dhb = 0.0; + s_ptr->lk = 0.0; + for (i =0; i < 8; i++) { + s_ptr->logk[i] = 0.0; + } + s_ptr->count_add_logk = 0; + s_ptr->add_logk = NULL; + s_ptr->lg = 0.0; + s_ptr->lm = 0.0; + s_ptr->la = 0.0; + s_ptr->dg = 0.0; + s_ptr->moles = 0.0; + s_ptr->type = 0; + s_ptr->gflag = 0; + s_ptr->check_equation = TRUE; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct species *s_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for species. + * + * Arguments: + * name input, a character string to be located in species. + * i is obsolete. + * + * Returns: + * If found, pointer to the appropriate species structure is returned. + * else, NULL pointer is returned. + */ + struct species *s_ptr; + ENTRY item, *found_item; + + item.key = name; + item.data = NULL; + found_item = hsearch_multi(species_hash_table, item, FIND); + if (found_item != NULL) { + s_ptr = (struct species *) (found_item->data); + return (s_ptr); + } + return (NULL); +} +/* ---------------------------------------------------------------------- */ +struct species *s_store (char *name, LDBLE z, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for species. + * + * Pointer to a species structure is always returned. + * + * If the string is not found, a new entry is made at the end of + * the elements array (position count_elements) and count_elements is + * incremented. A new entry is made in the hash table. Pointer to + * the new structure is returned. + * If "name" is found and replace is true, pointers in old species structure + * are freed and replaced with additional input. + * If "name" is found and replace is false, the old species structure is not + * modified and a pointer to it is returned. + * + * Arguments: + * name input, character string to be found in "species". + * z input, charge on "name" + * replace_if_found input, TRUE means reinitialize species if found + * FALSE means just return pointer if found. + * + * Returns: + * pointer to species structure "s" where "name" can be found. + */ + int n; + struct species *s_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + item.key = name; + item.data = NULL; + found_item = hsearch_multi(species_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + s_ptr = (struct species *) (found_item->data); + return (s_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + s_ptr = (struct species *) (found_item->data); + s_free(s_ptr); + s_init(s_ptr); + } else { + n = count_s++; + /* make sure there is space in s */ + if (count_s >= max_s) { + space ((void **) ((void *) &s), count_s, &max_s, sizeof(struct species *)); + } + /* Make new species structure */ + s[n] = s_alloc(); + s_ptr = s[n]; + } + /* set name and z in pointer in species structure */ + s_ptr->name = string_hsave( name ); + s_ptr->z = z; +/* + * Update hash table + */ + item.key = s_ptr->name; + item.data = (void *) s_ptr; + found_item = hsearch_multi(species_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in species_store."); + error_msg(error_string, CONTINUE); + } + + return (s_ptr); +} +/* ********************************************************************** + * + * Routines related to structure "s_s_assemblage" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct s_s_assemblage *s_s_assemblage_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct s_s_assemblage *s_s_assemblage_ptr; + s_s_assemblage_ptr = (struct s_s_assemblage *) PHRQ_malloc(sizeof (struct s_s_assemblage)); + if (s_s_assemblage_ptr == NULL) malloc_error(); + s_s_assemblage_ptr->description = NULL; + s_s_assemblage_ptr->count_s_s = 0; + s_s_assemblage_ptr->s_s = NULL; + return ( s_s_assemblage_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct s_s_assemblage *s_s_assemblage_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search of array s_s_assemblage to find user number k. + * Assumes s_s_assemblage is in sort order. + * + * Input: k, user number to find. + * + * Output: n, position in array s_s_assemblage for user number k. + * + * Return: pointer to s_s_assemblage structure for user number k, if found. + * NULL if not found. + */ + void *void_ptr; + if (count_s_s_assemblage == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) s_s_assemblage, + (size_t) count_s_s_assemblage, + (size_t) sizeof(struct s_s_assemblage), + s_s_assemblage_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct s_s_assemblage *) void_ptr - s_s_assemblage); + return ( (struct s_s_assemblage *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct s_s_assemblage *s_s_assemblage_ptr1, *s_s_assemblage_ptr2; + s_s_assemblage_ptr1 = (const struct s_s_assemblage *) ptr1; + s_s_assemblage_ptr2 = (const struct s_s_assemblage *) ptr2; + if (s_s_assemblage_ptr1->n_user > s_s_assemblage_ptr2->n_user) return(1); + if (s_s_assemblage_ptr1->n_user < s_s_assemblage_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int s_s_assemblage_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare s_s_assemblage user numbers + */ + const int *nptr1; + const struct s_s_assemblage *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct s_s_assemblage *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_copy(struct s_s_assemblage *s_s_assemblage_old_ptr, + struct s_s_assemblage *s_s_assemblage_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies s_s_assemblage data from s_s_assemblage_old_ptr to s_s_assemblage_new_ptr. + * Space for a s_s_assemblage_new_ptr must already be malloced. + * Space for list of pure phases in assemblage is malloced here. + */ + int i, count_comps, count_s_s; + char token[MAX_LENGTH]; +/* + * Store data for structure s_s_assemblage + */ + memcpy(s_s_assemblage_new_ptr, s_s_assemblage_old_ptr, sizeof(struct s_s_assemblage)); + s_s_assemblage_new_ptr->n_user = n_user_new; + s_s_assemblage_new_ptr->n_user_end = n_user_new; + sprintf(token, "S_S_Assemblage defined in simulation %d.", simulation); + s_s_assemblage_new_ptr->description = string_duplicate(token); + s_s_assemblage_new_ptr->new_def = FALSE; +/* + * Malloc space for s_s structures and fill + */ + count_s_s = s_s_assemblage_old_ptr->count_s_s; + s_s_assemblage_new_ptr->s_s = (struct s_s *) PHRQ_malloc( (size_t) count_s_s * sizeof(struct s_s)); + if (s_s_assemblage_new_ptr->s_s == NULL) malloc_error(); + memcpy( (void *) s_s_assemblage_new_ptr->s_s, + (void *) s_s_assemblage_old_ptr->s_s, + (size_t) count_s_s * sizeof(struct s_s) ); +/* + * Malloc space for components + */ + for (i = 0; i < count_s_s; i++) { + count_comps = s_s_assemblage_old_ptr->s_s[i].count_comps; + s_s_assemblage_new_ptr->s_s[i].comps = (struct s_s_comp *) PHRQ_malloc( (size_t) count_comps * sizeof(struct s_s_comp)); + if (s_s_assemblage_new_ptr->s_s[i].comps == NULL) malloc_error(); + memcpy( (void *) s_s_assemblage_new_ptr->s_s[i].comps, + (void *) s_s_assemblage_old_ptr->s_s[i].comps, + (size_t) count_comps * sizeof(struct s_s_comp) ); + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an s_s_assemblage definition from position n + * to position count_s_s_assemblage. + */ + space ((void **) ((void *) &s_s_assemblage), count_s_s_assemblage, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + s_s_assemblage_copy(&s_s_assemblage[n], &s_s_assemblage[count_s_s_assemblage], n_user); + count_s_s_assemblage++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies s_s_assemblage[n_user_old] to old n_user_new space if + * found or to s_s_assemblage[count_s_s_assemblage] if not found. + * S_S_Assemblage array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + struct s_s_assemblage *s_s_assemblage_ptr_old, *s_s_assemblage_ptr_new; +/* + * Find n_user_old in structure array s_s_assemblage + */ + if (n_user_old == n_user_new) return(OK); + s_s_assemblage_ptr_old = s_s_assemblage_bsearch(n_user_old, &n_old); + if (s_s_assemblage_ptr_old == NULL) { + sprintf(error_string, "S_S_Assemblage %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array s_s_assemblage or make new space + */ + sort = FALSE; + s_s_assemblage_ptr_new = s_s_assemblage_bsearch(n_user_new, &n_new); + if (s_s_assemblage_ptr_new != NULL) { + s_s_assemblage_free(s_s_assemblage_ptr_new); + } else { + space ((void **) ((void *) &s_s_assemblage), count_s_s_assemblage, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + if (n_user_new < s_s_assemblage[count_s_s_assemblage-1].n_user) sort = TRUE; + n_new = count_s_s_assemblage++; + } +/* + * Copy data + */ + s_s_assemblage_copy(&s_s_assemblage[n_old], &s_s_assemblage[n_new], n_user_new); + if (sort == TRUE) s_s_assemblage_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array s_s_assemblage. + */ +{ + int i; + int n_old; + struct s_s_assemblage *s_s_assemblage_ptr_old; +/* + * Find n_user_old in structure array + */ + s_s_assemblage_ptr_old = s_s_assemblage_bsearch(n_user_old, &n_old); + if (s_s_assemblage_ptr_old != NULL) { + /* + * Delete s_s_assemblage + */ + s_s_assemblage_free(&s_s_assemblage[n_old]); + + for(i = n_old + 1; i < count_s_s_assemblage; i++) { + memcpy( (void *) &s_s_assemblage[i - 1], (void *) &s_s_assemblage[i], + (size_t) sizeof (struct s_s_assemblage) ); + } + count_s_s_assemblage--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_free (struct s_s_assemblage *s_s_assemblage_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free space allocated for s_s_assemblage structure + */ + int i; + + if (s_s_assemblage_ptr == NULL) return(ERROR); + s_s_assemblage_ptr->description = (char *) free_check_null (s_s_assemblage_ptr->description); + for (i = 0; i < s_s_assemblage_ptr->count_s_s; i++) { + s_s_assemblage_ptr->s_s[i].comps = (struct s_s_comp *) free_check_null(s_s_assemblage_ptr->s_s[i].comps); + } + s_s_assemblage_ptr->s_s = (struct s_s *) free_check_null (s_s_assemblage_ptr->s_s); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_init (struct s_s_assemblage *s_s_assemblage_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ + s_s_assemblage_ptr->n_user = n_user; + s_s_assemblage_ptr->n_user_end = n_user_end; + s_s_assemblage_ptr->description = string_duplicate(description); + s_s_assemblage_ptr->new_def = TRUE; + s_s_assemblage_ptr->count_s_s = 0; + s_s_assemblage_ptr->s_s = (struct s_s *) PHRQ_malloc((size_t) sizeof(struct s_s)); + if (s_s_assemblage_ptr->s_s == NULL) malloc_error(); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_ptr_to_user(struct s_s_assemblage *s_s_assemblage_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies s_s_assemblage_ptr_old to old n_user_new space if + * found or to s_s_assemblage[count_s_s_assemblage] if not found. + * S_S_Assemblage array may not be in sort order after the copy. + */ + int n_new, sort; + struct s_s_assemblage *s_s_assemblage_ptr_new; +/* + * Find n_user_old in structure array s_s_assemblage + */ + if (s_s_assemblage_ptr_old == NULL) { + sprintf(error_string, "S_S_Assemblage pointer is NULL."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array s_s_assemblage or make new space + */ + sort = FALSE; + s_s_assemblage_ptr_new = s_s_assemblage_bsearch(n_user_new, &n_new); + if (s_s_assemblage_ptr_new == s_s_assemblage_ptr_old) return(OK); + if (s_s_assemblage_ptr_new != NULL) { + s_s_assemblage_free(s_s_assemblage_ptr_new); + } else { + space ((void **) ((void *) &s_s_assemblage), count_s_s_assemblage, &max_s_s_assemblage, sizeof(struct s_s_assemblage)); + if (n_user_new < s_s_assemblage[count_s_s_assemblage-1].n_user) sort = TRUE; + n_new = count_s_s_assemblage++; + } +/* + * Copy data + */ + s_s_assemblage_copy(s_s_assemblage_ptr_old, &s_s_assemblage[n_new], n_user_new); + if (sort == TRUE) s_s_assemblage_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct s_s_assemblage *s_s_assemblage_replicate(struct s_s_assemblage *s_s_assemblage_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct s_s_assemblage *s_s_assemblage_ptr; + s_s_assemblage_ptr = s_s_assemblage_alloc(); + s_s_assemblage_copy(s_s_assemblage_old_ptr, s_s_assemblage_ptr, n_user_new); + return (s_s_assemblage_ptr); +} +/* ---------------------------------------------------------------------- */ +struct s_s_assemblage *s_s_assemblage_search (int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "s_s_assemblage" for user number n_user. + * + * Arguments: + * n_user input, user number + * n output, position in s_s_assemblage + * + * Returns: + * if found, the address of the s_s_assemblage element + * if not found, NULL + */ + int i; + for (i=0; i < count_s_s_assemblage; i++) { + if ( s_s_assemblage[i].n_user == n_user) { + *n = i; + return (&(s_s_assemblage[i])); + } + } +/* + * S_S_Assemblage not found + */ + return (NULL); +} +/* ---------------------------------------------------------------------- */ +int s_s_assemblage_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of s_s_assemblage structures + */ + if (count_s_s_assemblage > 0) { + qsort (s_s_assemblage, (size_t) count_s_s_assemblage, (size_t) sizeof(struct s_s_assemblage), + s_s_assemblage_compare); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct s_s *s_s_ptr1, *s_s_ptr2; + s_s_ptr1 = (const struct s_s *) ptr1; + s_s_ptr2 = (const struct s_s *) ptr2; + return(strcmp_nocase(s_s_ptr1->name, s_s_ptr2->name)); + +} +/* ********************************************************************** + * + * Routines related to structure "save_values" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct save_values *save_values_bsearch (struct save_values *k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search save_values to find if one exists with given coefficients + * Save_Values is assumed to be in sort order by count_subscripts and + * values of subscripts + */ + void *void_ptr; + if (count_save_values == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) k, + (char *) save_values, + (size_t) count_save_values, + (size_t) sizeof(struct save_values), + save_values_compare); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct save_values *) void_ptr - save_values); + return ( (struct save_values *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int save_values_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + int i; + const struct save_values *save_values_ptr1, *save_values_ptr2; + save_values_ptr1 = (const struct save_values *) ptr1; + save_values_ptr2 = (const struct save_values *) ptr2; + if (save_values_ptr1->count_subscripts < save_values_ptr2->count_subscripts) { + return(-1); + } else if (save_values_ptr1->count_subscripts > save_values_ptr2->count_subscripts) { + return(1); + } else { + for (i=0; i < save_values_ptr1->count_subscripts ;i++) { + if (save_values_ptr1->subscripts[i] < save_values_ptr2->subscripts[i]) { + return(-1); + } else if (save_values_ptr1->subscripts[i] > save_values_ptr2->subscripts[i]) { + return(1); + } + } + } + return(0); +} +/* ---------------------------------------------------------------------- */ +int save_values_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of save_values structures + */ + if (count_save_values > 0) { + qsort (save_values, (size_t) count_save_values, (size_t) sizeof(struct save_values), + save_values_compare); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int save_values_store(struct save_values *s_v) +/* ---------------------------------------------------------------------- */ +{ +/* + * Look for subscripts + */ + int n, i; + struct save_values *s_v_ptr; + + s_v_ptr = save_values_bsearch(s_v, &n); + if (s_v_ptr != NULL) { + s_v_ptr->value = s_v->value; + } else { + save_values = (struct save_values *) PHRQ_realloc(save_values, (size_t) (count_save_values + 1) * sizeof( struct save_values)); + if (save_values == NULL) malloc_error(); + save_values[count_save_values].value = s_v->value; + save_values[count_save_values].count_subscripts = s_v->count_subscripts; + i = s_v->count_subscripts; + if (i == 0) i = 1; + save_values[count_save_values].subscripts = (int *) PHRQ_malloc ((size_t) i * sizeof(int)); + if (save_values[count_save_values].subscripts == NULL) malloc_error(); + save_values[count_save_values].subscripts = (int *) memcpy(save_values[count_save_values].subscripts, s_v->subscripts, (size_t) i * sizeof(int)); + count_save_values++; + save_values_sort(); + } + + if (count_save_values > 0) { + qsort (save_values, (size_t) count_save_values, (size_t) sizeof(struct save_values), + save_values_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "solution" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +int conc_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct conc *conc_ptr1, *conc_ptr2; + conc_ptr1 = (const struct conc *) ptr1; + conc_ptr2 = (const struct conc *) ptr2; + return(strcmp_nocase(conc_ptr1->description, conc_ptr2->description)); + +} +/* ---------------------------------------------------------------------- */ +int conc_init (struct conc *conc_ptr) +/* ---------------------------------------------------------------------- */ +{ + if (conc_ptr == NULL) return(ERROR); + conc_ptr->equation_name = NULL; + conc_ptr->phase = NULL; + conc_ptr->phase_si = 0.0; + conc_ptr->units=NULL; + conc_ptr->n_pe=-1; + conc_ptr->as=NULL; + conc_ptr->gfw= 0.0; + return OK; +} +/* ---------------------------------------------------------------------- */ +int isotope_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + int i; + const struct isotope *iso_ptr1, *iso_ptr2; + + iso_ptr1 = (const struct isotope *) ptr1; + iso_ptr2 = (const struct isotope *) ptr2; + i = strcmp_nocase(iso_ptr1->elt_name, iso_ptr2->elt_name); + if (i != 0) return(i); + if (iso_ptr1->isotope_number < iso_ptr2->isotope_number) { + return(-1); + } else if (iso_ptr1->isotope_number > iso_ptr2->isotope_number) { + return(1); + } + return(0); +} +/* ---------------------------------------------------------------------- */ +struct solution *solution_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a solution structure + * arguments + * input: none + * return: pointer to a solution structure + */ +{ + int max_mass_balance; + struct solution *solution_ptr; + solution_ptr=(struct solution *) PHRQ_malloc(sizeof(struct solution)); + if (solution_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL + */ + solution_ptr->description=NULL; + solution_ptr->units=NULL; +/* + * Initial allocation of space for totals and activities + */ + max_mass_balance=MAX_MASS_BALANCE; + space ((void **) &(solution_ptr->totals), INIT, &max_mass_balance, sizeof (struct conc)); + max_mass_balance=MAX_MASS_BALANCE; + solution_ptr->totals[0].description = NULL; + space ((void **) &(solution_ptr->master_activity), INIT, &max_mass_balance, sizeof (struct master_activity)); + solution_ptr->master_activity[0].description = NULL; + solution_ptr->species_gamma = NULL; + solution_ptr->count_species_gamma = 0; +/* + * Initial allocation of space for pe's + */ + solution_ptr->pe = pe_data_alloc(); +/* + * Initial allocation of space for isotopes + */ + solution_ptr->isotopes = (struct isotope *) PHRQ_malloc(sizeof(struct isotope)); + if (solution_ptr->isotopes == NULL) malloc_error(); + solution_ptr->new_def=TRUE; + + return(solution_ptr); +} +/* ---------------------------------------------------------------------- */ +struct solution *solution_bsearch (int k, int *n, int print) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search of solution solution array to find user number k. + * Assumes array solution is in sort order. + * + * Input: k user number to find. + * print, TRUE print warning if solution not found. + * Output: n, position of solution ptr in solution array. + * Return: pointer to solution structure if found + * NULL if not found. + */ + void *void_ptr; + void_ptr = NULL; + if (count_solution > 0) { + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) solution, + (size_t) count_solution, + (size_t) sizeof(struct solution *), + solution_compare_int); + } + if (void_ptr == NULL && print == TRUE) { + sprintf(error_string, "Solution %d not found.", k); + error_msg(error_string, CONTINUE); + } + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + + *n = (int) ((struct solution **) void_ptr - solution); + return (* (struct solution **) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int solution_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare solution user numbers + */ + const struct solution *nptr1; + const struct solution *nptr2; + + nptr1= *(const struct solution **) ptr1; + nptr2= *(const struct solution **) ptr2; + if (nptr1->n_user > nptr2->n_user) return(1); + if (nptr1->n_user < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int solution_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare solution user number to an integer + */ + const int *nptr1; + const struct solution *nptr2; + + nptr1= (const int *) ptr1; + nptr2= *(const struct solution **) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +static struct solution *solution_copy(struct solution *solution_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies solution data to new structure. + * Space for new structure is malloced here. + * + * Input: solution_old_ptr, pointer to structure to be copied. + * n_user_new, user number to give to the new solution. + * + * Return: pointer to new solution structure. + */ + int i; + int count_totals, count_master_activity; + struct solution *solution_new_ptr; +/* + * malloc space for new solution structure + */ + solution_new_ptr = (struct solution *) PHRQ_malloc(sizeof(struct solution)); + if (solution_new_ptr == NULL) malloc_error(); +/* + * Copy solution data, but set pointers pe and totals to NULL + */ + memcpy ( (void *) solution_new_ptr, (void *) solution_old_ptr, (size_t) sizeof (struct solution)); + solution_new_ptr->n_user = n_user_new; + solution_new_ptr->n_user_end = n_user_new; + solution_new_ptr->description = string_duplicate(solution_old_ptr->description); +/* + * Count totals data and malloc space + */ + for (i = 0; solution_old_ptr->totals[i].description != NULL; i++); + count_totals = i + 1; + solution_new_ptr->totals = (struct conc *) PHRQ_malloc( (size_t) count_totals * sizeof(struct conc)); + if (solution_new_ptr->totals == NULL) malloc_error(); +/* + * Copy totals data + */ + memcpy ( (void *) solution_new_ptr->totals, (void *) solution_old_ptr->totals, (size_t) count_totals * sizeof (struct conc)); +/* + * Count master activity guesses and malloc space + */ + for (i = 0; solution_old_ptr->master_activity[i].description != NULL; i++); + count_master_activity = i + 1; + solution_new_ptr->master_activity = (struct master_activity *) PHRQ_malloc( (size_t) count_master_activity * sizeof(struct master_activity)); + if (solution_new_ptr->master_activity == NULL) malloc_error(); +/* + * Copy master activity guesses + */ + memcpy ( (void *) solution_new_ptr->master_activity, (void *) solution_old_ptr->master_activity, (size_t) count_master_activity * sizeof (struct master_activity)); +/* + * malloc space for species gammas + */ + if (solution_old_ptr->count_species_gamma > 0) { + solution_new_ptr->species_gamma = (struct master_activity *) PHRQ_malloc( (size_t) solution_old_ptr->count_species_gamma * sizeof(struct master_activity)); + if (solution_new_ptr->species_gamma == NULL) malloc_error(); + /* + * Copy species gammas + */ + memcpy ( (void *) solution_new_ptr->species_gamma, (void *) solution_old_ptr->species_gamma, (size_t) solution_old_ptr->count_species_gamma * sizeof (struct master_activity)); + solution_new_ptr->count_species_gamma = solution_old_ptr->count_species_gamma; + } else { + solution_new_ptr->species_gamma = NULL; + solution_new_ptr->count_species_gamma = 0; + } +/* + * Copy pe data + */ + solution_new_ptr->pe = pe_data_dup (solution_old_ptr->pe); +/* + * Malloc and copy isotope data + */ + if (solution_old_ptr->count_isotopes > 0) { + solution_new_ptr->count_isotopes = solution_old_ptr->count_isotopes; + solution_new_ptr->isotopes = (struct isotope *) PHRQ_malloc((size_t) solution_old_ptr->count_isotopes * sizeof(struct isotope)); + if (solution_new_ptr->isotopes == NULL) malloc_error(); + memcpy(solution_new_ptr->isotopes, solution_old_ptr->isotopes, (size_t) solution_old_ptr->count_isotopes * sizeof(struct isotope)); + } else { + solution_new_ptr->count_isotopes = 0; + solution_new_ptr->isotopes = NULL; + } +/* + * Return pointer to new structure + */ + return(solution_new_ptr); +} +/* ---------------------------------------------------------------------- */ +int solution_copy_to_last(int n, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies solution from pointer solution[n]. Makes new structure + * and saves pointer in solution[count_solution]. + */ + /* Make sure solution array is large enough */ + if (count_solution + 1 >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, + sizeof (struct solution *) ); + } + /* malloc space and copy solution */ + solution[count_solution] = solution_copy(solution[n], n_user_new); + count_solution++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solution_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees structure if it does + * Copies structure for solution[n_user_old] to new space + * Saves pointer in old position if it existed, no sort necessary + * Otherwise saves in count_solution position, sort may be necessary + * Solution array is in sort order on exit + */ + int n, n_old, n_new, sort; + struct solution *solution_old_ptr, *solution_new_ptr; +/* + * Find solution n_user_old + */ + if (n_user_old == n_user_new) return(OK); + solution_old_ptr = solution_bsearch(n_user_old, &n_old, TRUE); + if (solution_old_ptr == NULL) { + sprintf(error_string, "Solution %d not found.", n_user_old); + error_msg(error_string, STOP); + } +/* + * Check if solution n_user_new already exists + */ + solution_new_ptr = solution_bsearch(n_user_new, &n_new, FALSE); + if (solution_new_ptr != NULL) { + n = n_new; + solution_free(solution_new_ptr); + sort = FALSE; + } else { + n = count_solution; + count_solution++; + if (n_user_new > solution[n-1]->n_user) { + sort = FALSE; + } else { + sort = TRUE; + } + } + solution[n] = solution_copy(solution_old_ptr, n_user_new); +/* + * Make sure surface array is large enough + */ + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, + sizeof (struct solution *) ); + } +/* + * Sort solution if necessary + */ + if (sort == TRUE) solution_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solution_delete (int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Delete a solution structure: free memory and renumber solution. + */ + struct solution *solution_ptr; + int j, n; + solution_ptr = solution_bsearch(n_user, &n, FALSE); + if (solution_ptr != NULL) { + solution_free ( solution[n] ); + for (j=n; j < ( count_solution -1 ); j++) { + solution[j]=solution[j+1]; + } + count_solution--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solution_free (struct solution *solution_ptr) +/* ---------------------------------------------------------------------- */ +{ + if (solution_ptr == NULL) return(OK); +/* + * Free all memory unique to a solution structure, free solution_ptr too. + */ + solution_ptr->description = (char *) free_check_null (solution_ptr->description); +/* Free struct conc array */ + solution_ptr->totals = (struct conc *) free_check_null (solution_ptr->totals); + solution_ptr->master_activity = (struct master_activity *) free_check_null (solution_ptr->master_activity); + solution_ptr->species_gamma = (struct master_activity *) free_check_null (solution_ptr->species_gamma); + solution_ptr->count_species_gamma = 0; +/* Free struct pe_data array */ + pe_data_free (solution_ptr->pe); +/* Free isotope data */ + solution_ptr->isotopes = (struct isotope *) free_check_null (solution_ptr->isotopes); +/* Free struct solution */ + solution_ptr = (struct solution *) free_check_null (solution_ptr); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int solution_ptr_to_user(struct solution *solution_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees structure if it does + * Copies structure for solution[n_user_old] to new space + * Saves pointer in old position if it existed, no sort necessary + * Otherwise saves in count_solution position, sort may be necessary + * Solution array is in sort order on exit + */ + int n, n_new, sort; + struct solution *solution_new_ptr; +/* + * Find solution n_user_old + */ + if (solution_old_ptr == NULL) { + sprintf(error_string, "Solution pointer is NULL."); + error_msg(error_string, STOP); + } +/* + * Check if solution n_user_new already exists + */ + solution_new_ptr = solution_bsearch(n_user_new, &n_new, FALSE); + if (solution_new_ptr == solution_old_ptr) return(OK); + if (solution_new_ptr != NULL) { + n = n_new; + solution_free(solution_new_ptr); + sort = FALSE; + } else { + n = count_solution; + count_solution++; + /* + * Make sure surface array is large enough + */ + if (count_solution >= max_solution) { + space ((void **) ((void *) &(solution)), count_solution, &max_solution, + sizeof (struct solution *) ); + } + if (n_user_new > solution[n-1]->n_user) { + sort = FALSE; + } else { + sort = TRUE; + } + } + solution[n] = solution_copy(solution_old_ptr, n_user_new); +/* + * Sort solution if necessary + */ + if (sort == TRUE) solution_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct solution *solution_replicate(struct solution *solution_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + return(solution_copy(solution_old_ptr, n_user_new)); +} +/* ---------------------------------------------------------------------- */ +int solution_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of pointers to solution structures, solution. + */ + if (count_solution > 0) { + qsort (solution, + (size_t) count_solution, + (size_t) sizeof(struct solution *), + solution_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "species_list" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +static int species_list_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + int j; + char *name1, *name2; + const struct species_list *nptr1, *nptr2; + + nptr1= (const struct species_list *) ptr1; + nptr2= (const struct species_list *) ptr2; + +/* + * Put H+ first + */ + if (nptr1->master_s != nptr2->master_s) { + if (nptr1->master_s == s_hplus) return (-1); + if (nptr2->master_s == s_hplus) return (1); + } +/* + * Other element valence states + */ + if (nptr1->master_s->secondary != NULL) { + name1 = nptr1->master_s->secondary->elt->name; + } else { + name1 = nptr1->master_s->primary->elt->name; + } + if (nptr2->master_s->secondary != NULL) { + name2 = nptr2->master_s->secondary->elt->name; + } else { + name2 = nptr2->master_s->primary->elt->name; + } +/* + * Compare name of primary or secondary master species; log molality + */ + + j = strcmp( name1, name2 ); + +/* + * Different master species + */ + if (j != 0 ) return(j); + +/* + * Else, descending order by log molality + */ + if ( nptr1->s->lm > nptr2->s->lm) { + return (-1); + } else if ( nptr1->s->lm < nptr2->s->lm) { + return (1); + } else { + return (0); + } +} +/* ---------------------------------------------------------------------- */ +int species_list_compare_alk (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct species_list *nptr1, *nptr2; + double alk1, alk2; + + nptr1= (const struct species_list *) ptr1; + nptr2= (const struct species_list *) ptr2; +/* + * Else, descending order by log molality + */ + alk1 = fabs(under(nptr1->s->lm)*nptr1->s->alk); + alk2 = fabs(under(nptr2->s->lm)*nptr2->s->alk); + + if ( alk1 > alk2) { + return (-1); + } else if ( alk1 < alk2) { + return (1); + } else { + return (0); + } +} +/* ---------------------------------------------------------------------- */ +int species_list_compare_master (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + char *name1, *name2; + const struct species_list *nptr1, *nptr2; + + nptr1= (const struct species_list *) ptr1; + nptr2= (const struct species_list *) ptr2; + +/* + * Put H+ first + */ + if (nptr1->master_s != nptr2->master_s) { + if (nptr1->master_s == s_hplus) return (-1); + if (nptr2->master_s == s_hplus) return (1); + } +/* + * Other element valence states + */ + if (nptr1->master_s->secondary != NULL) { + name1 = nptr1->master_s->secondary->elt->name; + } else { + name1 = nptr1->master_s->primary->elt->name; + } + if (nptr2->master_s->secondary != NULL) { + name2 = nptr2->master_s->secondary->elt->name; + } else { + name2 = nptr2->master_s->primary->elt->name; + } +/* + * Compare name of primary or secondary master species; log molality + */ + + return(strcmp( name1, name2 )); +} +/* ---------------------------------------------------------------------- */ +int species_list_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort list using rules in species_list_compare + */ + if (count_species_list > 0) { + qsort (&species_list[0], (size_t) count_species_list, + (size_t) sizeof(struct species_list), species_list_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "surface" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct surface *surface_alloc (void) +/* ---------------------------------------------------------------------- */ +{ + struct surface *surface_ptr; + surface_ptr = (struct surface *) PHRQ_malloc(sizeof (struct surface)); + if (surface_ptr == NULL) malloc_error(); + surface_ptr->description = NULL; + surface_ptr->count_comps = 0; + surface_ptr->comps = NULL; + surface_ptr->count_charge = 0; + surface_ptr->charge = NULL; + return ( surface_ptr ); +} +/* ---------------------------------------------------------------------- */ +struct surface *surface_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search of array surface to find user number k. + * Assumes array surface is in sort order. + * + * Input: k, user number to find. + * Output: n, position in array surface of user number k. + * Return: pointer to surface structure if found, + * NULL if not found. + */ + void *void_ptr; + if (count_surface == 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) surface, + (size_t) count_surface, + (size_t) sizeof(struct surface), + surface_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct surface *) void_ptr - surface); + return ( (struct surface *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int surface_comp_compare(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct surface_comp *surface_comp_ptr1, *surface_comp_ptr2; + surface_comp_ptr1 = (const struct surface_comp *) ptr1; + surface_comp_ptr2 = (const struct surface_comp *) ptr2; + return(strcmp_nocase(surface_comp_ptr1->master->elt->name, surface_comp_ptr2->master->elt->name)); +} +/* ---------------------------------------------------------------------- */ +int surface_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct surface *surface_ptr1, *surface_ptr2; + surface_ptr1 = (const struct surface *) ptr1; + surface_ptr2 = (const struct surface *) ptr2; + if (surface_ptr1->n_user > surface_ptr2->n_user) return(1); + if (surface_ptr1->n_user < surface_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int surface_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare surface user numbers to integer + */ + const int *nptr1; + const struct surface *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct surface *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int surface_copy(struct surface *surface_old_ptr, struct surface *surface_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies data from surface_old_ptr to surface_new_ptr. + * Space for a surface structure must already be malloced. + * User number of new surface structure is n_user. + */ + int count_comps, count_charge, i; + char token[MAX_LENGTH]; +/* + * Store data for structure surface + */ + memcpy(surface_new_ptr, surface_old_ptr, sizeof(struct surface)); + count_comps = surface_old_ptr->count_comps; + count_charge = surface_old_ptr->count_charge; + surface_new_ptr->n_user = n_user_new; + surface_new_ptr->n_user_end = n_user_new; + surface_new_ptr->new_def = surface_old_ptr->new_def; + sprintf(token, "Surface defined in simulation %d.", simulation); + surface_new_ptr->description = string_duplicate(token); + surface_new_ptr->solution_equilibria = FALSE; + surface_new_ptr->n_solution = -10; +/* + * Write surface_comp structure for each surface component + */ + surface_new_ptr->comps = (struct surface_comp *) PHRQ_malloc((size_t) (count_comps) * sizeof (struct surface_comp)); + if (surface_new_ptr->comps == NULL) malloc_error(); + memcpy(surface_new_ptr->comps, surface_old_ptr->comps, + (size_t) (count_comps) * sizeof (struct surface_comp)); + for ( i = 0; i < count_comps; i++) { + surface_new_ptr->comps[i].totals = elt_list_dup(surface_old_ptr->comps[i].totals); + } +/* + * Write surface_charge structure for each surface + */ + if (surface_old_ptr->edl == TRUE) { + surface_new_ptr->charge = (struct surface_charge *) PHRQ_malloc((size_t) (count_charge) * sizeof (struct surface_charge)); + if (surface_new_ptr->charge == NULL) malloc_error(); + memcpy(surface_new_ptr->charge, surface_old_ptr->charge, + (size_t) (count_charge) * sizeof (struct surface_charge)); + for ( i = 0; i < count_charge; i++) { + surface_new_ptr->charge[i].diffuse_layer_totals = elt_list_dup(surface_old_ptr->charge[i].diffuse_layer_totals); + surface_new_ptr->charge[i].g = NULL; + } + } else { + surface_new_ptr->charge = NULL; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_copy_to_last(int n, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies an surface definition to position count_surface. + */ + space ((void **) ((void *) &surface), count_surface, &max_surface, sizeof(struct surface)); + surface_copy(&surface[n], &surface[count_surface], n_user); + count_surface++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies surface[n_user_old] to old n_user_new space if + * found or to surface[count_surface] if not found. + * Surface array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + struct surface *surface_ptr_old, *surface_ptr_new; +/* + * Find n_user_old in structure array surface + */ + if (n_user_old == n_user_new) return(OK); + surface_ptr_old = surface_bsearch(n_user_old, &n_old); + if (surface_ptr_old == NULL) { + sprintf(error_string, "Surface %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array surface or make new space + */ + sort = FALSE; + surface_ptr_new = surface_bsearch(n_user_new, &n_new); + if (surface_ptr_new != NULL) { + surface_free(surface_ptr_new); + } else { + space ((void **) ((void *) &surface), count_surface, &max_surface, sizeof(struct surface)); + if (n_user_new < surface[count_surface-1].n_user) sort = TRUE; + n_new = count_surface++; + } +/* + * Copy data + */ + surface_copy(&surface[n_old], &surface[n_new], n_user_new); + if (sort == TRUE) surface_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_delete(int n_user_old) +/* ---------------------------------------------------------------------- */ +/* + * Frees space for user number n_user_old, removes structure from + * array surface. + */ +{ + int i; + int n_old; + struct surface *surface_ptr_old; +/* + * Find n_user_old in structure array + */ + surface_ptr_old = surface_bsearch(n_user_old, &n_old); + if (surface_ptr_old != NULL) { + /* + * Delete surface + */ + surface_free(&surface[n_old]); + + for(i = n_old + 1; i < count_surface; i++) { + memcpy( (void *) &surface[i - 1], (void *) &surface[i], + (size_t) sizeof (struct surface) ); + } + count_surface--; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_free(struct surface *surface_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees all space related to surface_ptr, but not surface_ptr. + */ + int k; + + if (surface_ptr == NULL) return(ERROR); + surface_ptr->description = (char *) free_check_null(surface_ptr->description); +/* + * totals, then comps + */ + for (k = 0; k < surface_ptr->count_comps; k++) { + surface_ptr->comps[k].totals = (struct elt_list *) free_check_null(surface_ptr->comps[k].totals); + } + surface_ptr->comps = (struct surface_comp *) free_check_null (surface_ptr->comps); +/* + * diffuse_layer_totals and g, then charge + */ + if (surface_ptr->edl == TRUE) { + for (k = 0; k < surface_ptr->count_charge; k++) { + surface_ptr->charge[k].diffuse_layer_totals = (struct elt_list *) free_check_null(surface_ptr->charge[k].diffuse_layer_totals); + surface_ptr->charge[k].g = (struct surface_diff_layer *) free_check_null(surface_ptr->charge[k].g); + } + } + surface_ptr->charge = (struct surface_charge *) free_check_null (surface_ptr->charge); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_init(struct surface *surface_ptr, int n_user, int n_user_end, char *description) +/* ---------------------------------------------------------------------- */ +{ + + if (surface_ptr == NULL) return(ERROR); + + surface_ptr->n_user = n_user; + surface_ptr->n_user_end = n_user_end; + surface_ptr->description = string_duplicate(description); + surface_ptr->new_def = TRUE; + surface_ptr->diffuse_layer = FALSE; + surface_ptr->edl = TRUE; + surface_ptr->only_counter_ions = FALSE; + surface_ptr->donnan = FALSE; + surface_ptr->debye_units = 0.0; + surface_ptr->transport = FALSE; + surface_ptr->thickness = 1e-8; + surface_ptr->solution_equilibria = FALSE; + surface_ptr->n_solution = -999; +/* + * Malloc one surface_comp structure + */ + surface_ptr->count_comps = 0; + surface_ptr->comps = (struct surface_comp *) PHRQ_malloc( (size_t) sizeof (struct surface_comp)); + if (surface_ptr->comps == NULL) malloc_error(); + surface_ptr->comps[0].master = NULL; + surface_ptr->comps[0].totals = NULL; + surface_ptr->comps[0].phase_name = NULL; + surface_ptr->comps[0].rate_name = NULL; + surface_ptr->comps[0].charge = -1; + surface_ptr->comps[0].moles = 0; + surface_ptr->comps[0].cb = 0; +/* + * Malloc one charge structure + */ + surface_ptr->count_charge = 0; + surface_ptr->charge = (struct surface_charge *) PHRQ_malloc( (size_t) sizeof (struct surface_charge)); + if (surface_ptr->charge == NULL) malloc_error(); + + surface_ptr->related_phases = FALSE; + surface_ptr->related_rate = FALSE; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int surface_ptr_to_user(struct surface *surface_ptr_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies surface_ptr_old to old n_user_new space if + * found or to surface[count_surface] if not found. + * Surface array may not be in sort order after the copy. + */ + int n_new, sort; + struct surface *surface_ptr_new; +/* + * Find n_user_old in structure array surface + */ + if (surface_ptr_old == NULL) { + sprintf(error_string, "Surface pointer is NULL."); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_new in structure array surface or make new space + */ + sort = FALSE; + surface_ptr_new = surface_bsearch(n_user_new, &n_new); + if (surface_ptr_new == surface_ptr_old) return(OK); + if (surface_ptr_new != NULL) { + surface_free(surface_ptr_new); + } else { + space ((void **) ((void *) &surface), count_surface, &max_surface, sizeof(struct surface)); + if (n_user_new < surface[count_surface-1].n_user) sort = TRUE; + n_new = count_surface++; + } +/* + * Copy data + */ + surface_copy(surface_ptr_old, &surface[n_new], n_user_new); + if (sort == TRUE) surface_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct surface *surface_replicate(struct surface *surface_old_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ + struct surface *surface_ptr; + surface_ptr = surface_alloc(); + surface_copy(surface_old_ptr, surface_ptr, n_user_new); + return (surface_ptr); +} +/* ---------------------------------------------------------------------- */ +struct surface *surface_search(int n_user, int *n, int print) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "surface" for user number n_user. + * + * Arguments: + * n_user input, user number. + * n output, position in surface. + * + * Returns: + * if found, pointer to surface structure + * if not found, NULL + */ + int i; + for (i = 0; i < count_surface; i++) { + if (n_user == surface[i].n_user) { + break; + } + } + if (i >= count_surface) { + if ( print == TRUE) { + sprintf(error_string, "Surface %d not found.", n_user); + error_msg(error_string, CONTINUE); + } + *n = -999; + return(NULL); + } + *n = i; + return(&surface[i]); +} +/* ---------------------------------------------------------------------- */ +int surface_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of surface structures + */ + if (count_surface > 0) { + qsort (surface, (size_t) count_surface, (size_t) sizeof(struct surface), + surface_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "temperature" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +struct temperature *temperature_bsearch (int k, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* + * Binary search of array temperature to find user number k. + * Assumes array temperature is in sort order. + * + * Input: k, user number to find. + * Output: n, position in array temperature of user number k. + * Return: pointer to temperature structure if found, + * NULL if not found. + */ + void *void_ptr; + if (count_temperature <= 0) { + *n = -999; + return(NULL); + } + void_ptr = (void *) + bsearch ( (char *) &k, + (char *) temperature, + (size_t) count_temperature, + (size_t) sizeof(struct temperature), + temperature_compare_int); + if (void_ptr == NULL) { + *n = -999; + return(NULL); + } + *n = (int) ((struct temperature *) void_ptr - temperature); + return ( (struct temperature *) void_ptr); +} +/* ---------------------------------------------------------------------- */ +int temperature_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct temperature *temperature_ptr1, *temperature_ptr2; + temperature_ptr1 = (const struct temperature *) ptr1; + temperature_ptr2 = (const struct temperature *) ptr2; + if (temperature_ptr1->n_user > temperature_ptr2->n_user) return(1); + if (temperature_ptr1->n_user < temperature_ptr2->n_user) return(-1); + return (0); + +} +/* ---------------------------------------------------------------------- */ +static int temperature_compare_int(const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare temperature user numbers + */ + const int *nptr1; + const struct temperature *nptr2; + + nptr1= (const int *) ptr1; + nptr2= (const struct temperature *) ptr2; + if (*nptr1 > nptr2->n_user) return(1); + if (*nptr1 < nptr2->n_user) return(-1); + return (0); +} +/* ---------------------------------------------------------------------- */ +int temperature_copy(struct temperature *temperature_old_ptr, + struct temperature *temperature_new_ptr, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies temperature data from temperature_old_ptr to new location, temperature_new_ptr. + * Space for the temperature_new_ptr structure must already be malloced. + * Space for temperature components is malloced here. + */ + int count; + char token[MAX_LENGTH]; +/* + * Copy old to new + */ + memcpy(temperature_new_ptr, temperature_old_ptr, sizeof (struct temperature)); +/* + * Store data for structure temperature + */ + temperature_new_ptr->n_user = n_user_new; + temperature_new_ptr->n_user_end = n_user_new; + sprintf(token, "Temperature defined in simulation %d.", simulation); + temperature_new_ptr->description = string_duplicate(token); +/* + * Count temperature components and allocate space + */ + if (temperature_old_ptr->count_t < 0) { + count = 2; + } else { + count = temperature_old_ptr->count_t; + } + temperature_new_ptr->t = (double *) PHRQ_malloc((size_t) (count) * sizeof (double)); + if (temperature_new_ptr->t == NULL) malloc_error(); + memcpy(temperature_new_ptr->t, temperature_old_ptr->t, + (size_t) (count * sizeof (double))); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int temperature_duplicate(int n_user_old, int n_user_new) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks if n_user_new exists, and frees space if it does + * Copies temperature[n_user_old] to old n_user_new space if + * found or to temperature[count_temperature] if not found. + * Temperature array may not be in sort order after the copy. + */ + int n_old, n_new, sort; + char token[MAX_LENGTH]; + int count_t; + struct temperature *temperature_ptr_old, *temperature_ptr_new; +/* + * Find n_user_old in structure array temperature or make new space + */ + if (n_user_old == n_user_new) return(OK); + temperature_ptr_old = temperature_bsearch(n_user_old, &n_old); + if (temperature_ptr_old == NULL) { + sprintf(error_string, "Temperature %d not found.", n_user_old); + error_msg(error_string, CONTINUE); + input_error++; + return(ERROR); + } +/* + * Find n_user_old in structure array temperature or make new space + */ + sort = FALSE; + temperature_ptr_new = temperature_bsearch(n_user_new, &n_new); + if (temperature_ptr_new != NULL) { + temperature_free(&temperature[n_new]); + } else { + temperature = (struct temperature *) PHRQ_realloc( temperature, + (size_t) (count_temperature + 1) * + sizeof (struct temperature)); + if (temperature == NULL) malloc_error(); + if (n_user_new < temperature[count_temperature-1].n_user) sort = TRUE; + n_new = count_temperature++; + } +/* + * Store data for structure temperature + */ + count_t = temperature[n_old].count_t; + temperature[n_new].n_user = n_user_new; + temperature[n_new].n_user_end = n_user_new; + sprintf(token, "Temperature defined in simulation %d.", simulation); + temperature[n_new].description = string_duplicate(token); + temperature[n_new].count_t = count_t; + if (count_t < 0) count_t = 2; +/* + * Count temperature components and allocate space + */ + temperature[n_new].t = (LDBLE *) PHRQ_malloc((size_t) (count_t) * + sizeof (LDBLE)); + if (temperature[n_new].t == NULL) malloc_error(); +/* + * Write temperature_comp structure for each temperature component + */ + memcpy(temperature[n_new].t, temperature[n_old].t, + (size_t) (count_t) * sizeof (LDBLE)); + if (sort == TRUE) temperature_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int temperature_free (struct temperature *temperature_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Free space allocated for temperature structure, does not free temperature_ptr. + */ + if (temperature_ptr == NULL) return(ERROR); + + temperature_ptr->description = (char *) free_check_null (temperature_ptr->description); + temperature_ptr->t = (LDBLE *) free_check_null (temperature_ptr->t); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct temperature *temperature_search(int n_user, int *n) +/* ---------------------------------------------------------------------- */ +{ +/* Linear search of the structure array "temperature" for user number n_user. + * + * Arguments: + * n_user input, user number. + * n output, position in temperature. + * + * Returns: + * if found, pointer to temperature structure + * if not found, NULL + */ + int i; + for (i = 0; i < count_temperature; i++) { + if (n_user == temperature[i].n_user) { + break; + } + } + if (i >= count_temperature) { + *n = -999; + return(NULL); + } + *n = i; + return(&temperature[i]); +} +/* ---------------------------------------------------------------------- */ +int temperature_sort(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Sort array of temperature structures + */ + if (count_temperature > 0) { + qsort (temperature, (size_t) count_temperature, (size_t) sizeof(struct temperature), temperature_compare); + } + return(OK); +} +/* ********************************************************************** + * + * Routines related to structure "trxn" + * + * ********************************************************************** */ +/* ---------------------------------------------------------------------- */ +int rxn_token_temp_compare (const void *ptr1, const void *ptr2) +/* ---------------------------------------------------------------------- */ +{ + const struct rxn_token_temp *rxn_token_temp_ptr1, *rxn_token_temp_ptr2; + rxn_token_temp_ptr1 = (const struct rxn_token_temp *) ptr1; + rxn_token_temp_ptr2 = (const struct rxn_token_temp *) ptr2; + return(strcmp(rxn_token_temp_ptr1->name, rxn_token_temp_ptr2->name)); +} +/* ---------------------------------------------------------------------- */ +int trxn_add (struct reaction *r_ptr, LDBLE coef, int combine) +/* ---------------------------------------------------------------------- */ +{ +/* + * Adds reactions together. + * + * Global variable count_trxn determines which position in trxn is used. + * If count_trxn=0, then the equation effectively is copied into trxn. + * If count_trxn>0, then new equation is added to existing equation. + * + * Arguments: + * *r_ptr points to rxn structure to add. + * + * coef added equation is multiplied by coef. + * combine if TRUE, reaction is reaction is sorted and + * like terms combined. + */ + int i; + struct rxn_token *next_token; +/* + * Accumulate log k for reaction + */ + if (count_trxn == 0) { + memcpy( (void *) trxn.logk, (void *) r_ptr->logk, + (size_t) 7 * sizeof(LDBLE) ); + } else { + for (i=0; i < 7; i++) { + trxn.logk[i] += coef * (r_ptr->logk[i]); + } + } +/* + * Copy equation into work space + */ + next_token = r_ptr->token; + while (next_token->s != NULL) { + if (count_trxn + 1 >= max_trxn) { + space ((void **) &(trxn.token), count_trxn+1, &max_trxn, + sizeof(struct rxn_token_temp)); + } + trxn.token[count_trxn].name = next_token->s->name; + trxn.token[count_trxn].s = next_token->s; + trxn.token[count_trxn].coef = coef*next_token->coef; + count_trxn++; + next_token++; + } + if (combine == TRUE) trxn_combine(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int trxn_combine (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Combines coefficients of tokens that are equal in temporary + * reaction structure, trxn. + */ + int j, k; +/* + * Sort trxn species + */ + trxn_sort(); +/* + * Combine trxn tokens + */ + j=1; + for ( k=2; k < count_trxn; k++) { + if ( ( j > 0 ) && ( trxn.token[k].s == trxn.token[j].s) ) { + trxn.token[j].coef += trxn.token[k].coef; + if (equal(trxn.token[j].coef, 0.0, 1e-5)) j--; + } else { + j++; + if ( k != j ) { + trxn.token[j].name = trxn.token[k].name; + trxn.token[j].s = trxn.token[k].s; + trxn.token[j].coef = trxn.token[k].coef; + } + } + } + count_trxn=j+1; /* number excluding final NULL */ + return(OK); +} +/* ---------------------------------------------------------------------- */ +int trxn_copy (struct reaction *rxn_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies trxn to a reaction structure. + * + * Input: rxn_ptr, pointer to reaction structure to copy trxn to. + * + */ + int i; +/* + * Copy logk data + */ + for (i=0; i<7; i++) { + rxn_ptr->logk[i]=trxn.logk[i]; + } +/* + * Copy tokens + */ + for (i=0; i < count_trxn; i++ ) { + rxn_ptr->token[i].s = trxn.token[i].s; + rxn_ptr->token[i].coef = trxn.token[i].coef; + } + rxn_ptr->token[count_trxn].s=NULL; + + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE trxn_find_coef(const char *str, int start) +/* ---------------------------------------------------------------------- */ +{ +/* + * Finds coefficient of specified token in trxn. + * Input: str, token name in reaction. + * + * Return: 0.0, if token not found. + * coefficient of token, if token found. + */ + int i; + LDBLE coef; + + coef=0.0; + for (i=start; iname, str) == 0) { + coef=trxn.token[i].coef; + break; + } + } + return(coef); +} +/* ---------------------------------------------------------------------- */ +int trxn_multiply (LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ +/* + * Multiplies temporary reaction, trxn, by a constant + * + * Arguments: + * input: coef multiplier. + */ + int i; +/* + * Multiply log k for reaction + */ + for (i=0; i < 7; i++) { + trxn.logk[i] *= coef; + } +/* + * Multiply coefficients of reaction + */ + for (i=0; i < count_trxn; i++ ){ + trxn.token[i].coef *= coef; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int trxn_print (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Prints trxn + */ + int i; +/* + * Print log k for reaction + */ + + output_msg(OUTPUT_MESSAGE,"log k data:\n"); + for (i=0; i < 7; i++) { + output_msg(OUTPUT_MESSAGE,"\t%f",(double) trxn.logk[i]); + } + output_msg(OUTPUT_MESSAGE,"\n"); + +/* + * Print stoichiometry + */ + for (i=0; i 0) { + qsort(&trxn.token[1], + (size_t) count_trxn-1, + (size_t) sizeof(struct rxn_token_temp), + rxn_token_temp_compare); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int trxn_swap (const char *token) +/* ---------------------------------------------------------------------- */ +{ +/* + * Moves specified token to initial position in reaction. + * Input: token, token name to move to initial position. + * + * Return: ERROR, if token not found. + * OK, if token moved to initial position. + */ + int i, j; + LDBLE coef; +/* + * Locate token + */ + for (j=0; j < count_trxn; j++) { + if (strcmp(trxn.token[j].s->name,token) == 0 ) break; + } + if (j >= count_trxn ) { + input_error++; + sprintf(error_string,"Could not find token in equation, %s.", token); + error_msg(error_string, CONTINUE); + for (i=0; itype = 0; + unknown_ptr->moles = 0.0; + unknown_ptr->ln_moles = 0.0; + unknown_ptr->f = 0.0; + unknown_ptr->sum = 0.0; + unknown_ptr->delta = 0.0; + unknown_ptr->la = 0.0; + unknown_ptr->number = 0; + unknown_ptr->description=NULL; + unknown_ptr->master = NULL; + unknown_ptr->phase = NULL; + unknown_ptr->si = 0.0; + unknown_ptr->gas_phase=NULL; + unknown_ptr->total=NULL; + unknown_ptr->s=NULL; + unknown_ptr->exch_comp = NULL; + unknown_ptr->pure_phase = NULL; + unknown_ptr->s_s = NULL; + unknown_ptr->s_s_comp = NULL; + unknown_ptr->s_s_comp_number = 0; + unknown_ptr->s_s_in = FALSE; + unknown_ptr->surface_comp = NULL; + unknown_ptr->related_moles = 0.0; + unknown_ptr->potential_unknown = NULL; + unknown_ptr->phase_unknown = NULL; + unknown_ptr->surface_charge = NULL; + unknown_ptr->mass_water = 0.0; + unknown_ptr->dissolve_only = FALSE; + + return(unknown_ptr); +} +/* ---------------------------------------------------------------------- */ +int unknown_delete(int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Delete unknow from list x + */ + int j; + + unknown_free(x[i]); + for (j=i; j < (count_unknowns); j++) { + x[j] = x[j+1]; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int unknown_free(struct unknown *unknown_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Frees space allocated to an unknown structure, frees unknown_ptr. + */ + if (unknown_ptr == NULL) return(ERROR); + unknown_ptr->master = (struct master **) free_check_null (unknown_ptr->master); + unknown_ptr = (struct unknown *) free_check_null (unknown_ptr); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int system_duplicate (int i, int save_old) +/* ---------------------------------------------------------------------- */ +{ + int n; + + if (solution_bsearch(i,&n, TRUE) != NULL) solution_duplicate(i, save_old); + if (pp_assemblage_bsearch(i,&n) != NULL) pp_assemblage_duplicate(i, save_old); + if (exchange_bsearch(i,&n) != NULL) exchange_duplicate(i, save_old); + if (surface_bsearch(i,&n) != NULL) surface_duplicate(i, save_old); + if (gas_phase_bsearch(i,&n) != NULL) gas_phase_duplicate(i, save_old); + if (kinetics_bsearch(i,&n) != NULL) kinetics_duplicate(i, save_old); + if (s_s_assemblage_bsearch(i,&n) != NULL) s_s_assemblage_duplicate(i, save_old); + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct logk *logk_store (char *name, int replace_if_found) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for logk. + * + * Pointer to a logk structure is always returned. + * + * If the string is not found, a new entry is made in the hash table. Pointer to + * the new structure is returned. + * If "name" is found and replace is true, pointers in old logk structure + * are freed and replaced with additional input. + * If "name" is found and replace is false, the old logk structure is not + * modified and a pointer to it is returned. + * + * Arguments: + * name input, character string to be found in "logk". + * replace_if_found input, TRUE means reinitialize logk structure if found + * FALSE means just return pointer if found. + * + * Returns: + * pointer to logk structure "logk" where "name" can be found. + */ + int n; + struct logk *logk_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + str_tolower(name); + item.key = name; + item.data = NULL; + found_item = hsearch_multi(logk_hash_table, item, FIND); + + if (found_item != NULL && replace_if_found == FALSE) { + logk_ptr = (struct logk *) (found_item->data); + return (logk_ptr); + } else if (found_item != NULL && replace_if_found == TRUE) { + logk_ptr = (struct logk *) (found_item->data); + logk_init(logk_ptr); + } else { + n = count_logk++; + /* make sure there is space in s */ + if (count_logk >= max_logk) { + space ((void **) ((void *) &logk), count_logk, &max_logk, sizeof(struct logk *)); + } + /* Make new logk structure */ + logk[n] = logk_alloc(); + logk_ptr = logk[n]; + } + /* set name and z in pointer in logk structure */ + logk_ptr->name = string_hsave( name ); +/* + * Update hash table + */ + item.key = logk_ptr->name; + item.data = (void *) logk_ptr; + found_item = hsearch_multi(logk_hash_table, item, ENTER); + if (found_item == NULL) { + sprintf(error_string, "Hash table error in logk_store."); + error_msg(error_string, CONTINUE); + } + + return (logk_ptr); +} +/* ---------------------------------------------------------------------- */ +struct logk *logk_alloc(void) +/* ---------------------------------------------------------------------- */ +/* + * Allocates space to a logk structure, initializes + * arguments: void + * return: pointer to a logk structure + */ +{ + struct logk *logk_ptr; + logk_ptr=(struct logk *) PHRQ_malloc(sizeof(struct logk)); + if (logk_ptr == NULL) malloc_error(); +/* + * set pointers in structure to NULL, variables to zero + */ + logk_init(logk_ptr); + + return(logk_ptr); +} +/* ---------------------------------------------------------------------- */ +static int logk_init(struct logk *logk_ptr) +/* ---------------------------------------------------------------------- */ +/* + * return: pointer to a logk structure + */ +{ + int i; +/* + * set pointers in structure to NULL + */ + logk_ptr->name=NULL; +/* + * set varibles = 0 + */ + logk_ptr->lk = 0.0; + for (i =0; i < 8; i++) { + logk_ptr->log_k[i] = 0.0; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +struct logk *logk_search (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function locates the string "name" in the hash table for logk. + * + * Arguments: + * name input, character string to be found in "logk". + * + * Returns: + * pointer to logk structure "logk" where "name" can be found. + * or NULL if not found. + */ + struct logk *logk_ptr; + ENTRY item, *found_item; +/* + * Search list + */ + str_tolower(name); + item.key = name; + item.data = NULL; + found_item = hsearch_multi(logk_hash_table, item, FIND); + + if (found_item != NULL) { + logk_ptr = (struct logk *) (found_item->data); + return (logk_ptr); + } + return(NULL); +} +/* ---------------------------------------------------------------------- */ +int entity_exists (char *name, int n_user) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution, 0 Solution + * reaction, 1 Reaction + * exchange, 2 Exchange + * surface, 3 Surface + * gas_phase, 4 Gas_phase + * equilibrium_phases, 5 Pure_phase + * solid_solution, 6 Ss_phase + * kinetics, 7 Kinetics + * mix, 8 Mix + * reaction_temperature 9 Temperature + * unknown 10 UnKnown + */ + int i, return_value; + char *ptr; + char token[MAX_LENGTH]; + enum entity_type type; +/* + * Read keyword + */ + ptr = name; + copy_token (token, &ptr, &i); + type = get_entity_enum(token); + return_value = TRUE; + switch (type) { + case UnKnown: + warning_msg("EXISTS expecting keyword solution, mix, kinetics, reaction, reaction_temperature, equilibrium_phases, exchange, surface, gas_phase, or solid_solutions."); + return_value = 2; + break; + case Solution: /* Solution */ + if (solution_bsearch (n_user, &i, FALSE) == NULL) { + return_value = FALSE; + } + break; + case Pure_phase: /* Pure phases */ + if(pp_assemblage_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Reaction: /* Reaction */ + if(irrev_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Mix: /* Mix */ + if(mix_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Exchange: /* Ex */ + if(exchange_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Surface: /* Surface */ + if(surface_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Temperature: /* Temperature */ + if(temperature_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Gas_phase: /* Gas */ + if(gas_phase_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Kinetics: /* Kinetics */ + if(kinetics_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + case Ss_phase: /* solid_solutions */ + if(s_s_assemblage_bsearch (n_user, &i) == NULL) { + return_value = FALSE; + } + break; + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +enum entity_type get_entity_enum (char *name) +/* ---------------------------------------------------------------------- */ +{ +/* + * Reads solution, 0 Solution + * reaction, 1 Reaction + * exchange, 2 Exchange + * surface, 3 Surface + * gas_phase, 4 Gas_phase + * equilibrium_phases, 5 Pure_phase + * solid_solution, 6 Ss_phase + * kinetics, 7 Kinetics + * mix, 8 Mix + * reaction_temperature 9 Temperature + * unknown 10 UnKnown + * + */ + int i; + char *ptr; + char token[MAX_LENGTH]; +/* + * Read keyword + */ + ptr = name; + copy_token (token, &ptr, &i); + check_key (token); + switch (next_keyword) { + case -1: /* Have not read line with keyword */ + case 0: /* End encountered */ + case 1: /* EOF encountered */ + case 2: /* Read aqueous model */ + case 3: /* Read master species */ + case 5: + case 9: + case 10: + case 11: + case 12: + case 14: + case 15: + case 18: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 30: + case 31: + case 32: + case 34: + case 35: + case 38: + case 39: + warning_msg("EXISTS expecting keyword solution, mix, kinetics, reaction, reaction_temperature, equilibrium_phases, exchange, surface, gas_phase, or solid_solutions."); + return(UnKnown); + break; + case 4: /* Solution */ + return(Solution); + break; + case 6: /* Pure phases */ + case 26: + case 27: + case 28: + case 29: + return(Pure_phase); + break; + case 7: /* Reaction */ + return(Reaction); + break; + case 8: /* Mix */ + return(Mix); + break; + case 13: /* Ex */ + return(Exchange); + break; + case 16: /* Surface */ + return(Surface); + break; + case 17: /* Temperature */ + return(Temperature); + break; + case 19: /* Gas */ + return(Gas_phase); + break; + case 33: /* Kinetics */ + return(Kinetics); + break; + case 40: /* solid_solutions */ + case 41: /* solid_solution */ + return(Ss_phase); + break; + } + return(UnKnown); +} +/* + * copier routines + */ +/* ---------------------------------------------------------------------- */ +int copier_add(struct copier *copier_ptr, int n_user, int start, int end) +/* ---------------------------------------------------------------------- */ +/* + * add new set of copy instructions + */ +{ + + if (copier_ptr->count >= copier_ptr->max) { + copier_ptr->max = copier_ptr->count*2; + copier_ptr->n_user = (int *) PHRQ_realloc(copier_ptr->n_user, (size_t) (copier_ptr->max*sizeof(int))); + if (copier_ptr->n_user == NULL) malloc_error(); + copier_ptr->start = (int *) PHRQ_realloc(copier_ptr->start, (size_t) (copier_ptr->max*sizeof(int))); + if (copier_ptr->start == NULL) malloc_error(); + copier_ptr->end = (int *) PHRQ_realloc(copier_ptr->end, (size_t) (copier_ptr->max*sizeof(int))); + if (copier_ptr->end == NULL) malloc_error(); + } + copier_ptr->n_user[copier_ptr->count] = n_user; + copier_ptr->start[copier_ptr->count] = start; + copier_ptr->end[copier_ptr->count] = end; + copier_ptr->count++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int copier_free(struct copier *copier_ptr) +/* ---------------------------------------------------------------------- */ +/* + * initialize copier structure + */ +{ + + copier_ptr->n_user = (int *) free_check_null(copier_ptr->n_user); + copier_ptr->start = (int *) free_check_null(copier_ptr->start); + copier_ptr->end = (int *) free_check_null(copier_ptr->end); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int copier_init(struct copier *copier_ptr) +/* ---------------------------------------------------------------------- */ +/* + * initialize copier structure + */ +{ + + copier_ptr->count = 0; + copier_ptr->max = 10; + copier_ptr->n_user = (int *) PHRQ_malloc((size_t) (copier_ptr->max*sizeof(int))); + copier_ptr->start = (int *) PHRQ_malloc((size_t) (copier_ptr->max*sizeof(int))); + copier_ptr->end = (int *) PHRQ_malloc((size_t) (copier_ptr->max*sizeof(int))); + return(OK); +} diff --git a/sundialsmath.cpp b/sundialsmath.cpp new file mode 100644 index 00000000..2ec5ee28 --- /dev/null +++ b/sundialsmath.cpp @@ -0,0 +1,76 @@ +/******************************************************************* + * * + * File : sundialsmath.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the implementation file for a C math library. * + * * + *******************************************************************/ + + +#include +#include +#include "sundialsmath.h" +#include "sundialstypes.h" +#include "output.h" + +static char const svnid[] = "$Id: sundialsmath.c 78 2005-02-01 22:47:12Z dlpark $"; + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) +#define TWO RCONST(2.0) + + +realtype UnitRoundoff(void) +{ + realtype u; + volatile realtype one_plus_u; + + u = ONE; + one_plus_u = ONE + u; + while (one_plus_u != ONE) { + u /= TWO; + one_plus_u = ONE + u; + } + u *= TWO; + + return(u); +} + + +realtype RPowerI(realtype base, int exponent) +{ + int i, expt; + realtype prod; + + prod = ONE; + expt = ABS(exponent); + for(i=1; i <= expt; i++) prod *= base; + if (exponent < 0) prod = ONE/prod; + return(prod); +} + + +realtype RPowerR(realtype base, realtype exponent) +{ + + if (base <= ZERO) return(ZERO); + + /* return((realtype)pow((double)base,(double)exponent));*/ + return((realtype)pow(base,exponent)); +} + + +realtype RSqrt(realtype x) +{ + if (x <= ZERO) return(ZERO); + + /* return((realtype) sqrt((double) x));*/ + return((realtype) sqrt( x)); +} diff --git a/sundialsmath.h b/sundialsmath.h new file mode 100644 index 00000000..6c29aa28 --- /dev/null +++ b/sundialsmath.h @@ -0,0 +1,130 @@ +/******************************************************************* + * * + * File : sundialsmath.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This is the header file for a C math library. The routines * + * listed here work with the type realtype as defined in * + * sundialstypes.h. * + * To do single precision floating point arithmetic, set the type * + * realtype to be float. To do double precision arithmetic, set * + * the type realtype to be double. The default implementations * + * for RPowerR and RSqrt call standard math library functions * + * which do double precision arithmetic. If this is unacceptable * + * when realtype is float, then the user should re-implement * + * these two routines by calling single precision routines * + * available on his/her machine. * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidsundialsmath[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _sundialsmath_h +#define _sundialsmath_h + +#include "sundialstypes.h" + + +/****************************************************************** + * * + * Macros : MIN, MAX, ABS, SQR * + *----------------------------------------------------------------* + * MIN(A, B) returns the minimum of A and B. * + * * + * MAX(A, B) returns the maximum of A and B. * + * * + * ABS(A) returns the absolute value of A. * + * * + * SQR(A) returns the square of A. * + * * + ******************************************************************/ +#ifndef MIN +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif + +#ifndef MAX +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#endif + +#ifndef ABS +#define ABS(A) ((A < 0) ? -(A) : (A)) +#endif + +#ifndef SQR +#define SQR(A) ((A) * (A)) +#endif + +/****************************************************************** + * * + * Function : UnitRoundoff * + * Usage : realtype uround; * + * uround = UnitRoundoff(); * + *----------------------------------------------------------------* + * UnitRoundoff returns the unit roundoff u for real floating * + * point arithmetic, where u is defined to be the smallest * + * positive real such that 1.0 + u != 1.0. * + * * + ******************************************************************/ + +realtype UnitRoundoff(void); + + +/****************************************************************** + * * + * Function : RPowerI * + * Usage : int exponent; * + * realtype base, ans; * + * ans = RPowerI(base,exponent); * + *----------------------------------------------------------------* + * RPowerI returns the value base^exponent, where base is a * + * realtype and exponent is an int. * + * * + ******************************************************************/ + +realtype RPowerI(realtype base, int exponent); + + +/****************************************************************** + * * + * Function : RPowerR * + * Usage : realtype base, exponent, ans; * + * ans = RPowerR(base,exponent); * + *----------------------------------------------------------------* + * RPowerR returns the value base^exponent, where both base and * + * exponent are realtype. If base < 0.0, then RPowerR returns 0.0 * + * * + ******************************************************************/ + +realtype RPowerR(realtype base, realtype exponent); + + +/****************************************************************** + * * + * Function : RSqrt * + * Usage : realtype sqrt_x; * + * sqrt_x = RSqrt(x); * + *----------------------------------------------------------------* + * RSqrt(x) returns the square root of x. If x < 0.0, then RSqrt * + * returns 0.0. * + * * + ******************************************************************/ + +realtype RSqrt(realtype x); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/sundialstypes.h b/sundialstypes.h new file mode 100644 index 00000000..a81ed34d --- /dev/null +++ b/sundialstypes.h @@ -0,0 +1,144 @@ +#include "phrqtype.h" +/******************************************************************* + * * + * File : sundialstypes.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 26 June 2002 * + *-----------------------------------------------------------------* + * Copyright (c) 2002, The Regents of the University of California * + * Produced at the Lawrence Livermore National Laboratory * + * All rights reserved * + * For details, see sundials/shared/LICENSE * + *-----------------------------------------------------------------* + * This header file exports three types: realtype, integertype, * + * and booleantype, as well as the constants TRUE and FALSE. * + * * + * Users should #include "sundialstypes.h" in any file that * + * shhould be easily modifiable to work with different real or * + * integer types and use the exported names realtype and * + * integertype within such a file. * + * The types for realtype and integertype below have been set to * + * double and long int, respectively. A user should modify these * + * type declarations as he/she sees fit. For example, if a user * + * wants the work with type float because double precision * + * floating point arithmetic is too expensive on the user's * + * machine, then the definition below should be changed to: * + * * + * typedef float realtype; * + * * + * Similarly, if a user does not need to work with extremely large * + * integers (see the system header file for the limits * + * on type int and long int on your machine), then the user * + * should change the definition below to: * + * * + * typedef int integertype; * + * * + * The constants SUNDIALS_FLOAT, SUNDIALS_DOUBLE, SUNDIALS_INT, * + * SUNDIALS_LONG indicate the underlying types for realtype and * + * integertype. They should be set as follows: * + * * + * (1) #define SUNDIALS_FLOAT 1 * + * #define SUNDIALS_DOUBLE 0 (real is float) * + * * + * (2) #define SUNDIALS_FLOAT 0 * + * #define SUNDIALS_DOUBLE 1 (real is double) * + * * + * (3) #define SUNDIALS_INT 1 * + * #define SUNDIALS_LONG 0 (integer is int) * + * * + * (4) #define SUNDIALS_INT 0 * + * #define SUNDIALS_LONG 1 (integer is long int) * + * * + * Thus the legal types for realtype are float and double, while * + * the legal types for integertype are int and long int. * + * The macro RCONST gives a user a convenient way to define real * + * constants. To use the real constant 1.0, for example, the * + * user should write * + * * + * #define ONE RCONST(1.0) * + * * + * If realtype is double, then RCONST(1.0) expands to 1.0. * + * If realtype is float, then RCONST(1.0) expands to 1.0F. * + * There is never a need to explicitly cast 1.0 to (realtype). * + * * + *******************************************************************/ +#ifdef PHREEQC_IDENT +static char const svnidsundialstypes[] = "$Id$"; +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _sundialstypes_h +#define _sundialstypes_h + + +/****************************************************************** + * * + * Types : realtype, integertype * + *----------------------------------------------------------------* + * The types realtype and integertype are currently set to double * + * and int, respectively. See the documentation at the top for * + * usage details and a description of associated constants and * + * macros. * + * * + ******************************************************************/ + +#ifdef USE_LONG_DOUBLE + typedef long double realtype; +#else + typedef double realtype; +#endif +typedef long int integertype; + +#define SUNDIALS_FLOAT 0 +#define SUNDIALS_DOUBLE 1 + +#define SUNDIALS_LONG 1 +#define SUNDIALS_INT 0 + +#if SUNDIALS_FLOAT + +#define RCONST(x) x##F + +#elif SUNDIALS_DOUBLE + +#define RCONST(x) x + +#endif + + +/****************************************************************** + * * + * Type : booleantype * + * Constants : FALSE, TRUE * + *----------------------------------------------------------------* + * ANSI C does not have a built-in boolean type. Below is the * + * definition for a new type booleantype. The advantage of using * + * the name booleantype (instead of int) is an increase in code * + * readability. * + * It allows the programmer to make a distinction between int and * + * boolean data. Variables of type booleantype are intended to * + * have only the two values FALSE and TRUE which are defined * + * below to be equal to 0 and 1, respectively. * + * * + ******************************************************************/ + +#ifndef booleantype +#define booleantype int +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/tally.cpp b/tally.cpp new file mode 100644 index 00000000..2211863b --- /dev/null +++ b/tally.cpp @@ -0,0 +1,1006 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: tally.c 265 2005-04-25 13:57:00Z dlpark $"; +/* + * storage + */ +struct buffer { + char *name; + struct master *master; + LDBLE moles; + LDBLE gfw; +}; +struct buffer *buffer; +int count_component; +struct tally { + char *name; + enum entity_type type; + char *add_formula; + LDBLE moles; + struct elt_list *formula; + /* + * first total is initial + * second total is final + * third total is difference (final - initial) + */ + struct buffer *total[3]; +}; +struct tally *tally_table; +int count_tally_table_columns; +int count_tally_table_rows; + +static int elt_list_to_tally_table(struct buffer *buffer_ptr); + +/* + Calling sequence + +Initialization: +--------------- + +build_tally_table(); finds all elements (rows), + possible return values (columns), + allocates space +get_tally_table_rows_columns(int *rows, int *columns) + returns number of rows and columns in table +get_tally_table_row_heading(int row, char *string) + row is C row number + returns row descripter for row +get_tally_table_column_heading(int column, int *type, char *string) + column is C column number + returns column heading for column + +Each call to phreeqc: +--------------------- + +zero_tally_table(); initialize table to 0s +set_reaction_moles(n_user, moles) n_user is reservoir number + moles is number of moles of reaction to add + +int set_reaction_temperature(n_user, tc) + +fill_tally_table(int *n_user, int index_conservative, int n_buffer) + n_user is reservoir number + index_conservative is solution number + where conservative mixing is stored + slot is 0 for initial + + run phreeqc here. + +fill_tally_table(int *n_user, int index_conservative, int n_buffer) + n_user is reservoir number + index_conservative is solution number + where conservative mixing is stored + slot is 1 for final +store_tally_table(double *array, int row_dim, int col_dim, double fill_factor) + row_dim is Fortran dimension + col_dim is Fortran dimension + array is space from Fortran + stores conservative mixing (column 0) + stores reaction (column 1) + difference between slot 1 and slot 0 for + all other intities (columns 2-n) + +Finalization: +------------- +int free_tally_table(void); Frees space + +*/ + +/* ---------------------------------------------------------------------- */ +int get_all_components(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Counts components in any defined solution, gas_phase, exchanger, + * surface, or pure_phase_assemblage + * + * Returns n_comp, which is total, including H, O, elements, and Charge + * names contains character strings with names of components + */ + int i, j; +/* + * Accumulate all aqueous components + */ + add_all_components_tally(); +/* + * Count components, 2 for hydrogen, oxygen, + others, + */ + count_component = 0; + for (i = 0; i < count_master; i++) { + if (master[i]->total > 0.0 && master[i]->s->type == AQ) { + count_component++; + } + } +/* + * Put information in buffer. + * Buffer contains an entry for every primary master + * species that can be used in the transport problem. + * Each entry in buffer is sent to HST for transort. + */ + buffer = (struct buffer *) PHRQ_malloc ((size_t) count_component * sizeof(struct buffer)); + j = 0; + for (i = 0; i < count_master; i++) { + if (master[i]->total > 0.0 && master[i]->s->type == AQ) { + buffer[j].name = master[i]->elt->name; + buffer[j].master = master[i]; + buffer[j].gfw = master[i]->elt->gfw; + j++; + } + } +#ifdef SKIP + output_msg(OUTPUT_MESSAGE, "List of Components:\n"); + for (i = 0; i < count_component; i++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\n", i+1, buffer[i].name); + /* + for (j=0; buffer[i].name[j] != '\0'; j++) { + names[i * length + j] = buffer[i].name[j]; + } + */ + } +#endif + /* + * Return value + */ + /**n_comp = count_component;*/ + count_tally_table_rows = count_component; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int store_tally_table(double *array, int row_dim, int col_dim, double fill_factor) +/* ---------------------------------------------------------------------- */ +{ + int i,j; + if (tally_table == NULL) { + input_error++; + error_msg("Tally table not defined, get_tally_table_rows_columns", CONTINUE); + return(ERROR); + } + if (count_tally_table_rows > row_dim) { + input_error++; + error_msg("Too many tally table rows for Fortran storage, store_tally_table", CONTINUE); + return(ERROR); + } + if (count_tally_table_columns > col_dim) { + input_error++; + error_msg("Too many tally table columns for Fortran storage, store_tally_table", CONTINUE); + return(ERROR); + } + /* + * store conservative mixing solution + */ + for (j = 0; j < count_tally_table_rows; j++) { + array[j] = tally_table[0].total[1][j].moles; + } + /* + * store reaction solution + */ + for (j = 0; j < count_tally_table_rows; j++) { + array[row_dim + j] = tally_table[1].total[1][j].moles; + } + /* + * Calculate deltas + */ + + diff_tally_table(); + + /* + * store deltas for all other columns + */ + for (i = 2; i < count_tally_table_columns; i++) { + for (j = 0; j < count_tally_table_rows; j++) { + array[i*row_dim + j] = tally_table[i].total[2][j].moles/fill_factor; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_tally_table_rows_columns(int *rows, int *columns) +/* ---------------------------------------------------------------------- */ +{ + *rows = 0; + *columns = 0; + if (tally_table == NULL) { + input_error++; + error_msg("tally table not defined, get_tally_table_rows_columns", CONTINUE); + return(ERROR); + } + *rows = count_tally_table_rows; + *columns = count_tally_table_columns; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_tally_table_row_heading(int row, char *string) +/* ---------------------------------------------------------------------- */ +{ + /* + * row is C row number + */ + strcpy(string, ""); + if (tally_table == NULL) { + input_error++; + error_msg("Tally table not defined, get_tally_table row_heading", CONTINUE); + return(ERROR); + } + if (row >= count_tally_table_rows) { + input_error++; + error_msg("Row exceeds tally table size, get_tally_table row_heading", CONTINUE); + return(ERROR); + } + strcpy(string, buffer[row].name); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int get_tally_table_column_heading(int column, int *type, char *string) +/* ---------------------------------------------------------------------- */ +{ + /* + * column is C column number + */ + *type = -1; + strcpy(string, ""); + if (tally_table == NULL) { + input_error++; + error_msg("tally table not defined, get_tally_table_column_heading", CONTINUE); + return(ERROR); + } + if (column >= count_tally_table_columns) { + input_error++; + error_msg("column exceeds tally table size, get_tally_table_column_heading", CONTINUE); + return(ERROR); + } + strcpy(string, tally_table[column].name); + *type = tally_table[column].type; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int free_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ + int i, k; + if (tally_table == NULL) return(OK); + for (i = 0; i < count_tally_table_columns; i++) { + if (tally_table[i].formula != NULL) (struct elt_list *) free_check_null(tally_table[i].formula); + for (k = 0; k < 3; k++) { + tally_table[i].total[k] = (struct buffer *) free_check_null(tally_table[i].total[k]); + } + } + tally_table = (struct tally *) free_check_null(tally_table); + buffer = (struct buffer *) free_check_null(buffer); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int zero_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k; + for (i = 0; i < count_tally_table_columns; i++) { + for (j = 0; j < count_tally_table_rows; j++) { + for (k = 0; k < 3; k++) { + tally_table[i].total[k][j].moles = 0; + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int diff_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + /* + output_msg(OUTPUT_MESSAGE,"Difference\n\n"); + */ + for (i = 0; i < count_tally_table_columns; i++) { + for (j = 0; j < count_tally_table_rows; j++) { + tally_table[i].total[2][j].moles = tally_table[i].total[1][j].moles - tally_table[i].total[0][j].moles; + } + + /* + output_msg(OUTPUT_MESSAGE, "Column %d\t%s\tType: %d\n", i, tally_table[i].name, tally_table[i].type); + for (j = 0; j < count_tally_table_rows; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\t%e\n", j, tally_table[i].total[2][j].name, (double) tally_table[i].total[2][j].moles); + } + */ + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + output_msg(OUTPUT_MESSAGE,"Tally_table\n\n"); + for (i = 0; i < count_tally_table_columns; i++) { + output_msg(OUTPUT_MESSAGE, "%s\tType: %d\n", tally_table[i].name, tally_table[i].type); + output_msg(OUTPUT_MESSAGE,"\n"); + output_msg(OUTPUT_MESSAGE, "\t%15s\t%15s\t%15s\n", "Initial", "Final", "Difference"); + for (j = 0; j < count_tally_table_rows; j++) { + output_msg(OUTPUT_MESSAGE,"%5s\t%15g\t%15g\t%15g\n", buffer[j].name, tally_table[i].total[0][j].moles, tally_table[i].total[1][j].moles, tally_table[i].total[2][j].moles); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int fill_tally_table(int *n_user, int index_conservative, int n_buffer) +/* ---------------------------------------------------------------------- */ +{ +/* + * Routine accumulates elements from all solutions, phases, gas phases, + * exchangers, and surfaces. + */ + int i, j, k, n; + struct solution *solution_ptr; + struct irrev *irrev_ptr; + struct pp_assemblage *pp_assemblage_ptr; + struct exchange *exchange_ptr; + struct surface *surface_ptr; + struct s_s_assemblage *s_s_assemblage_ptr; + struct gas_phase *gas_phase_ptr; + struct kinetics *kinetics_ptr; + struct kinetics_comp *kinetics_comp_ptr; + int found; + LDBLE moles; + char *ptr; + /* + * Cycle through tally table columns + */ + for (i = 0; i < count_tally_table_columns; i++) { + switch (tally_table[i].type) { + case Solution: +/* + * fill solution + */ + if (n_user[Solution] < 0 || n_buffer == 0) break; + if (i == 0) { + solution_ptr = solution_bsearch(index_conservative, &n, TRUE); + } else if (i == 1) { + solution_ptr = solution_bsearch(n_user[Solution], &n, TRUE); + } else { + solution_ptr = NULL; + error_msg("Solution is not in first two columns of tally_table", STOP); + } + if (solution_ptr == NULL) break; + xsolution_zero(); + add_solution(solution_ptr, 1.0, 1.0); + count_elts = 0; + paren_count = 0; + for (j=0; j < count_master; j++) { + if (master[j]->total > 0.0) { + ptr = master[j]->elt->primary->elt->name; + get_elts_in_species (&ptr, master[j]->total); + } + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Reaction: + /* + * fill reaction + */ + if (n_user[Reaction] < 0) break; + irrev_ptr = irrev_bsearch(n_user[Reaction], &n); + if (irrev_ptr == NULL) break; + count_elts = 0; + paren_count = 0; + if (n_buffer == 1) { + moles = irrev_ptr->steps[0]; + } else { + moles = 0.0; + } + add_elt_list(irrev_ptr->elts, moles); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Pure_phase: + /* + * fill an equilibrium phase + */ + if (n_user[Pure_phase] < 0) break; + pp_assemblage_ptr = pp_assemblage_bsearch(n_user[Pure_phase], &n); + if (pp_assemblage_ptr == NULL) break; + for (j = 0; j < pp_assemblage_ptr->count_comps; j++) { + if (pp_assemblage_ptr->pure_phases[j].name == tally_table[i].name) break; + if (strcmp_nocase(pp_assemblage_ptr->pure_phases[j].name, tally_table[i].name) == 0) break; + } + if (j >= pp_assemblage_ptr->count_comps) break; + count_elts = 0; + paren_count = 0; + moles = pp_assemblage_ptr->pure_phases[j].moles; + add_elt_list(tally_table[i].formula, moles); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Exchange: + /* + * fill exchange + */ + if (n_user[Exchange] < 0) break; + exchange_ptr = exchange_bsearch(n_user[Exchange], &n); + if (exchange_ptr == NULL) break; + count_elts = 0; + paren_count = 0; + for (j = 0; j < exchange_ptr->count_comps; j++) { + add_elt_list(exchange_ptr->comps[j].totals, 1.0); + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Surface: + /* + * fill surface + */ + if (n_user[Surface] < 0) break; + surface_ptr = surface_bsearch(n_user[Surface], &n); + if (surface_ptr == NULL) break; + count_elts = 0; + paren_count = 0; + for (j = 0; j < surface_ptr->count_comps; j++) { + add_elt_list(surface_ptr->comps[j].totals, 1.0); + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Ss_phase: + /* + * fill an solid solution phase + */ + if (n_user[Ss_phase] < 0) break; + s_s_assemblage_ptr = s_s_assemblage_bsearch(n_user[Ss_phase], &n); + if (s_s_assemblage_ptr == NULL) break; + found = FALSE; + moles = 0.0; + for (j = 0; j < s_s_assemblage_ptr->count_s_s; j++) { + for (k = 0; k < s_s_assemblage_ptr->s_s[j].count_comps; k++) { + if (s_s_assemblage_ptr->s_s[j].comps[k].phase->name == tally_table[i].name) break; + if (strcmp_nocase(s_s_assemblage_ptr->s_s[j].comps[k].phase->name, tally_table[i].name) == 0) break; + } + if (k < s_s_assemblage_ptr->s_s[j].count_comps) { + moles = s_s_assemblage_ptr->s_s[j].comps[k].moles; + found = TRUE; + break; + } + } + if (found == FALSE) break; + count_elts = 0; + paren_count = 0; + add_elt_list(tally_table[i].formula, moles); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Gas_phase: + /* + * fill in gas phase + */ + if (n_user[Gas_phase] < 0) break; + gas_phase_ptr = gas_phase_bsearch(n_user[Gas_phase], &n); + if (gas_phase_ptr == NULL) break; + count_elts = 0; + paren_count = 0; + for (j = 0; j < gas_phase_ptr->count_comps; j++) { + add_elt_list(gas_phase_ptr->comps[j].phase->next_elt, gas_phase_ptr->comps[j].moles); + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Kinetics: + /* + * fill in kinetics + */ + if (n_user[Kinetics] < 0) break; + kinetics_ptr = kinetics_bsearch(n_user[Kinetics], &n); + if (kinetics_ptr == NULL) break; + kinetics_comp_ptr = NULL; + for (j = 0; j < kinetics_ptr->count_comps; j++) { + kinetics_comp_ptr = &kinetics_ptr->comps[j]; + if (kinetics_comp_ptr->rate_name == tally_table[i].name) break; + if (strcmp_nocase(kinetics_comp_ptr->rate_name, tally_table[i].name) == 0) break; + } + if (j >= kinetics_ptr->count_comps) break; + moles = kinetics_comp_ptr->m; + count_elts = 0; + paren_count = 0; + add_elt_list(tally_table[i].formula, moles); + elt_list_to_tally_table(tally_table[i].total[n_buffer]); + break; + case Mix: + break; + case Temperature: + break; + case UnKnown: + break; + } +#ifdef SKIP + output_msg(OUTPUT_MESSAGE, "Column %d\t%s\tType: %d\n", i, tally_table[i].name, tally_table[i].type); + for (j = 0; j < count_tally_table_rows; j++) { + output_msg(OUTPUT_MESSAGE, "\t%d\t%s\t%e\n", j, tally_table[i].total[n_buffer][j].name, (double) tally_table[i].total[n_buffer][j].moles); + } +#endif + } + + return(OK); +} + +/* ---------------------------------------------------------------------- */ +int elt_list_to_tally_table(struct buffer *buffer_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + for (i = 0; i < count_tally_table_rows; i++) { + buffer_ptr[i].moles=0.0; + } + /* + * copy element list amounts to buffer in tally table + * for column number + */ + + for ( j=0; j < count_elts; j++ ) { + if (elt_list[j].elt->primary->s == s_h2o) continue; + if (elt_list[j].elt->primary->s == s_hplus) continue; + if (elt_list[j].elt->primary->s == s_h3oplus) continue; + if (elt_list[j].elt->primary->type != AQ) continue; + for (i = 0; i < count_tally_table_rows; i++) { + if (elt_list[j].elt->primary == buffer_ptr[i].master->elt->primary) { + buffer_ptr[i].moles=elt_list[j].coef; + break; + } + } + if (i >= count_tally_table_rows) { + error_msg("Should not be here in elt_list_to_tally_table", STOP); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int build_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Routine accumulates elements from all solutions, phases, gas phases, + * exchangers, and surfaces. Counts number of aqueous components + * to transport. Stores in global variable count_component. + * Also calculates a number greater than all user numbers and + * stores in global variable first_user_number. + */ + int i, j, k, l, n, p, save_print_use; + int count_tt_reaction, count_tt_exchange, count_tt_surface, count_tt_gas_phase; + int count_tt_pure_phase, count_tt_ss_phase, count_tt_kinetics; + struct pp_assemblage *pp_assemblage_ptr; + struct pure_phase *pure_phase_ptr; + struct s_s_assemblage *s_s_assemblage_ptr; + struct s_s *s_s_ptr; + struct s_s_comp *s_s_comp_ptr; + struct kinetics *kinetics_ptr; + struct kinetics_comp *kinetics_comp_ptr; + struct phase *phase_ptr; + + + char token[MAX_LENGTH]; + char *ptr; + + if (svnid == NULL) fprintf(stderr," "); +/* + * make list of all elements in all entitites + * defines the number of rows in the table + */ + get_all_components(); + + save_print_use = pr.use; + pr.use = FALSE; +/* + * find nuber of columns + */ + count_tally_table_columns = 0; +/* + * add one for conservative mixing + */ + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Solution_conservative"); + tally_table[n].type = Solution; +/* + * add one for mixing plus reaction + */ + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Solution_reaction"); + tally_table[n].type = Solution; +/* + * add one for reactions + */ + if (count_irrev > 0) { + count_tt_reaction = 1; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Reaction"); + tally_table[n].type = Reaction; + } else { + count_tt_reaction = 0; + } +/* + * add one for exchangers + */ + if (count_exchange > 0) { + count_tt_exchange = 1; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Exchange"); + tally_table[n].type = Exchange; + } else { + count_tt_exchange = 0; + } +/* + * add one for surface + */ + if (count_surface > 0) { + count_tt_surface = 1; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Surface"); + tally_table[n].type = Surface; + } else { + count_tt_surface = 0; + } +/* + * add one for gases + */ + if (count_gas_phase > 0) { + count_tt_gas_phase = 1; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = string_hsave("Gas_phase"); + tally_table[n].type = Gas_phase; + } else { + count_tt_gas_phase = 0; + } +/* + * Count pure phases + */ + count_tt_pure_phase = 0; + if (count_pp_assemblage > 0) { + /* + * Go through all pure phases in pure phase assemblages + */ + for (i = 0; i < count_pp_assemblage; i++) { + pp_assemblage_ptr = &pp_assemblage[i]; + for (j = 0; j < pp_assemblage_ptr->count_comps; j++) { + pure_phase_ptr = &pp_assemblage_ptr->pure_phases[j]; + /* + * check if already in tally_table + */ + for (k = 1; k < count_tally_table_columns; k++) { + if (tally_table[k].type == Pure_phase && + tally_table[k].name == pure_phase_ptr->phase->name && + tally_table[k].add_formula == pure_phase_ptr->add_formula) break; + } + if (k < count_tally_table_columns) continue; + /* + * Add to table + */ + count_tt_pure_phase++; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = pure_phase_ptr->phase->name; + tally_table[n].type = Pure_phase; + tally_table[n].add_formula = pure_phase_ptr->add_formula; + count_elts = 0; + paren_count = 0; + if (pure_phase_ptr->add_formula != NULL) { + strcpy(token, pure_phase_ptr->add_formula); + ptr = &(token[0]); + get_elts_in_species (&ptr, 1.0); + } else { + strcpy(token, pure_phase_ptr->phase->formula); + add_elt_list(pure_phase_ptr->phase->next_elt, 1.0); + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + tally_table[n].formula = elt_list_save(); + } + } + } +/* + * Add solid-solution pure phases + */ + count_tt_ss_phase = 0; + if (count_pp_assemblage > 0) { + /* + * Go through all components of all solid solutions in solid-solution assemblages + */ + for (i = 0; i < count_s_s_assemblage; i++) { + s_s_assemblage_ptr = &s_s_assemblage[i]; + for (j = 0; j < s_s_assemblage_ptr->count_s_s; j++) { + s_s_ptr = &s_s_assemblage_ptr->s_s[j]; + for (k = 0; k < s_s_ptr->count_comps; k++) { + s_s_comp_ptr = &s_s_ptr->comps[k]; + /* + * check if already in tally_table + */ + for (l = 1; l < count_tally_table_columns; l++) { + if (tally_table[l].type == Ss_phase && + tally_table[l].name == s_s_comp_ptr->phase->name) break; + } + if (l < count_tally_table_columns) continue; + /* + * Add to table + */ + count_tt_ss_phase++; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = s_s_comp_ptr->phase->name; + tally_table[n].type = Ss_phase; + count_elts = 0; + paren_count = 0; + strcpy(token, s_s_comp_ptr->phase->formula); + add_elt_list(s_s_comp_ptr->phase->next_elt, 1.0); + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + tally_table[n].formula = elt_list_save(); + } + } + } + } +/* + * Add kinetic reactants + */ + count_tt_kinetics = 0; + if (count_kinetics > 0) { + for (i = 0; i < count_kinetics; i++) { + kinetics_ptr = &kinetics[i]; + for (j = 0; j < kinetics_ptr->count_comps; j++) { + kinetics_comp_ptr = &kinetics_ptr->comps[j]; + /* + * check if already in tally_table + */ + for (l = 1; l < count_tally_table_columns; l++) { + if (tally_table[l].type == Kinetics && + tally_table[l].name == kinetics_comp_ptr->rate_name) break; + } + if (l < count_tally_table_columns) continue; + /* + * Add to table + */ + count_tt_kinetics++; + n = count_tally_table_columns; + extend_tally_table(); + tally_table[n].name = kinetics_comp_ptr->rate_name; + tally_table[n].type = Kinetics; + /* + * get formula for kinetic component + */ + count_elts = 0; + paren_count = 0; + phase_ptr = NULL; + if (kinetics_ptr->comps[j].count_list == 1) { + strcpy(token, kinetics_ptr->comps[j].list[0].name); + phase_ptr = phase_bsearch(token, &p, FALSE); + } + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, 1.0); + } else { + for (k = 0; k < kinetics_ptr->comps[j].count_list; k++) { + ptr = kinetics_ptr->comps[j].list[k].name; + get_elts_in_species (&ptr, 1.0 * kinetics_ptr->comps[j].list[k].coef); + } + } + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + tally_table[n].formula = elt_list_save(); + } + } + } +#ifdef SKIP + /* + * Debug print for table definition + */ + output_msg(OUTPUT_MESSAGE, "List of rows for tally table\n"); + for (i = 0; i < count_tally_table_rows; i++) { + output_msg(OUTPUT_MESSAGE, "\t%-s\n", buffer[i].name); + } + output_msg(OUTPUT_MESSAGE, "\nList of columns for tally table\n"); + for (i = 0; i < count_tally_table_columns; i++) { + output_msg(OUTPUT_MESSAGE, "\t%-20s\tType: %d\n", tally_table[i].name, tally_table[i].type); + if (tally_table[i].formula != NULL) { + for (j = 0; tally_table[i].formula[j].elt != NULL; j++) { + output_msg(OUTPUT_MESSAGE,"\t\t%-10s\t%f\n", tally_table[i].formula[j].elt->name, (double) tally_table[i].formula[j].coef); + } + } + } +#endif + pr.use = save_print_use; + return(OK); +} +/* ---------------------------------------------------------------------- */ +void add_all_components_tally(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Routine accumulates elements from all solutions, phases, gas phases, + * exchangers, and surfaces. Counts number of aqueous components + * to transport. Stores in global variable count_component. + * Also calculates a number greater than all user numbers and + * stores in global variable first_user_number. + */ + int i, save_print_use; + + save_print_use = pr.use; + pr.use = FALSE; +/* + * Delete solutions less than -1 + */ + while (count_solution > 0 && solution[0]->n_user < -1) { + i = solution[0]->n_user; + solution_delete(i); + } +/* + * add all solutions + */ + xsolution_zero(); + for (i = 0; i < count_solution; i++) { + add_solution(solution[i], 1.0/solution[i]->mass_water, 1.0); + } +/* + * add all irrev reactions + */ + for (i = 0; i < count_irrev; i++) { + add_reaction(&irrev[i], 1, 1.0); + } +/* + * Add pure phases + */ + for (i = 0; i < count_pp_assemblage; i++) { + add_pp_assemblage(&pp_assemblage[i]); + } +/* + * Exchangers + */ + for (i = 0; i < count_exchange; i++) { + add_exchange(&exchange[i]); + } +/* + * Surfaces + */ + for (i = 0; i < count_surface; i++) { + add_surface(&surface[i]); + } +/* + * Gases + */ + for (i = 0; i < count_gas_phase; i++) { + add_gas_phase(&gas_phase[i]); + } +/* + * Add solid-solution pure phases + */ + for (i = 0; i < count_s_s_assemblage; i++) { + add_s_s_assemblage(&s_s_assemblage[i]); + } +/* + * Add elements in kinetic reactions + */ + for (i = 0; i < count_kinetics; i++) { + calc_dummy_kinetic_reaction_tally(&kinetics[i]); + add_kinetics(&kinetics[i]); + } +/* + * reset pr.use + */ + pr.use = save_print_use; + return; +} +/* ---------------------------------------------------------------------- */ +int calc_dummy_kinetic_reaction_tally(struct kinetics *kinetics_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Go through kinetic components and add positive amount of each reactant + */ + int i, j; + LDBLE coef; + char token[MAX_LENGTH]; + char *ptr; + struct phase *phase_ptr; +/* + * Go through list and generate list of elements and + * coefficient of elements in reaction + */ + free_check_null(kinetics_ptr->totals); + count_elts = 0; + paren_count = 0; + for (i=0; i < kinetics_ptr->count_comps; i++) { + coef = 1.0; +/* + * Reactant is a pure phase, copy formula into token + */ + phase_ptr = NULL; + if (kinetics_ptr->comps[i].count_list == 1) { + strcpy(token, kinetics_ptr->comps[i].list[0].name); + phase_ptr = phase_bsearch(token, &j, FALSE); + } + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, coef); + } else { + for (j = 0; j < kinetics_ptr->comps[i].count_list; j++) { + ptr = kinetics_ptr->comps[i].list[j].name; + get_elts_in_species (&ptr, coef); + } + } + + } + kinetics_ptr->totals = elt_list_save(); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int extend_tally_table(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + /* + * adds another column to tally_table + * increments number of columns + */ + tally_table = (struct tally *)PHRQ_realloc((void *) tally_table, (size_t) (count_tally_table_columns + 1) * sizeof(struct tally)); + if (tally_table == NULL) malloc_error(); + for (i = 0; i < 3; i++) { + tally_table[count_tally_table_columns].total[i] = (struct buffer *)PHRQ_malloc( (size_t) (count_tally_table_rows) * sizeof( struct buffer )); + if (tally_table[count_tally_table_columns].total[i] == NULL) malloc_error(); + for (j = 0; j < count_tally_table_rows; j++) { + tally_table[count_tally_table_columns].total[i][j].name = buffer[j].name; + tally_table[count_tally_table_columns].total[i][j].master = buffer[j].master; + } + } + tally_table[count_tally_table_columns].name = NULL; + tally_table[count_tally_table_columns].type = UnKnown; + tally_table[count_tally_table_columns].add_formula = NULL; + tally_table[count_tally_table_columns].moles = 0.0; + tally_table[count_tally_table_columns].formula = NULL; + count_tally_table_columns++; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_reaction_moles(int n_user, LDBLE moles) +/* ---------------------------------------------------------------------- */ +{ + int n; + struct irrev *irrev_ptr; + + irrev_ptr = irrev_bsearch(n_user, &n); + if (irrev_ptr == NULL) return(ERROR); + irrev_ptr->steps[0] = moles; + irrev_ptr->count_steps = 1; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_reaction_temperature(int n_user, LDBLE tc) +/* ---------------------------------------------------------------------- */ +{ + int n; + struct temperature *temperature_ptr; + + temperature_ptr = temperature_bsearch(n_user, &n); + if (temperature_ptr == NULL) return(ERROR); + temperature_ptr->t[0] = tc; + temperature_ptr->count_t = 1; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_kinetics_time(int n_user, LDBLE step) +/* ---------------------------------------------------------------------- */ +{ + int n; + struct kinetics *kinetics_ptr; + + kinetics_ptr = kinetics_bsearch(n_user, &n); + if (kinetics_ptr == NULL) return(ERROR); + kinetics_ptr->steps[0] = step; + kinetics_ptr->count_steps = 1; + return(OK); +} + diff --git a/test.xml b/test.xml new file mode 100644 index 00000000..72bbd502 --- /dev/null +++ b/test.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + diff --git a/tidy.cpp b/tidy.cpp new file mode 100644 index 00000000..b76b509f --- /dev/null +++ b/tidy.cpp @@ -0,0 +1,3333 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: tidy.c 407 2005-07-27 22:06:36Z dlpark $"; + +static int check_species_input(void); +static LDBLE coef_in_master(struct master *master_ptr); +static int phase_rxn_to_trxn(struct phase *phase_ptr); +static int reset_last_model(void); +static int rewrite_eqn_to_primary(void); +static int rewrite_eqn_to_secondary(void); +static int species_rxn_to_trxn(struct species *s_ptr); +static int tidy_min_exchange(void); +static int tidy_kin_exchange(void); +static int tidy_gas_phase(void); +static int tidy_inverse(void); +static int tidy_isotopes (void); +static int tidy_isotope_ratios(void); +static int tidy_isotope_alphas(void); +static int tidy_kin_surface(void); +static int tidy_master_isotope (void); +static int tidy_min_surface(void); +static int tidy_phases(void); +static int tidy_pp_assemblage(void); +static int tidy_solutions(void); +static int tidy_s_s_assemblage(void); +static int tidy_species(void); +static int tidy_surface(void); + +static LDBLE a0, a1, kc, kb; +static int scan(LDBLE f(LDBLE x), LDBLE *xx0, LDBLE *xx1); +static LDBLE halve(LDBLE f(LDBLE x), LDBLE x0, LDBLE x1, LDBLE tol); +static LDBLE f_spinodal(LDBLE x); +static int solve_misc(LDBLE *xxc1, LDBLE *xxc2, LDBLE tol); +static int s_s_calc_a0_a1(struct s_s *s_s_ptr); +#define ZERO_TOL 1.0e-30 + +/* ---------------------------------------------------------------------- */ +int tidy_model(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + int n_user, last; + if (svnid == NULL) fprintf(stderr," "); + /* + * Determine if any new elements, species, phases have been read + */ + new_model = FALSE; + new_pp_assemblage = FALSE; + new_surface = FALSE; + new_exchange = FALSE; + new_reaction = FALSE; + new_temperature = FALSE; + new_mix = FALSE; + new_solution = FALSE; + new_gas_phase = FALSE; + new_inverse = FALSE; + new_punch = FALSE; + new_surface = FALSE; + new_s_s_assemblage = FALSE; + new_kinetics = FALSE; + new_pitzer = FALSE; + if (keyword[2].keycount > 0 || /*"species"*/ + keyword[3].keycount > 0 || /*"master"*/ + keyword[5].keycount > 0 || /*"phases"*/ + keyword[11].keycount > 0 || /*"exchange_species"*/ + keyword[12].keycount > 0 || /*"master_exchange_species"*/ + keyword[14].keycount > 0 || /*"surface_species"*/ + keyword[15].keycount > 0 || /*"master_surface_species"*/ + keyword[36].keycount > 0 || /*"rates"*/ + keyword[47].keycount > 0 || /*"llnl_aqueous_model_parameters"*/ + (keyword[49].keycount > 0 && simulation == 0) || /*"database"*/ + keyword[51].keycount > 0 || /*"named_analytical_expressions"*/ + keyword[54].keycount > 0 || /*"isotopes"*/ + keyword[55].keycount > 0 || /*"calculate_values"*/ + keyword[56].keycount > 0 || /*"isotopes_ratios",*/ + keyword[57].keycount > 0 || /*"isotopes_alphas"*/ + keyword[59].keycount > 0 ) { /*"pitzer"*/ + new_model = TRUE; + } + if (keyword[6].keycount > 0) new_pp_assemblage = TRUE; /*"pure_phases"*/ + if (keyword[16].keycount > 0) new_surface = TRUE; /*"surface"*/ + if (keyword[13].keycount > 0) new_exchange = TRUE; /*"exchange"*/ + if (keyword[7].keycount > 0) new_reaction = TRUE; /*"reaction"*/ + if (keyword[17].keycount > 0) new_temperature = TRUE; /*"reacton_temperature"*/ + if (keyword[8].keycount > 0) new_mix = TRUE; /*"mix"*/ + if (keyword[4].keycount > 0 || /*"solution"*/ + keyword[43].keycount > 0 ) { /*"spread_solution"*/ + new_solution = TRUE; + } + if (keyword[19].keycount > 0) new_gas_phase = TRUE; /*"gas_phase"*/ + if (keyword[18].keycount > 0) new_inverse = TRUE; /*"inverse_modeling"*/ + if (keyword[22].keycount > 0 || /*"selected_output"*/ + keyword[39].keycount > 0 ) { /*"user_punch"*/ + new_punch = TRUE; + } + if (keyword[40].keycount > 0) new_s_s_assemblage = TRUE;/*"solid_solutions"*/ + if (keyword[33].keycount > 0) new_kinetics = TRUE; /*"kinetics"*/ + if (keyword[58].keycount > 0) new_copy = TRUE; /*"copy"*/ + if (keyword[59].keycount > 0) new_pitzer = TRUE; /*"pitzer"*/ + + /* + 0 "eof" + 1 "end" + 2 "species" + 3 "master" + 4 "solution" + 5 "phases" + 6 "pure_phases" + 7 "reaction" + 8 "mix" + 9 "use" + 10 "save" + 11 "exchange_species" + 12 "master_exchange_species" + 13 "exchange" + 14 "surface_species" + 15 "master_surface_species" + 16 "surface" + 17 "reacton_temperature" + 18 "inverse_modeling" + 19 "gas_phase" + 20 "transport" + 21 "debug" + 22 "selected_output" + 23 "select_output" + 24 "knobs" + 25 "print" + 26 "equilibrium_phases" + 27 "equilibria" + 28 "equilibrium" + 29 "pure" + 30 "title" + 31 "comment" + 32 "advection" + 33 "kinetics" + 34 "incremental_reactions" + 35 "incremental" + 36 "rates" + 37 "solution_s" + 38 "user_print" + 39 "user_punch" + 40 "solid_solutions" + 41 "solid_solution" + 42 "solution_spread" + 43 "spread_solution" + 44 "selected_out" + 45 "select_out" + 46 "user_graph" + 47 "llnl_aqueous_model_parameters" + 48 "llnl_aqueous_model" + 49 "database" + 50 "named_analytical_expression" + 51 "named_analytical_expressions" + 52 "named_expressions" + 53 "named_log_k" + 54 "isotopes" + 55 "calculate_values" + 56 "isotopes_ratios", + 57 "isotopes_alphas" + 58 "copy" + 59 "pitzer" + */ + +/* + * Sort arrays + */ + +/* species */ + if (new_model == TRUE) { + qsort (s, + (size_t) count_s, + (size_t) sizeof (struct species *), + s_compare); + +/* master species */ + qsort (master, + (unsigned) count_master, + sizeof(struct master *), + master_compare); + +/* elements */ + qsort (elements, + (size_t) count_elements, + (size_t) sizeof (struct element *), + element_compare); +/* phases */ + qsort (phases, + (size_t) count_phases, + (size_t) sizeof (struct phase *), + phase_compare); + + } +/* pure_phases */ + if (new_pp_assemblage) pp_assemblage_sort(); + +/* solid solutions */ + if (new_s_s_assemblage) s_s_assemblage_sort(); + +/* exchangers */ + if (new_exchange) exchange_sort(); +/* surfaces */ + if (new_surface) surface_sort(); +#ifdef SKIP +/* mixtures */ + qsort (mix, + (size_t) count_mix, + (size_t) sizeof (struct mix), + mix_compare); +#endif + +/* mixtures */ +/* !!!!! + * In transport mode, with stagnant cells, cell number is 'n_mix_user' for + * both mix with stagnant cells and for dispersive mix. + * qsort(mix) then fails. Hence ... + */ + + if ((state != TRANSPORT) || (simul_tr < 2) || (stag_data->count_stag == 0)) { + mix_sort(); + } + +/* gas_phase */ + if (new_gas_phase) gas_phase_sort(); + +/* kinetics */ + if (new_kinetics) kinetics_sort(); +/* + * Check pointers, write reactions for species + */ + if (new_model) { + tidy_species(); + + tidy_phases(); + + tidy_master_isotope(); +/* + * calculate gfw of water, kg/mole + */ + compute_gfw("H2O", &gfw_water); + gfw_water *= 0.001; + } +/* + * tidy surface data + */ + if (new_model || new_surface) tidy_surface(); +/* + * tidy inverse data + */ + if (new_inverse) tidy_inverse(); +/* + * tidy gas phase data + */ + if (new_gas_phase) tidy_gas_phase(); +/* + * tidy pp_assemblage data + */ + if (new_model || new_pp_assemblage) tidy_pp_assemblage(); +/* + * tidy s_s_assemblage data + */ + if (new_model || new_s_s_assemblage) tidy_s_s_assemblage(); +/* + * tidy exchange data, after pp_assemblages + */ + if (new_exchange) tidy_min_exchange(); + if (new_exchange) tidy_kin_exchange(); +/* + * tidy surface data + */ + if (new_surface) tidy_min_surface(); + if (new_surface) tidy_kin_surface(); +/* + * tidy solution isotope data + */ + if (new_solution) tidy_isotopes(); + if (new_model) tidy_isotope_ratios(); + if (new_model) tidy_isotope_alphas(); +/* + * Duplicate reaction + */ + if (new_reaction) { + for ( i = 0; i < count_irrev; i++) { + if ( irrev[i].n_user_end > irrev[i].n_user ) { + n_user = irrev[i].n_user; + last = irrev[i].n_user_end; + irrev[i].n_user_end = irrev[i].n_user; + for (j = n_user + 1; j <= last; j++) { + irrev_duplicate(n_user, j); + } + } + } + } +/* + * Duplicate kinetics + */ + if (new_kinetics) { + for ( i = 0; i < count_kinetics; i++) { + if ( kinetics[i].n_user_end > kinetics[i].n_user ) { + n_user = kinetics[i].n_user; + last = kinetics[i].n_user_end; + kinetics[i].n_user_end = kinetics[i].n_user; + for (j = n_user + 1; j <= last; j++) { + kinetics_duplicate(n_user, j); + } + } + } + } +/* + * Duplicate temperature + */ + if (new_temperature) { + temperature_sort(); + for ( i = 0; i < count_temperature; i++) { + if ( temperature[i].n_user_end > temperature[i].n_user ) { + n_user = temperature[i].n_user; + last = temperature[i].n_user_end; + temperature[i].n_user_end = temperature[i].n_user; + for (j = n_user + 1; j <= last; j++) { + temperature_duplicate(n_user, j); + } + } + } + } +/* + * Tidy pitzer information + */ + if (pitzer_model && new_model) pitzer_tidy(); +/* + * Tidy punch information + */ + if (input_error == 0 && (new_punch || new_model)) tidy_punch(); +/* + * Tidy solution information + */ + if (new_solution) tidy_solutions(); + + /* if (new_model || new_exchange || new_pp_assemblage || new_surface || new_gas_phase || new_kinetics) reset_last_model(); */ + if (new_model) reset_last_model(); +/* + * make sure essential species are defined + */ + if (s_h2o == NULL) { + input_error++; + error_msg("H2O not defined.", STOP); + } + if (s_h2o->primary == NULL) { + input_error++; + error_msg("H2O, primary master species for O, not defined.", CONTINUE); + } + if (s_h2o->secondary == NULL) { + input_error++; + error_msg("H2O, secondary master species for O(-2), not defined.", CONTINUE); + } + if (s_hplus == NULL && s_h3oplus == NULL) { + input_error++; + error_msg("Neither H+ nor H3O+ are defined in solution_species.", STOP); + } else if (s_hplus == NULL && s_h3oplus != NULL) { + s_hplus = s_h3oplus; + s_h3oplus = NULL; + } else if (s_hplus != NULL && s_h3oplus == NULL) { + } else if (s_hplus != NULL && s_h3oplus != NULL) { + input_error++; + error_msg("Can not define both H+ and H3O+ in solution_species.", STOP); + } + if (s_hplus->primary == NULL) { + input_error++; + error_msg("H3O+, primary master species for H, not defined.", CONTINUE); + } + if (s_hplus->secondary == NULL) { + input_error++; + error_msg("H3O+, secondary master species for H(1), not defined.", CONTINUE); + } + if (s_eminus == NULL) { + input_error++; + error_msg("e- not defined in solution_species.", CONTINUE); + } + if (s_eminus->primary == NULL) { + input_error++; + error_msg("e-, primary master species for E-, not defined.", CONTINUE); + } + if (pitzer_model == FALSE) { + if (s_h2 == NULL) { + input_error++; + error_msg("H2(aq) not defined in solution_species.", CONTINUE); + } + if (s_o2 == NULL) { + input_error++; + error_msg("O2(aq) not defined in solution_species.", CONTINUE); + } + } + element_h_one = element_store ("H(1)"); + if (element_h_one == NULL) { + input_error++; + error_msg("H(1) not defined in solution_master_species.", CONTINUE); + } +/* + * Error check, program termination + */ + if (input_error > 0 || parse_error > 0 ) { + error_msg("Calculations terminating due to input errors.", STOP); + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int check_species_input(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Check species data for completeness + */ + int i; + int return_value; + + return_value = OK; + for (i=0; i < count_s; i++) { + if (s[i]->next_elt == NULL) { + input_error++; + return_value = ERROR; + sprintf(error_string, "Elements in species have not been tabulated, %s.", s[i]->name); + error_msg(error_string, CONTINUE); + } + if (s[i]->rxn == NULL) { + input_error++; + return_value = ERROR; + sprintf(error_string, "Reaction for species has not been defined, %s.", s[i]->name); + error_msg(error_string, CONTINUE); + } else { + select_log_k_expression(s[i]->logk, s[i]->rxn->logk); + add_other_logk(s[i]->rxn->logk, s[i]->count_add_logk, s[i]->add_logk); + } + } + return(return_value); +} +/* ---------------------------------------------------------------------- */ +int select_log_k_expression(LDBLE *source_k, LDBLE *target_k) +/* ---------------------------------------------------------------------- */ +{ + int j, analytic; + + analytic = FALSE; + for (j=2; j < 7; j++) { + if (source_k[j] != 0.0) { + analytic = TRUE; + break; + } + } + if (analytic == TRUE) { + target_k[0] = 0.0; + target_k[1] = 0.0; + for (j=2; j < 7; j++) { + target_k[j] = source_k[j]; + } + } else { + target_k[0] = source_k[0]; + target_k[1] = source_k[1]; + for (j=2; j < 7; j++) { + target_k[j] = 0.0; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int add_other_logk(LDBLE *source_k, int count_add_logk, struct name_coef *add_logk) +/* ---------------------------------------------------------------------- */ +{ + int i, j, analytic; + struct logk *logk_ptr; + char token[MAX_LENGTH]; + LDBLE coef; + ENTRY item, *found_item; + + if (count_add_logk == 0) return(OK); + for (i = 0; i < count_add_logk; i++) { + coef = add_logk[i].coef; + strcpy(token, add_logk[i].name); + str_tolower(token); + item.key = token; + item.data = NULL; + found_item = hsearch_multi(logk_hash_table, item, FIND); + if (found_item == NULL) { + input_error++; + sprintf(error_string,"Could not find named temperature expression, %s\n", token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + logk_ptr = (struct logk *) found_item->data; + analytic = FALSE; + for (j=2; j < 7; j++) { + if (logk_ptr->log_k[j] != 0.0) { + analytic = TRUE; + break; + } + } + if (analytic == TRUE) { + for (j=2; j < 7; j++) { + source_k[j] += logk_ptr->log_k[j]*coef; + } + } else { + source_k[0] += logk_ptr->log_k[0]*coef; + source_k[1] += logk_ptr->log_k[1]*coef; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE coef_in_master(struct master *master_ptr) +/* ---------------------------------------------------------------------- */ +{ + int l; + LDBLE coef; + char *ptr; + char elt_name[MAX_LENGTH]; + struct elt_list *next_elt; + + coef = 0.0; + ptr = master_ptr->elt->name; + get_elt(&ptr, elt_name, &l); + for (next_elt = master_ptr->s->next_elt; next_elt->elt != NULL; next_elt++) { + if ( strcmp(elt_name, next_elt->elt->name) == 0 ) { + coef= next_elt->coef; + break; + } + } + return(coef); +} +/* ---------------------------------------------------------------------- */ +int rewrite_eqn_to_secondary(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Write equation for species in terms of secondary species + * Result is in trxn. + */ + LDBLE coef; + int repeat, i, add_count; + struct rxn_token_temp *token_ptr; +/* + * + */ + add_count=0; + repeat=TRUE; +/* + * Reduce reaction equation to primary and secondary species + */ + while (repeat == TRUE) { + repeat = FALSE; + /* Check for too many iterations */ + if (++add_count > MAX_ADD_EQUATIONS) { + parse_error++; + sprintf(error_string, "Could not reduce equation to secondary master species, %s.", trxn.token[0].name); + error_msg(error_string, CONTINUE); + break; + } + + for (i=1; i < count_trxn; i++) { + token_ptr = &(trxn.token[i]); + if (token_ptr->s->secondary == NULL && + token_ptr->s->primary == NULL) { + coef=token_ptr->coef; + trxn_add(token_ptr->s->rxn, coef, TRUE); + repeat=TRUE; + break; + } + } + } + trxn_combine(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int rewrite_eqn_to_primary(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Write equation for secondary master species in terms of primary master species + * Store result in reaction structure for master species + * rewrite if necessary. + * + */ + int repeat, j, add_count; + +/* + * Check secondary master species + */ + repeat=TRUE; + add_count=0; +/* + * Check if reaction contains only primary master species + */ + while (repeat == TRUE) { + repeat=FALSE; +/* + * Check for too many iterations + */ + if (++add_count > MAX_ADD_EQUATIONS) { + parse_error++; + sprintf(error_string, "Could not reduce equation to primary master species, %s.", trxn.token[0].s->name); + error_msg(error_string, CONTINUE); + break; + } +/* + * Go through species in reaction for secondary master species, look for non-primary + * species as reactants, rewrite + */ + for (j=1; j < count_trxn; j++) { + if (trxn.token[j].s->primary == NULL) { + trxn_add(trxn.token[j].s->rxn, trxn.token[j].coef, TRUE); + repeat = TRUE; + break; + } + } + } + trxn_combine(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_gas_phase(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, n_user, last; + struct phase *phase_ptr; +/* + * Find all gases for each gas_phase in phase list + */ + for (i = 0; i < count_gas_phase; i++) { + if (gas_phase[i].new_def != TRUE) continue; + gas_phase[i].new_def = FALSE; + for (j=0; j < gas_phase[i].count_comps; j++) { + phase_ptr = phase_bsearch(gas_phase[i].comps[j].name, &k, FALSE); + if (phase_ptr == NULL) { + input_error++; + sprintf(error_string, "Gas not found in PHASES data base, %s.", gas_phase[i].comps[j].name); + error_msg(error_string, CONTINUE); + continue; + } else { + gas_phase[i].comps[j].phase = phase_ptr; + } +/* + * Fixed pressure + */ + if (gas_phase[i].type == PRESSURE) { + if (gas_phase[i].solution_equilibria == TRUE) { + input_error++; + sprintf(error_string, "Gas phase %d: can not use '-equilibrium' option with fixed pressure gas phase.", gas_phase[i].n_user); + error_msg(error_string, CONTINUE); + } + /* calculate moles */ + if (gas_phase[i].comps[j].p_read != NAN) { + gas_phase[i].comps[j].moles = gas_phase[i].comps[j].p_read * + gas_phase[i].volume/R_LITER_ATM/gas_phase[i].temperature; + } else { + input_error++; + sprintf(error_string, "Gas phase %d: partial pressure of gas component %s not defined.", gas_phase[i].n_user, gas_phase[i].comps[j].name); + error_msg(error_string, CONTINUE); + } + } else { +/* + * Fixed volume + */ + if (gas_phase[i].solution_equilibria == FALSE) { + if (gas_phase[i].comps[j].p_read != NAN) { + gas_phase[i].comps[j].moles = gas_phase[i].comps[j].p_read * gas_phase[i].volume/R_LITER_ATM/gas_phase[i].temperature; + } else { + input_error++; + sprintf(error_string, "Gas phase %d: moles of gas component %s not defined.", gas_phase[i].n_user, gas_phase[i].comps[j].name); + error_msg(error_string, CONTINUE); + } + } + } +/* + * Duplicate gas phase, only if not solution equilibria + */ + } + if (gas_phase[i].solution_equilibria == FALSE) { + n_user = gas_phase[i].n_user; + last = gas_phase[i].n_user_end; + gas_phase[i].n_user_end = gas_phase[i].n_user; + for (j = n_user + 1; j <= last; j++) { + gas_phase_duplicate(n_user, j); + } + } else { + gas_phase[i].new_def = TRUE; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_inverse(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * After all of data are read, fill in data for an inverse structure, + * including master species pointers, phase pointers, and uncertainties + * and a list of all elements from phases or -balance input. + */ + int i, j, k, l; + int count_in; + LDBLE value; + struct inv_elts *inv_elts; + struct master *master_ptr; + struct master *master_alk_ptr; + struct elt_list *elt_list_ptr; + master_alk_ptr = master_bsearch("Alkalinity"); + for (i = 0; i < count_inverse; i++) { + if (inverse[i].new_def != TRUE) continue; +/* + * Set default uncertainties for all solutions, if necessary + */ + if (inverse[i].count_uncertainties < inverse[i].count_solns) { + inverse[i].uncertainties = (LDBLE *)PHRQ_realloc(inverse[i].uncertainties, (size_t) inverse[i].count_solns * sizeof (LDBLE)); + if (inverse[i].uncertainties == NULL) malloc_error(); + for (j = inverse[i].count_uncertainties; j < inverse[i].count_solns; j++) { + inverse[i].uncertainties[j] = inverse[i].uncertainties[inverse[i].count_uncertainties - 1]; + } + } +/* + * Set default ph uncertainties for all solutions, if necessary + */ + if (inverse[i].count_ph_uncertainties < inverse[i].count_solns) { + inverse[i].ph_uncertainties = (LDBLE *)PHRQ_realloc(inverse[i].ph_uncertainties, (size_t) inverse[i].count_solns * sizeof (LDBLE)); + if ( inverse[i].ph_uncertainties == NULL) malloc_error(); + for (j = inverse[i].count_ph_uncertainties; j < inverse[i].count_solns; j++) { + inverse[i].ph_uncertainties[j] = inverse[i].ph_uncertainties[inverse[i].count_ph_uncertainties - 1]; + } + } +/* + * Set default force for all solutions + */ + if (inverse[i].count_force_solns < inverse[i].count_solns) { + inverse[i].force_solns = (int *) PHRQ_realloc(inverse[i].force_solns, (size_t) inverse[i].count_solns * sizeof (int)); + if (inverse[i].force_solns == NULL) malloc_error(); + for (j = inverse[i].count_force_solns; j < inverse[i].count_solns; j++) { + inverse[i].force_solns[j] = FALSE; + } + } +/* + * Find master species for element, set uncertainties + */ + for (j = 0; j < inverse[i].count_elts; j++) { + inverse[i].elts[j].master = master_bsearch_primary(inverse[i].elts[j].name); + if (inverse[i].elts[j].master == NULL) { + input_error++; + sprintf(error_string, "No master species for element, %s.", inverse[i].elts[j].name); + error_msg(error_string, CONTINUE); + continue; + } + inverse[i].elts[j].uncertainties = (double *) PHRQ_realloc(inverse[i].elts[j].uncertainties, (size_t) inverse[i].count_solns * sizeof (LDBLE)); + if (inverse[i].elts[j].uncertainties == NULL) malloc_error(); + if (inverse[i].elts[j].count_uncertainties == 0) { +/* use default uncertainties for element */ + for (k=0; k < inverse[i].count_solns; k++) { + inverse[i].elts[j].uncertainties[k] = inverse[i].uncertainties[k]; + } + } else if (inverse[i].elts[j].count_uncertainties < inverse[i].count_solns) { +/* use input uncertainties, fill in any missing at end */ + value = inverse[i].elts[j].uncertainties[inverse[i].elts[j].count_uncertainties - 1]; + for (k=inverse[i].elts[j].count_uncertainties; k < inverse[i].count_solns; k++) { + inverse[i].elts[j].uncertainties[k] = value; + } + } + } +/* + * Find phase + */ + count_elts = 0; + paren_count = 0; + for (j = 0; j < inverse[i].count_phases; j++) { + inverse[i].phases[j].phase = phase_bsearch(inverse[i].phases[j].name, &k, FALSE); + if (inverse[i].phases[j].phase == NULL) { + input_error++; + sprintf(error_string, "Could not find phase, %s.", inverse[i].phases[j].name); + error_msg(error_string, CONTINUE); + continue; + } +/* + * Find isotope elements + */ + if (inverse[i].phases[j].count_isotopes > 0) { + for (k = 0; k < inverse[i].phases[j].count_isotopes; k++) { + inverse[i].phases[j].isotopes[k].primary = NULL; + inverse[i].phases[j].isotopes[k].master = NULL; + master_ptr = master_bsearch(inverse[i].phases[j].isotopes[k].elt_name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Element not found for isotope calculation: %s.", + inverse[i].phases[j].isotopes[k].elt_name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->primary != TRUE) { + input_error++; + sprintf(error_string, "Isotope ratio may only be used" + " for total element in phase.\n" + "Secondary species not allowed: %s.", + master_ptr->elt->name); + error_msg(error_string, CONTINUE); + continue; + } + inverse[i].phases[j].isotopes[k].primary = master_ptr; + inverse[i].phases[j].isotopes[k].master = master_ptr; + /* find coefficient for element */ + for (elt_list_ptr=inverse[i].phases[j].phase->next_elt; + elt_list_ptr->elt != NULL; elt_list_ptr++) { + if (elt_list_ptr->elt == master_ptr->elt) { + inverse[i].phases[j].isotopes[k].coef = elt_list_ptr->coef; + break; + } + } + if (elt_list_ptr == NULL) { + input_error++; + sprintf(error_string, "Element, %s,for which isotope ratio was defined is not found in phase, %s", + master_ptr->elt->name, inverse[i].phases[j].phase->name); + error_msg(error_string, CONTINUE); + continue; + } + } + qsort (inverse[i].phases[j].isotopes, + (size_t) inverse[i].phases[j].count_isotopes, + (size_t) sizeof(struct isotope), + isotope_compare); + } + add_elt_list(inverse[i].phases[j].phase->next_elt, 1.0); + + } + if (input_error > 0) return(ERROR); +/* + * Sort elements in reaction and combine + */ + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } +/* + * Mark master species list + */ + for (j=0; j < count_master; j++) master[j]->in = FALSE; + for (j=0; j < count_elts; j++) { + elt_list[j].elt->master->in = TRUE; + } + /* Include all input elements */ + for (j = 0; j < inverse[i].count_elts; j++) { + inverse[i].elts[j].master->in = TRUE; + } + s_eminus->primary->in = TRUE; /* Include electrons */ + master_alk_ptr->in = TRUE; /* Include alkalinity */ +/* + * Unmark primary and mark secondary master species for redox elements + */ + count_in = 0; + inverse[i].count_redox_rxns = 0; + for (j=0; j < count_master; j++) { + /* skip all secondary master species in this loop */ + if (master[j]->primary == FALSE || master[j]->in == FALSE ) continue; + count_in++; + if (j+1 == count_master) continue; + /* if next master species is secondary, mark all + secondary master species until a primary is found */ + if (master[j+1]->primary == FALSE) { + master[j]->in = FALSE; + count_in--; + for (k=j+1; k < count_master; k++) { + if (master[k]->primary == FALSE) { + count_in++; + master[k]->in = TRUE; + if (master[k]->s->primary == NULL) { + inverse[i].count_redox_rxns++; + } + } else { + break; + } + } + } + } +/* + * Save list of master species in inv_elts structure + */ + inv_elts = (struct inv_elts *) PHRQ_malloc( (size_t) (count_in) * sizeof(struct inv_elts)); + if (inv_elts == NULL) malloc_error(); + count_in = 0; + for (j=0; j < count_master; j++) { + /* skip H(1) and O(-2) */ + if (master[j]->s == s_hplus || master[j]->s == s_h2o) continue; + if (master[j]->in == TRUE) { + /* set master */ + inv_elts[count_in].master = master[j]; + /* alloc uncertainties and set default */ + inv_elts[count_in].uncertainties = (double *) PHRQ_malloc((size_t) inverse[i].count_solns * sizeof(LDBLE)); + if (inv_elts[count_in].uncertainties == NULL) malloc_error(); + for(k=0; k < inverse[i].count_solns; k++) { + inv_elts[count_in].uncertainties[k] = inverse[i].uncertainties[k]; + } + count_in++; + } + } + if (s_co3->secondary->in == TRUE) { + inverse[i].carbon = TRUE; + } else { + inverse[i].carbon = FALSE; + } +/* + * copy in input uncertainties + */ + /* copy primary redox to all secondary redox */ + for (j=0; j < inverse[i].count_elts; j++) { + master_ptr = master_bsearch(inverse[i].elts[j].name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Element not found, %s.", inverse[i].elts[j].name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->primary == FALSE || master_ptr->s->secondary == NULL) continue; + for (k=0; k < count_in; k++) { + if (master_ptr == inv_elts[k].master->elt->primary) { + for (l=0; l < inverse[i].count_solns; l++) { + inv_elts[k].uncertainties[l] = inverse[i].elts[j].uncertainties[l]; + } + } + } + inverse[i].elts[j].uncertainties = (double *) free_check_null(inverse[i].elts[j].uncertainties); + } + /* copy masters that are not primary redox */ + for (j=0; j < inverse[i].count_elts; j++) { + master_ptr = master_bsearch(inverse[i].elts[j].name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Element not found, %s.", inverse[i].elts[j].name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->primary == TRUE && master_ptr->s->secondary != NULL) continue; + for (k=0; k < count_in; k++) { + if (master_ptr == inv_elts[k].master) { + for(l=0; l < inverse[i].count_solns; l++) { + inv_elts[k].uncertainties[l] = inverse[i].elts[j].uncertainties[l]; + } + break; + } + } + inverse[i].elts[j].uncertainties = (double *) free_check_null(inverse[i].elts[j].uncertainties); + } +/* + * replace elts in inverse struct + */ + inverse[i].elts = (struct inv_elts *) free_check_null(inverse[i].elts); + inverse[i].elts = inv_elts; + inverse[i].count_elts = count_in; + for (j = 0; j < inverse[i].count_elts; j++) { +#ifdef SKIP +/* make another pointer alkalinity uncertainties */ + if (inverse[i].elts[j].master == master_alk_ptr) { + inverse[i].alk_uncertainties = free_check_null(inverse[i].alk_uncertainties); + inverse[i].alk_uncertainties = inverse[i].elts[j].uncertainties; + } +#endif +/* debug + output_msg(OUTPUT_MESSAGE, "\t%d\t%s", j, inverse[i].elts[j].master->elt->name); + for (k = 0; k < inverse[i].count_solns; k++) { + output_msg(OUTPUT_MESSAGE, "\t%f", inverse[i].elts[j].uncertainties[k]); + } + output_msg(OUTPUT_MESSAGE,"\n"); + */ + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_phases(void) +/* ---------------------------------------------------------------------- */ +{ + int i; +/* + * Rewrite all phases to secondary species + */ + for (i=0; i < count_phases; i++) { +/* + * Check equation + */ + if (phases[i]->check_equation == TRUE) { + phase_rxn_to_trxn(phases[i]); + if (check_eqn(FALSE) == ERROR) { + input_error++; + sprintf(error_string, "Equation for phase %s does not balance.", + phases[i]->name); + error_msg(error_string, CONTINUE); + } + } +/* + * Rewrite equation + */ + select_log_k_expression(phases[i]->logk, phases[i]->rxn->logk); + add_other_logk(phases[i]->rxn->logk, phases[i]->count_add_logk, phases[i]->add_logk); + count_trxn=0; + trxn_add (phases[i]->rxn, 1.0, FALSE); + trxn_reverse_k(); + rewrite_eqn_to_secondary(); + trxn_reverse_k(); + rxn_free (phases[i]->rxn_s); + phases[i]->rxn_s = rxn_alloc(count_trxn+1); + trxn_copy (phases[i]->rxn_s); + /* debug + trxn_print(); + */ + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_pp_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, l, n_user, first, last; + struct phase *phase_ptr; + LDBLE coef; + char *ptr; +/* + * Find pointers for pure phases + */ + for ( i = 0; i < count_pp_assemblage; i++) { + count_elts = 0; + paren_count = 0; + coef = 1.0; + pp_assemblage[i].new_def = FALSE; + for (j=0; j < pp_assemblage[i].count_comps; j++) { + phase_ptr = phase_bsearch(pp_assemblage[i].pure_phases[j].name, &k, FALSE); + if (phase_ptr == NULL) { + input_error++; + sprintf(error_string, "Phase not found in data base, %s.", pp_assemblage[i].pure_phases[j].name); + error_msg(error_string, CONTINUE); + continue; + } else { + pp_assemblage[i].pure_phases[j].phase = phase_ptr; + add_elt_list(phase_ptr->next_elt, coef); + + } + if (pp_assemblage[i].pure_phases[j].add_formula != NULL) { + first = count_elts; + phase_ptr = phase_bsearch(pp_assemblage[i].pure_phases[j].add_formula, &k, FALSE); + if (phase_ptr != NULL) { + pp_assemblage[i].pure_phases[j].add_formula = phase_ptr->formula; + } + ptr = pp_assemblage[i].pure_phases[j].add_formula; + get_elts_in_species(&ptr, coef); + /* check that all elements are in the database */ + for (l = first; l < count_elts; l++) { + if (elt_list[l].elt->master == NULL) { + input_error++; + sprintf(error_string, "Element \"%s\" in alternative phase for \"%s\" in EQUILIBRIUM_PHASES not found in database.", elt_list[l].elt->name, pp_assemblage[i].pure_phases[j].name); + error_msg(error_string, CONTINUE); + } + } + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine (); + } + pp_assemblage[i].next_elt = (struct elt_list *) free_check_null(pp_assemblage[i].next_elt); + pp_assemblage[i].next_elt = elt_list_save(); + +/* + * Store list with all elements in phases and add formulae + */ + +/* + * Duplicate pure phases if necessary + */ + if ( pp_assemblage[i].n_user_end > pp_assemblage[i].n_user ) { + n_user = pp_assemblage[i].n_user; + last = pp_assemblage[i].n_user_end; + pp_assemblage[i].n_user_end = pp_assemblage[i].n_user; + for (j = n_user + 1; j <= last; j++) { + pp_assemblage_duplicate(n_user, j); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_s_s_assemblage(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, k1, n_user, last; + struct phase *phase_ptr; + struct s_s *s_s_ptr; + LDBLE nb, nc, n_tot, xb, xc, dnb, dnc, a0, a1; + LDBLE xb2, xb3, xb4, xc2, xc3; + LDBLE moles; +/* + * Find pointers for pure phases + */ + for ( i = 0; i < count_s_s_assemblage; i++) { + count_elts = 0; + paren_count = 0; + for (j=0; j < s_s_assemblage[i].count_s_s; j++) { + for (k=0; k < s_s_assemblage[i].s_s[j].count_comps; k++) { + phase_ptr = phase_bsearch(s_s_assemblage[i].s_s[j].comps[k].name, &k1, FALSE); + if (phase_ptr == NULL) { + input_error++; + sprintf(error_string, "Phase not found in data base, %s, assemblage %d.", s_s_assemblage[i].s_s[j].comps[k].name, s_s_assemblage[i].n_user); + error_msg(error_string, CONTINUE); + s_s_assemblage[i].s_s[j].comps[k].phase = NULL; + continue; + } else { + s_s_assemblage[i].s_s[j].comps[k].phase = phase_ptr; + s_s_assemblage[i].s_s[j].comps[k].phase->moles_x = 0; + s_s_assemblage[i].s_s[j].comps[k].phase->fraction_x = 0; + } + if (s_s_assemblage[i].s_s[j].comps[k].moles == NAN) { + input_error++; + sprintf(error_string, "Moles of solid solution component not defined, %s, assemblage %d.", s_s_assemblage[i].s_s[j].comps[k].name, s_s_assemblage[i].n_user); + error_msg(error_string, CONTINUE); + continue; + } + } + + if (s_s_assemblage[i].new_def == TRUE) { + /* + * Calculate a0 and a1 first + */ + s_s_calc_a0_a1(&(s_s_assemblage[i].s_s[j])); + s_s_ptr = &(s_s_assemblage[i].s_s[j]); + + n_tot = 0; + for (k = 0; k < s_s_ptr->count_comps; k++) { + moles = s_s_assemblage[i].s_s[j].comps[k].moles; + if (s_s_assemblage[i].s_s[j].comps[k].moles <= 0.0) { + moles = MIN_TOTAL; + s_s_assemblage[i].s_s[j].comps[k].initial_moles = moles; + } + n_tot += moles; + } + + for (k = 0; k < s_s_ptr->count_comps; k++) { + moles = s_s_assemblage[i].s_s[j].comps[k].moles; + if (s_s_assemblage[i].s_s[j].comps[k].moles <= 0.0) { + moles = MIN_TOTAL; + } + s_s_assemblage[i].s_s[j].comps[k].fraction_x = moles / n_tot; + s_s_assemblage[i].s_s[j].comps[k].log10_fraction_x = log10(moles / n_tot); + } + a0 = s_s_assemblage[i].s_s[j].a0; + a1 = s_s_assemblage[i].s_s[j].a1; + +/* + * Binary solid solution + */ + if (a0 != 0.0 || a1 != 0) { + s_s_assemblage[i].s_s[j].dn = 1.0 / n_tot; + nc = s_s_assemblage[i].s_s[j].comps[0].moles; + if (nc == 0) nc = MIN_TOTAL; + nb = s_s_assemblage[i].s_s[j].comps[1].moles; + if (nb == 0) nb = MIN_TOTAL; + xc = nc/n_tot; + xb = nb/n_tot; + + /* lambdas */ + s_s_assemblage[i].s_s[j].comps[0].log10_lambda = xb*xb*(a0 - a1*(3 -4*xb))/LOG_10; + s_s_assemblage[i].s_s[j].comps[1].log10_lambda = xc*xc*(a0 + a1*(4*xb - 1))/LOG_10; + + /* derivatives wrt nc and nb */ + xc2 = xc*xc; + xc3 = xc2*xc; + xb2 = xb*xb; + xb3 = xb2*xb; + xb4 = xb3*xb; + + /* component 1 */ + dnb = -2*a0*xb*xc2 - 8*a1*xb2*xc2 + 6*a1*xb*xc2 - 4*a1*xc*xb4 - 8*a1*xb3*xc2 - + 4*a1*xb2*xc3 - 2*a0*xc*xb2 - 8*a1*xc*xb3 + 6*a1*xc*xb2 + 1; + s_s_assemblage[i].s_s[j].comps[0].dnb = dnb/n_tot; + dnc = 2*a0*xb3 + 2*a0*xc*xb2 + 8*a1*xb4 + 8*a1*xc*xb3 - 2*a1*xb3 - 6*a1*xc*xb2; + s_s_assemblage[i].s_s[j].comps[0].dnc = - xb/nc + dnc/n_tot; + s_s_assemblage[i].s_s[j].comps[0].dn = 1.0 / n_tot; + + /* component 2*/ + dnb = 2*a0*xb*xc2 + 2*a0*xc3 + 8*a1*xb2*xc2 + 8*a1*xb*xc3 - 2*a1*xb*xc2 -6*a1*xc3; + s_s_assemblage[i].s_s[j].comps[1].dnb = -xc/nb + dnb/n_tot; + dnc = -2*a0*xc*xb2 - 8*a1*xc*xb3 + 2*a1*xc*xb2 - 2*a0*xb*xc2 - 8*a1*xb2*xc2 + 6*a1*xb*xc2 + 1; + s_s_assemblage[i].s_s[j].comps[1].dnc = dnc/n_tot; + s_s_prep(s_s_assemblage[i].s_s[j].tk, &(s_s_assemblage[i].s_s[j]), TRUE); + s_s_assemblage[i].s_s[j].comps[1].dn = 1.0 / n_tot; +/* + * Ideal solid solution + */ + } else { + s_s_assemblage[i].s_s[j].dn = 1.0 / n_tot; + for (k = 0; k < s_s_ptr->count_comps; k++) { + s_s_assemblage[i].s_s[j].comps[k].log10_lambda = 0; + moles = s_s_assemblage[i].s_s[j].comps[k].moles; + if (moles <= 0.0) moles = MIN_TOTAL; + s_s_assemblage[i].s_s[j].comps[k].dnb = (n_tot - moles)/(moles*n_tot); + s_s_assemblage[i].s_s[j].comps[k].dn = 1.0 / n_tot; + } + } + } + } + s_s_assemblage[i].new_def = FALSE; + +/* + * Duplicate s_s_assemblage if necessary + */ + n_user = s_s_assemblage[i].n_user; + last = s_s_assemblage[i].n_user_end; + s_s_assemblage[i].n_user_end = s_s_assemblage[i].n_user; + for (j = n_user + 1; j <= last; j++) { + s_s_assemblage_duplicate(n_user, j); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_punch(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, l; + char token[MAX_LENGTH]; +/* + * tidy punch information + */ + if (punch.high_precision == FALSE) { + l = 12; + } else { + l = 20; + } + if (punch.in == TRUE && pr.punch == TRUE) { + /* totals */ + + for (i = 0; i < punch.count_totals; i++) { + punch.totals[i].master = master_bsearch(punch.totals[i].name); + } + + /* molalities */ + + for (i = 0; i < punch.count_molalities; i++) { + punch.molalities[i].s = s_search(punch.molalities[i].name); + } + + /* log activities */ + + for (i = 0; i < punch.count_activities; i++) { + punch.activities[i].s = s_search(punch.activities[i].name); + } + + /* equilibrium phases */ + + for (i = 0; i < punch.count_pure_phases; i++) { + punch.pure_phases[i].phase = phase_bsearch(punch.pure_phases[i].name, &j, FALSE); + } + + /* saturation indices */ + + for (i = 0; i < punch.count_si; i++) { + punch.si[i].phase = phase_bsearch(punch.si[i].name, &j, FALSE); + } + + /* gases */ + + for (i = 0; i < punch.count_gases; i++) { + punch.gases[i].phase = phase_bsearch(punch.gases[i].name, &j, FALSE); + } + } + if (punch.new_def == TRUE && punch.in == TRUE && pr.punch == TRUE) { + + /* constant stuff, sim, pH, etc. */ + + if (punch.sim == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "sim"); + } + if (punch.state == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "state"); + } + if (punch.soln == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "soln"); + } + if (punch.dist == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "dist_x"); + } + if (punch.time == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "time"); + } + if (punch.step == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "step"); + } + if (punch.ph == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "pH"); + } + if (punch.pe == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "pe"); + } + if (punch.rxn == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "reaction"); + } + if (punch.temp == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "temp"); + } + if (punch.alk == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "Alk"); + } + if (punch.mu == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "mu"); + } + if (punch.water == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "mass_H2O"); + } + if (punch.charge_balance == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "charge"); + } + if (punch.percent_error == TRUE) { + output_msg(OUTPUT_PUNCH, "%*s\t", l, "pct_err"); + } + /* totals */ + + for (i = 0; i < punch.count_totals; i++) { + output_msg(OUTPUT_PUNCH,"%*s\t", l, punch.totals[i].name); + if (punch.totals[i].master == NULL) { + sprintf(error_string, "Did not find master species," + " %s.", punch.totals[i].name); + warning_msg(error_string); + } + } + + /* molalities */ + + for (i = 0; i < punch.count_molalities; i++) { + strcpy(token,"m_"); + strcat(token, punch.molalities[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + if (punch.molalities[i].s == NULL) { + sprintf(error_string, "Did not find species," + " %s.", punch.molalities[i].name); + warning_msg(error_string); + } + } + + /* log activities */ + + for (i = 0; i < punch.count_activities; i++) { + strcpy(token,"la_"); + strcat(token, punch.activities[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + if (punch.activities[i].s == NULL) { + sprintf(error_string, "Did not find species, " + "%s.", punch.activities[i].name); + warning_msg(error_string); + } + } + + /* equilibrium phases */ + + for (i = 0; i < punch.count_pure_phases; i++) { + strcpy(token,"d_"); + strcat(token, punch.pure_phases[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t%*s\t", l, punch.pure_phases[i].name, l, token); + if (punch.pure_phases[i].phase == NULL) { + sprintf(error_string, "Did not find phase, " + "%s.", punch.pure_phases[i].name); + warning_msg(error_string); + } + } + + /* saturation indices */ + + for (i = 0; i < punch.count_si; i++) { + strcpy(token,"si_"); + strcat(token, punch.si[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + if (punch.si[i].phase == NULL) { + sprintf(error_string, "Did not find phase, " + "%s.", punch.si[i].name); + warning_msg(error_string); + } + } + + /* gases */ + + if (punch.count_gases > 0) { + output_msg(OUTPUT_PUNCH, "%*s\t%*s\t%*s\t", l, "pressure", l, "total mol", l, "volume"); + } + for (i = 0; i < punch.count_gases; i++) { + strcpy(token,"g_"); + strcat(token, punch.gases[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + if (punch.gases[i].phase == NULL) { + sprintf(error_string, "Did not find phase, " + "%s.", punch.gases[i].name); + warning_msg(error_string); + } + } + + /* kinetics */ + + for (i = 0; i < punch.count_kinetics; i++) { + strcpy(token,"k_"); + strcat(token, punch.kinetics[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + strcpy(token,"dk_"); + strcat(token, punch.kinetics[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + } + + /* solid solutions */ + + for (i = 0; i < punch.count_s_s; i++) { + strcpy(token,"s_"); + strcat(token, punch.s_s[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + } + + /* isotopes */ + + for (i = 0; i < punch.count_isotopes; i++) { + if (isotope_ratio_search(punch.isotopes[i].name) == NULL) { + sprintf(error_string, "Did not find isotope_ratio definition for " + "%s in -isotopes of SELECTED_OUTPUT.\n%s must be defined in ISOTOPE_RATIO data block.", punch.isotopes[i].name, punch.isotopes[i].name); + warning_msg(error_string); + } + strcpy(token,"I_"); + strcat(token, punch.isotopes[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + } + + /* calculate_values */ + + for (i = 0; i < punch.count_calculate_values; i++) { + if (calculate_value_search(punch.calculate_values[i].name) == NULL) { + sprintf(error_string, "Did not find calculate_values definition for " + "%s in -calculate_values of SELECTED_OUTPUT.\n%s must be defined in CALCULATE_VALUES data block.", punch.calculate_values[i].name, punch.calculate_values[i].name); + warning_msg(error_string); + } + strcpy(token,"V_"); + strcat(token, punch.calculate_values[i].name); + output_msg(OUTPUT_PUNCH,"%*s\t", l, token); + } + + /* user_punch */ + if (punch.user_punch == TRUE) { + for (i = 0; i < user_punch_count_headings; i++) { + output_msg(OUTPUT_PUNCH,"%*s\t", l, user_punch_headings[i]); + } + } + output_msg(OUTPUT_PUNCH,"\n"); + punch.new_def = FALSE; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_species(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + struct master *master_ptr; + char c, *ptr; +/* + * Make sure species pointers are ok + */ + if (check_species_input() == ERROR) { + error_msg("Calculations terminating due to input errors.", STOP); + } +/* + * Set secondary and primary pointers in species structures + */ + for (i=0; i < count_s; i++) { + s[i]->number = i; + s[i]->primary=NULL; + s[i]->secondary=NULL; + if (s[i]->check_equation == TRUE ) { + species_rxn_to_trxn(s[i]); + if (check_eqn(TRUE) == ERROR) { + input_error++; + sprintf(error_string, "Equation for species %s does not balance.", + s[i]->name); + error_msg(error_string, CONTINUE); + } + } + } + for (i=0; i < count_master; i++) { + ptr = master[i]->elt->name; + if (ptr[0] != '[') { + while ((c = (int) *(++ptr)) != '\0') { + if (isupper((int) c) ) { + input_error++; + sprintf(error_string, "Element or valence name in SOLUTION_MASTER_SPECIES should include only one element, %s.", master[i]->elt->name); + error_msg(error_string, CONTINUE); + break; + } + } + } + /* store sequence number in master structure */ + master[i]->number = i; + if (master[i]->primary == TRUE) { + master[i]->s->primary=master[i]; + } else { + master[i]->s->secondary=master[i]; + } + if (strcmp(master[i]->elt->name,"C") == 0) { + s_co3=master[i]->s; + } + if (master[i]->gfw_formula != NULL) { + if(compute_gfw(master[i]->gfw_formula, &master[i]->gfw) == ERROR){ + input_error++; + sprintf(error_string, "Calculating gfw for master species, %s, formula %s.", + master[i]->elt->name, master[i]->gfw_formula); + error_msg(error_string, CONTINUE); + } + } + } +/* + * Write equations for all master species in terms of primary + * master species, set coefficient of element in master species + */ + for (i=0; i < count_master; i++) { + count_trxn=0; + if ( master[i]->s->primary != NULL ) { + trxn_add(master[i]->s->rxn, 1.0, FALSE); + trxn_add(master[i]->s->rxn, -1.0, TRUE); + } else { + trxn_add(master[i]->s->rxn, 1.0, FALSE); + rewrite_eqn_to_primary(); + } + rxn_free(master[i]->rxn_primary); + master[i]->rxn_primary = rxn_alloc(count_trxn+1); + trxn_copy (master[i]->rxn_primary); + master[i]->coef = coef_in_master(master[i]); + } +/* + * Rewrite all species to secondary species + */ + for (i=0; i < count_s; i++) { + count_trxn=0; + if ( s[i]->primary != NULL || s[i]->secondary != NULL ) { + trxn_add (s[i]->rxn, 1.0, FALSE); + trxn_add (s[i]->rxn, -1.0, TRUE); + } else { + trxn_add (s[i]->rxn, 1.0, FALSE); + rewrite_eqn_to_secondary(); + } + rxn_free (s[i]->rxn_s); + s[i]->rxn_s = rxn_alloc(count_trxn+1); + trxn_copy (s[i]->rxn_s); + /* calculate alkalinity */ + s[i]->alk = calc_alk(s[i]->rxn_s); + /* set co2 coefficient */ + s[i]->co2 = 0.0; + for (j=1; j < count_trxn; j++) { + if (trxn.token[j].s == s_co3) { + s[i]->co2 = trxn.token[j].coef; + break; + } + } + } +/* + * Set pointer in element to master species + */ + for (i=0; i < count_elements; i++) { + elements[i]->master = master_bsearch(elements[i]->name); + if (elements[i]->master == NULL) { + input_error++; + sprintf(error_string, "No master species for element %s.", elements[i]->name); + error_msg(error_string, CONTINUE); + } + elements[i]->primary = master_bsearch_primary(elements[i]->name); + if (elements[i]->primary == NULL) { + input_error++; + sprintf(error_string, "No master species for element %s.", elements[i]->name); + error_msg(error_string, CONTINUE); + } + } +/* + * Make sure all primary master species for redox elements + * are also secondary master species + */ + for (i = 0; i < count_master; i++) { + if (master[i]->primary == FALSE) { + master_ptr = master[i]->s->secondary->elt->primary; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Every primary master species for a redox element\n" + "\tmust also be a secondary master species.\n" + "\tError in definitions related to %s .\n", + master[i]->s->name); + error_msg(error_string, CONTINUE); + + } else if (master_ptr->s->secondary == NULL) { + input_error++; + sprintf(error_string, "Every primary master species for a redox element\n" + "\tmust also be a secondary master species.\n" + "\t%s is the primary master species for element %s.\n" + "\tAnother entry in SOLUTION_MASTER_SPECIES is needed.\n" + "\tDefine species %s as a secondary master species for a valence state.\n" + "\tFor example: \n" + "\t%s(0)\t%s alk gfw", + master_ptr->s->name, master_ptr->elt->name, + master_ptr->s->name, master_ptr->elt->name, + master_ptr->s->name); + error_msg(error_string, CONTINUE); + } + } + } +/* + * Calculate H and O if alternate mass balance is given + */ + for (i = 0; i < count_s; i++) { + if (s[i]->next_secondary != NULL) { + s[i]->h = 0.0; + s[i]->o = 0.0; + for (j = 0; s[i]->next_secondary[j].elt != NULL; j++) { + if (s[i]->next_secondary[j].elt->primary == NULL) continue; + if (s[i]->next_secondary[j].elt->primary->s == s_hplus) { + s[i]->h += s[i]->next_secondary[j].coef; + } else if (s[i]->next_secondary[j].elt->primary->s == s_h2o) { + s[i]->o += s[i]->next_secondary[j].coef; + } else if (s[i]->mole_balance != NULL) { + master_ptr = s[i]->next_secondary[j].elt->master; + if (master_ptr->primary == TRUE) { + if (master_ptr->s->secondary != NULL) { + master_ptr = master_ptr->s->secondary; + } + } + if (master_ptr->coef != 1) { + s[i]->next_secondary[j].coef /= master_ptr->coef; + } + } + } + if (s[i]->type == EX) { + for (j = 0; s[i]->next_secondary[j].elt != NULL; j++) { + if (s[i]->next_secondary[j].elt->primary->s->type == EX) { + s[i]->equiv = s[i]->next_secondary[j].coef; + break; + } + } + } + } + } +#ifdef SKIP + for (i = 0; i < count_s; i++) { + if (match_elts_in_species(s[i]->name, "*{C,[13C]}{O,[18O]}3*") == TRUE) { + output_msg(OUTPUT_MESSAGE, "Match: %s\n", s[i]->name); + } + } +#endif + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_surface(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * After all of data are read, fill in master species for surface comps + * Sort surface + */ + int i, j, k; + struct surface *surface_ptr; + struct master *master_ptr; + + for (k = 0; k < count_surface; k++) { + surface_ptr = &surface[k]; + for (i = 0; i < surface_ptr->count_comps; i++ ) { +/* + * Find master species for each surface, setup unknown structure + */ + for (j = 0; surface_ptr->comps[i].totals[j].elt != NULL; j++) { + master_ptr = surface_ptr->comps[i].totals[j].elt->master; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Master species not in data base for %s, " + "skipping element.", surface_ptr->comps[i].totals[j].elt->name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != SURF) continue; +/* + * Set flags + */ + surface_ptr->comps[i].master = master_ptr; + break; + } + } +/* + * Sort components + */ + if (input_error == 0) { + qsort (surface[k].comps, + (size_t) surface_ptr->count_comps, + (size_t) sizeof(struct surface_comp), + surface_comp_compare); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_solutions(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Define n_user for any solutions read by solution_spread that + * don't have n_user defined + */ + int i, l, n, last; + struct conc *tot_ptr; + char *ptr; + struct master *master_ptr; + char token[MAX_LENGTH]; + for (n=0; n < count_solution; n++) { + /* + * Check that elements are in database + */ + if (solution[n] != NULL && solution[n]->new_def == TRUE) { + /* + * Sort totals by description + */ + i = 0; + while(solution[n]->totals[i].description != NULL) i++; + qsort (solution[n]->totals, + (size_t) i, + (size_t) sizeof(struct conc), + conc_compare); + /* + * sort isotopes + */ + if (solution[n]->count_isotopes > 0) { + qsort (solution[n]->isotopes, + (size_t) solution[n]->count_isotopes, + (size_t) sizeof(struct isotope), + isotope_compare); + } else { + solution[n]->isotopes = (struct isotope *) free_check_null(solution[n]->isotopes); + } + for ( i=0; solution[n]->totals[i].description != NULL; i++) { + tot_ptr=&(solution[n]->totals[i]); + if (strcmp(tot_ptr->description,"H(1)") == 0 || + strcmp(tot_ptr->description,"E" ) == 0 ) { + tot_ptr->moles = 0.0; + continue; + } + ptr = tot_ptr->description; + copy_token(token, &ptr, &l); + master_ptr = master_bsearch (token); + if (master_ptr == NULL) { + sprintf(error_string, "Could not find element in database, %s.\n\tConcentration is set to zero.", tot_ptr->description); + warning_msg(error_string); + tot_ptr->input_conc = 0.0; + continue; + } + } + } + } + /* + * Calculate solution numbers + */ + for (n=0; n < count_solution; n++) { + if (solution[n] != NULL && solution[n]->new_def == TRUE && solution[n]->n_user < 0) { + last = 0; + for (i=0; i < count_solution; i++) { + if (solution[i]->n_user > last) last = solution[i]->n_user; + if (solution[i]->n_user_end > last) last = solution[i]->n_user_end; + } + if (save.solution == TRUE) { + if (save.n_solution_user > last) last = save.n_solution_user; + if (save.n_solution_user_end > last) last = save.n_solution_user_end; + } + for (i=0; i < count_solution; i++) { + if (solution[i]->new_def == TRUE && solution[i]->n_user < 0) { + solution[i]->n_user = ++last; + solution[i]->n_user_end = last; + if (use.solution_in == TRUE && use.n_solution_user == -1) { + use.n_solution_user = last; + } + } + } + break; + } + } + solution_sort(); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int species_rxn_to_trxn(struct species *s_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copy reaction from reaction structure to + * temp reaction structure. + */ + int i; + + for (i = 0; s_ptr->rxn->token[i].s != NULL; i++) { + trxn.token[i].name = s_ptr->rxn->token[i].s->name; + trxn.token[i].z = s_ptr->rxn->token[i].s->z; + trxn.token[i].s = s_ptr->rxn->token[i].s; + trxn.token[i].unknown = NULL; + trxn.token[i].coef = s_ptr->rxn->token[i].coef; + count_trxn = i + 1; + if (count_trxn + 1 >= max_trxn) { + space ((void **) &(trxn.token), count_trxn+1, &max_trxn, + sizeof(struct rxn_token_temp)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int phase_rxn_to_trxn(struct phase *phase_ptr) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copy reaction from reaction structure to + * temp reaction structure. + */ + int i, l; + char *ptr; + char token[MAX_LENGTH]; + LDBLE z; + + trxn.token[0].name = phase_ptr->formula; + /* charge */ + ptr = phase_ptr->formula; + get_token ( &ptr, token, &z, &l); + trxn.token[0].z = z; + trxn.token[0].s = NULL; + trxn.token[0].unknown = NULL; + /*trxn.token[0].coef = -1.0;*/ + /* check for leading coefficient of 1.0 for phase did not work */ + trxn.token[0].coef = phase_ptr->rxn->token[0].coef; + for (i = 1; phase_ptr->rxn->token[i].s != NULL; i++) { + trxn.token[i].name = phase_ptr->rxn->token[i].s->name; + trxn.token[i].z = phase_ptr->rxn->token[i].s->z; + trxn.token[i].s = NULL; + trxn.token[i].unknown = NULL; + trxn.token[i].coef = phase_ptr->rxn->token[i].coef; + count_trxn = i + 1; + if (count_trxn + 1 >= max_trxn) { + space ((void **) &(trxn.token), count_trxn+1, &max_trxn, + sizeof(struct rxn_token_temp)); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_isotopes (void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Isotope ratios for each element or element valence state + */ + int i, j, k, l, n; + int count_isotopes, primary_number, count_primary; + LDBLE isotope_number; + struct master *master_ptr, *primary_ptr; + struct solution *solution_ptr; + struct isotope *new_isotopes; + struct isotope *primary_isotopes; + char token[MAX_LENGTH]; + + primary_number = 0; + primary_ptr = NULL; + for (n = 0; n < count_solution; n++) { + if (solution[n]->new_def != TRUE) continue; + if (solution[n]->count_isotopes == 0) continue; + solution_ptr = solution[n]; + primary_isotopes = (struct isotope *) PHRQ_malloc((size_t) (sizeof(struct isotope))); + if (primary_isotopes == NULL) malloc_error(); + count_primary = 0; + new_isotopes = (struct isotope *) PHRQ_malloc((size_t) (sizeof(struct isotope))); + if (new_isotopes == NULL) malloc_error(); + count_isotopes = 0; +/* + * Make list of primary master species for isotopes + */ + for (i = 0; i < solution_ptr->count_isotopes; i++) { + master_ptr = master_bsearch_primary(solution_ptr->isotopes[i].elt_name); + isotope_number = solution_ptr->isotopes[i].isotope_number; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "In isotope calculation: element not defined: %s.", + solution_ptr->isotopes[i].elt_name); + error_msg(error_string, CONTINUE); + continue; + } + for (j = 0; j < count_primary; j++) { + if (primary_isotopes[j].master == master_ptr && + primary_isotopes[j].isotope_number == isotope_number) break; + } + if (j == count_primary) { + primary_isotopes = (struct isotope *) PHRQ_realloc(primary_isotopes, (size_t) (count_primary + 1) * sizeof(struct isotope)); + if (primary_isotopes == NULL) malloc_error(); + primary_isotopes[count_primary].master = master_ptr; + primary_isotopes[count_primary].isotope_number = isotope_number; + count_primary++; + } + } + if (input_error > 0) return(ERROR); +/* + * Go through all redox states of the list of primary species and isotope number + */ + for (j = 0; j < count_primary; j++) { + + /* find index number of master species, set flag to FALSE */ + master_ptr = primary_isotopes[j].master; + isotope_number = primary_isotopes[j].isotope_number; + for (k = 0; k < count_master; k++) { + if (master[k] == master_ptr) { + primary_number = k; + primary_ptr = master[k]; + } + master[k]->isotope = FALSE; + } + + /* go through isotopes of solution and fill in master species */ + for (l = 0; l < solution_ptr->count_isotopes; l++) { + master_ptr = master_bsearch(solution_ptr->isotopes[l].elt_name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "In isotope calculation: element not defined: %s.", + solution_ptr->isotopes[l].elt_name); + error_msg(error_string, CONTINUE); + continue; + } + + /* only fill for pertinent isotope */ + if (master_ptr->elt->primary != primary_ptr) continue; + if (solution_ptr->isotopes[l].isotope_number != isotope_number) continue; + + /* for primary, fill in ratio for all secondary species */ + if (master_ptr->primary == TRUE && master_ptr->s->secondary != NULL ) { + for (k = primary_number + 1; k < count_master; k++) { + if (master[k]->elt->primary != primary_ptr) break; + master[k]->isotope_ratio = solution_ptr->isotopes[l].ratio; + master[k]->isotope_ratio_uncertainty = solution_ptr->isotopes[l].ratio_uncertainty; + if (master[k]->isotope == TRUE) { + sprintf(error_string, "In isotope calculation: redefinition of isotope ratio for %s.", solution_ptr->isotopes[l].elt_name); + error_msg(error_string, CONTINUE); + } + master[k]->isotope = TRUE; + } + + /* for secondary and non redox, set ratio */ + } else { + master_ptr->isotope_ratio = solution_ptr->isotopes[l].ratio; + master_ptr->isotope_ratio_uncertainty = solution_ptr->isotopes[l].ratio_uncertainty; + if (master_ptr->isotope == TRUE) { + sprintf(error_string, "In isotope calculation: redefinition of isotope ratio for %s.", solution_ptr->isotopes[l].elt_name); + error_msg(error_string, CONTINUE); + } + master_ptr->isotope = TRUE; + } + } +/* + * Write new isotope structure + */ + for (k = 0; k < count_master; k++) { + /* skip primary master species of redox elements */ + if (master[k]->primary == TRUE && + master[k]->s->secondary != NULL) continue; + if (master[k]->elt->primary == primary_ptr && master[k]->isotope == FALSE) { + input_error++; + sprintf(error_string, "Isotopic ratio not defined for element or valence state %g%s.", (double) isotope_number, master[k]->elt->name); + error_msg(error_string, CONTINUE); + } + if (master[k]->isotope == FALSE) continue; + new_isotopes = (struct isotope *) PHRQ_realloc(new_isotopes, (size_t) (count_isotopes + 1) * sizeof(struct isotope)); + if (new_isotopes == NULL) malloc_error(); + new_isotopes[count_isotopes].master = master[k]; + new_isotopes[count_isotopes].primary = primary_ptr; + new_isotopes[count_isotopes].isotope_number = isotope_number; + new_isotopes[count_isotopes].elt_name = master[k]->elt->name; + new_isotopes[count_isotopes].total = 0; + new_isotopes[count_isotopes].ratio = master[k]->isotope_ratio; + new_isotopes[count_isotopes].ratio_uncertainty = master[k]->isotope_ratio_uncertainty; + sprintf(token,"%d%s", (int) isotope_number, master[k]->elt->name); + new_isotopes[count_isotopes].isotope_name = string_hsave(token); + count_isotopes++; + } + } + primary_isotopes = (struct isotope *) free_check_null(primary_isotopes); + solution_ptr->isotopes = (struct isotope *) free_check_null(solution_ptr->isotopes); + solution_ptr->isotopes = new_isotopes; + solution_ptr->count_isotopes = count_isotopes; + qsort (solution_ptr->isotopes, + (size_t) count_isotopes, + (size_t) sizeof(struct isotope), + isotope_compare); + } + + return (OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_kin_exchange(void) +/* ---------------------------------------------------------------------- */ +/* + * If exchanger is related to mineral, exchanger amount is + * set in proportion + */ +{ + int i, j, k, n; + struct kinetics *kinetics_ptr; + struct exch_comp *comp_ptr; + struct master *master_ptr; + char *ptr; + LDBLE conc; + + for (i=0; i < count_exchange; i++) { + if (exchange[i].new_def == FALSE) continue; + if (exchange[i].n_user < 0) continue; + for (j = 0; j < exchange[i].count_comps; j++) { + if (exchange[i].comps[j].rate_name == NULL) continue; + comp_ptr = &exchange[i].comps[j]; + comp_ptr->master = NULL; + n = exchange[i].n_user; + + /* First find exchange master species */ + + for (k=0; comp_ptr->totals[k].elt != NULL; k++) { + /* Find master species */ + master_ptr = comp_ptr->totals[k].elt->master; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Master species not in data " + "base for %s, skipping element.", + comp_ptr->totals[k].elt->name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != EX) continue; + comp_ptr->master = master_ptr; + break; + } + if (comp_ptr->master == NULL) { + input_error++; + sprintf(error_string, "Exchange formula does not contain an exchange master species, %s", comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + + /* Now find associated kinetic reaction ... */ + if ((kinetics_ptr=kinetics_bsearch(n, &k)) == NULL) { + input_error++; + sprintf(error_string, "Kinetics %d must be defined to use exchange related to kinetic reaction, %s", n, comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + for (k=0; kcount_comps; k++) { + if (strcmp_nocase(comp_ptr->rate_name, kinetics_ptr->comps[k].rate_name) == 0) { + break; + } + } + if (k == kinetics_ptr->count_comps) { + input_error++; + sprintf(error_string,"Kinetic reaction, %s, related to exchanger, %s, not found in KINETICS %d", comp_ptr->rate_name, comp_ptr->formula, n); + error_msg(error_string, CONTINUE); + continue; + } + + /* use database name for phase */ + comp_ptr->rate_name = kinetics_ptr->comps[k].rate_name; + + /* make exchanger concentration proportional to mineral ... */ + conc=kinetics_ptr->comps[k].m * comp_ptr->phase_proportion; + + count_elts = 0; + paren_count = 0; + ptr = comp_ptr->formula; + get_elts_in_species(&ptr, conc); + comp_ptr->totals = (struct elt_list *) free_check_null(comp_ptr->totals); + comp_ptr->totals = elt_list_save(); +/* + * No check on availability of exchange elements + */ + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_min_exchange(void) +/* ---------------------------------------------------------------------- */ +/* + * If exchanger is related to mineral, exchanger amount is + * set in proportion + */ +{ + int i, j, k, n, jj; + struct pp_assemblage *pp_a_ptr; + struct exch_comp *comp_ptr; + struct master *master_ptr; + char *ptr; + LDBLE conc; + + for (i=0; i < count_exchange; i++) { + if (exchange[i].new_def == FALSE) continue; + if (exchange[i].n_user < 0) continue; + for (j = 0; j < exchange[i].count_comps; j++) { + if (exchange[i].comps[j].phase_name == NULL) continue; + comp_ptr = &exchange[i].comps[j]; + comp_ptr->master = NULL; + n = exchange[i].n_user; + + /* First find exchange master species */ + + for (k=0; comp_ptr->totals[k].elt != NULL; k++) { + /* Find master species */ + master_ptr = comp_ptr->totals[k].elt->master; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Master species not in data " + "base for %s, skipping element.", + comp_ptr->totals[k].elt->name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != EX) continue; + comp_ptr->master = master_ptr; + break; + } + if (comp_ptr->master == NULL) { + input_error++; + sprintf(error_string, "Exchange formula does not contain an exchange master species, %s", comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + + /* Now find the mineral on which exchanger depends... */ + if ((pp_a_ptr=pp_assemblage_bsearch(n, &k)) == NULL) { + input_error++; + sprintf(error_string, "Equilibrium_phases %d must be defined to use exchange related to mineral phase, %s", n, comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + for (k=0; kcount_comps; k++) { + if (strcmp_nocase(comp_ptr->phase_name, pp_a_ptr->pure_phases[k].name) == 0) { + break; + } + } + if (k == pp_a_ptr->count_comps) { + input_error++; + sprintf(error_string,"Mineral, %s, related to exchanger, %s, not found in Equilibrium_Phases %d", comp_ptr->phase_name, comp_ptr->formula, n); + error_msg(error_string, CONTINUE); + continue; + } + /* use database name for phase */ + comp_ptr->phase_name = pp_a_ptr->pure_phases[k].phase->name; + /* make exchanger concentration proportional to mineral ... */ + conc=pp_a_ptr->pure_phases[k].moles * comp_ptr->phase_proportion; + count_elts = 0; + paren_count = 0; + ptr = comp_ptr->formula; + get_elts_in_species(&ptr, conc); + comp_ptr->totals = (struct elt_list *) free_check_null(comp_ptr->totals); + comp_ptr->totals = elt_list_save(); +/* + * make sure exchange elements are in phase + */ + count_elts = 0; + paren_count = 0; + ptr = comp_ptr->formula; + get_elts_in_species(&ptr, -comp_ptr->phase_proportion); + ptr = pp_a_ptr->pure_phases[k].phase->formula; + get_elts_in_species(&ptr, 1.0); + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + for (jj = 0; jj < count_elts; jj++) { + if (elt_list[jj].elt->primary->s->type != EX && elt_list[jj].coef < 0) { + input_error++; + sprintf(error_string,"Stoichiometry of exchanger, %s * %g mol sites/mol phase,\n\tmust be a subset of the related phase %s, %s.", comp_ptr->formula, (double) comp_ptr->phase_proportion, pp_a_ptr->pure_phases[k].phase->name, pp_a_ptr->pure_phases[k].phase->formula); + error_msg(error_string, CONTINUE); + break; + } + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_min_surface(void) +/* ---------------------------------------------------------------------- */ +/* + * If surface is related to mineral, surface amount is + * set in proportion + */ +{ + int i, j, k, n, jj; + struct pp_assemblage *pp_a_ptr; + struct surface_comp *comp_ptr; + struct master *master_ptr; + char *ptr; + LDBLE conc; + + for (i=0; i < count_surface; i++) { + if (surface[i].new_def == FALSE) continue; + if (surface[i].n_user < 0) continue; + for (j = 0; j < surface[i].count_comps; j++) { + if (surface[i].comps[j].phase_name == NULL) continue; + comp_ptr = &surface[i].comps[j]; + comp_ptr->master = NULL; + n = surface[i].n_user; + + /* First find surface master species */ + + for (k=0; comp_ptr->totals[k].elt != NULL; k++) { + /* Find master species */ + master_ptr = comp_ptr->totals[k].elt->master; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Master species not in data " + "base for %s, skipping element.", + comp_ptr->totals[k].elt->name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != SURF) continue; + comp_ptr->master = master_ptr; + break; + } + if (comp_ptr->master == NULL) { + input_error++; + sprintf(error_string, "Surface formula does not contain a surface master species, %s", comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + + /* Now find the mineral on which surface depends... */ + if ((pp_a_ptr=pp_assemblage_bsearch(n, &k)) == NULL) { + input_error++; + sprintf(error_string, "Equilibrium_phases %d must be defined to use surface related to mineral phase, %s", n, comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + for (k=0; kcount_comps; k++) { + if (strcmp_nocase(comp_ptr->phase_name, pp_a_ptr->pure_phases[k].name) == 0) { + break; + } + } + if (k == pp_a_ptr->count_comps) { + input_error++; + sprintf(error_string,"Mineral, %s, related to surface, %s, not found in Equilibrium_Phases %d", comp_ptr->phase_name, comp_ptr->formula, n); + error_msg(error_string, CONTINUE); + continue; + } + if (pp_a_ptr->pure_phases[k].phase == NULL) { + input_error++; + sprintf(error_string,"Mineral, %s, related to surface, %s, not found in database.", pp_a_ptr->pure_phases[k].name, comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + /* use database name for phase */ + comp_ptr->phase_name = pp_a_ptr->pure_phases[k].phase->name; + /* make surface concentration proportional to mineral ... */ + conc=pp_a_ptr->pure_phases[k].moles * comp_ptr->phase_proportion; +/* if (conc < MIN_RELATED_SURFACE) conc = 0.0; */ + ptr = comp_ptr->formula; + count_elts = 0; + paren_count = 0; + get_elts_in_species(&ptr, conc); + comp_ptr->totals = (struct elt_list *) free_check_null(comp_ptr->totals); + comp_ptr->totals = elt_list_save(); + + /* area */ + surface[i].charge[comp_ptr->charge].grams = pp_a_ptr->pure_phases[k].moles; +/* + * make sure surface elements are in phase + */ + count_elts = 0; + paren_count = 0; + ptr = pp_a_ptr->pure_phases[k].phase->formula; + get_elts_in_species(&ptr, 1.0); + for (jj = 0; jj < surface[i].count_comps; jj++) { + if (comp_ptr->charge != surface[i].comps[jj].charge) continue; + if (surface[i].comps[jj].master->s->z != 0.0) { + input_error++; + sprintf(error_string, "Master species of surface, %s, must be uncharged if the number of sites is related to a phase.", surface[i].comps[jj].master->s->name); + error_msg(error_string, CONTINUE); + } + ptr = surface[i].comps[jj].master->s->name; + get_elts_in_species(&ptr, -surface[i].comps[jj].phase_proportion); + } + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); +/* Makes no sense: sorbed species need not be in mineral structure... */ +/* For example, if master species is SurfOH, then increasing the amount of surface + * adds SurfOH to the system, the OH must then come from phase, + * otherwise, O and H are not conserved + */ + for (jj = 0; jj < count_elts; jj++) { + if (elt_list[jj].elt->primary->s->type != SURF && elt_list[jj].coef < 0) { + input_error++; + sprintf(error_string,"Element %s in sum of surface sites,\n" + "\tincluding %s * %g mol sites/mol phase,\n" + "\texceeds stoichiometry in the related phase %s, %s.", + elt_list[jj].elt->name, + comp_ptr->master->s->name, + (double) comp_ptr->phase_proportion, + pp_a_ptr->pure_phases[k].phase->name, + pp_a_ptr->pure_phases[k].phase->formula); + error_msg(error_string, CONTINUE); + break; + } + } + + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_kin_surface(void) +/* ---------------------------------------------------------------------- */ +/* + * If surface is related to mineral, surface amount is + * set in proportion + */ +{ + int i, j, k, n, jj, l; + struct kinetics *kinetics_ptr; + struct surface_comp *comp_ptr; + struct master *master_ptr; + struct phase *phase_ptr; + char token[MAX_LENGTH]; + char *ptr; + LDBLE conc; + struct elt_list *elt_list_kinetics; + int count_elts_kinetics; + + n = -999; + comp_ptr = NULL; + for (i=0; i < count_surface; i++) { + if (surface[i].new_def == FALSE) continue; + if (surface[i].n_user < 0) continue; + for (j = 0; j < surface[i].count_comps; j++) { + if (surface[i].comps[j].rate_name == NULL) continue; + comp_ptr = &surface[i].comps[j]; + comp_ptr->master = NULL; + n = surface[i].n_user; + + /* First find surface master species */ + + for (k=0; comp_ptr->totals[k].elt != NULL; k++) { + /* Find master species */ + master_ptr = comp_ptr->totals[k].elt->master; + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Master species not in data " + "base for %s, skipping element.", + comp_ptr->totals[k].elt->name); + error_msg(error_string, CONTINUE); + continue; + } + if (master_ptr->type != SURF) continue; + comp_ptr->master = master_ptr; + break; + } + if (comp_ptr->master == NULL) { + input_error++; + sprintf(error_string, "Surface formula does not contain a surface master species, %s", comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + + /* Now find the kinetic reaction on which surface depends... */ + if ((kinetics_ptr=kinetics_bsearch(n, &k)) == NULL) { + input_error++; + sprintf(error_string, "Kinetics %d must be defined to use surface related to kinetic reaction, %s", n, comp_ptr->formula); + error_msg(error_string, CONTINUE); + continue; + } + for (k=0; kcount_comps; k++) { + if (strcmp_nocase(comp_ptr->rate_name, kinetics_ptr->comps[k].rate_name) == 0) { + break; + } + } + if (k == kinetics_ptr->count_comps) { + input_error++; + sprintf(error_string,"Kinetic reaction, %s, related to surface, %s, not found in Kinetics %d", comp_ptr->rate_name, comp_ptr->formula, n); + error_msg(error_string, CONTINUE); + continue; + } + + /* use database name for phase */ + comp_ptr->rate_name = kinetics_ptr->comps[k].rate_name; + + /* make surface concentration proportional to mineral ... */ + conc=kinetics_ptr->comps[k].m * comp_ptr->phase_proportion; + +/* if (conc < MIN_RELATED_SURFACE) conc = 0.0; */ + ptr = comp_ptr->formula; + count_elts = 0; + paren_count = 0; + get_elts_in_species(&ptr, conc); + comp_ptr->totals = (struct elt_list *) free_check_null(comp_ptr->totals); + comp_ptr->totals = elt_list_save(); + + /* area */ + surface[i].charge[comp_ptr->charge].grams = kinetics_ptr->comps[k].m; + } +/* + * check on elements + */ + /* Go through each kinetic reaction, add all related surface compositions + * check for negative values + */ + if (surface[i].related_rate == FALSE) continue; + kinetics_ptr=kinetics_bsearch(n, &k); + for (k=0; k < kinetics_ptr->count_comps; k++) { + count_elts = 0; + paren_count = 0; + + /* added in kinetics formula */ + for (j = 0; j < kinetics_ptr->comps[k].count_list; j++) { + phase_ptr = NULL; + strcpy(token, kinetics_ptr->comps[k].list[j].name); + phase_ptr = phase_bsearch(token, &jj, FALSE); + if (phase_ptr != NULL) { + add_elt_list(phase_ptr->next_elt, 1.0); + } else { + ptr = kinetics_ptr->comps[k].list[j].name; + get_elts_in_species (&ptr, kinetics_ptr->comps[k].list[j].coef); + } + } + /* save kinetics formula */ + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + elt_list_kinetics = elt_list_save(); + count_elts_kinetics = count_elts; + + /* get surface formulas */ + count_elts = 0; + paren_count = 0; + for (j = 0; j < surface[i].count_comps; j++) { + comp_ptr = &surface[i].comps[j]; + if (comp_ptr->rate_name == NULL) continue; + if (strcmp_nocase(comp_ptr->rate_name, kinetics_ptr->comps[k].rate_name) == 0) { + ptr = comp_ptr->formula; + get_elts_in_species(&ptr, -1 * comp_ptr->phase_proportion); + } + } + if (count_elts > 0 ) { + qsort (elt_list, (size_t) count_elts, + (size_t) sizeof(struct elt_list), elt_list_compare); + elt_list_combine(); + } + for (j = 0; j < count_elts; j++) { + if (elt_list[j].elt->primary->s->type <= H2O) { + for (l = 0; l < count_elts_kinetics; l++) { + if (elt_list[j].elt == elt_list_kinetics[l].elt) { + break; + } + } + if (l == count_elts_kinetics) { + input_error++; + sprintf(error_string,"Stoichiometry of surface, %s * %g mol sites/mol reactant,\n\tmust be a subset of the formula defined for the related reactant %s.\n\tElement %s is not present in reactant formula.", comp_ptr->formula, (double) comp_ptr->phase_proportion, comp_ptr->rate_name, elt_list[j].elt->name); + error_msg(error_string, CONTINUE); + } else if (fabs(elt_list[j].coef) > fabs(elt_list_kinetics[l].coef)) { + input_error++; + sprintf(error_string,"Stoichiometry of surface, %s * %g mol sites/mol reactant,\n\tmust be a subset of the formula defined for the related reactant %s.\n\tCoefficient of element %s in surface exceeds amount present in reactant formula.", comp_ptr->formula, (double) comp_ptr->phase_proportion, comp_ptr->rate_name, elt_list[j].elt->name); + error_msg(error_string, CONTINUE); + } + } + } + elt_list_kinetics = (struct elt_list *) free_check_null(elt_list_kinetics); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int s_s_prep(LDBLE t, struct s_s *s_s_ptr, int print) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, converged, divisions; + LDBLE r, rt, ag0, ag1, crit_pt; + LDBLE xc, tc; + LDBLE x, x0, x1, xsm1, xsm2, xb1, xb2; + LDBLE xc1, xc2; + LDBLE facb1, faca1, spim1, xblm1, acrae, acrael, xliapt, xliapm; + LDBLE xaly, xaly1, xaly2; + LDBLE faca, facb, spialy, facal, facbl; + LDBLE tol; + + if (pr.s_s_assemblage == FALSE) print = FALSE; + tol = 1e-6; + r = R_KJ_DEG_MOL; + rt = r * t; + a0 = s_s_ptr->ag0 / rt; + a1 = s_s_ptr->ag1 / rt; + s_s_ptr->a0 = a0; + s_s_ptr->a1 = a1; + ag0 = a0*rt; + ag1 = a1*rt; + kc = exp( k_calc(s_s_ptr->comps[0].phase->rxn->logk, t) * LOG_10); + kb = exp( k_calc(s_s_ptr->comps[1].phase->rxn->logk, t) * LOG_10); + crit_pt = fabs(a0) + fabs(a1); +/* + * Default, no miscibility or spinodal gaps + */ + s_s_ptr->miscibility = FALSE; + s_s_ptr->spinodal = FALSE; + xsm1 = 0.5; + xsm2 = 0.5; + xb1 = 0.5; + xb2 = 0.5; + xc1 = 0; + xc2 = 0; + + if (crit_pt >= tol) { +/* + * Miscibility gap information + */ + if (fabs(a1) < tol) { + xc = 0.5; + tc = ag0/(2*r); + } else { + xc = 0.5 + (pow((ag0*ag0 + 27*ag1*ag1), 0.5) - ag0) / (18*ag1); + tc = (12*ag1*xc - 6*ag1 + 2*ag0) * (xc - xc*xc)/r; + } + if (print == TRUE) { + sprintf(error_string,"Description of Solid Solution %s", s_s_ptr->name); + dup_print(error_string, TRUE); + } + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t Temperature: %g kelvin\n", (double) t); + output_msg(OUTPUT_MESSAGE,"\t A0 (dimensionless): %g\n", (double) a0); + output_msg(OUTPUT_MESSAGE,"\t A1 (dimensionless): %g\n", (double) a1); + output_msg(OUTPUT_MESSAGE,"\t A0 (kJ/mol): %g\n", (double) ag0); + output_msg(OUTPUT_MESSAGE,"\t A1 (kJ/mol): %g\n\n", (double) ag1); + } + if (xc < 0 || xc > 1) { + if (print == TRUE) output_msg(OUTPUT_MESSAGE,"No miscibility gap above 0 degrees kelvin.\n"); + } else { + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t Critical mole-fraction of component 2: %g\n", (double) xc); + output_msg(OUTPUT_MESSAGE,"\t Critical temperature: %g kelvin\n", (double) tc); + output_msg(OUTPUT_MESSAGE,"\n(The critical temperature calculation assumes that the Guggenheim model\ndefined at %g kelvin is valid at the critical temperature.)\n\n\n", (double) t); + } + } +/* + * Calculate miscibility and spinodal gaps + */ + if (tc >= t) { + + /* search for sign changes */ + x0 = 0; + x1 = 1; + if (scan(f_spinodal, &x0, &x1) == TRUE) { + + /* find first spinodal pt */ + xsm1 = halve(f_spinodal, x0, x1, tol); + s_s_ptr->spinodal = TRUE; + + /* find second spinodal pt */ + x0 = x1; + x1 = 1; + if (scan(f_spinodal, &x0, &x1) == TRUE) { + xsm2 = halve(f_spinodal, x0, x1, tol); + } else { + error_msg("Failed to find second spinodal point.", STOP); + } + } + } + } +/* + * Now find Miscibility gap + */ + if (s_s_ptr->spinodal == TRUE) { + if (print == TRUE) output_msg(OUTPUT_MESSAGE,"\t Spinodal-gap mole fractions, component 2: %g\t%g\n", (double) xsm1, (double) xsm2); + converged = FALSE; + if (converged == FALSE) { + for (i = 1; i < 3; i++) { + divisions = (int) pow(10.,i); + for (j = 0; j < divisions; j++) { + for (k = divisions; k > 0; k--) { + xc1 = (LDBLE) j / divisions + 0.001; + xc2 = (LDBLE) k / divisions; + converged = solve_misc(&xc1, &xc2, tol); + if (converged == TRUE) break; + } + if (converged == TRUE) break; + } + if (converged == TRUE) break; + } + } + if (converged == FALSE) { + error_msg("Failed to find miscibility gap.", STOP); + } + s_s_ptr->miscibility = TRUE; + if (xc1 < xc2) { + xb1 = 1 - xc2; + xb2 = 1 - xc1; + xc1 = 1 - xb1; + xc2 = 1 - xb2; + } else { + xb1 = 1 - xc1; + xb2 = 1 - xc2; + } + facb1 = kb*xb1*exp(xc1*xc1*(a0 + a1*(4*xb1 -1))); + faca1 = kc*xc1*exp(xb1*xb1*(a0 - a1*(3-4*xb1))); + spim1 = log10(faca1 + facb1); + xblm1 = 1./(1. + faca1/facb1); + acrae = facb1/faca1; + acrael = log10(acrae); + xliapt = log10(facb1); + xliapm = log10(faca1); + + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE, "\t Miscibility-gap fractions, component 2: %g\t%g\n", (double) xb1, (double) xb2); + output_msg(OUTPUT_MESSAGE, "\n\t\t\tEutectic Point Calculations\n\n"); + output_msg(OUTPUT_MESSAGE, "\t Aqueous activity ratio (comp2/comp1): %g\n", (double) acrae); + output_msg(OUTPUT_MESSAGE, "\t Log aqueous activity ratio (comp2/comp1): %g\n", (double) acrael); + output_msg(OUTPUT_MESSAGE, "\t Aqueous activity fraction of component 2: %g\n", (double) xblm1); + output_msg(OUTPUT_MESSAGE, "\t Log IAP (component 2): %g\n", (double) xliapt); + output_msg(OUTPUT_MESSAGE, "\t Log IAP (component 1): %g\n", (double) xliapm); + output_msg(OUTPUT_MESSAGE, "\t Log Sum Pi: %g\n", (double) spim1); + } + s_s_ptr->tk = t; + s_s_ptr->xb1 = xb1; + s_s_ptr->xb2 = xb2; + } +/* + * Alyotropic point calculation + */ + xaly = -1.0; + x = a0*a0 + 3*a1*a1 + 6*a1*log(kb/kc); + if (x > 0) { + if (fabs(x - a0*a0) >= tol) { + xaly1 = (-(a0 - 3*a1) + pow(x, 0.5)) / (6*a1); + xaly2 = (-(a0 - 3*a1) - pow(x, 0.5)) / (6*a1); + if (xaly1 >= 0 && xaly1 <= 1) { + xaly = xaly1; + } + if (xaly2 >= 0 && xaly2 <= 1) { + xaly = xaly2; + } + } else { + xaly = 0.5 + log(kb/kc) / (2*a0); + } + if (xaly > 0 && xaly < 1) { + faca = kc * (1 - xaly) * exp(xaly*xaly*(a0 - a1 * (3 - 4*xaly))); + facb = kb * xaly * exp((1 - xaly)*(1 - xaly)*(a0 + a1 * (4*xaly - 1.0))); + spialy = log10(faca + facb); + facal = log10(faca); + facbl = log10(facb); + if (xaly > xb1 && xaly < xb2) { + if (print == TRUE) output_msg(OUTPUT_MESSAGE,"\nLocal minimum in the solidus curve coresponding to a maximum\nin the minimum stoichiometric saturation curve.\n\n"); + } else { + if (print == TRUE) output_msg(OUTPUT_MESSAGE,"\n\t\t\tAlyotropic Point\n\n"); + } + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE,"\t Solid mole fraction of component 2: %g\n", (double) xaly); + output_msg(OUTPUT_MESSAGE,"\t Log IAP (component 2): %g\n", (double) facbl); + output_msg(OUTPUT_MESSAGE,"\t Log IAP (component 1): %g\n", (double) facal); + output_msg(OUTPUT_MESSAGE,"\t Log Sum Pi: %g\n", (double) spialy); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +static LDBLE halve(LDBLE f(LDBLE x), LDBLE x0, LDBLE x1, LDBLE tol) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE x, y, y0, dx; + + y0 = f(x0); + dx = (x1 - x0); +/* + * Loop for interval halving + */ + for (i = 0; i < 100; i++) { + dx *= 0.5; + x = x0 + dx; + y = f( x); + if (dx < tol || y == 0) { + break; + } +#ifdef SKIP + if (y0*y < 0) { + x1 = x; + } else { + x0 = x; + y0 = y; + } +#endif + if (y0*y >= 0) { + x0 = x; + y0 = y; + } + } + return(x0 + dx); +} +/* ---------------------------------------------------------------------- */ +static int scan(LDBLE f(LDBLE x), LDBLE *xx0, LDBLE *xx1) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + LDBLE fx0, fx1, divisions; + LDBLE x0, x1, diff; + + x0 = *xx0; + x1 = *xx1; + diff = x1 - x0; + for (j = 0; j < 3; j++) { + fx0 = f(x0); + divisions = (int) pow(10, j); + for (i = 1; i < divisions; i++) { + x1 = *xx0 + diff * (LDBLE) i / divisions; + fx1 = f(x1); + if (fx0 * fx1 <= 0) { + *xx0 = x0; + *xx1 = x1; + return (TRUE); + } + x0 = x1; + fx0 = fx1; + } + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +static LDBLE f_spinodal(LDBLE x) +/* ---------------------------------------------------------------------- */ +{ + LDBLE fx; + fx = -12*a1*x*x*x + (18*a1 - 2*a0)*x*x + (2*a0 - 6*a1)*x - 1.0; + return(fx); +} +/* ---------------------------------------------------------------------- */ +int slnq (int n, LDBLE *a, LDBLE *delta, int ncols, int print) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, m; +/* debug + */ + int row; + + LDBLE b; +/* Debug +*/ + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nArray in slnq: \n\n"); + for (i=0; i < ncols - 1; i++) { + row=i*(n+1); + for (j=0; j < ncols; j++) { + output_msg(OUTPUT_MESSAGE,"%10.2e",(double) a[row+j]); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + output_msg(OUTPUT_MESSAGE,"\n"); + } + + if (n == 0) return(OK); +/* Trivial case */ + if (n == 1) { + if ( fabs(a[0]) < ZERO_TOL) goto slnq_error; + delta[0]=a[1]/a[0]; + return(OK); + } + +/* Reduction loop */ + for (i=0; i < n-1; i++) { + b=fabs(a[i*ncols + i]); + m=i; + +/* Find maximum value in column */ + for ( j=i+1; j < n; j++) { + if (fabs(a[j*ncols + i]) > b) { + b=fabs(a[j*ncols + i]); + m=j; + } + } + +/* Check for singularity */ + if ( b < ZERO_TOL ) goto slnq_error; + +/* Exchange rows if necessary */ + if (m != i) { + for ( j=i; j <= n; j++ ) { + b=a[i*ncols + j]; + a[i*ncols + j]=a[m*ncols + j]; + a[m*ncols + j]=b; + } + } + +/* Make a[i][i]=1.0 */ + for (j=n; j >= i; j--) { + a[i*ncols + j] /= a[i*ncols + i]; + } + +/* Reduction step */ + for (j=i+1; j < n; j++) { + if (a[j*ncols + i] == 0.0) continue; + b=-a[j*ncols + i]; + for (k=i+1; k <= n ; k++) { + a[j*ncols + k] += b*a[i*ncols + k]; + } + } + } + +/* Calculation of delta[n] */ + if (fabs(a[(n-1)*ncols + n-1]) > ZERO_TOL) { + delta[n-1]=a[(n-1)*ncols + n]/a[(n-1)*ncols + n - 1]; + } else { + output_msg(OUTPUT_MESSAGE,"Error: Divide by zero in slnq.\n"); + delta[n]=0.0; + goto slnq_error; + } + +/* Back substitution for other delta values */ + for (i=n-2; i>=0; i--) { + delta[i]=a[i*ncols + n]; + for (j = i+1; j < n; j++) { + delta[i] -= a[i*ncols + j]*delta[j]; + } + } + if (print == TRUE) { + output_msg(OUTPUT_MESSAGE,"\nResults from slnq: \n\n"); + for (i=0; i 1 || x1 < 0 || x2 > 1 || x2 < 0) { + d[0] *= 0.5; + d[1] *= 0.5; + } else { + repeat = FALSE; + } + }; + xc1 = x1; + xc2 = x2; + + if (fabs(xc1 - xc2) < .01) { + converged = FALSE; + break; + } + } + if (i == max_iter) converged = FALSE; + *xxc1 = xc1; + *xxc2 = xc2; + return(converged); +} +/* ---------------------------------------------------------------------- */ +static int s_s_calc_a0_a1(struct s_s *s_s_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i, done; + LDBLE r, rt, *p; + LDBLE q1, q2, xbq1, xbq2, xb1, xb2, xc1, xc2; + LDBLE r1, r2, pa1, pb1, pa2, pb2, xsm1, xsm2; + LDBLE pn9, pn10, c5, c6, pl9, pl10, pj9, pj10; + LDBLE xc, tc; + LDBLE spialy, azero, phi1, phi2, test; + LDBLE dq1, dq2, denom, ratio, dr1, dr2, x21, x22, x61, x62; + LDBLE a0, a1, ag0, ag1; + LDBLE wg2, wg1, alpha2, alpha3; + LDBLE kc, kb; + LDBLE xaly, xcaly, alpha0, alpha1, fx, fx1; + LDBLE tol; + + tol = 1e-6; + rt = s_s_ptr->tk * R_KJ_DEG_MOL; + if (s_s_ptr->comps[0].phase == NULL || s_s_ptr->comps[1].phase == NULL) { + input_error++; + sprintf(error_string, "Two components were not defined for %s solid solution", s_s_ptr->name); + error_msg(error_string, CONTINUE); + return(ERROR); + } + kc = exp( k_calc(s_s_ptr->comps[0].phase->rxn->logk, s_s_ptr->tk) * LOG_10); + kb = exp( k_calc(s_s_ptr->comps[1].phase->rxn->logk, s_s_ptr->tk) * LOG_10); + + p = s_s_ptr->p; + + a0 = 0; + a1 = 0; + ag0 = 0; + ag1 = 0; + dq2 = 0; + switch (s_s_ptr->input_case) { + /* + * dimensionless a0 and a1 + */ + case 0: + a0 = p[0]; + a1 = p[1]; + ag0 = a0*rt; + ag1 = a1*rt; + break; + /* + * two activity coefficients + * q1, q2, xbq1, xbq2 + */ + case 1: + q1 = p[0]; + q2 = p[1]; + xbq1 = p[2]; + xbq2 = p[3]; + done = FALSE; + if (fabs(1 - xbq1) > 0 && q1 > 0) { + dq1 = log(q1)/ ((1 - xbq1)*(1 - xbq1)); + if (xbq2 <= 0 || xbq2 > 1) { + a0 = dq1; + a1 = 0; + done = TRUE; + } + } + if (done == FALSE) { + if (fabs(xbq2) < 0 || q2 <= 0) { + input_error++; + sprintf(error_string, "No solution possible for A0 and A1 calculation from two activity coefficients, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + done = TRUE; + } + } + if (done == FALSE) { + dq2 = log(q2) / (xbq2 * xbq2); + if (xbq1 < 0. || xbq2 > 1.) { + a0 = dq2; + a1 = 0; + done = TRUE; + } + } + if (done == FALSE) { + denom = 4 * (xbq1 - xbq2) + 2; + if (fabs(denom) >= tol) { + if (fabs(1 - xbq1) > 0 && q1 > 0) { + dq1 = log(q1)/ ((1 - xbq1)*(1 - xbq1)); + a0 = (dq1 * (3 - 4*xbq2) + dq2 * (4*xbq1 - 1)) / denom; + a1 = (dq1 - dq2) / denom; + done = TRUE; + } + } + } + if (done == FALSE) { + input_error++; + sprintf(error_string, "No solution possible for A0 and A1 calculation from two activity coefficients, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + } + /* io = 1 */ + ag0 = a0*rt; + ag1 = a1*rt; + break; + /* + * two distribution coefficients + * q1, q2, xbq1, xbq2 + */ + case 2: + q1 = p[0]; + q2 = p[1]; + xbq1 = p[2]; + xbq2 = p[3]; + ratio = kc/kb; + dr1 = log(q1/ratio); + x21 = 2*xbq1 - 1; + if (fabs(xbq1 - xbq2) < tol || xbq2 < 0) { + a0 = dr1 / x21; + a1 = 0; + } else { + dr2 = log(q2/ratio); + x22 = 2*xbq2 - 1; + if (xbq1 < 0.) { + a0 = dr2/x22; + a1 = 0; + } else { + x61 = 6*xbq1*xbq1 - 6*xbq1 + 1; + x62 = 6*xbq2*xbq2 - 6*xbq2 + 1; + if (fabs(x22*x61 - x21*x62) < tol) { + input_error++; + sprintf(error_string, "No solution possible for A0 and A1 calculation from two distribution coefficients, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + } + a0 = (x61*dr2 - x62*dr1) / (x22*x61 - x21*x62); + a1 = (x21*dr2 - x22*dr1) / (x21*x62 - x22*x61); + } + } + + /* io = 1 */ + ag0 = a0*rt; + ag1 = a1*rt; + break; + /* + * from miscibility gap fractions + * q1, q2 + */ + case 3: + q1 = p[0]; + q2 = p[1]; + xb1 = q1; + xb2 = q2; + xc1 = 1 - xb1; + xc2 = 1 - xb2; + r1 = log(xb1/xb2); + r2 = log(xc1/xc2); + pa1 = xc2*xc2 - xc1*xc1; + pb1 = 3*(xc2*xc2 - xc1*xc1) - 4*(xc2*xc2*xc2 - xc1*xc1*xc1); + pa2 = xb2*xb2 - xb1*xb1; + pb2 = -(3*(xb2*xb2 - xb1*xb1) - 4*(xb2*xb2*xb2 - xb1*xb1*xb1)); + a0 = (r1 - pb1/pb2*r2) / (pa1 - pa2*pb1/pb2); + a1 = (r1 - pa1/pa2*r2) / (pb1 -pb2*pa1/pa2); + + /* io = 1 */ + ag0 = a0*rt; + ag1 = a1*rt; + break; + /* + * from spinodal gap fractions + * q1, q2 + */ + case 4: + q1 = p[0]; + q2 = p[1]; + xsm1 = q1; + xsm2 = q2; + pn9 = 1/xsm1; + pn10 = 1/xsm2; + c5 = 1 - xsm1; + c6 = 1 - xsm2; + pl9 = 6*c5 - 12*c5*c5; + pl10 = 6*c6 - 12*c6*c6; + pj9 = 2*c5; + pj10 = 2*c6; + a0 = (pn9 - pl9/pl10*pn10) / (pj9 - pl9/pl10*pj10); + a1 = (pn9 - pj9/pj10*pn10) / (pl9 - pj9/pj10*pl10); + + /* io = 1 */ + ag0 = a0*rt; + ag1 = a1*rt; + break; + /* + * from critical point + * q1, q2 + */ + case 5: + xc = p[0]; + tc = p[1]; + r = R_KJ_DEG_MOL; + ag1 = r*tc* (2*xc - 1) / (12*xc*xc*(1 - xc)*(1 - xc)); + ag0 = (r*tc / (xc*(1 - xc)) - (12*xc - 6)*ag1) / 2; + + /* io = 0 */ + a0 = ag0/rt; + a1 = ag1/rt; + break; + /* + * from alyotropic point + * q1, q2 + */ + case 6: + q1 = p[0]; + q2 = p[1]; + xaly = q1; + r = log(kb/kc); + alpha0 = 2*xaly - 1; + alpha1 = 6*xaly*(xaly - 1) + 1; + spialy = pow(10., q2); + a0 = -999.; + a1 = -999.; + if (fabs(alpha0) < tol) { + input_error++; + sprintf(error_string, "No solution possible for A0 and A1 calculation from alyotropic point, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + } else { + azero = 1; + if (fabs(alpha0) > tol) azero = r/alpha0; + xcaly = 1 - xaly; +/* + * Solve for a0 by Newton's method + */ + for (i = 0; i < 50; i++) { + phi1 = xcaly*xcaly*(azero + (r - azero*alpha0)*(4*xaly - 1)/alpha1); + phi2 = xaly*xaly*(azero + (3 - 4*xaly)*(azero*alpha0 - r)/alpha1); + phi1 = xaly*kb*exp(phi1); + phi2 = xcaly*kc*exp(phi2); + fx = phi1 + phi2 - spialy; + fx1 = xcaly*xcaly*(1 - alpha0*(4*xaly - 1)/alpha1)*phi1 + + xaly*xaly*(1 + alpha0*(3 - 4*xaly)/alpha1)*phi2; + if (fabs(fx1) < 1e-10) { + input_error++; + sprintf(error_string, "Could not find A0 and A1 calculation from alyotropic point, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + break; + } + a0 = azero - fx/fx1; + test = fabs(a0 - azero) + fabs(fx); + azero = a0; + if (test < tol) break; + } + if (i == 50) { + input_error++; + sprintf(error_string, "Too many iterations, could not find A0 and A1 calculation from alyotropic point, %s.\n", s_s_ptr->name); + error_msg(error_string, CONTINUE); + } else { + a1 = (r - a0 *alpha0) / alpha1; + + /* io = 0 */ + ag0 = a0 * rt; + ag1 = a1 * rt; + } + + } + break; + /* + * dimensional (kJ/mol) Guggenheim parameters + * ag0, ag1 + */ + case 7: + ag0 = p[0]; + ag1 = p[1]; + a0 = ag0 / rt; + a1 = ag1 / rt; + break; + /* + * Waldbaum-Thompson + * wg2, wg1 + */ + case 8: + wg2 = p[0]; + wg1 = p[1]; + ag0 = (wg2 + wg1) / 2; + ag1 = (wg2 - wg1) / 2; + a0 = ag0 / rt; + a1 = ag1 / rt; + break; + /* + * Margules + * alpha2, alpha3 + */ + case 9: + alpha2 = p[0]; + alpha3 = p[1]; + a0 = alpha2 + 3*alpha3/4; + a1 = alpha3/4; + ag0 = a0 * rt; + ag1 = a1 * rt; + break; + } + + s_s_ptr->ag0 = ag0; + s_s_ptr->ag1 = ag1; + s_s_ptr->a0 = a0; + s_s_ptr->a1 = a1; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_master_isotope(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct master *master_ptr; + + for (i = 0; i < count_master_isotope; i++) { + /* + * Mark master species list as minor isotope + */ + if (master_isotope[i]->minor_isotope == TRUE) { + master_ptr = master_bsearch(master_isotope[i]->name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "Did not find master species for isotope, %s", master_isotope[i]->name); + error_msg(error_string,CONTINUE); + master_isotope[i]->master = NULL; + continue; + } else { + master_isotope[i]->master = master_ptr; + } + master_ptr->minor_isotope = TRUE; + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_isotope_ratios(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct master *master_ptr; + struct master_isotope *master_isotope_ptr; + struct calculate_value *calculate_value_ptr; + + for (i = 0; i < count_isotope_ratio; i++) { + /* + * Mark master species list as minor isotope + */ + master_isotope_ptr = master_isotope_search(isotope_ratio[i]->isotope_name); + if (master_isotope_ptr == NULL) { + input_error++; + sprintf(error_string, "For ISOTOPE_RATIO %s, did not find ISOTOPE definition for this isotope, %s", isotope_ratio[i]->name, isotope_ratio[i]->isotope_name); + error_msg(error_string,CONTINUE); + } + master_ptr = master_bsearch(isotope_ratio[i]->isotope_name); + if (master_ptr == NULL) { + input_error++; + sprintf(error_string, "For ISOTOPE_RATIO %s, did not find SOLUTION_MASTER_SPECIES for isotope, %s", isotope_ratio[i]->name, isotope_ratio[i]->isotope_name); + error_msg(error_string,CONTINUE); + } + calculate_value_ptr = calculate_value_search(isotope_ratio[i]->name); + if (calculate_value_ptr == NULL) { + input_error++; + sprintf(error_string, "For ISOTOPE_RATIOS %s, did not find corresponding CALCULATE_VALUE definition", isotope_ratio[i]->name); + error_msg(error_string,CONTINUE); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int tidy_isotope_alphas(void) +/* ---------------------------------------------------------------------- */ +{ + int i; + struct calculate_value *calculate_value_ptr; + struct logk *logk_ptr; + + for (i = 0; i < count_isotope_alpha; i++) { + /* + * Mark master species list as minor isotope + */ + calculate_value_ptr = calculate_value_search(isotope_alpha[i]->name); + if (calculate_value_ptr == NULL) { + input_error++; + sprintf(error_string, "For ISOTOPE_ALPHAS %s, did not find corresponding CALCULATE_VALUE definition", isotope_alpha[i]->name); + error_msg(error_string,CONTINUE); + } + if (isotope_alpha[i]->named_logk != NULL) { + logk_ptr = logk_search(isotope_alpha[i]->named_logk); + if (logk_ptr == NULL) { + input_error++; + sprintf(error_string, "For ISOTOPE_ALPHAS %s, did not find corresponding NAMED_EXPRESSION definition %s.", isotope_alpha[i]->name, isotope_alpha[i]->named_logk); + error_msg(error_string,CONTINUE); + } + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int reset_last_model(void) +/* ---------------------------------------------------------------------- */ +{ +/* + * Initialize model + */ + last_model.force_prep = TRUE; + last_model.count_exchange = 0; + last_model.exchange = (struct master **) free_check_null(last_model.exchange); + last_model.count_gas_phase = 0; + last_model.gas_phase = (struct phase **) free_check_null(last_model.gas_phase); + last_model.count_s_s_assemblage = 0; + last_model.s_s_assemblage = (char **) free_check_null(last_model.s_s_assemblage); + last_model.count_pp_assemblage = 0; + last_model.pp_assemblage = (struct phase **) free_check_null(last_model.pp_assemblage); + last_model.add_formula = (char **) free_check_null(last_model.add_formula); + last_model.si = (LDBLE *) free_check_null(last_model.si); + last_model.diffuse_layer = FALSE; + last_model.count_surface_comp = 0; + last_model.surface_comp = (struct master **) free_check_null(last_model.surface_comp); + last_model.count_surface_charge = 0; + last_model.surface_charge = (struct master **) free_check_null(last_model.surface_charge); + return(OK); +} diff --git a/transport.cpp b/transport.cpp new file mode 100644 index 00000000..4dba3182 --- /dev/null +++ b/transport.cpp @@ -0,0 +1,844 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: transport.c 78 2005-02-01 22:47:12Z dlpark $"; + +static int init_mix(void); +static int init_heat_mix(int nmix); +static int heat_mix(int heat_nmix); +static int mix_stag(int i, LDBLE stagkin_time, int punch, LDBLE step_fraction_kin); + + +LDBLE *heat_mix_array; +LDBLE *temp1, *temp2; +int heat_nmix; +LDBLE heat_mix_f_imm, heat_mix_f_m; + +/* ---------------------------------------------------------------------- */ +int transport(void) +/* ---------------------------------------------------------------------- */ +{ + int i, j, k, n; + int j_imm, n_m, n_imm; + LDBLE b, f, mix_f_m, mix_f_imm; + LDBLE water_m, water_imm; + int first_c, last_c, b_c; + int nmix; + int max_iter; + char token[MAX_LENGTH]; + LDBLE kin_time, stagkin_time, kin_time_save; + struct mix *mix_ptr; + int punch_boolean; + LDBLE step_fraction; + if (svnid == NULL) fprintf(stderr," "); + + state = TRANSPORT; +/* mass_water_switch = TRUE; */ +/* + * Check existence of solutions + */ + j = -1; + /* check column solutions */ + for (i = 1; i <= count_cells; i++) { + use.solution_ptr = solution_bsearch(i, &n, TRUE); + if (use.solution_ptr == NULL) { + input_error++; + sprintf(error_string, "Solution %d is needed for transport, but is not defined.", i); + error_msg(error_string, CONTINUE); + } else { + cell_data[i-1].temp = use.solution_ptr->tc; + } + } + + /* check solution 0 */ + if (ishift == 1) { + if (solution_bsearch(0, &n, TRUE) == NULL) { + input_error++; + sprintf(error_string, "Solution 0 is needed for transport, but is not defined."); + error_msg(error_string, CONTINUE); + } + } + + /* check solution count_cells */ + if (ishift == -1) { + if (solution_bsearch(count_cells+1, &n, TRUE) == NULL) { + input_error++; + sprintf(error_string, "Solution %d is needed for transport, but is not defined.", count_cells+1); + error_msg(error_string, CONTINUE); + } + } +/* + * Stop if error + */ + if (input_error > 0) { + error_msg("Program terminating due to input errors.", STOP); + } +/* + * Initialize temperature in stagnant cells ... + */ + for (n=1; n<=stag_data->count_stag; n++) { + for (i=1; i <= count_cells; i++) { + k = i+1+n*count_cells; + use.solution_ptr = solution_bsearch(k, &use.n_solution, FALSE); + if (use.solution_ptr != NULL) { + cell_data[k-1].temp = use.solution_ptr->tc; + } + } + } + + if (solution_bsearch(0, &n, FALSE) == NULL) solution_duplicate(1,0); + if (solution_bsearch(count_cells+1, &n, FALSE) == NULL) solution_duplicate(count_cells, count_cells+1); + +/* + * Initialize mixing factors, define kinetics times + */ + if ((stag_data->exch_f > 0) && (stag_data->count_stag == 1)) { + mix_ptr = &mix[0]; + for (i = 0; i < count_mix; i++) mix_free(mix_ptr++); + count_mix = 2*count_cells; + mix = (struct mix *) PHRQ_realloc(mix, (size_t) count_mix * sizeof(struct mix)); + if (mix == NULL) malloc_error(); + memset(mix, 0, sizeof(struct mix) * count_mix); + } + nmix = init_mix(); + heat_nmix = init_heat_mix(nmix); + if (nmix < 2) stagkin_time = timest; else stagkin_time = timest/nmix; + if (ishift != 0 ) kin_time = timest/(1+nmix); else kin_time = stagkin_time; + kin_time_save = kin_time; + +/* Reaction defined for a shift... */ + step_fraction = 1.0/(1.0+nmix); + +/* + * Set boundary conditions, transport direction + */ + last_model.force_prep = TRUE; + if ((ishift == 0) || (bcon_first == 1) || (bcon_last == 1)) { + b_c = 1; + } else { + b_c = 0; + } + if (ishift >= 0) { + last_c = count_cells; + first_c = 1; + } else { + last_c = 1; + first_c = count_cells; + } +/* + * First equilibrate solutions + */ + dup_print("Equilibrating initial solutions", TRUE); + transport_step = 0; + for (i=1; i <= count_cells; i++) { + set_initial_moles(i); + cell_no = i; + set_and_run_wrapper(i, NOMIX, FALSE, i, 0.0); + if (cell_data[i-1].punch == TRUE) punch_all(); + if (cell_data[i-1].print == TRUE) print_all(); + saver(); + } +/* + * Also stagnant cells + */ + for (n=1; n<=stag_data->count_stag; n++) { + for (i=1; i <= count_cells; i++) { + k = i+1+n*count_cells; + cell_no = k; + if (solution_bsearch(k, &use.n_solution, FALSE) != 0 ) { + set_initial_moles(k); + set_and_run_wrapper(k, NOMIX, FALSE, k, 0.0); + if ((cell_data[k-1].punch == TRUE)) punch_all(); + if ((cell_data[k-1].print == TRUE) && (transport_step % print_modulus == 0)) print_all(); + saver(); + } + } + } +/* + * Define stagnant/mobile mix structure, if not read explicitly. + * + * With count_stag = 1, mix factors are calculated from exchange factor à + * (= exch_f), mobile é_m (= th_m) and immobile é_im (= th_im) porosity. + * These variables are read under keyword TRANSPORT, after stagnant, in + * structure stag_data. + * MIX 'cell_no' in input file can be an alternative for the calculation here. + */ + + if ((stag_data->exch_f > 0) && (stag_data->count_stag == 1)) { + + b = stag_data->th_m / (stag_data->th_m + stag_data->th_im); + f = exp( - stag_data->exch_f * stagkin_time / (b * stag_data->th_im) ); + mix_f_imm = b - b * f; + mix_f_m = mix_f_imm * stag_data->th_im / stag_data->th_m; + + n = 0; + for (i=1; i <= count_cells; i++) { + j = i; + j_imm = j + (1 + count_cells); + if (solution_bsearch(j, &n_m, TRUE) == NULL) { + error_msg("Could not find mobile cell solution in TRANSPORT.", STOP); + } + if (solution_bsearch(j_imm, &n_imm, TRUE) == NULL) { + error_msg("Could not find immobile cell solution in TRANSPORT.", STOP); + } + water_m = solution[n_m]->mass_water; + water_imm = solution[n_imm]->mass_water; +/* + * Define C_m = (1 - mix_f_m) * C_m0 + mix_f_m) * C_im0 + */ + mix[n].comps = (struct mix_comp *) PHRQ_malloc((size_t) 2*sizeof(struct mix_comp)); + if (mix[n].comps == NULL) malloc_error(); + mix[n].count_comps = 2; + mix[n].description = string_duplicate(" "); + mix[n].n_user = j; + mix[n].n_user_end = j; + mix[n].comps[0].n_solution = j; + mix[n].comps[0].fraction = 1 - mix_f_m; + mix[n].comps[1].n_solution = j_imm; + mix[n].comps[1].fraction = mix_f_m*water_m/water_imm; + n++; +/* + * Define C_im = mix_f_imm * C_m0 + (1 - mix_f_imm) * C_im0, or... + */ + mix[n].comps = (struct mix_comp *) PHRQ_malloc((size_t) 2*sizeof(struct mix_comp)); + if (mix[n].comps == NULL) malloc_error(); + mix[n].count_comps = 2; + mix[n].description = string_duplicate(" "); + mix[n].n_user = j_imm; + mix[n].n_user_end = j_imm; + mix[n].comps[0].n_solution = j_imm; + mix[n].comps[0].fraction = 1 - mix_f_imm; + mix[n].comps[1].n_solution = j; + mix[n].comps[1].fraction = mix_f_imm*water_imm/water_m; + n++; + } + + if (heat_nmix > 0) { +/* + * Assumption: D_e used for calculating exch_f in input file equals diffc + */ + f = stag_data->exch_f * (heat_diffc - diffc) / diffc / tempr; + f = exp( - f * stagkin_time / (b * stag_data->th_im) ); + heat_mix_f_imm = b - b * f; + heat_mix_f_m = heat_mix_f_imm * stag_data->th_im / stag_data->th_m; + } + } +/* + * Now transport + */ + max_iter = 0; + for (transport_step = transport_start; transport_step <= count_shifts; transport_step++) { + /* + * Set initial moles of phases + */ + for (i = 1; i <= count_cells; i++) { + set_initial_moles(i); + } + +/* + * Start diffusing if boundary cond = 1, (fixed c, or closed) + */ + if (b_c == 1) { + + /* For half of mixing steps */ + + for (j = 1; j <= floor(nmix/2); j++) { + rate_sim_time_start = (transport_step - 1) * timest + (j-1) * kin_time; + rate_sim_time = rate_sim_time_start + kin_time; + + sprintf(token, "Transport step %3d. Mixrun %3d.", transport_step, j); + dup_print(token, FALSE); + + if (heat_nmix > 0) { + heat_mix(heat_nmix); + /* equilibrate again ... */ + for (i=1; i <= count_cells; i++) { + cell_no = i; + set_and_run_wrapper(i, NOMIX, FALSE, i, 0.0); + saver(); + } + } + + /* Go through cells */ + + for (i = 1; i <= count_cells; i++) { + +#ifdef SKIP +/* this is somewhere lost; quickened in set_and_run ... */ + if (i == 1) { + last_model.force_prep = TRUE; + } +#endif + if (iterations > max_iter) max_iter = iterations; + sprintf(token, "Transport step %3d. Mixrun %3d. Cell %3d. (Max. iter %3d)", transport_step, j, i, max_iter); + status(0, token); + + cell_no = i; + run_reactions(i, kin_time, DISP, step_fraction); + + /* punch and output file */ + if ((ishift == 0) && (j == nmix) && + ((stag_data->count_stag == 0) || + solution_bsearch(i+1+count_cells, &use.n_solution, FALSE) == 0)){ + if ((cell_data[i-1].punch == TRUE) && + (transport_step % punch_modulus == 0)) punch_all(); + if ((cell_data[i-1].print == TRUE) && + (transport_step % print_modulus == 0)) print_all(); + } + if (i > 1) solution_duplicate(-2, i-1); + saver(); + } + solution_duplicate(-2, count_cells); + + /* Stagnant zone mixing after completion of each + diffusive/dispersive step ... */ + + rate_sim_time_start = (transport_step - 1)*timest + (j-1)*stagkin_time; + rate_sim_time = rate_sim_time_start + stagkin_time; + + if (stag_data->count_stag > 0) { + if ((ishift == 0) && (j == nmix)) punch_boolean = TRUE; else punch_boolean = FALSE; + for (i = 1; i <= count_cells; i++) mix_stag(i, stagkin_time, punch_boolean, step_fraction); + } + } + } +/* + * Advective transport + */ + if (ishift !=0) { + sprintf(token, "Transport step %3d.", transport_step); + dup_print(token, FALSE); + if (b_c == 1) { + rate_sim_time_start = (transport_step -1)*timest + (j-1)*kin_time; + } else { + rate_sim_time_start = (transport_step -1)*timest; + } + rate_sim_time = rate_sim_time_start + kin_time; + +/* halftime kinetics for resident water in first cell ... */ + if (kinetics_bsearch(first_c, &i) != NULL && count_cells > 1) { + cell_no = first_c; + kin_time = kin_time_save / 2; + run_reactions(first_c, kin_time, NOMIX, 0.0); + saver(); + kin_time = kin_time_save; + } + + /* for each cell in column */ +/* Begin revision Dec 7, 1999 */ + for (i = last_c; i != (first_c-ishift); i-=ishift) { + solution_duplicate(i-ishift, i); + } +/* + * thermal diffusion when nmix = 0... + */ + if ((nmix == 0) && (heat_nmix > 0)) { + heat_mix(heat_nmix); + /* equilibrate again ... */ + for (i=1; i <= count_cells; i++) { + cell_no = i; + set_and_run_wrapper(i, NOMIX, FALSE, i, 0.0); + saver(); + } + } + + for (i = 1; i <= count_cells; i++) { + if (i == first_c && count_cells > 1) kin_time /= 2; + sprintf(token, "Transport step %3d. Mixrun %3d. Cell %3d. (Max. iter %3d)", transport_step, 0, i, max_iter); + status(0, token); + cell_no = i; + run_reactions(i, kin_time, NOMIX, step_fraction); + if (iterations > max_iter) max_iter = iterations; +/* end revision Dec 7, 1999 */ + + if ((nmix == 0) && + ((stag_data->count_stag == 0) || + (solution_bsearch(i+1+count_cells, &use.n_solution, FALSE) == 0))) { + if ((cell_data[i-1].punch == TRUE) && + (transport_step % punch_modulus == 0)) punch_all(); + if ((cell_data[i-1].print == TRUE) && + (transport_step % print_modulus == 0)) print_all(); + } + if (i == first_c && count_cells > 1) kin_time = kin_time_save; + saver(); + + /* If nmix is zero, stagnant zone mixing after + advective step ... */ + + if ((nmix == 0) && (stag_data->count_stag > 0)) mix_stag(i, stagkin_time, TRUE, step_fraction); + } + } + +/* + * Further dispersive and diffusive transport + */ + if (b_c != 1) j = 1; + for (j = j; j <= nmix; j++) { + sprintf(token, "Transport step %3d. Mixrun %3d.", transport_step, j); + dup_print(token, FALSE); + rate_sim_time_start = (transport_step - 1)*timest + (j - 1) * kin_time; + if (ishift != 0) rate_sim_time_start += kin_time; + rate_sim_time = rate_sim_time_start + kin_time; + + if (heat_nmix > 0) { + heat_mix(heat_nmix); + /* equilibrate again ... */ + for (i=1; i <= count_cells; i++) { + cell_no = i; + set_and_run_wrapper(i, NOMIX, FALSE, i, 0.0); + saver(); + } + } + + /* for each cell in column */ + + for (i = 1; i <= count_cells; i++) { + if (iterations > max_iter) max_iter = iterations; + sprintf(token, "Transport step %3d. Mixrun %3d. Cell %3d. (Max. iter %3d)", transport_step, j, i, max_iter); + status(0, token); + cell_no = i; + run_reactions(i, kin_time, DISP, step_fraction); + + if ((j == nmix) && + ((stag_data->count_stag == 0) || + (solution_bsearch(i+1+count_cells, &use.n_solution, FALSE) == 0))) { + if ((cell_data[i-1].punch == TRUE) && + (transport_step % punch_modulus == 0)) punch_all(); + if ((cell_data[i-1].print == TRUE) && + (transport_step % print_modulus == 0)) { + print_all(); + } + } + if (i > 1) solution_duplicate(-2, i-1); + saver(); + } + solution_duplicate(-2, count_cells); + /* Stagnant zone mixing after completion of each + diffusive/dispersive step ... */ + + rate_sim_time_start = (transport_step - 1)*timest + (j - 1) * stagkin_time; + rate_sim_time = rate_sim_time_start + stagkin_time; + + if (stag_data->count_stag > 0) { + if (j == nmix) punch_boolean = TRUE; else punch_boolean = FALSE; + for (i = 1; i <= count_cells; i++) mix_stag(i, stagkin_time, punch_boolean, step_fraction); + } + } + if (dump_modulus != 0 && (transport_step % dump_modulus) == 0) dump(); + } +#ifdef DOS + output_msg(OUTPUT_SCREEN, "\n"); +#else + output_msg(OUTPUT_SCREEN, "%s%-80s", "\n", " "); +#endif + /* free_model_allocs(); */ +/* + * free mix structures + */ + if ((stag_data->exch_f > 0) && (stag_data->count_stag == 1)) { + mix_ptr = &mix[0]; + for (i = 0; i < count_mix; i++) mix_free(mix_ptr++); + count_mix =0; + } else { + if (nmix > 0) { + mix_ptr = &mix[count_mix - count_cells]; + for (i = count_mix - count_cells; i < count_mix; i++) { + mix_free(mix_ptr++); + } + count_mix -= count_cells; + mix = (struct mix *) PHRQ_realloc(mix, (size_t) (count_mix + 1)*sizeof(struct mix)); + if (mix == NULL) malloc_error(); + } + } + if (heat_nmix > 0) { + free_check_null(heat_mix_array); + free_check_null(temp1); + free_check_null(temp2); + } + + initial_total_time += rate_sim_time; + rate_sim_time = 0; + mass_water_switch = FALSE; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int init_mix(void) +/* ---------------------------------------------------------------------- */ +{ + LDBLE dav, lav, mixf, maxmix, corr_disp; + int i, n, nmix, count_comps, max_mix; + LDBLE *m; + + m = (LDBLE *) PHRQ_malloc((count_cells+1)*sizeof(LDBLE)); + if (m == NULL) malloc_error(); + +/* + * Define mixing factors among inner cells + */ + corr_disp = 1.; + if (correct_disp == TRUE && ishift != 0) { + if (bcon_first == 3) corr_disp += 1. / count_cells; + if (bcon_last == 3) corr_disp += 1. / count_cells; + } + maxmix = 0.0; + for (i=1; i < count_cells; i++) { + lav = (cell_data[i-1].length + cell_data[i].length)/2; + if (ishift != 0) { + dav = (cell_data[i-1].disp + cell_data[i].disp)/2; + } else { + dav = 0; + } + mixf = (diffc*timest/lav + dav) * corr_disp / lav; + + if (mixf > maxmix) maxmix = mixf; + m[i] = mixf; /* m[i] has mixf with lower cell */ + } +/* + * Also for boundary cells + */ + if (bcon_first == 1) { + lav = cell_data[0].length; + if (ishift != 0) { + dav = cell_data[0].disp; + } else { + dav = 0; + } + mixf = (diffc*timest/lav + dav)/lav; + if (mixf > maxmix) maxmix = mixf; + m[0] = 2*mixf; + } else { + m[0] = 0; + } + if (bcon_last == 1) { + lav = cell_data[count_cells-1].length; + if (ishift != 0) { + dav = cell_data[count_cells-1].disp; + } else { + dav = 0; + } + mixf = (diffc*timest/lav + dav)/lav; + if (mixf > maxmix) maxmix = mixf; + m[count_cells] = 2*mixf; + } else { + m[count_cells] = 0; + } +/* + * Find number of mixes + */ + if (maxmix == 0) { + nmix = 0; + } else { + if ((bcon_first == 1) || (bcon_last == 1)) { + nmix = 1 + (int) floor(4.5 * maxmix); + } else { + nmix = 1 + (int) floor(3.0 * maxmix); + } + if ((ishift != 0) && ((bcon_first == 1) || (bcon_last == 1))) { + if (nmix < 2) nmix = 2; + } + for (i=0; i<=count_cells; i++) m[i] /= nmix; + } + /* + * Fill mix structure + */ + if (nmix != 0) { + mix = (struct mix *) PHRQ_realloc(mix, (size_t) (count_mix + count_cells)*sizeof(struct mix)); + if (mix == NULL) malloc_error(); + count_mix += count_cells; + for (n = count_mix-count_cells; ncount_stag + 1) + 1) { + max_mix = count_cells * (stag_data->count_stag + 1) + 1; + } + for (i=1; i<=count_cells; i++) { + dav = 0; + count_comps = 0; + mix[n].description = (char *) free_check_null(mix[n].description); + mix[n].description = string_duplicate(" "); +/* + * max_mix brings n_user outside range of active cells + * mix[n].n_user = mix[n].n_user_end = -999 has same effect + * but max_mix keeps mix in sort order in case mix_bsearch + * is used + */ + mix[n].n_user = max_mix + i ; + mix[n].n_user_end = max_mix + i ; + + mix[n].comps[count_comps].n_solution = i-1; + mix[n].comps[count_comps].fraction = m[i-1]; + dav += m[i-1]; + count_comps++; + mix[n].comps[count_comps].n_solution = i+1; + mix[n].comps[count_comps].fraction = m[i]; + dav += m[i]; + count_comps++; + mix[n].comps[count_comps].n_solution = i; + mix[n].comps[count_comps].fraction = 1.0 - dav; + + n++; + } + } + m = (LDBLE *) free_check_null(m); + return(nmix); +} +/* ---------------------------------------------------------------------- */ +int mix_stag(int i, LDBLE kin_time, int punch, LDBLE step_fraction) +/* ---------------------------------------------------------------------- */ +{ + int n, k, l; + LDBLE t_imm; + struct solution *ptr_imm, *ptr_m; +#ifdef SKIP + char str[MAX_LENGTH]; +#endif +/* + * Kinetics in transport cell is done while transporting + */ + for (n=1; n<=stag_data->count_stag; n++) { + k = i+1+n*count_cells; + if ((ptr_imm = solution_bsearch(k, &use.n_solution, FALSE)) != NULL ) { + if (n == 1) { + if (heat_nmix > 0) { + ptr_m = solution_bsearch(i, &use.n_solution, FALSE); + t_imm = heat_mix_f_imm * ptr_m->tc + (1 - heat_mix_f_imm) * ptr_imm->tc; + ptr_m->tc = heat_mix_f_m * ptr_imm->tc + (1 - heat_mix_f_m) * ptr_m->tc; + cell_data[i-1].temp = ptr_m->tc; + cell_data[k-1].temp = ptr_imm->tc = t_imm; + /* equilibrate again ... */ + cell_no = i; + set_and_run_wrapper(i, NOMIX, FALSE, i, 0.0); + saver(); + cell_no = k; + set_and_run_wrapper(k, NOMIX, FALSE, k, 0.0); + saver(); + } +/* + * Mobile cell, kinetics already done ... + */ + cell_no = i; + set_and_run_wrapper(i, STAG, FALSE, -2, 0.0); + if ((use.kinetics_ptr = kinetics_bsearch(i, &l)) != NULL) { + use.n_kinetics_user = i; + use.kinetics_in = TRUE; + } + if ((punch == TRUE) && + (cell_data[i-1].punch == TRUE) && + (transport_step % punch_modulus == 0)) punch_all(); + if ((punch == TRUE) && + (cell_data[i-1].print == TRUE) && + (transport_step % print_modulus == 0)) { + print_all(); + } + saver(); + } + cell_no = k; + run_reactions(k, kin_time, STAG, step_fraction); + if ((cell_data[k-1].punch == TRUE) && + (punch == TRUE) && + (transport_step % punch_modulus == 0)) punch_all(); + if ((cell_data[k-1].print == TRUE) && + (punch == TRUE) && + (transport_step % print_modulus == 0)) { + print_all(); + } + saver(); + } + } + for (n=1; n<=stag_data->count_stag; n++) { + k = i+1+n*count_cells; + if (solution_bsearch(k, &use.n_solution, FALSE) != 0 ) { + solution_duplicate(-2-k, k); + if (n == 1) solution_duplicate(-2, i); + } + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int init_heat_mix(int nmix) +/* ---------------------------------------------------------------------- */ +{ + LDBLE lav, mixf, maxmix, corr_disp; + int i, j, k, n; + int heat_nmix; + LDBLE t0; +/* + * Check for need to model thermal diffusion... + */ + if (heat_diffc <= diffc) return(0); + if (count_cells < 2) return(0); + + heat_nmix = 0; + t0 = solution_bsearch(0, &n, FALSE)->tc; + for (i = 0; i < count_cells; i++) { + if (fabs(cell_data[i].temp - t0) > 1.0) { + heat_nmix = 1; + break; + } + } + if (heat_nmix == 0) { + if (fabs(solution_bsearch(count_cells+1, &n, FALSE)->tc - t0) > 1.0) heat_nmix = 1; + for (n = 1; n <= stag_data->count_stag; n++) { + for (i = 1; i < count_cells; i++) { + k = i+1+n*count_cells; + if (solution_bsearch(k, &j, FALSE) != 0 ) { + if (fabs(cell_data[k-1].temp - t0) > 1.0) { + heat_nmix = 1; + break; + } + } + } + } + } + if (heat_nmix == 0) return(0); +/* + * Initialize arrays... + */ + heat_mix_array = (LDBLE *) PHRQ_malloc((count_cells+2)*sizeof(LDBLE)); + if (heat_mix_array == NULL) malloc_error(); + temp1 = (LDBLE *) PHRQ_malloc((count_cells + 2)*sizeof(LDBLE)); + if (temp1 == NULL) malloc_error(); + temp2 = (LDBLE *) PHRQ_malloc((count_cells + 2)*sizeof(LDBLE)); + if (temp2 == NULL) malloc_error(); +/* + * Define mixing factors among inner cells... + */ + corr_disp = 1.; + if (correct_disp == TRUE && ishift != 0) { + if (bcon_first == 3) corr_disp += 1. / count_cells; + if (bcon_last == 3) corr_disp += 1. / count_cells; + } + if (nmix > 0) corr_disp /= nmix; + maxmix = 0.0; + for (i=1; i < count_cells; i++) { + lav = (cell_data[i-1].length + cell_data[i].length)/2; + mixf = (heat_diffc - diffc) * timest * corr_disp / tempr / (lav *lav); + if (mixf > maxmix) maxmix = mixf; + heat_mix_array[i+1] = mixf; /* m[i] has mixf with lower cell */ + } +/* + * Also for boundary cells + */ + if (bcon_first == 1) { + lav = cell_data[0].length; + mixf = (heat_diffc - diffc) * timest * corr_disp / tempr /(lav * lav); + if (2*mixf > maxmix) maxmix = 2*mixf; + heat_mix_array[1] = 2*mixf; + } else { + heat_mix_array[1] = 0; + } + if (bcon_last == 1) { + lav = cell_data[count_cells-1].length; + mixf = (heat_diffc - diffc) * timest * corr_disp / tempr /(lav * lav); + if (2*mixf > maxmix) maxmix = 2*mixf; + heat_mix_array[count_cells+1] = 2*mixf; + } else { + heat_mix_array[count_cells+1] = 0; + } +/* + * Find number of mixes + */ + if (maxmix == 0) { + heat_nmix = 0; + } else { + heat_nmix = 1 + (int) floor(3.0 * maxmix); + for (i=1; i <= count_cells + 1; i++) heat_mix_array[i] /= heat_nmix; + } + + return(heat_nmix); +} +/* ---------------------------------------------------------------------- */ +int heat_mix(int heat_nmix) +/* ---------------------------------------------------------------------- */ +{ + int i, j; + + for (i = 1; i <= count_cells; i++) temp1[i] = solution_bsearch(i, &j, FALSE)->tc; + temp1[0] = solution_bsearch(0, &j, FALSE)->tc; + temp1[count_cells+1] = solution_bsearch((count_cells+1), &j, FALSE)->tc; + + for (i = 1; i <= heat_nmix; i++) { + for (j = 1; j <= count_cells; j++) { + temp2[j] = heat_mix_array[j] * temp1[j-1] + + heat_mix_array[j+1] * temp1[j+1] + + (1 - heat_mix_array[j] - heat_mix_array[j+1]) * temp1[j]; + } + for (j = 1; j <= count_cells; j++) temp1[j] = temp2[j]; + } + + for (i = 1; i <= count_cells; i++) { + cell_data[i-1].temp = temp1[i]; + solution_bsearch(i, &j, FALSE)->tc = temp1[i]; + } + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int set_initial_moles(int i) +/* ---------------------------------------------------------------------- */ +{ + struct pp_assemblage *pp_assemblage_ptr; + struct gas_phase *gas_phase_ptr; + struct kinetics *kinetics_ptr; + struct s_s_assemblage *s_s_assemblage_ptr; + int j, k, n; + /* + * Pure phase assemblage + */ + pp_assemblage_ptr = pp_assemblage_bsearch (i, &n); + if (pp_assemblage_ptr != NULL) { + for (j = 0; j < pp_assemblage_ptr->count_comps; j++) { + pp_assemblage_ptr->pure_phases[j].initial_moles = pp_assemblage_ptr->pure_phases[j].moles; + if (pp_assemblage_ptr->pure_phases[j].initial_moles < 0) pp_assemblage_ptr->pure_phases[j].initial_moles = 0; + } + } + /* + * Gas phase + */ + gas_phase_ptr = gas_phase_bsearch (i, &n); + if (gas_phase_ptr != NULL) { + for (j = 0; j < gas_phase_ptr->count_comps; j++) { + gas_phase_ptr->comps[j].initial_moles = gas_phase_ptr->comps[j].moles; + } + } + /* + * Kinetics + */ + kinetics_ptr = kinetics_bsearch (i, &n); + if (kinetics_ptr != NULL) { + for (j = 0; j < kinetics_ptr->count_comps; j++) { + kinetics_ptr->comps[j].initial_moles = kinetics_ptr->comps[j].m; + } + } + /* + * Solid solutions + */ + s_s_assemblage_ptr = s_s_assemblage_bsearch (i, &n); + if (s_s_assemblage_ptr != NULL) { + for (k = 0; k < s_s_assemblage_ptr->count_s_s; k++) { + for (j = 0; j < s_s_assemblage_ptr->s_s[k].count_comps; j++) { + s_s_assemblage_ptr->s_s[k].comps[j].init_moles = s_s_assemblage_ptr->s_s[k].comps[j].moles; + } + } + } + return(OK); +} diff --git a/utilities.cpp b/utilities.cpp new file mode 100644 index 00000000..40a6e640 --- /dev/null +++ b/utilities.cpp @@ -0,0 +1,1471 @@ +#define EXTERNAL extern +#include "global.h" +#include "phqalloc.h" +#include "output.h" +#include "phrqproto.h" + +static char const svnid[] = "$Id: utilities.c 674 2005-11-21 15:01:22Z dlpark $"; + +#ifdef PHREEQ98 +extern int AutoLoadOutputFile, CreateToC; +extern int ProcessMessages, ShowProgress, ShowProgressWindow, ShowChart; +extern int outputlinenr; +extern int stop_calculations; +void AddToCEntry(char* a, int l, int i); +void ApplicationProcessMessages(void); +/* void check_line_breaks(char *s); */ +char err_str98[80]; +int copy_title(char *token_ptr, char **ptr, int *length); +extern int clean_up_null(void); +#endif + +static int isamong(char c, const char *s_l); + +/* ---------------------------------------------------------------------- */ +int add_elt_list(struct elt_list *elt_list_ptr, LDBLE coef) +/* ---------------------------------------------------------------------- */ +{ + struct elt_list *elt_list_ptr1; + if (svnid == NULL) fprintf(stderr," "); + + if (elt_list_ptr == NULL) return(OK); + + for (elt_list_ptr1=elt_list_ptr; elt_list_ptr1->elt != NULL; elt_list_ptr1++) { + if (count_elts >= max_elts) { + space ((void **) ((void *) &elt_list), count_elts, &max_elts, + sizeof(struct elt_list)); + } + elt_list[count_elts].elt = elt_list_ptr1->elt; + elt_list[count_elts].coef = elt_list_ptr1->coef * coef; + count_elts++; + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +LDBLE calc_alk(struct reaction *rxn_ptr) +/* ---------------------------------------------------------------------- */ +{ + int i; + LDBLE return_value; + struct master *master_ptr; + + return_value = 0.0; + for ( i=1; rxn_ptr->token[i].s != NULL; i++) { + master_ptr = rxn_ptr->token[i].s->secondary; + if (master_ptr == NULL ) { + master_ptr = rxn_ptr->token[i].s->primary; + } + if (master_ptr == NULL ) { + sprintf(error_string, "Non-master species in secondary reaction, %s.", rxn_ptr->token[0].s->name); + error_msg(error_string, CONTINUE); + input_error++; + break; + } + return_value += rxn_ptr->token[i].coef * master_ptr->alk; + } + return (return_value); +} +/* ---------------------------------------------------------------------- */ +int compute_gfw(const char *string, LDBLE *gfw) +/* ---------------------------------------------------------------------- */ +{ +/* + * Input: string contains a chemical formula + * Output: gfw contains the calculated gfw + */ + int i; + char token[MAX_LENGTH]; + char *ptr; + + count_elts=0; + paren_count=0; + strcpy(token, string); + ptr = token; + if (get_elts_in_species (&ptr, 1.0) == ERROR) { + return(ERROR); + } + *gfw=0.0; + for (i=0; i < count_elts; i++) { + if (elt_list[i].elt->gfw <= 0.0) { + return(ERROR); + } + *gfw += elt_list[i].coef*(elt_list[i].elt)->gfw; + } + return (OK); +} +/* ---------------------------------------------------------------------- */ +int copy_token (char *token_ptr, char **ptr, int *length) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies from **ptr to *token_ptr until first space is encountered. + * + * Arguments: + * *token_ptr output, place to store token + * + * **ptr input, character string to read token from + * output, next position after token + * + * length output, length of token + * + * Returns: + * UPPER, + * LOWER, + * DIGIT, + * EMPTY, + * UNKNOWN. + */ + int i, return_value; + char c; + +/* + * Read to end of whitespace + */ + while ( isspace((int) (c=**ptr)) ) (*ptr)++; +/* + * Check what we have + */ + if ( isupper((int) c) || c == '[') { + return_value=UPPER; + } else if ( islower((int) c) ) { + return_value=LOWER; + } else if ( isdigit((int) c) || c=='.' || c=='-') { + return_value=DIGIT; + } else if ( c == '\0') { + return_value=EMPTY; + } else { + return_value=UNKNOWN; + } +/* + * Begin copying to token + */ + i=0; + while ( ( ! isspace ((int) (c=**ptr)) ) && + /* c != ',' && */ + c != ';' && + c != '\0' ) { + token_ptr[i]=c; + (*ptr)++; + i++; + } + token_ptr[i]='\0'; + *length=i; +#ifdef PHREEQ98 + if ((return_value == DIGIT) && (strstr(token_ptr, ",") != NULL)) { + sprintf(error_string, "Commas are not allowed as decimal separator: %s.", token_ptr); + error_msg(error_string, CONTINUE); + } +#endif + return(return_value); +} +#ifdef PHREEQ98 +/* ---------------------------------------------------------------------- */ +int copy_title(char *token_ptr, char **ptr, int *length) +/* ---------------------------------------------------------------------- */ +{ +/* + * Copies from **ptr to *token_ptr until first space or comma is encountered. + * + * Arguments: + * *token_ptr output, place to store token + * + * **ptr input, character string to read token from + * output, next position after token + * + * length output, length of token + * + * Returns: + * UPPER, + * LOWER, + * DIGIT, + * EMPTY, + * UNKNOWN. + */ + int i, return_value; + char c; + int Quote = FALSE; + +/* + * Read to end of whitespace + */ + while ( isspace((int) (c=**ptr)) || (c == ',') || (c == '"')) { + if (c == '"') Quote = TRUE; + (*ptr)++; + } +/* + * Check what we have + */ + if ( isupper((int) c) ) { + return_value=UPPER; + } else if ( islower((int) c) ) { + return_value=LOWER; + } else if ( isdigit((int) c) || c=='.' || c=='-') { + return_value=DIGIT; + } else if ( c == '\0') { + return_value=EMPTY; + } else { + return_value=UNKNOWN; + } +/* + * Begin copying to token + */ + i=0; + if (Quote == TRUE) { + while ( ( (int) (c=**ptr) != '"' ) && + c != '\0' ) { + token_ptr[i]=c; + (*ptr)++; + i++; + } + } else { + while ( ( ! isspace ((int) (c=**ptr)) ) && + c != ',' && + c != ';' && + c != '\0' ) { + token_ptr[i]=c; + (*ptr)++; + i++; + } + } + token_ptr[i]='\0'; + *length=i; + return(return_value); +} +#endif +/* ---------------------------------------------------------------------- */ +int dup_print(const char *ptr, int emphasis) +/* ---------------------------------------------------------------------- */ +{ +/* + * print character string to output and logfile + * if emphasis == TRUE the print is set off by + * a row of dashes before and after the character string. + * + */ + int l, i; + char *dash; + + if (pr.headings == FALSE) return(OK); +#ifdef PHREEQ98 + if ((CreateToC == TRUE) && (AutoLoadOutputFile == TRUE)) { + if (strstr(ptr,"Reading") == ptr) AddToCEntry((char*)ptr, 1, outputlinenr); + else if (strstr(ptr,"Beginning") == ptr) AddToCEntry((char*)ptr, 2, outputlinenr); + else if ((strstr(ptr,"TITLE") != ptr) && (strstr(ptr,"End") != ptr)) AddToCEntry((char*)ptr, 3, outputlinenr); + } +#endif + l = strlen(ptr); + dash = (char *) PHRQ_malloc((size_t) (l+2) * sizeof(char)); + if (dash == NULL) malloc_error(); + if (emphasis == TRUE) { + for (i = 0; i < l; i++) dash[i] = '-'; + dash[i] = '\0'; + output_msg(OUTPUT_MESSAGE,"%s\n%s\n%s\n\n", dash, ptr, dash); + output_msg(OUTPUT_LOG,"%s\n%s\n%s\n\n", dash, ptr, dash); + } else { + output_msg(OUTPUT_MESSAGE,"%s\n\n", ptr); + output_msg(OUTPUT_LOG,"%s\n\n", ptr); + } + dash = (char*) free_check_null(dash); + + return(OK); +} +/* ---------------------------------------------------------------------- */ +int equal (LDBLE a, LDBLE b, LDBLE eps) +/* ---------------------------------------------------------------------- */ +{ +/* + * Checks equality between two LDBLE precision numbers + */ + if( fabs(a-b) <= eps ) return(TRUE); + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +void *free_check_null(void *ptr) +/* ---------------------------------------------------------------------- */ +{ + if (ptr != NULL) { + free(ptr); + } + return(NULL); +} +/* ---------------------------------------------------------------------- */ +int get_token(char **eqnaddr, char *string, LDBLE *z, int *l) +/* ---------------------------------------------------------------------- */ +/* + * Function finds next species in equation, coefficient has already + * been removed. Also determines charge on the species. + * + * Arguments: + * *eqnaddr input, pointer to position in eqn to start parsing + * output, pointer to a pointer to next position in eqn to start + * parsing. + * *string input pointer to place to store token + * *z charge on token + * *l length of token + * + * Returns: + * ERROR, + * OK. + */ +{ + int i, j; + int ltoken, lcharge; + char c; + char *ptr, *ptr1, *rest; + char charge[MAX_LENGTH]; + + rest=*eqnaddr; + ptr=*eqnaddr; + i=0; +/* + * Find end of token or begining of charge + */ + while ( ( (c=*ptr) != '+' ) && + (c != '-') && + (c != '=') && + (c != '\0') ) { + string[i++]=c; + if (c == '[') { + ptr++; + while ((c=*ptr) != ']') { + if (c == '\0') { + sprintf(error_string, "No final bracket \"]\" for element name, %s.", string); + error_msg(error_string, CONTINUE); + return(ERROR); + } + string[i++]=c; + if (i >= MAX_LENGTH ) { + output_msg(OUTPUT_MESSAGE, + "Species name greater than MAX_LENGTH (%d) characters.\n%s\n", + MAX_LENGTH,string); + return(ERROR); + } + ptr++; + } + string[i++]=c; + } + + /* check for overflow of space */ + if (i >= MAX_LENGTH ) { + output_msg(OUTPUT_MESSAGE, + "Species name greater than MAX_LENGTH (%d) characters.\n%s\n", + MAX_LENGTH,string); + return(ERROR); + } + ptr++; + } + string[i]='\0'; + ltoken=i; +/* + * Check for an empty string + */ + if(i == 0){ + sprintf(error_string, "NULL string detected in get_token, %s.",rest); + error_msg(error_string, CONTINUE); + return(ERROR); + } +/* + * End of token is = or \0, charge is zero + */ + if(c == '=' || c == '\0'){ + *eqnaddr=ptr; + lcharge=0; + *z=0.0; + } else { +/* + * Copy characters into charge until next species or end is detected + */ + j=0; + ptr1=ptr; + while( (isalpha((int) (c=*ptr1)) == FALSE) && + (c != '(') && + (c != ')') && + (c != ']') && + (c != '[') && + (c != '=') && + (c != '\0') ) { + charge[j++]=c; + /* error if no more space */ + if (j >= MAX_LENGTH ) { + error_msg("The charge on a species has exceeded MAX_LENGTH characters.", CONTINUE); + return(ERROR); + } + ptr1++; + } +/* + * Go back to last + or - if not end of side, + * everything before the last + or - in charge is part of the charge + */ + if( (c != '=') && (c != '\0') ) { + while( ((c=*ptr1) != '+') && (c != '-') ) { + j--; + ptr1--; + } + } + charge[j]='\0'; + lcharge=j; + *eqnaddr=ptr1; +/* + * Charge has been written, now need to check if charge has legal format + */ + if ( get_charge( charge, z) == OK ) { + strcat( string, charge); + } else { + return(ERROR); + } + } + *l=ltoken+lcharge; + return(OK); +} +/* ---------------------------------------------------------------------- */ +int isamong(char c, const char *s_l) +/* ---------------------------------------------------------------------- */ +/* + * Function checks if c is among the characters in the string s + * + * Arguments: + * c input, character to check + * *s string of characters + * + * Returns: + * TRUE if c is in set, + * FALSE if c in not in set. + */ +{ + int i; + + for (i=0; s_l[i] != '\0'; i++) { + if (c == s_l[i]) { + return(TRUE); + } + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +int islegit(const char c) +/* ---------------------------------------------------------------------- */ +/* + * Function checks for legal characters for chemical equations + * + * Argument: + * c input, character to check + * + * Returns: + * TRUE if c is in set, + * FALSE if c in not in set. + */ +{ + if( isalpha((int) c) || + isdigit((int) c) || + isamong(c,"+-=().:_[]") ){ + return(TRUE); + } + return(FALSE); +} +/* ---------------------------------------------------------------------- */ +void malloc_error (void) +/* ---------------------------------------------------------------------- */ +{ + error_msg("NULL pointer returned from malloc or realloc.", + CONTINUE); + error_msg("Program terminating.", STOP); + return; +} +/* ---------------------------------------------------------------------- */ +int parse_couple(char *token) +/* ---------------------------------------------------------------------- */ +{ +/* + * Parse couple puts redox couples in standard form + * "+" is removed and couples are rewritten in sort + * order. + */ + int e1, e2, p1, p2; + char *ptr; + char elt1[MAX_LENGTH], elt2[MAX_LENGTH], paren1[MAX_LENGTH], paren2[MAX_LENGTH]; + + if (strcmp_nocase_arg1(token,"pe") == 0) { + str_tolower(token); + return(OK); + } + while (replace("+","",token) == TRUE); + ptr=token; + get_elt( &ptr, elt1, &e1); + if (*ptr != '(') { + sprintf(error_string, "Element name must be followed by " + "parentheses in redox couple, %s.", token); + error_msg(error_string, CONTINUE); + parse_error++; + return(ERROR); + } + paren_count=1; + paren1[0]='('; + p1=1; + while ( ptr != '\0') { + ptr++; + if (*ptr == '/' || *ptr == '\0') { + sprintf(error_string, "End of line or ""/"" encountered before end of parentheses, %s.", token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + paren1[p1++]=*ptr; + if (*ptr == '(') paren_count++; + if (*ptr == ')') paren_count--; + if (paren_count == 0) break; + } + paren1[p1]='\0'; + ptr++; + if (*ptr != '/') { + sprintf(error_string, " ""/"" must follow parentheses " + "ending first half of redox couple, %s.", token); + error_msg(error_string, CONTINUE); + parse_error++; + return(ERROR); + } + ptr++; + get_elt( &ptr, elt2, &e2); + if (strcmp(elt1,elt2) != 0) { + sprintf(error_string, "Redox couple must be two redox states " + "of the same element, %s.", token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + if (*ptr != '(') { + sprintf(error_string, "Element name must be followed by " + "parentheses in redox couple, %s.", token); + error_msg(error_string, CONTINUE); + parse_error++; + return(ERROR); + } + paren2[0]='('; + paren_count=1; + p2=1; + while ( *ptr != '\0') { + ptr++; + if (*ptr == '/' || *ptr == '\0') { + sprintf(error_string, "End of line or ""/"" encountered" + " before end of parentheses, %s.", token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + + paren2[p2++]=*ptr; + if (*ptr == '(') paren_count++; + if (*ptr == ')') paren_count--; + if (paren_count == 0) break; + } + paren2[p2]='\0'; + if (strcmp(paren1,paren2) < 0) { + strcpy(token,elt1); + strcat(token,paren1); + strcat(token,"/"); + strcat(token,elt2); + strcat(token,paren2); + } else if (strcmp(paren1,paren2) > 0) { + strcpy(token,elt2); + strcat(token,paren2); + strcat(token,"/"); + strcat(token,elt1); + strcat(token,paren1); + } else { + sprintf(error_string, "Both parts of redox couple are the same, %s.",token); + error_msg(error_string, CONTINUE); + return(ERROR); + } + return(OK); +} +/* ---------------------------------------------------------------------- */ +int print_centered(const char *string) +/* ---------------------------------------------------------------------- */ +{ + int i, l, l1, l2; + char token[MAX_LENGTH]; + +#ifdef PHREEQ98 + if ((CreateToC == TRUE) && (AutoLoadOutputFile == TRUE)) AddToCEntry((char*)string, 4, outputlinenr); +#endif + l = strlen(string); + l1 = (79 - l)/2; + l2 = 79 -l -l1; + for (i=0; i < l1; i++) token[i]='-'; + token[i]='\0'; + strcat(token, string); + for (i=0; i < l2; i++) token[i + l1 + l]='-'; + token[79] = '\0'; + output_msg(OUTPUT_MESSAGE,"%s\n\n",token); + return(OK); +} +/* ---------------------------------------------------------------------- */ +int replace(const char *str1, const char *str2, char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function replaces str1 with str2 in str + * + * Arguments: + * str1 search str for str1 + * str2 replace str1 if str1 found in str + * str string to be searched + * + * Returns + * TRUE if string was replaced + * FALSE if string was not replaced + */ + int l, l1, l2; + char *ptr_start; + + ptr_start=strstr(str, str1); +/* + * Str1 not found, return + */ + if (ptr_start == NULL) return(FALSE); +/* + * Str1 found, replace Str1 with Str2 + */ + l=strlen(str); + l1=strlen(str1); + l2=strlen(str2); +/* + * Make gap in str long enough for str2 + */ +#ifdef SKIP + if (l2 < l1) { + for (ptr = (ptr_start + l1); ptr < ptr_start + l; ptr++) { + ptr1= ptr + l2 - l1; + *ptr1=*ptr; + if (*ptr == '\0') break; + } + } else { + for ( ptr = (str+l); ptr >= ptr_start + l1; ptr--) { + ptr1=ptr+l2-l1; + *ptr1=*ptr; + } + } +#endif + /* The plus one includes the terminating NULL */ + memmove(ptr_start + l2, ptr_start + l1, l - (ptr_start - str + l1) + 1); +/* + * Copy str2 into str + */ +#ifdef SKIP + ptr1=ptr_start; + for (ptr = (char *) str2; *ptr != '\0'; ptr++) { + *ptr1=*ptr; + ptr1++; + } +#endif + memcpy(ptr_start, str2, l2); + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +void space (void **ptr, int i, int *max, int struct_size) +/* ---------------------------------------------------------------------- */ +{ +/* + * Routine has 4 functions, allocate space, reallocate space, test to + * determine whether space is available, and free space. + * + * Arguments: + * ptr pointer to malloced space + * i value for test + * i = INIT, allocates space + * i >= 0 && i < max, space is available, return + * i >= max, reallocate space + * i = FREE, free space. + * max maximum value for i with available space + * struct size size of structure to be allocated + */ +/* + * Return if space exists + */ + if ( ( i >= 0 ) && ( i + 1 < *max ) ) { + return; + } +/* + * Realloc space + */ + if ( i+1 >= *max ) { + if (*max > 1000) { + *max += 1000; + } else { + *max *= 2; + } + if (i+1 > *max) *max = i + 1; + *ptr = PHRQ_realloc( *ptr, (size_t) (*max)*struct_size ); + if (*ptr == NULL ) malloc_error(); + return; + } +/* + * Allocate space + */ + if ( i == INIT ) { +/* free(*ptr); */ + *ptr=PHRQ_malloc((size_t) (*max)*struct_size); + if (*ptr == NULL ) malloc_error(); + return; + } +/* + * Free space + */ +/* + if ( i == FREE ) { + free(*ptr); + return; + } + */ +/* + * Error + */ + error_msg("Illegal argument to function space.", CONTINUE); + error_msg("Program terminating.", STOP); + return; +} +/* ---------------------------------------------------------------------- */ +void squeeze_white(char *s_l) +/* ---------------------------------------------------------------------- */ +/* + * Delete all white space from string s + * + * Argument: + * *s_l input, character string, possibly containing white space + * output, character string with all white space removed + * + * Return: void + */ +{ + int i, j; + + for (i = j = 0; s_l[i] != '\0'; i++){ + if (! isspace((int) s_l[i])) s_l[j++]=s_l[i]; + } + s_l[j]='\0'; +} +/* ---------------------------------------------------------------------- */ +void str_tolower(char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Replaces string, str, with same string, lower case + */ + char *ptr; + ptr=str; + while (*ptr != '\0') { + *ptr= (char) tolower(*ptr); + ptr++; + } +} +/* ---------------------------------------------------------------------- */ +void str_toupper(char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Replaces string, str, with same string, lower case + */ + char *ptr; + ptr=str; + while (*ptr != '\0') { + *ptr= (char) toupper(*ptr); + ptr++; + } +} +/* ---------------------------------------------------------------------- */ +int strcmp_nocase(const char *str1, const char *str2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare two strings disregarding case + */ + int c1, c2; + while ((c1 = tolower(*str1++)) == (c2 = tolower(*str2++))) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} +/* ---------------------------------------------------------------------- */ +int strcmp_nocase_arg1(const char *str1, const char *str2) +/* ---------------------------------------------------------------------- */ +{ +/* + * Compare two strings disregarding case + */ + int c1, c2; + while ((c1 = tolower(*str1++)) == (c2 = *str2++)) { + if (c1 == '\0') return(0); + } + if (c1 < c2) return(-1); + return(1); +} +/* ---------------------------------------------------------------------- */ +char * string_duplicate (const char *token) +/* ---------------------------------------------------------------------- */ +{ + int l; + char *str; + + if (token == NULL) return NULL; + l = strlen(token); + str = (char *) PHRQ_malloc((size_t) (l +1) * sizeof(char) ); + if (str == NULL) malloc_error(); + strcpy (str, token); + return(str); +} +/* ---------------------------------------------------------------------- */ +char *string_hsave (const char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Save character string str + * + * Arguments: + * str input string to save. + * l input, length of str + * + * Returns: + * starting address of saved string (str) + */ + char *new_string; + ENTRY item, *found_item; + + new_string = string_duplicate(str); + item.key = new_string; + item.data = new_string; + found_item = hsearch_multi(strings_hash_table, item, ENTER); + if (found_item->key == new_string) { + count_strings++; + return(new_string); + } + new_string = (char*) free_check_null(new_string); + return(found_item->key); +} +/* ---------------------------------------------------------------------- */ +LDBLE under (LDBLE xval) +/* ---------------------------------------------------------------------- */ +{ +/* + * Exponentiate a number, x, but censor large and small numbers + * log values less than MIN_LM are set to 0 + * log values greater than MAX_LM are set to 10**MAX_LM + */ +/* if (xval < MIN_LM) { */ + if (xval < -40.) { + return(0.0); + } +/* if (xval > MAX_LM) { */ + if (xval > 3.) { + return ( 1.0e3 ); +/* return ( pow (10.0, MAX_LM));*/ + } +/* return (pow (10.0, xval)); */ + return (exp (xval * LOG_10)); +} +/* ---------------------------------------------------------------------- */ +int backspace_screen (int spaces) +/* ---------------------------------------------------------------------- */ +{ + int i; + char token[MAX_LENGTH]; + for (i = 0; i < spaces; i++) { + token[i] = '\b'; + } + token[i] = '\0'; + output_msg(OUTPUT_SCREEN,"%s",token); + return(OK); +} +#ifndef PHREEQCI_GUI +/* ---------------------------------------------------------------------- */ +int status (int count, const char *str) +/* ---------------------------------------------------------------------- */ +{ + static int spinner; + char sim_str[20]; + char state_str[45]; + char spin_str[2]; +/* char all[MAX_LENGTH]; */ +#ifdef PHREEQ98 + if (ProcessMessages) ApplicationProcessMessages(); + if (stop_calculations == TRUE) error_msg("Execution canceled by user.", STOP); +#endif + + if (pr.status == FALSE || phast == TRUE) return(OK); + sprintf(sim_str,"Simulation %d.", simulation); + sprintf(state_str," "); + sprintf(spin_str," "); + + if (state == INITIALIZE) { + output_msg(OUTPUT_SCREEN,"\n%-80s","Initializing..."); + + status_on = TRUE; + return(OK); + } +/* + * If str is defined print it + */ + if (str != NULL) { + if (status_on == TRUE) { + backspace_screen(80); + } else { + status_on = TRUE; + } +#ifdef DOS + backspace_screen(80); + /* if (state == TRANSPORT ) backspace_screen(80); */ + output_msg(OUTPUT_SCREEN, "%-79s", str); +#else + output_msg(OUTPUT_SCREEN, "%-80s", str); +#endif + } else if (state != TRANSPORT && state != PHAST ) { + if (state == INITIAL_SOLUTION) { + sprintf(state_str, "Initial solution %d.", use.solution_ptr->n_user); + } else if (state == INITIAL_EXCHANGE) { + sprintf(state_str, "Initial exchange %d.", use.exchange_ptr->n_user); + } else if (state == INITIAL_SURFACE) { + sprintf(state_str, "Initial surface %d.", use.surface_ptr->n_user); + } else if (state == INVERSE) { + sprintf(state_str, "Inverse %d. Models = %d.", + use.inverse_ptr->n_user, count); + } else if (state == REACTION) { + if (use.kinetics_in == TRUE) { + sprintf(state_str, "Kinetic step %d.", reaction_step); + } else { + sprintf(state_str, "Reaction step %d.", reaction_step); + } + } else if (state == ADVECTION || state == TRANSPORT) { + if (state == ADVECTION) { + sprintf(state_str, "Advection, shift %d.", advection_step); + } else if (state == TRANSPORT) { + sprintf(state_str, "Transport, shift %d.", transport_step); + } + spinner++; + if (spinner == 1) { + spin_str[0] = '/'; + } else if (spinner == 2) { + spin_str[0] = '-'; + } else { + spin_str[0] = '\\'; + spinner = 0; + } + } + if (status_on == TRUE) { + backspace_screen(80); + } else { + status_on = TRUE; + } + if (use.kinetics_in == TRUE) { +#ifdef DOS + backspace_screen(80); + output_msg(OUTPUT_SCREEN, "%-15s%-27s%37s", sim_str, state_str, " "); +#else + output_msg(OUTPUT_SCREEN, "%-15s%-27s%38s", sim_str, state_str, " "); +#endif + + } else { +#ifdef DOS + backspace_screen(80); + output_msg(OUTPUT_SCREEN, "%-15s%-27s%1s%36s", sim_str, state_str, spin_str, " "); +#else + output_msg(OUTPUT_SCREEN, "%-15s%-27s%1s%37s", sim_str, state_str, spin_str, " "); +#endif + } + } + return(OK); +} +#endif /*PHREEQCI_GUI*/ +/* +** Dynamic hashing, after CACM April 1988 pp 446-457, by Per-Ake Larson. +** Coded into C, with minor code improvements, and with hsearch(3) interface, +** by ejp@ausmelb.oz, Jul 26, 1988: 13:16; +** also, hcreate/hdestroy routines added to simulate hsearch(3). +** +** These routines simulate hsearch(3) and family, with the important +** difference that the hash table is dynamic - can grow indefinitely +** beyond its original size (as supplied to hcreate()). +** +** Performance appears to be comparable to that of hsearch(3). +** The 'source-code' options referred to in hsearch(3)'s 'man' page +** are not implemented; otherwise functionality is identical. +** +** Compilation controls: +** DEBUG controls some informative traces, mainly for debugging. +** HASH_STATISTICS causes HashAccesses and HashCollisions to be maintained; +** when combined with DEBUG, these are displayed by hdestroy(). +** +** Problems & fixes to ejp@ausmelb.oz. WARNING: relies on pre-processor +** concatenation property, in probably unnecessary code 'optimisation'. +** Esmond Pitt, Austec (Asia/Pacific) Ltd +** ...!uunet.UU.NET!munnari!ausmelb!ejp,ejp@ausmelb.oz +*/ + +# include + +/* +** Fast arithmetic, relying on powers of 2, +** and on pre-processor concatenation property +*/ + +/* rewrote to remove MUL and DIV */ +#ifdef SKIP +# define MUL(x,y) ((x) << (y/**/Shift)) +# define DIV(x,y) ((x) >> (y/**/Shift)) +#endif +# define MOD(x,y) ((x) & ((y)-1)) + +/* +** local data templates +*/ + + +/* +** external routines +*/ + +/* +extern char *calloc(); +extern int free(); + */ +/* +** Entry points +*/ + + +/* +** Internal routines +*/ + +static Address Hash_multi(HashTable *Table, char *Key); +static void ExpandTable_multi(HashTable *Table); + +/* +** Local data +*/ + +#ifdef HASH_STATISTICS +static long HashAccesses, HashCollisions; +#endif + +/* +** Code +*/ + +int hcreate_multi(unsigned Count, HashTable **HashTable_ptr) +{ + int i; + HashTable *Table; + /* + ** Adjust Count to be nearest higher power of 2, + ** minimum SegmentSize, then convert into segments. + */ + i = SegmentSize; + while (i < (int) Count) + i <<= 1; +/* Count = DIV(i,SegmentSize); */ + Count = ((i) >> (SegmentSizeShift)); + + Table = (HashTable*) PHRQ_calloc(sizeof(HashTable),1); + *HashTable_ptr = Table; + + if (Table == NULL) + return(0); + /* + ** resets are redundant - done by calloc(3) + ** + Table->SegmentCount = Table->p = Table->KeyCount = 0; + */ + /* + ** Allocate initial 'i' segments of buckets + */ + for (i = 0; i < (int) Count; i++) + { + Table->Directory[i] = (Segment*)PHRQ_calloc(sizeof(Segment),SegmentSize); + if (Table->Directory[i] == NULL) + { + hdestroy_multi(Table); + return(0); + } + Table->SegmentCount++; + } +/* Table->maxp = MUL(Count,SegmentSize); */ + Table->maxp = (short) ((Count) << (SegmentSizeShift)); + Table->MinLoadFactor = 1; + Table->MaxLoadFactor = DefaultMaxLoadFactor; +#ifdef DEBUG + output_msg(OUTPUT_STDERR, + "[hcreate] Table %x Count %d maxp %d SegmentCount %d\n", + Table, + Count, + Table->maxp, + Table->SegmentCount + ); +#endif +#ifdef HASH_STATISTICS + HashAccesses = HashCollisions = 0; +#endif + return(1); +} + +void hdestroy_multi(HashTable *Table) +{ + int i,j; + Segment *seg; + Element *p,*q; + + if (Table != NULL) + { + for (i = 0; i < Table->SegmentCount; i++) + { + /* test probably unnecessary */ + if ((seg = Table->Directory[i]) != NULL) { + for (j = 0; j < SegmentSize; j++) { + p = seg[j]; + while (p != NULL) { + q = p->Next; + free((void*)p); + p = q; + } + } + free(Table->Directory[i]); + } + } + free(Table); + /* Table = NULL; */ +#if defined(HASH_STATISTICS) && defined(DEBUG) + output_msg(OUTPUT_STDERR, + "[hdestroy] Accesses %ld Collisions %ld\n", + HashAccesses, + HashCollisions + ); +#endif + } +} + +ENTRY * hsearch_multi(HashTable *Table, ENTRY item, ACTION action) +/* ACTION FIND/ENTER */ +{ + Address h; + Segment *CurrentSegment; + int SegmentIndex; + int SegmentDir; + Segment *p,q; + + assert(Table != NULL); /* Kinder really than return(NULL); */ +#ifdef HASH_STATISTICS + HashAccesses++; +#endif + h = Hash_multi(Table, item.key); +/* SegmentDir = DIV(h,SegmentSize); */ + SegmentDir = ((h) >> (SegmentSizeShift)); + SegmentIndex = MOD(h,SegmentSize); + /* + ** valid segment ensured by Hash() + */ + CurrentSegment = Table->Directory[SegmentDir]; + assert(CurrentSegment != NULL); /* bad failure if tripped */ + p = &CurrentSegment[SegmentIndex]; + q = *p; + /* + ** Follow collision chain + */ + while (q != NULL && strcmp(q->Key,item.key)) + { + p = &q->Next; + q = *p; +#ifdef HASH_STATISTICS + HashCollisions++; +#endif + } + if ( + q != NULL /* found */ + || + action == FIND /* not found, search only */ + || + (q = (Element*)PHRQ_calloc(sizeof(Element),1)) + == + NULL /* not found, no room */ + ) + return((ENTRY*)q); + *p = q; /* link into chain */ + /* + ** Initialize new element + */ + q->Key = item.key; + q->Data =(char*) item.data; + /* + ** cleared by calloc(3) + q->Next = NULL; + */ + /* + ** Table over-full? + */ +/* if (++Table->KeyCount / MUL(Table->SegmentCount,SegmentSize) > Table->MaxLoadFactor) */ + if (++Table->KeyCount / ((Table->SegmentCount) << (SegmentSizeShift)) > Table->MaxLoadFactor) + ExpandTable_multi(Table); /* doesn't affect q */ + return((ENTRY*)q); +} + +/* +** Internal routines +*/ + +static Address Hash_multi(HashTable *Table, char *Key) +{ + Address h,address; + register unsigned char *k = (unsigned char*)Key; + + h = 0; + /* + ** Convert string to integer + */ + while (*k) + h = h*Prime1 ^ (*k++ - ' '); + h %= Prime2; + address = MOD(h,Table->maxp); + if (address < (unsigned long) Table->p) + address = MOD(h,(Table->maxp << 1)); /* h % (2*Table->maxp) */ + return(address); +} + +void ExpandTable_multi(HashTable *Table) +{ + Address NewAddress; + int OldSegmentIndex,NewSegmentIndex; + int OldSegmentDir,NewSegmentDir; + Segment *OldSegment,*NewSegment; + Element *Current,**Previous,**LastOfNew; + +/* if (Table->maxp + Table->p < MUL(DirectorySize,SegmentSize)) */ + if (Table->maxp + Table->p < ((DirectorySize) << (SegmentSizeShift))) + { + /* + ** Locate the bucket to be split + */ +/* OldSegmentDir = DIV(Table->p,SegmentSize); */ + OldSegmentDir = ((Table->p) >> (SegmentSizeShift)); + OldSegment = Table->Directory[OldSegmentDir]; + OldSegmentIndex = MOD(Table->p,SegmentSize); + /* + ** Expand address space; if necessary create a new segment + */ + NewAddress = Table->maxp + Table->p; +/* NewSegmentDir = DIV(NewAddress,SegmentSize); */ + NewSegmentDir = ((NewAddress) >> (SegmentSizeShift)); + NewSegmentIndex = MOD(NewAddress,SegmentSize); + if (NewSegmentIndex == 0) + Table->Directory[NewSegmentDir] = (Segment*)PHRQ_calloc(sizeof(Segment),SegmentSize); + NewSegment = Table->Directory[NewSegmentDir]; + /* + ** Adjust state variables + */ + Table->p++; + if (Table->p == Table->maxp) + { + Table->maxp <<= 1; /* Table->maxp *= 2 */ + Table->p = 0; + } + Table->SegmentCount++; + /* + ** Relocate records to the new bucket + */ + Previous = &OldSegment[OldSegmentIndex]; + Current = *Previous; + LastOfNew = &NewSegment[NewSegmentIndex]; + *LastOfNew = NULL; + while (Current != NULL) + { + if (Hash_multi(Table, Current->Key) == NewAddress) + { + /* + ** Attach it to the end of the new chain + */ + *LastOfNew = Current; + /* + ** Remove it from old chain + */ + *Previous = Current->Next; + LastOfNew = &Current->Next; + Current = Current->Next; + *LastOfNew = NULL; + } + else + { + /* + ** leave it on the old chain + */ + Previous = &Current->Next; + Current = Current->Next; + } + } + } +} + + +void free_hash_strings(HashTable *Table) +{ + int i,j; + Segment *seg; + Element *p,*q; + + if (Table != NULL) + { + for (i = 0; i < Table->SegmentCount; i++) + { + /* test probably unnecessary */ + if ((seg = Table->Directory[i]) != NULL) { + for (j = 0; j < SegmentSize; j++) { + p = seg[j]; + while (p != NULL) { + q = p->Next; + p->Data = (char*) free_check_null((void*)p->Data); + p = q; + } + } + } + } +#if defined(HASH_STATISTICS) && defined(DEBUG) + output_msg(OUTPUT_STDERR, + "[hdestroy] Accesses %ld Collisions %ld\n", + HashAccesses, + HashCollisions + ); +#endif + } +} +/* ---------------------------------------------------------------------- */ +int string_trim (char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function trims white space from left and right of string + * + * Arguments: + * str string to trime + * + * Returns + * TRUE if string was changed + * FALSE if string was not changed + * EMPTY if string is all whitespace + */ + int i, l, start, end, length; + char *ptr_start; + + l=strlen(str); + /* + * leading whitespace + */ + for (i = 0; i < l; i++) { + if (isspace((int) str[i])) continue; + break; + } + if (i == l) return(EMPTY); + start = i; + ptr_start = &(str[i]); + /* + * trailing whitespace + */ + for (i = l-1; i >= 0; i--) { + if (isspace((int) str[i])) continue; + break; + } + end = i; + if (start == 0 && end == l) return(FALSE); + length = end - start + 1; + memmove((void *) str, (void *) ptr_start, (size_t) length); + str[length] = '\0'; + + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int string_trim_right (char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function trims white space from right of string + * + * Arguments: + * str string to trime + * + * Returns + * TRUE if string was changed + * FALSE if string was not changed + * EMPTY if string is all whitespace + */ + int i, l, end, length; + + l=strlen(str); + for (i = l-1; i >= 0; i--) { + if (isspace((int) str[i])) continue; + break; + } + end = i; + length = end + 1; + str[length] = '\0'; + if (end == 0) return(EMPTY); + if (end == l) return(FALSE); + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +int string_trim_left (char *str) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function trims white space from left of string + * + * Arguments: + * str string to trime + * + * Returns + * TRUE if string was changed + * FALSE if string was not changed + * EMPTY if string is all whitespace + */ + int i, l, start, end, length; + char *ptr_start; + + l=strlen(str); + /* + * leading whitespace + */ + for (i = 0; i < l; i++) { + if (isspace((int) str[i])) continue; + break; + } + if (i == l) return(EMPTY); + start = i; + ptr_start = &(str[i]); + end = l; + if (start == 0 && end == l) return(FALSE); + length = end - start + 1; + memmove((void *) str, (void *) ptr_start, (size_t) length); + str[length] = '\0'; + + return(TRUE); +} +/* ---------------------------------------------------------------------- */ +char *string_pad (char *str, int i) +/* ---------------------------------------------------------------------- */ +{ +/* + * Function returns new string padded to width i + * or returns str if longer + * Arguments: + * str string to pad + * + * Returns + * new string of with i + */ + int j, l, max; + char *str_ptr; + + l=strlen(str); + max = l; + if (l < i) max = i; + str_ptr = (char *) PHRQ_malloc((size_t) ((max+1) * sizeof(char))); + if (str_ptr == NULL) malloc_error(); + strcpy(str_ptr, str); + if (i > l) { + for (j = l; j < i; j++) { + str_ptr[j] = ' '; + } + str_ptr[i] = '\0'; + } + return(str_ptr); +}