pyEQL 1.4.0rc9__cp311-cp311-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. pyEQL/__init__.py +50 -0
  2. pyEQL/_phreeqc.cpython-311-darwin.so +0 -0
  3. pyEQL/activity_correction.py +879 -0
  4. pyEQL/database/geothermal.dat +5693 -0
  5. pyEQL/database/llnl.dat +19305 -0
  6. pyEQL/database/phreeqc_license.txt +54 -0
  7. pyEQL/database/pyeql_db.json +35607 -0
  8. pyEQL/engines.py +1153 -0
  9. pyEQL/equilibrium.py +227 -0
  10. pyEQL/functions.py +281 -0
  11. pyEQL/phreeqc/__init__.py +5 -0
  12. pyEQL/phreeqc/bindings.cpp +84 -0
  13. pyEQL/phreeqc/core.py +239 -0
  14. pyEQL/phreeqc/database/Amm.dat +1968 -0
  15. pyEQL/phreeqc/database/CMakeLists.txt +32 -0
  16. pyEQL/phreeqc/database/ColdChem.dat +267 -0
  17. pyEQL/phreeqc/database/Concrete_PHR.dat +158 -0
  18. pyEQL/phreeqc/database/Concrete_PZ.dat +195 -0
  19. pyEQL/phreeqc/database/Kinec.v2.dat +12039 -0
  20. pyEQL/phreeqc/database/Kinec_v3.dat +12159 -0
  21. pyEQL/phreeqc/database/Makefile.am +28 -0
  22. pyEQL/phreeqc/database/Makefile.in +530 -0
  23. pyEQL/phreeqc/database/PHREEQC_ThermoddemV1.10_15Dec2020.dat +12965 -0
  24. pyEQL/phreeqc/database/Tipping_Hurley.dat +4137 -0
  25. pyEQL/phreeqc/database/__init__.py +0 -0
  26. pyEQL/phreeqc/database/core10.dat +6824 -0
  27. pyEQL/phreeqc/database/frezchem.dat +634 -0
  28. pyEQL/phreeqc/database/iso.dat +7235 -0
  29. pyEQL/phreeqc/database/llnl.dat +19310 -0
  30. pyEQL/phreeqc/database/minteq.dat +5654 -0
  31. pyEQL/phreeqc/database/minteq.v4.dat +13212 -0
  32. pyEQL/phreeqc/database/phreeqc.dat +1972 -0
  33. pyEQL/phreeqc/database/phreeqc_rates.dat +3158 -0
  34. pyEQL/phreeqc/database/pitzer.dat +1044 -0
  35. pyEQL/phreeqc/database/sit.dat +14348 -0
  36. pyEQL/phreeqc/database/wateq4f.dat +4036 -0
  37. pyEQL/phreeqc/ext/README.md +10 -0
  38. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/CMakeLists.txt +476 -0
  39. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/INSTALL +302 -0
  40. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/IPhreeqc.rc +61 -0
  41. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/IPhreeqcConfig.cmake.in +4 -0
  42. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/Makefile.am +8 -0
  43. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/Makefile.in +816 -0
  44. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/aclocal.m4 +1217 -0
  45. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/CTestScript.cmake +167 -0
  46. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/CSelectedOutput.cpp.o +0 -0
  47. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/IPhreeqc.cpp.o +0 -0
  48. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/IPhreeqcLib.cpp.o +0 -0
  49. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/IPhreeqc_interface_F.cpp.o +0 -0
  50. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/Var.c.o +0 -0
  51. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Dictionary.cpp.o +0 -0
  52. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/ExchComp.cxx.o +0 -0
  53. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Exchange.cxx.o +0 -0
  54. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/GasComp.cxx.o +0 -0
  55. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/GasPhase.cxx.o +0 -0
  56. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/ISolution.cxx.o +0 -0
  57. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/ISolutionComp.cxx.o +0 -0
  58. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/KineticsComp.cxx.o +0 -0
  59. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/NameDouble.cxx.o +0 -0
  60. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/NumKeyword.cxx.o +0 -0
  61. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/PBasic.cpp.o +0 -0
  62. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/PHRQ_io_output.cpp.o +0 -0
  63. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/PPassemblage.cxx.o +0 -0
  64. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/PPassemblageComp.cxx.o +0 -0
  65. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Phreeqc.cpp.o +0 -0
  66. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/PhreeqcKeywords/Keywords.cpp.o +0 -0
  67. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Pressure.cxx.o +0 -0
  68. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Reaction.cxx.o +0 -0
  69. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/ReadClass.cxx.o +0 -0
  70. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SS.cxx.o +0 -0
  71. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SSassemblage.cxx.o +0 -0
  72. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SScomp.cxx.o +0 -0
  73. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SelectedOutput.cpp.o +0 -0
  74. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Serializer.cxx.o +0 -0
  75. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Solution.cxx.o +0 -0
  76. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SolutionIsotope.cxx.o +0 -0
  77. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/StorageBin.cxx.o +0 -0
  78. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/StorageBinList.cpp.o +0 -0
  79. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Surface.cxx.o +0 -0
  80. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SurfaceCharge.cxx.o +0 -0
  81. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/SurfaceComp.cxx.o +0 -0
  82. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/System.cxx.o +0 -0
  83. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Temperature.cxx.o +0 -0
  84. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/Use.cpp.o +0 -0
  85. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/UserPunch.cpp.o +0 -0
  86. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/advection.cpp.o +0 -0
  87. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/basicsubs.cpp.o +0 -0
  88. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/cl1.cpp.o +0 -0
  89. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/common/PHRQ_base.cxx.o +0 -0
  90. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/common/PHRQ_io.cpp.o +0 -0
  91. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/common/Parser.cxx.o +0 -0
  92. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/common/Utils.cxx.o +0 -0
  93. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/cvdense.cpp.o +0 -0
  94. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/cvode.cpp.o +0 -0
  95. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/cxxKinetics.cxx.o +0 -0
  96. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/cxxMix.cxx.o +0 -0
  97. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/dense.cpp.o +0 -0
  98. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/dumper.cpp.o +0 -0
  99. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/gases.cpp.o +0 -0
  100. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/input.cpp.o +0 -0
  101. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/integrate.cpp.o +0 -0
  102. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/inverse.cpp.o +0 -0
  103. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/isotopes.cpp.o +0 -0
  104. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/kinetics.cpp.o +0 -0
  105. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/mainsubs.cpp.o +0 -0
  106. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/model.cpp.o +0 -0
  107. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/nvector.cpp.o +0 -0
  108. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/nvector_serial.cpp.o +0 -0
  109. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/parse.cpp.o +0 -0
  110. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/phqalloc.cpp.o +0 -0
  111. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/pitzer.cpp.o +0 -0
  112. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/pitzer_structures.cpp.o +0 -0
  113. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/prep.cpp.o +0 -0
  114. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/print.cpp.o +0 -0
  115. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/read.cpp.o +0 -0
  116. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/readtr.cpp.o +0 -0
  117. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/runner.cpp.o +0 -0
  118. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/sit.cpp.o +0 -0
  119. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/smalldense.cpp.o +0 -0
  120. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/spread.cpp.o +0 -0
  121. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/step.cpp.o +0 -0
  122. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/structures.cpp.o +0 -0
  123. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/sundialsmath.cpp.o +0 -0
  124. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/tally.cpp.o +0 -0
  125. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/tidy.cpp.o +0 -0
  126. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/transport.cpp.o +0 -0
  127. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CMakeFiles/IPhreeqc.dir/src/phreeqcpp/utilities.cpp.o +0 -0
  128. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/CTestTestfile.cmake +6 -0
  129. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/DartConfiguration.tcl +109 -0
  130. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/cmake_install.cmake +45 -0
  131. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/build/libIPhreeqc.a +0 -0
  132. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/ar-lib +270 -0
  133. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/compile +347 -0
  134. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/config.guess +1441 -0
  135. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/config.sub +1813 -0
  136. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/depcomp +791 -0
  137. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/install-sh +508 -0
  138. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/ltmain.sh +11156 -0
  139. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/missing +215 -0
  140. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/config/test-driver +148 -0
  141. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/configure +23867 -0
  142. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/configure.ac +136 -0
  143. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Amm.dat +1968 -0
  144. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/CMakeLists.txt +32 -0
  145. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/ColdChem.dat +267 -0
  146. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Concrete_PHR.dat +158 -0
  147. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Concrete_PZ.dat +195 -0
  148. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Kinec.v2.dat +12039 -0
  149. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Kinec_v3.dat +12159 -0
  150. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Makefile.am +28 -0
  151. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Makefile.in +530 -0
  152. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/PHREEQC_ThermoddemV1.10_15Dec2020.dat +12965 -0
  153. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/Tipping_Hurley.dat +4137 -0
  154. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/core10.dat +6824 -0
  155. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/frezchem.dat +634 -0
  156. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/iso.dat +7235 -0
  157. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/llnl.dat +19310 -0
  158. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/minteq.dat +5654 -0
  159. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/minteq.v4.dat +13212 -0
  160. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/phreeqc.dat +1972 -0
  161. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/phreeqc_rates.dat +3158 -0
  162. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/pitzer.dat +1044 -0
  163. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/sit.dat +14348 -0
  164. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/database/wateq4f.dat +4036 -0
  165. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/CMakeLists.txt +35 -0
  166. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/IPhreeqc.pdf +0 -0
  167. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/Makefile.am +24 -0
  168. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/Makefile.in +545 -0
  169. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/NOTICE +51 -0
  170. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/Phreeqc_2_1999_manual.pdf +0 -0
  171. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/Phreeqc_3_2013_manual.pdf +0 -0
  172. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/README +428 -0
  173. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/RELEASE +7294 -0
  174. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/IPhreeqc_8h.html +5096 -0
  175. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/IPhreeqc_8h_source.html +389 -0
  176. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/IPhreeqc_8hpp.html +83 -0
  177. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/IPhreeqc_8hpp_source.html +478 -0
  178. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/Var_8h.html +318 -0
  179. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/Var_8h_source.html +200 -0
  180. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/bc_s.png +0 -0
  181. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/bdwn.png +0 -0
  182. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/classIPhreeqc.html +2274 -0
  183. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/classIPhreeqc.png +0 -0
  184. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/classIPhreeqcStop.html +69 -0
  185. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/classIPhreeqcStop.png +0 -0
  186. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/closed.png +0 -0
  187. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html +68 -0
  188. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/doxygen.css +1440 -0
  189. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/doxygen.png +0 -0
  190. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/dynsections.js +97 -0
  191. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2blank.png +0 -0
  192. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2doc.png +0 -0
  193. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2folderclosed.png +0 -0
  194. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2folderopen.png +0 -0
  195. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2lastnode.png +0 -0
  196. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2link.png +0 -0
  197. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2mlastnode.png +0 -0
  198. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2mnode.png +0 -0
  199. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2node.png +0 -0
  200. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2plastnode.png +0 -0
  201. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2pnode.png +0 -0
  202. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2splitbar.png +0 -0
  203. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/ftv2vertline.png +0 -0
  204. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/index.html +58 -0
  205. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/jquery.js +31 -0
  206. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/nav_f.png +0 -0
  207. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/nav_g.png +0 -0
  208. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/nav_h.png +0 -0
  209. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/open.png +0 -0
  210. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/structVAR.html +143 -0
  211. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/sync_off.png +0 -0
  212. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/sync_on.png +0 -0
  213. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/tab_a.png +0 -0
  214. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/tab_b.png +0 -0
  215. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/tab_h.png +0 -0
  216. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/tab_s.png +0 -0
  217. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/html/tabs.css +60 -0
  218. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/doc/phreeqc3.chm +0 -0
  219. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/CMakeLists.txt +11 -0
  220. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/Makefile.am +88 -0
  221. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/Makefile.in +696 -0
  222. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/CMakeLists.txt +1 -0
  223. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/CMakeLists.txt +35 -0
  224. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/CMakeLists.txt.in +21 -0
  225. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/README.txt +44 -0
  226. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/advect.c +101 -0
  227. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/ic +17 -0
  228. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/c/advect/phreeqc.dat +1579 -0
  229. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/CMakeLists.txt +10 -0
  230. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/README.txt +3 -0
  231. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/excel/CMakeLists.txt +9 -0
  232. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/excel/phreeqc.dat +1582 -0
  233. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/excel/runphreeqc.xls +0 -0
  234. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/excel/withcallback.xls +0 -0
  235. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/CMakeLists.txt +11 -0
  236. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/Gypsum.py +52 -0
  237. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/parallel_advect.py +465 -0
  238. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/phreeqc.dat +1582 -0
  239. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/pitzer.dat +790 -0
  240. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/com/python/wateq4f.dat +3846 -0
  241. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/CMakeLists.txt +1 -0
  242. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/CMakeLists.txt +35 -0
  243. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/CMakeLists.txt.in +20 -0
  244. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/README.txt +45 -0
  245. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/advect.cpp +110 -0
  246. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/ic +17 -0
  247. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/cpp/advect/phreeqc.dat +1579 -0
  248. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/CMakeLists.txt +1 -0
  249. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/CMakeLists.txt +44 -0
  250. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/CMakeLists.txt.in +24 -0
  251. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/README.txt +45 -0
  252. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/advect.F90 +102 -0
  253. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/ic +17 -0
  254. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/fortran/advect/phreeqc.dat +1579 -0
  255. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/CMakeLists.txt +26 -0
  256. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/CMakeLists.txt.in +20 -0
  257. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/README.txt +37 -0
  258. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/ex2 +26 -0
  259. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/main.cpp +20 -0
  260. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/phreeqc.dat +1837 -0
  261. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/examples/using-cmake/post-install.cmake.in +7 -0
  262. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/CMakeLists.txt +185 -0
  263. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/FileTest.cpp +171 -0
  264. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/FileTest.h +34 -0
  265. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/Makefile.am +18 -0
  266. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/Makefile.in +466 -0
  267. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/TestCVar.cpp +9 -0
  268. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/TestIPhreeqc.cpp +4901 -0
  269. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/TestIPhreeqcLib.cpp +4644 -0
  270. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/TestSelectedOutput.cpp +669 -0
  271. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/TestVar.cpp +10 -0
  272. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/conv_fail.in +11 -0
  273. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/dump +42 -0
  274. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/iso.dat +7231 -0
  275. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/kinn20140218 +349 -0
  276. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/missing_e.dat +1556 -0
  277. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/multi_punch +105 -0
  278. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/multi_punch_no_set +102 -0
  279. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/phreeqc.dat.90a6449 +1935 -0
  280. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/gtest/phreeqc.dat.old +1556 -0
  281. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/m4/libtool.m4 +8388 -0
  282. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/m4/ltoptions.m4 +437 -0
  283. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/m4/ltsugar.m4 +124 -0
  284. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/m4/ltversion.m4 +23 -0
  285. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/m4/lt~obsolete.m4 +99 -0
  286. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/resource.h +14 -0
  287. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/CSelectedOutput.cpp +401 -0
  288. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/CSelectedOutput.hxx +77 -0
  289. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/CVar.hxx +162 -0
  290. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Debug.h +12 -0
  291. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/ErrorReporter.hxx +70 -0
  292. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc.cpp +1889 -0
  293. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc.f.inc +91 -0
  294. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc.f90.inc +603 -0
  295. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc.h +2182 -0
  296. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc.hpp +1027 -0
  297. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqcCallbacks.h +19 -0
  298. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqcF.f +653 -0
  299. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqcLib.cpp +1098 -0
  300. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc_interface.F90 +1283 -0
  301. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc_interface_F.cpp +535 -0
  302. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/IPhreeqc_interface_F.h +162 -0
  303. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Makefile.am +210 -0
  304. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Makefile.in +1294 -0
  305. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/README.Fortran +17 -0
  306. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Var.c +84 -0
  307. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Var.h +152 -0
  308. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/Version.h +36 -0
  309. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fimpl.h +282 -0
  310. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap.cpp +646 -0
  311. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap.h +163 -0
  312. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap1.cpp +24 -0
  313. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap2.cpp +24 -0
  314. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap3.cpp +24 -0
  315. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap4.cpp +24 -0
  316. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap5.cpp +24 -0
  317. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap6.cpp +25 -0
  318. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap7.cpp +25 -0
  319. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/fwrap8.cpp +24 -0
  320. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ChartHandler.cpp +225 -0
  321. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ChartHandler.h +59 -0
  322. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ChartObject.cpp +1382 -0
  323. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ChartObject.h +444 -0
  324. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/CurveObject.cpp +42 -0
  325. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/CurveObject.h +79 -0
  326. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Dictionary.cpp +41 -0
  327. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Dictionary.h +28 -0
  328. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ExchComp.cxx +398 -0
  329. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ExchComp.h +117 -0
  330. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Exchange.cxx +466 -0
  331. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Exchange.h +74 -0
  332. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Form1.h +1184 -0
  333. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Form1.resX +36 -0
  334. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/GasComp.cxx +265 -0
  335. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/GasComp.h +59 -0
  336. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/GasPhase.cxx +659 -0
  337. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/GasPhase.h +103 -0
  338. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ISolution.cxx +40 -0
  339. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ISolution.h +53 -0
  340. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ISolutionComp.cxx +202 -0
  341. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ISolutionComp.h +138 -0
  342. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/KineticsComp.cxx +318 -0
  343. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/KineticsComp.h +81 -0
  344. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/NA.h +1 -0
  345. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/NameDouble.cxx +537 -0
  346. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/NameDouble.h +66 -0
  347. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/NumKeyword.cxx +190 -0
  348. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/NumKeyword.h +67 -0
  349. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PBasic.cpp +8350 -0
  350. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PBasic.h +572 -0
  351. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PHRQ_io_output.cpp +411 -0
  352. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PPassemblage.cxx +375 -0
  353. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PPassemblage.h +70 -0
  354. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PPassemblageComp.cxx +441 -0
  355. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PPassemblageComp.h +83 -0
  356. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Phreeqc.cpp +2087 -0
  357. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Phreeqc.h +2164 -0
  358. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PhreeqcKeywords/Keywords.cpp +242 -0
  359. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/PhreeqcKeywords/Keywords.h +104 -0
  360. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Pressure.cxx +417 -0
  361. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Pressure.h +43 -0
  362. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Reaction.cxx +284 -0
  363. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Reaction.h +57 -0
  364. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ReadClass.cxx +1150 -0
  365. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SS.cxx +609 -0
  366. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SS.h +128 -0
  367. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SSassemblage.cxx +317 -0
  368. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SSassemblage.h +59 -0
  369. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SScomp.cxx +297 -0
  370. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SScomp.h +66 -0
  371. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SelectedOutput.cpp +115 -0
  372. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SelectedOutput.h +209 -0
  373. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Serializer.cxx +213 -0
  374. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Serializer.h +42 -0
  375. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Solution.cxx +1795 -0
  376. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Solution.h +154 -0
  377. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SolutionIsotope.cxx +333 -0
  378. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SolutionIsotope.h +85 -0
  379. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/StorageBin.cxx +1507 -0
  380. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/StorageBin.h +141 -0
  381. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/StorageBinList.cpp +358 -0
  382. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/StorageBinList.h +81 -0
  383. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Surface.cxx +837 -0
  384. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Surface.h +108 -0
  385. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SurfaceCharge.cxx +617 -0
  386. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SurfaceCharge.h +137 -0
  387. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SurfaceComp.cxx +509 -0
  388. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/SurfaceComp.h +70 -0
  389. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/System.cxx +103 -0
  390. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/System.h +89 -0
  391. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Temperature.cxx +423 -0
  392. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Temperature.h +42 -0
  393. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Use.cpp +78 -0
  394. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/Use.h +159 -0
  395. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/UserPunch.cpp +32 -0
  396. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/UserPunch.h +39 -0
  397. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/ZedGraph.dll +0 -0
  398. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/advection.cpp +140 -0
  399. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/basicsubs.cpp +4333 -0
  400. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cl1.cpp +881 -0
  401. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/PHRQ_base.cxx +117 -0
  402. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/PHRQ_base.h +48 -0
  403. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/PHRQ_exports.h +20 -0
  404. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/PHRQ_io.cpp +914 -0
  405. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/PHRQ_io.h +207 -0
  406. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/Parser.cxx +1331 -0
  407. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/Parser.h +310 -0
  408. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/Utils.cxx +263 -0
  409. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/Utils.h +29 -0
  410. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/common/phrqtype.h +18 -0
  411. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cvdense.cpp +566 -0
  412. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cvdense.h +267 -0
  413. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cvode.cpp +3939 -0
  414. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cvode.h +940 -0
  415. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cxxKinetics.cxx +617 -0
  416. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cxxKinetics.h +78 -0
  417. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cxxMix.cxx +154 -0
  418. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/cxxMix.h +58 -0
  419. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/dense.cpp +175 -0
  420. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/dense.h +341 -0
  421. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/dumper.cpp +277 -0
  422. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/dumper.h +60 -0
  423. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/gases.cpp +748 -0
  424. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/global_structures.h +1672 -0
  425. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/input.cpp +133 -0
  426. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/integrate.cpp +1219 -0
  427. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/inverse.cpp +5135 -0
  428. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/isotopes.cpp +1813 -0
  429. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/kinetics.cpp +3180 -0
  430. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/mainsubs.cpp +2320 -0
  431. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/model.cpp +5843 -0
  432. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/nvector.cpp +272 -0
  433. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/nvector.h +485 -0
  434. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/nvector_serial.cpp +1032 -0
  435. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/nvector_serial.h +369 -0
  436. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/parse.cpp +1044 -0
  437. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/phqalloc.cpp +316 -0
  438. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/phqalloc.h +47 -0
  439. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/pitzer.cpp +2709 -0
  440. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/pitzer_structures.cpp +225 -0
  441. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/prep.cpp +6267 -0
  442. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/print.cpp +3673 -0
  443. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/read.cpp +10245 -0
  444. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/readtr.cpp +1495 -0
  445. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/runner.cpp +158 -0
  446. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/runner.h +33 -0
  447. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/sit.cpp +1684 -0
  448. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/smalldense.cpp +324 -0
  449. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/smalldense.h +261 -0
  450. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/spread.cpp +1309 -0
  451. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/step.cpp +1566 -0
  452. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/structures.cpp +3381 -0
  453. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/sundialsmath.cpp +133 -0
  454. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/sundialsmath.h +162 -0
  455. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/sundialstypes.h +183 -0
  456. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/tally.cpp +1288 -0
  457. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/tidy.cpp +5600 -0
  458. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/transport.cpp +6403 -0
  459. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/phreeqcpp/utilities.cpp +1339 -0
  460. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/src/thread.h +64 -0
  461. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/CMakeLists.txt +133 -0
  462. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/Makefile.am +45 -0
  463. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/Makefile.in +1128 -0
  464. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/ex2.in +26 -0
  465. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/main.f90 +31 -0
  466. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/main77.f +6 -0
  467. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/main_fortran.cxx +8 -0
  468. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/phreeqc.dat.in +1556 -0
  469. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/test_c.c +148 -0
  470. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/test_cxx.cxx +152 -0
  471. pyEQL/phreeqc/ext/iphreeqc-3.8.6-17100/tests/test_f90.F90 +328 -0
  472. pyEQL/phreeqc/iphreeqc_wrapper.cpp +75 -0
  473. pyEQL/phreeqc/solution.py +74 -0
  474. pyEQL/phreeqc/var.py +50 -0
  475. pyEQL/presets/Ringers lactate.yaml +20 -0
  476. pyEQL/presets/__init__.py +17 -0
  477. pyEQL/presets/normal saline.yaml +17 -0
  478. pyEQL/presets/rainwater.yaml +17 -0
  479. pyEQL/presets/seawater.yaml +29 -0
  480. pyEQL/presets/urine.yaml +26 -0
  481. pyEQL/presets/wastewater.yaml +21 -0
  482. pyEQL/py.typed +0 -0
  483. pyEQL/salt_ion_match.py +112 -0
  484. pyEQL/solute.py +163 -0
  485. pyEQL/solution.py +2714 -0
  486. pyEQL/utils.py +237 -0
  487. pyeql-1.4.0rc9.dist-info/METADATA +130 -0
  488. pyeql-1.4.0rc9.dist-info/RECORD +491 -0
  489. pyeql-1.4.0rc9.dist-info/WHEEL +6 -0
  490. pyeql-1.4.0rc9.dist-info/licenses/AUTHORS.md +21 -0
  491. pyeql-1.4.0rc9.dist-info/licenses/LICENSE.txt +20 -0
@@ -0,0 +1,3180 @@
1
+ #include "Utils.h"
2
+ #include "Phreeqc.h"
3
+ #include "phqalloc.h"
4
+
5
+ #include <time.h>
6
+
7
+ #include "StorageBin.h"
8
+ #include "Reaction.h"
9
+ #include "cxxKinetics.h"
10
+ #include "Solution.h"
11
+ #include "cxxMix.h"
12
+ #include "PPassemblage.h"
13
+ #include "Surface.h"
14
+ #include "Exchange.h"
15
+ #include "GasPhase.h"
16
+ #include "SSassemblage.h"
17
+ #include "Temperature.h"
18
+ #include "cxxKinetics.h"
19
+ #include <map>
20
+ #include <fstream>
21
+ #include <memory>
22
+ #include "nvector_serial.h" /* definitions of type N_Vector and macro */
23
+ /* NV_Ith_S, prototypes for N_VNew, N_VFree */
24
+ /* These macros are defined in order to write code which exactly matches
25
+ the mathematical problem description given above.
26
+
27
+ Ith(v,i) references the ith component of the vector v, where i is in
28
+ the range [1..NEQ] and NEQ is defined below. The Ith macro is defined
29
+ using the N_VIth macro in nvector.h. N_VIth numbers the components of
30
+ a vector starting from 0.
31
+
32
+ IJth(A,i,j) references the (i,j)th element of the dense matrix A, where
33
+ i and j are in the range [1..NEQ]. The IJth macro is defined using the
34
+ DENSE_ELEM macro in dense.h. DENSE_ELEM numbers rows and columns of a
35
+ dense matrix starting from 0. */
36
+
37
+ #define Ith(v,i) NV_Ith_S(v,i-1) /* Ith numbers components 1..NEQ */
38
+ #define IJth(A,i,j) DENSE_ELEM(A,i-1,j-1) /* IJth numbers rows,cols 1..NEQ */
39
+
40
+ #define MAX_DIVIDE 2
41
+ #define KINETICS_TOL 1e-8;
42
+
43
+ #if defined(PHREEQCI_GUI)
44
+ #ifdef _DEBUG
45
+ #define new DEBUG_NEW
46
+ #undef THIS_FILE
47
+ static char THIS_FILE[] = __FILE__;
48
+ #endif
49
+ #endif
50
+
51
+ /* ---------------------------------------------------------------------- */
52
+ int Phreeqc::
53
+ calc_kinetic_reaction(cxxKinetics *kinetics_ptr, LDBLE time_step)
54
+ /* ---------------------------------------------------------------------- */
55
+ {
56
+ /*
57
+ * Go through kinetic components to
58
+ * determine rates and
59
+ * a list of elements and amounts in
60
+ * the reaction.
61
+ */
62
+ int j, return_value;
63
+ LDBLE coef;
64
+ char l_command[] = "run";
65
+ class rate *rate_ptr;
66
+ /*
67
+ * Go through list and generate list of elements and
68
+ * coefficient of elements in reaction
69
+ */
70
+ return_value = OK;
71
+ count_elts = 0;
72
+ paren_count = 0;
73
+ rate_time = time_step;
74
+
75
+ /* t1 = clock(); */
76
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
77
+ {
78
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
79
+ coef = 0.0;
80
+ /*
81
+ * Send command to basic interpreter
82
+ */
83
+ rate_ptr = rate_search(kinetics_comp_ptr->Get_rate_name().c_str(), &j);
84
+ if (rate_ptr == NULL)
85
+ {
86
+ error_string = sformatf( "Rate not found for %s",
87
+ kinetics_comp_ptr->Get_rate_name().c_str());
88
+ error_msg(error_string, STOP);
89
+ }
90
+ else
91
+ {
92
+ rate_moles = NAN;
93
+ rate_m = kinetics_comp_ptr->Get_m();
94
+ rate_m0 = kinetics_comp_ptr->Get_m0();
95
+ rate_p = kinetics_comp_ptr->Get_d_params();
96
+ count_rate_p = (int) kinetics_comp_ptr->Get_d_params().size();
97
+ if (rate_ptr->new_def == TRUE)
98
+ {
99
+ if (basic_compile
100
+ (rates[j].commands.c_str(), &rates[j].linebase, &rates[j].varbase,
101
+ &rates[j].loopbase) != 0)
102
+ {
103
+ error_string = sformatf( "Fatal Basic error in rate %s.",
104
+ kinetics_comp_ptr->Get_rate_name().c_str());
105
+ error_msg(error_string, STOP);
106
+ }
107
+
108
+ rate_ptr->new_def = FALSE;
109
+ }
110
+ if (basic_run
111
+ (l_command, rates[j].linebase, rates[j].varbase,
112
+ rates[j].loopbase) != 0)
113
+ {
114
+ error_string = sformatf( "Fatal Basic error in rate %s.",
115
+ kinetics_comp_ptr->Get_rate_name().c_str());
116
+ error_msg(error_string, STOP);
117
+ }
118
+ if (std::isnan(rate_moles))
119
+ {
120
+ error_string = sformatf( "Moles of reaction not SAVEed for %s.",
121
+ kinetics_comp_ptr->Get_rate_name().c_str());
122
+ error_msg(error_string, STOP);
123
+ }
124
+ else
125
+ {
126
+
127
+ coef = rate_moles;
128
+ }
129
+ }
130
+ /*
131
+ * Accumulate moles of reaction for component
132
+ */
133
+ kinetics_comp_ptr->Set_moles(kinetics_comp_ptr->Get_moles() + coef);
134
+ if (coef == 0.0)
135
+ continue;
136
+ }
137
+ /* t2=clock();
138
+ printf("secs in reac %e, t2 %e\n", t2-t1, t1);
139
+ */
140
+ return (return_value);
141
+ }
142
+ /* ---------------------------------------------------------------------- */
143
+ int Phreeqc::
144
+ calc_final_kinetic_reaction(cxxKinetics *kinetics_ptr)
145
+ /* ---------------------------------------------------------------------- */
146
+ {
147
+ /*
148
+ * Go through kinetic components to
149
+ * using extrapolated values, which were
150
+ * stored in moles in run_kinetics
151
+ */
152
+ LDBLE coef;
153
+ class phase *phase_ptr;
154
+ class master *master_ptr;
155
+ int count= 0;
156
+ /*
157
+ * Go through list and generate list of elements and
158
+ * coefficient of elements in reaction
159
+ */
160
+ RESTART: // if limiting rates, jump to here
161
+ count++;
162
+ kinetics_ptr->Get_totals().clear();
163
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
164
+ {
165
+ count_elts = 0;
166
+ paren_count = 0;
167
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
168
+ if (kinetics_comp_ptr->Get_moles() > m_temp[i])
169
+ {
170
+ kinetics_comp_ptr->Set_moles(m_temp[i]);
171
+ kinetics_comp_ptr->Set_m(0);
172
+ }
173
+ coef = kinetics_comp_ptr->Get_moles();
174
+ if (coef == 0.0)
175
+ continue;
176
+ /*
177
+ * Reactant is a pure phase, copy formula into token
178
+ */
179
+ cxxNameDouble::iterator it = kinetics_comp_ptr->Get_namecoef().begin();
180
+ for ( ; it != kinetics_comp_ptr->Get_namecoef().end(); it++)
181
+ {
182
+ std::string name = it->first;
183
+ LDBLE coef1 = it->second;
184
+ phase_ptr = NULL;
185
+ int k;
186
+ phase_ptr = phase_bsearch(name.c_str(), &k, FALSE);
187
+ if (phase_ptr != NULL)
188
+ {
189
+ add_elt_list(phase_ptr->next_elt,
190
+ coef *coef1);
191
+ }
192
+ else
193
+ {
194
+ const char* ptr = name.c_str();
195
+ if (get_elts_in_species(&ptr, coef * coef1) == ERROR)
196
+ {
197
+ error_string = sformatf("Error in -formula: %s", name.c_str());
198
+ error_msg(error_string, CONTINUE);
199
+ }
200
+ }
201
+ }
202
+ if (use.Get_exchange_ptr() != NULL
203
+ && use.Get_exchange_ptr()->Get_related_rate())
204
+ {
205
+ cxxExchange * exchange_ptr = use.Get_exchange_ptr();
206
+ for(size_t j = 0; j < exchange_ptr->Get_exchange_comps().size(); j++)
207
+ {
208
+ std::string name(exchange_ptr->Get_exchange_comps()[j].Get_rate_name());
209
+ if (name.size() > 0)
210
+ {
211
+ if (strcmp_nocase
212
+ (kinetics_comp_ptr->Get_rate_name().c_str(),
213
+ name.c_str()) == 0)
214
+ {
215
+ /* found kinetics component */
216
+ std::string formula = exchange_ptr->Get_exchange_comps()[j].Get_formula().c_str();
217
+ const char* ptr = formula.c_str();
218
+ if (get_elts_in_species(&ptr, -coef*exchange_ptr->Get_exchange_comps()[j].Get_phase_proportion()) == ERROR)
219
+ {
220
+ error_string = sformatf("Error in -formula: %s", formula.c_str());
221
+ error_msg(error_string, CONTINUE);
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ }
228
+ if (use.Get_surface_ptr() != NULL && use.Get_surface_ptr()->Get_related_rate())
229
+ {
230
+ for (size_t j = 0; j < use.Get_surface_ptr()->Get_surface_comps().size(); j++)
231
+ {
232
+ cxxSurfaceComp *surface_comp_ptr = &(use.Get_surface_ptr()->Get_surface_comps()[j]);
233
+ if (surface_comp_ptr->Get_rate_name().size() > 0)
234
+ {
235
+ if (strcmp_nocase
236
+ (kinetics_comp_ptr->Get_rate_name().c_str(),
237
+ surface_comp_ptr->Get_rate_name().c_str()) == 0)
238
+ {
239
+ /* found kinetics component */
240
+ std::string temp_formula = surface_comp_ptr->Get_formula().c_str();
241
+ const char* cptr = temp_formula.c_str();
242
+ /* Surface = 0 when m becomes low ...
243
+ */
244
+ if (0.9 * surface_comp_ptr->Get_phase_proportion() *
245
+ (kinetics_comp_ptr->Get_m()) < MIN_RELATED_SURFACE)
246
+ {
247
+ master_ptr = master_bsearch(surface_comp_ptr->Get_master_element().c_str());
248
+ if (master_ptr != NULL)
249
+ {
250
+ master_ptr->total = 0.0;
251
+ }
252
+ }
253
+ else
254
+ {
255
+ if (get_elts_in_species(&cptr, -coef * surface_comp_ptr->Get_phase_proportion()) == ERROR)
256
+ {
257
+ error_string = sformatf("Error in -formula: %s", temp_formula.c_str());
258
+ error_msg(error_string, CONTINUE);
259
+ }
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ kinetics_comp_ptr->Set_moles_of_reaction(elt_list_NameDouble());
266
+ kinetics_ptr->Get_totals().add_extensive(kinetics_comp_ptr->Get_moles_of_reaction(), 1.0);
267
+ }
268
+ if (count > 2)
269
+ {
270
+ #if !defined(R_SO)
271
+ fprintf(stderr, "Too many limit_rates-.\n");
272
+ #else
273
+ error_msg("Too many limit_rates-.\n");
274
+ #endif
275
+ }
276
+ else
277
+ {
278
+ if (limit_rates(kinetics_ptr))
279
+ goto RESTART;
280
+ }
281
+ if (count > 2)
282
+ {
283
+ #if !defined(R_SO)
284
+ fprintf(stderr, "Too many limit_rates+.\n");
285
+ #else
286
+ error_msg("Too many limit_rates+.\n");
287
+ #endif
288
+ }
289
+ return (OK);
290
+ }
291
+
292
+ /* ---------------------------------------------------------------------- */
293
+ int Phreeqc::
294
+ rk_kinetics(int i, LDBLE kin_time, int use_mix, int nsaver,
295
+ LDBLE step_fraction)
296
+ /* ---------------------------------------------------------------------- */
297
+ {
298
+ /*
299
+ * Runge-Kutta-Fehlberg method; 6 evaluations of the derivative
300
+ * give O(h^5) global error and error estimate
301
+ * calc_kinetic_reaction(.., ..) calculates moles of intermediate derivatives;
302
+ * these are calc'd for the whole step h.
303
+ * calc_final_kinetic reaction(..) translates moles to PHREEQC reaction.
304
+ */
305
+ int k, save_old;
306
+ int l_bad, step_bad, step_ok;
307
+ int n_reactions;
308
+ LDBLE h, h_old, h_sum;
309
+ LDBLE l_error, error_max, safety, moles_max, moles_reduction;
310
+ cxxKinetics *kinetics_ptr;
311
+ int equal_rate, zero_rate;
312
+
313
+ cxxPPassemblage *pp_assemblage_save = NULL;
314
+ cxxSSassemblage *ss_assemblage_save = NULL;
315
+
316
+ LDBLE b31 = 3. / 40., b32 = 9. / 40.,
317
+ b51 = -11. / 54., b53 = -70. / 27., b54 = 35. / 27.,
318
+ b61 = 1631. / 55296., b62 = 175. / 512., b63 = 575. / 13824., b64 =
319
+ 44275. / 110592., b65 = 253. / 4096., c1 = 37. / 378., c3 =
320
+ 250. / 621., c4 = 125. / 594., c6 = 512. / 1771., dc5 =
321
+ -277. / 14336.;
322
+ LDBLE dc1 = c1 - 2825. / 27648., dc3 = c3 - 18575. / 48384., dc4 =
323
+ c4 - 13525. / 55296., dc6 = c6 - 0.25;
324
+ /*
325
+ * Save kinetics i and solution i, if necessary
326
+ */
327
+ save_old = -2 - (count_cells * (1 + stag_data.count_stag) + 2);
328
+ Utilities::Rxn_copy(Rxn_kinetics_map, i, save_old);
329
+ if (nsaver != i)
330
+ {
331
+ Utilities::Rxn_copy(Rxn_solution_map, i, save_old);
332
+ }
333
+
334
+ /*
335
+ * Malloc some space
336
+ */
337
+ kinetics_ptr = Utilities::Rxn_find(Rxn_kinetics_map, i);
338
+ if (kinetics_ptr == NULL)
339
+ return (OK);
340
+ n_reactions = (int) kinetics_ptr->Get_kinetics_comps().size();
341
+ rk_moles.resize(6 * (size_t)n_reactions);
342
+
343
+ /*if (use_mix != NOMIX) last_model.force_prep = TRUE; */
344
+ set_and_run_wrapper(i, use_mix, FALSE, i, step_fraction);
345
+ run_reactions_iterations += iterations;
346
+
347
+ saver();
348
+ if (state == TRANSPORT || state == PHAST)
349
+ {
350
+ set_transport(i, NOMIX, TRUE, i);
351
+ }
352
+ else if (state == ADVECTION)
353
+ {
354
+ set_advection(i, NOMIX, TRUE, i);
355
+ }
356
+ else if (state == REACTION)
357
+ {
358
+ set_reaction(i, NOMIX, TRUE);
359
+ }
360
+ kinetics_ptr = Utilities::Rxn_find(Rxn_kinetics_map, i);
361
+
362
+ step_bad = step_ok = 0;
363
+ l_bad = FALSE;
364
+ h_sum = 0.;
365
+ h = h_old = kin_time;
366
+ moles_max = 0.1;
367
+ moles_reduction = 1.0;
368
+ safety = 0.7;
369
+ if (kinetics_ptr->Get_rk() < 1)
370
+ kinetics_ptr->Set_rk(1);
371
+ else if (kinetics_ptr->Get_rk() > 3)
372
+ kinetics_ptr->Set_rk(6);
373
+
374
+ if (kinetics_ptr->Get_rk() == 6)
375
+ equal_rate = FALSE;
376
+ else
377
+ equal_rate = TRUE;
378
+ /*
379
+ * if step_divide > 1, initial timestep is divided
380
+ * if < 1, step_divide indicates maximal reaction...
381
+ */
382
+ if (kinetics_ptr->Get_step_divide() > 1.0)
383
+ {
384
+ h = h_old = kin_time / kinetics_ptr->Get_step_divide();
385
+ equal_rate = FALSE;
386
+ }
387
+ else if (kinetics_ptr->Get_step_divide() < 1.0)
388
+ moles_max = kinetics_ptr->Get_step_divide();
389
+
390
+ rate_sim_time = rate_sim_time_start + h_sum;
391
+
392
+ status(0, NULL);
393
+ while (h_sum < kin_time)
394
+ {
395
+
396
+ if (step_bad > kinetics_ptr->Get_bad_step_max())
397
+ {
398
+ error_string = sformatf(
399
+ "Bad RK steps > %d in cell %d. Please decrease (time)step or increase -bad_step_max.",
400
+ kinetics_ptr->Get_bad_step_max(), cell_no);
401
+ error_msg(error_string, STOP);
402
+ }
403
+
404
+ MOLES_TOO_LARGE:
405
+ if (moles_reduction > 1.0)
406
+ {
407
+ h_old = h;
408
+ h = safety * h / (1.0 + moles_reduction);
409
+ moles_reduction = 1.0;
410
+ equal_rate = FALSE;
411
+ l_bad = TRUE;
412
+ }
413
+ /*
414
+ * find k1
415
+ */
416
+ if (l_bad == TRUE)
417
+ {
418
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
419
+ {
420
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
421
+ rk_moles[j] *= (h / h_old);
422
+ kinetics_comp_ptr->Set_moles(rk_moles[j] * 0.2);
423
+ kinetics_comp_ptr->Set_m(m_temp[j]);
424
+ }
425
+ l_bad = FALSE;
426
+ }
427
+ else
428
+ {
429
+ /*
430
+ * define pointers for calc_kinetic_, they are lost after saver()...
431
+ */
432
+ if (state == TRANSPORT || state == PHAST)
433
+ {
434
+ set_transport(i, NOMIX, TRUE, i);
435
+ }
436
+ else if (state == ADVECTION)
437
+ {
438
+ set_advection(i, NOMIX, TRUE, i);
439
+ }
440
+ else if (state == REACTION)
441
+ {
442
+ set_reaction(i, NOMIX, TRUE);
443
+ }
444
+ /*
445
+ * Moles of minerals and solid solutions may change to make positive
446
+ * concentrations. Reactions may take out more than is present in
447
+ * solution.
448
+ */
449
+ if (use.Get_pp_assemblage_ptr() != NULL)
450
+ {
451
+ cxxPPassemblage * pp_assemblage_ptr = Utilities::Rxn_find(Rxn_pp_assemblage_map, use.Get_pp_assemblage_ptr()->Get_n_user());
452
+ assert(pp_assemblage_ptr);
453
+ pp_assemblage_save = new cxxPPassemblage(*pp_assemblage_ptr);
454
+ }
455
+ if (use.Get_ss_assemblage_ptr() != NULL)
456
+ {
457
+ cxxSSassemblage * ss_assemblage_ptr = Utilities::Rxn_find(Rxn_ss_assemblage_map, use.Get_ss_assemblage_ptr()->Get_n_user());
458
+ assert(ss_assemblage_ptr);
459
+ ss_assemblage_save = new cxxSSassemblage(*ss_assemblage_ptr);
460
+ }
461
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
462
+ {
463
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
464
+ kinetics_comp_ptr->Set_moles(0.);
465
+ m_temp[j] = kinetics_comp_ptr->Get_m();
466
+ }
467
+
468
+ rate_sim_time = rate_sim_time_start + h_sum;
469
+ calc_kinetic_reaction(kinetics_ptr, h);
470
+
471
+ /* store k1 in rk_moles ... */
472
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
473
+ {
474
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
475
+ if (moles_reduction * moles_max < fabs(kinetics_comp_ptr->Get_moles()))
476
+ {
477
+ moles_reduction = fabs(kinetics_comp_ptr->Get_moles()) / moles_max;
478
+ }
479
+ /* define reaction for calculating k2 ... */
480
+ rk_moles[j] = kinetics_comp_ptr->Get_moles();
481
+ kinetics_comp_ptr->Set_moles(kinetics_comp_ptr->Get_moles() * 0.2);
482
+ }
483
+ if (moles_reduction > 1.0)
484
+ goto MOLES_TOO_LARGE;
485
+ }
486
+ /*
487
+ * Quit rk with rk = 1 and equal rates ...
488
+ */
489
+ if (kinetics_ptr->Get_rk() == 1 && equal_rate)
490
+ {
491
+ zero_rate = TRUE;
492
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
493
+ {
494
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
495
+ kinetics_comp_ptr->Set_moles(rk_moles[j]);
496
+ if (fabs(kinetics_comp_ptr->Get_moles()) > MIN_TOTAL)
497
+ zero_rate = FALSE;
498
+ }
499
+
500
+ if (zero_rate == FALSE)
501
+ {
502
+ calc_final_kinetic_reaction(kinetics_ptr);
503
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
504
+ {
505
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
506
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
507
+ if (kinetics_comp_ptr->Get_m() < 1.e-30)
508
+ kinetics_comp_ptr->Set_m(0);
509
+ kinetics_comp_ptr->Set_moles(0.);
510
+ }
511
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) ==
512
+ MASS_BALANCE)
513
+ {
514
+ run_reactions_iterations += iterations;
515
+ moles_reduction = 9;
516
+ goto MOLES_TOO_LARGE;
517
+ }
518
+ run_reactions_iterations += iterations;
519
+ calc_kinetic_reaction(kinetics_ptr, h);
520
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
521
+ {
522
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
523
+ if (fabs(rk_moles[j] - kinetics_comp_ptr->Get_moles()) >
524
+ kinetics_comp_ptr->Get_tol())
525
+ {
526
+ equal_rate = FALSE;
527
+ break;
528
+ }
529
+ }
530
+ }
531
+ if (zero_rate || equal_rate)
532
+ {
533
+ /* removing the following line causes different results for
534
+ example 6 distributed with the program */
535
+ saver();
536
+
537
+ /* Free space */
538
+
539
+ if (pp_assemblage_save != NULL)
540
+ {
541
+ delete pp_assemblage_save;
542
+ pp_assemblage_save = NULL;
543
+ }
544
+ if (ss_assemblage_save != NULL)
545
+ {
546
+ delete ss_assemblage_save;
547
+ ss_assemblage_save = NULL;
548
+ }
549
+ goto EQUAL_RATE_OUT;
550
+ }
551
+ else
552
+ {
553
+ kinetics_ptr->Set_rk(3);
554
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
555
+ {
556
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
557
+ kinetics_comp_ptr->Set_moles(0.2 * rk_moles[j]);
558
+ }
559
+ }
560
+ }
561
+ /*
562
+ * Continue with rk ...
563
+ */
564
+ calc_final_kinetic_reaction(kinetics_ptr);
565
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
566
+ {
567
+ run_reactions_iterations += iterations;
568
+ moles_reduction = 9;
569
+ goto MOLES_TOO_LARGE;
570
+ }
571
+ run_reactions_iterations += iterations;
572
+
573
+ /*
574
+ * find k2
575
+ */
576
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
577
+ {
578
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
579
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
580
+ kinetics_comp_ptr->Set_moles(0.);
581
+ }
582
+ rate_sim_time = rate_sim_time_start + h_sum + 0.2 * h;
583
+ calc_kinetic_reaction(kinetics_ptr, h);
584
+
585
+ /* Reset to values of last saver() */
586
+ if (pp_assemblage_save != NULL)
587
+ {
588
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
589
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
590
+ }
591
+ if (ss_assemblage_save != NULL)
592
+ {
593
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
594
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
595
+ }
596
+
597
+ /* store k2 in rk_moles */
598
+ k = n_reactions;
599
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
600
+ {
601
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
602
+ if (moles_reduction * moles_max <
603
+ fabs(kinetics_comp_ptr->Get_moles()))
604
+ {
605
+ moles_reduction =
606
+ fabs(kinetics_comp_ptr->Get_moles()) / moles_max;
607
+ }
608
+ /* define reaction for calculating k3 */
609
+ rk_moles[k + j] = kinetics_comp_ptr->Get_moles();
610
+
611
+ kinetics_comp_ptr->Set_moles(b31 * rk_moles[j]
612
+ + b32 * rk_moles[k + j]);
613
+ /*
614
+ * check for equal_rate ...
615
+ */
616
+ if (equal_rate
617
+ && fabs(rk_moles[j] - rk_moles[k + j]) >
618
+ kinetics_comp_ptr->Get_tol())
619
+ {
620
+ equal_rate = FALSE;
621
+ }
622
+ }
623
+ if (moles_reduction > 1.0)
624
+ goto MOLES_TOO_LARGE;
625
+ /*
626
+ * Quit rk with rk = 2 and equal rates ...
627
+ */
628
+ if (kinetics_ptr->Get_rk() == 2 && equal_rate)
629
+ {
630
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
631
+ {
632
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
633
+ kinetics_comp_ptr->Set_moles(
634
+ 0.3 * rk_moles[j] + 0.7 * rk_moles[k + j]);
635
+ }
636
+ calc_final_kinetic_reaction(kinetics_ptr);
637
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
638
+ {
639
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
640
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
641
+ if (kinetics_comp_ptr->Get_m() < 1.e-30)
642
+ kinetics_comp_ptr->Set_m(0);
643
+ kinetics_comp_ptr->Set_moles(0.);
644
+ }
645
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
646
+ {
647
+ run_reactions_iterations += iterations;
648
+ moles_reduction = 9;
649
+ goto MOLES_TOO_LARGE;
650
+ }
651
+ run_reactions_iterations += iterations;
652
+ /*
653
+ * Move next calc'n to rk = 1 when initial rate equals final rate ...
654
+ */
655
+ calc_kinetic_reaction(kinetics_ptr, h);
656
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
657
+ {
658
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
659
+ if (fabs(rk_moles[j] - kinetics_comp_ptr->Get_moles()) >
660
+ kinetics_comp_ptr->Get_tol())
661
+ {
662
+ equal_rate = FALSE;
663
+ break;
664
+ }
665
+ }
666
+ if (equal_rate)
667
+ kinetics_ptr->Set_rk(1);
668
+
669
+ saver();
670
+
671
+ /* Free space */
672
+
673
+ if (pp_assemblage_save != NULL)
674
+ {
675
+ delete pp_assemblage_save;
676
+ pp_assemblage_save = NULL;
677
+ }
678
+ if (ss_assemblage_save != NULL)
679
+ {
680
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
681
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
682
+ }
683
+ goto EQUAL_RATE_OUT;
684
+ }
685
+ /*
686
+ * Continue runge_kutta..
687
+ */
688
+ calc_final_kinetic_reaction(kinetics_ptr);
689
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
690
+ {
691
+ run_reactions_iterations += iterations;
692
+ moles_reduction = 9;
693
+ goto MOLES_TOO_LARGE;
694
+ }
695
+ run_reactions_iterations += iterations;
696
+ /*
697
+ * find k3
698
+ */
699
+
700
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
701
+ {
702
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
703
+ kinetics_comp_ptr->Set_m (m_temp[j] - kinetics_comp_ptr->Get_moles());
704
+ kinetics_comp_ptr->Set_moles(0.);
705
+ }
706
+ rate_sim_time = rate_sim_time_start + h_sum + 0.3 * h;
707
+ calc_kinetic_reaction(kinetics_ptr, h);
708
+
709
+ /* Reset to values of last saver() */
710
+ if (pp_assemblage_save != NULL)
711
+ {
712
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
713
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
714
+ }
715
+ if (ss_assemblage_save != NULL)
716
+ {
717
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
718
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
719
+ }
720
+
721
+ /* store k3 in rk_moles */
722
+ k = 2 * n_reactions;
723
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
724
+ {
725
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
726
+ if (moles_reduction * moles_max <
727
+ fabs(kinetics_comp_ptr->Get_moles()))
728
+ {
729
+ moles_reduction =
730
+ fabs(kinetics_comp_ptr->Get_moles()) / moles_max;
731
+ }
732
+ /* define reaction for calculating k4 ... */
733
+ rk_moles[k + j] = kinetics_comp_ptr->Get_moles();
734
+
735
+ kinetics_comp_ptr->Set_moles(0.3 * rk_moles[j]
736
+ - 0.9 * rk_moles[n_reactions + j] + 1.2 * rk_moles[k + j]);
737
+ /*
738
+ * check for equal_rate ...
739
+ */
740
+ if (equal_rate
741
+ && fabs(rk_moles[j] - rk_moles[k + j]) >
742
+ kinetics_comp_ptr->Get_tol())
743
+ equal_rate = FALSE;
744
+ }
745
+ if (moles_reduction > 1.0)
746
+ goto MOLES_TOO_LARGE;
747
+ /*
748
+ * Quit rk with rk = 3 and equal rates ...
749
+ */
750
+ if (kinetics_ptr->Get_rk() == 3 && equal_rate)
751
+ {
752
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
753
+ {
754
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
755
+ kinetics_comp_ptr->Set_moles(0.5 * rk_moles[j]
756
+ - 1.5 * rk_moles[n_reactions + j] + 2 * rk_moles[k + j]);
757
+ }
758
+ calc_final_kinetic_reaction(kinetics_ptr);
759
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
760
+ {
761
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
762
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
763
+ if (kinetics_comp_ptr->Get_m() < 1.e-30)
764
+ kinetics_comp_ptr->Set_m(0.);
765
+ kinetics_comp_ptr->Set_moles(0.);
766
+ }
767
+
768
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
769
+ {
770
+ run_reactions_iterations += iterations;
771
+ moles_reduction = 9;
772
+ goto MOLES_TOO_LARGE;
773
+ }
774
+ run_reactions_iterations += iterations;
775
+ /*
776
+ * Move next calc'n to rk = 1 when initial rate equals final rate ...
777
+ */
778
+ calc_kinetic_reaction(kinetics_ptr, h);
779
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
780
+ {
781
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
782
+ if (fabs(rk_moles[j] - kinetics_comp_ptr->Get_moles()) >
783
+ kinetics_comp_ptr->Get_tol())
784
+ {
785
+ equal_rate = FALSE;
786
+ break;
787
+ }
788
+ }
789
+ if (equal_rate)
790
+ kinetics_ptr->Set_rk(1);
791
+
792
+ saver();
793
+
794
+ /* Free space */
795
+
796
+ if (pp_assemblage_save != NULL)
797
+ {
798
+ delete pp_assemblage_save;
799
+ pp_assemblage_save = NULL;
800
+ }
801
+ if (ss_assemblage_save != NULL)
802
+ {
803
+ delete ss_assemblage_save;
804
+ ss_assemblage_save = NULL;
805
+ }
806
+ goto EQUAL_RATE_OUT;
807
+ }
808
+ /*
809
+ * Continue runge_kutta..
810
+ */
811
+
812
+ calc_final_kinetic_reaction(kinetics_ptr);
813
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
814
+ {
815
+ run_reactions_iterations += iterations;
816
+ moles_reduction = 9;
817
+ goto MOLES_TOO_LARGE;
818
+ }
819
+ run_reactions_iterations += iterations;
820
+ /*
821
+ * find k4
822
+ */
823
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
824
+ {
825
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
826
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
827
+ kinetics_comp_ptr->Set_moles(0.);
828
+ }
829
+ rate_sim_time = rate_sim_time_start + h_sum + 0.6 * h;
830
+ calc_kinetic_reaction(kinetics_ptr, h);
831
+
832
+ /* Reset to values of last saver() */
833
+ if (pp_assemblage_save != NULL)
834
+ {
835
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
836
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
837
+ }
838
+ if (ss_assemblage_save != NULL)
839
+ {
840
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
841
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
842
+ }
843
+
844
+ /* store k4 in rk_moles */
845
+ k = 3 * n_reactions;
846
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
847
+ {
848
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
849
+ if (moles_reduction * moles_max <
850
+ fabs(kinetics_comp_ptr->Get_moles()))
851
+ {
852
+ moles_reduction =
853
+ fabs(kinetics_comp_ptr->Get_moles()) / moles_max;
854
+ }
855
+
856
+ /* define reaction for calculating k5 */
857
+ rk_moles[k + j] = kinetics_comp_ptr->Get_moles();
858
+ kinetics_comp_ptr->Set_moles(b51 * rk_moles[j]
859
+ + 2.5 * rk_moles[(size_t)n_reactions + j]
860
+ + b53 * rk_moles[2 * (size_t)n_reactions + j]
861
+ + b54 * rk_moles[(size_t)k + (size_t)j]);
862
+ }
863
+ if (moles_reduction > 1.0)
864
+ goto MOLES_TOO_LARGE;
865
+ calc_final_kinetic_reaction(kinetics_ptr);
866
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
867
+ {
868
+ run_reactions_iterations += iterations;
869
+ moles_reduction = 9;
870
+ goto MOLES_TOO_LARGE;
871
+ }
872
+ run_reactions_iterations += iterations;
873
+ /*
874
+ * find k5
875
+ */
876
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
877
+ {
878
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
879
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
880
+ kinetics_comp_ptr->Set_moles(0.);
881
+ }
882
+ rate_sim_time = rate_sim_time_start + h_sum + h;
883
+ calc_kinetic_reaction(kinetics_ptr, h);
884
+
885
+ /* Reset to values of last saver() */
886
+ if (pp_assemblage_save != NULL)
887
+ {
888
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
889
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
890
+ }
891
+ if (ss_assemblage_save != NULL)
892
+ {
893
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
894
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
895
+ }
896
+
897
+ /* store k5 in rk_moles */
898
+ k = 4 * n_reactions;
899
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
900
+ {
901
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
902
+ if (moles_reduction * moles_max <
903
+ fabs(kinetics_comp_ptr->Get_moles()))
904
+ {
905
+ moles_reduction =
906
+ fabs(kinetics_comp_ptr->Get_moles()) / moles_max;
907
+ }
908
+
909
+ /* define reaction for calculating k6 */
910
+ rk_moles[k + j] = kinetics_comp_ptr->Get_moles();
911
+ kinetics_comp_ptr->Set_moles(b61 * rk_moles[j]
912
+ + b62 * rk_moles[(size_t)n_reactions + j]
913
+ + b63 * rk_moles[2 * (size_t)n_reactions + j]
914
+ + b64 * rk_moles[3 * (size_t)n_reactions + j]
915
+ + b65 * rk_moles[(size_t)k + (size_t)j]);
916
+ }
917
+ if (moles_reduction > 1.0)
918
+ goto MOLES_TOO_LARGE;
919
+ calc_final_kinetic_reaction(kinetics_ptr);
920
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
921
+ {
922
+ run_reactions_iterations += iterations;
923
+ moles_reduction = 9;
924
+ goto MOLES_TOO_LARGE;
925
+ }
926
+ run_reactions_iterations += iterations;
927
+ /*
928
+ * find k6
929
+ */
930
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
931
+ {
932
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
933
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
934
+ kinetics_comp_ptr->Set_moles(0.);
935
+ }
936
+ rate_sim_time = rate_sim_time_start + h_sum + 0.875 * h;
937
+ calc_kinetic_reaction(kinetics_ptr, h);
938
+
939
+ /* Reset to values of last saver() */
940
+ if (pp_assemblage_save != NULL)
941
+ {
942
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
943
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
944
+ }
945
+ if (ss_assemblage_save != NULL)
946
+ {
947
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
948
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
949
+ }
950
+
951
+ /* store k6 in rk_moles */
952
+ k = 5 * n_reactions;
953
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
954
+ {
955
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
956
+ rk_moles[k + j] = kinetics_comp_ptr->Get_moles();
957
+ }
958
+
959
+ /*
960
+ * Evaluate error
961
+ */
962
+ error_max = 0.;
963
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
964
+ {
965
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
966
+ l_error = fabs(dc1 * rk_moles[j]
967
+ + dc3 * rk_moles[2 * (size_t)n_reactions + (size_t)j]
968
+ + dc4 * rk_moles[3 * (size_t)n_reactions + (size_t)j]
969
+ + dc5 * rk_moles[4 * (size_t)n_reactions + (size_t)j]
970
+ + dc6 * rk_moles[5 * (size_t)n_reactions + (size_t)j]);
971
+
972
+ /* tol is in moles/l */
973
+ l_error /= kinetics_comp_ptr->Get_tol();
974
+ if (l_error > error_max)
975
+ error_max = l_error;
976
+ }
977
+
978
+ /*
979
+ * repeat with smaller step
980
+ */
981
+ /* printf("timest %g ; error_max %g\n", h, error_max); */
982
+ if (error_max > 1)
983
+ {
984
+ h_old = h;
985
+ if (step_ok == 0)
986
+ h = h * safety / error_max;
987
+ else
988
+ h = h * safety * pow(error_max, (LDBLE) -0.25);
989
+ l_bad = TRUE;
990
+ step_bad++;
991
+ }
992
+ else
993
+ {
994
+ /*
995
+ * OK, calculate result
996
+ */
997
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
998
+ {
999
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
1000
+ kinetics_comp_ptr->Set_moles(c1 * rk_moles[j]
1001
+ + c3 * rk_moles[2 * (size_t)n_reactions + (size_t)j]
1002
+ + c4 * rk_moles[3 * (size_t)n_reactions + (size_t)j]
1003
+ + c6 * rk_moles[5 * (size_t)n_reactions + (size_t)j]);
1004
+ }
1005
+ calc_final_kinetic_reaction(kinetics_ptr);
1006
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
1007
+ {
1008
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
1009
+ kinetics_comp_ptr->Set_m(m_temp[j] - kinetics_comp_ptr->Get_moles());
1010
+ if (kinetics_comp_ptr->Get_m() < 1.e-30)
1011
+ kinetics_comp_ptr->Set_m(0);
1012
+ kinetics_comp_ptr->Set_moles(0.);
1013
+ }
1014
+
1015
+ if (set_and_run_wrapper(i, NOMIX, TRUE, i, 0.) == MASS_BALANCE)
1016
+ {
1017
+ run_reactions_iterations += iterations;
1018
+ moles_reduction = 9;
1019
+ goto MOLES_TOO_LARGE;
1020
+ }
1021
+ run_reactions_iterations += iterations;
1022
+ /*
1023
+ * Move next calc'n to rk = 1 when initial rate equals final rate ...
1024
+ */
1025
+ calc_kinetic_reaction(kinetics_ptr, h);
1026
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
1027
+ {
1028
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
1029
+ if (fabs(rk_moles[j] - kinetics_comp_ptr->Get_moles()) >
1030
+ kinetics_comp_ptr->Get_tol())
1031
+ {
1032
+ equal_rate = FALSE;
1033
+ break;
1034
+ }
1035
+ }
1036
+ if (equal_rate && kinetics_ptr->Get_rk() < 6)
1037
+ kinetics_ptr->Set_rk(1);
1038
+
1039
+ saver();
1040
+
1041
+ step_ok++;
1042
+ h_sum += h;
1043
+ /* Free space */
1044
+
1045
+ if (pp_assemblage_save != NULL)
1046
+ {
1047
+ delete pp_assemblage_save;
1048
+ pp_assemblage_save = NULL;
1049
+ }
1050
+ if (ss_assemblage_save != NULL)
1051
+ {
1052
+ delete ss_assemblage_save;
1053
+ ss_assemblage_save = NULL;
1054
+ }
1055
+ /*
1056
+ * and increase step size ...
1057
+ */
1058
+ if (h_sum < kin_time)
1059
+ {
1060
+ if (error_max > 0.000577)
1061
+ {
1062
+ h = h * safety * pow(error_max, (LDBLE) -0.2e0);
1063
+ }
1064
+ else
1065
+ {
1066
+ h *= 4;
1067
+ }
1068
+ if (h > (kin_time - h_sum))
1069
+ h = (kin_time - h_sum);
1070
+ }
1071
+ }
1072
+ {
1073
+ char str[MAX_LENGTH];
1074
+ snprintf(str, sizeof(str), "RK-steps: Bad%4d. OK%5d. Time %3d%%", step_bad,
1075
+ step_ok, (int) (100 * h_sum / kin_time));
1076
+ status(0, str, true);
1077
+ }
1078
+ }
1079
+
1080
+ EQUAL_RATE_OUT:
1081
+
1082
+ /*
1083
+ * Run one more time to get distribution of species
1084
+ */
1085
+ if (state >= REACTION || nsaver != i)
1086
+ {
1087
+ set_and_run_wrapper(i, NOMIX, FALSE, nsaver, 0.);
1088
+ run_reactions_iterations += iterations;
1089
+ }
1090
+ /* saver(); */ /* reset for printing */
1091
+ if (use_mix == DISP)
1092
+ {
1093
+ use.Set_mix_ptr(Utilities::Rxn_find(Dispersion_mix_map, i));
1094
+ use.Set_mix_in(true);
1095
+ use.Set_n_mix_user(i);
1096
+ }
1097
+ else if ((use_mix == STAG || use_mix == TRUE) && state == TRANSPORT)
1098
+ {
1099
+ use.Set_mix_ptr(Utilities::Rxn_find(Rxn_mix_map, i));
1100
+ if (use.Get_mix_ptr() != NULL)
1101
+ {
1102
+ use.Set_mix_in(true);
1103
+ use.Set_n_mix_user(i);
1104
+ }
1105
+ }
1106
+ /*
1107
+ * Restore solution i, if necessary
1108
+ */
1109
+ if (nsaver != i)
1110
+ {
1111
+ Utilities::Rxn_copy(Rxn_solution_map, save_old, i);
1112
+ }
1113
+ rk_moles.clear();
1114
+
1115
+ rate_sim_time = rate_sim_time_start + kin_time;
1116
+ use.Set_kinetics_in(true);
1117
+
1118
+ /* Free space */
1119
+
1120
+ if (pp_assemblage_save != NULL)
1121
+ {
1122
+ delete pp_assemblage_save;
1123
+ pp_assemblage_save = NULL;
1124
+ }
1125
+ if (ss_assemblage_save != NULL)
1126
+ {
1127
+ delete ss_assemblage_save;
1128
+ ss_assemblage_save = NULL;
1129
+ }
1130
+ return (OK);
1131
+ }
1132
+
1133
+ /* ---------------------------------------------------------------------- */
1134
+ int Phreeqc::
1135
+ set_and_run_wrapper(int i, int use_mix, int use_kinetics, int nsaver,
1136
+ LDBLE step_fraction)
1137
+ /* ---------------------------------------------------------------------- */
1138
+ {
1139
+ int j, converge, max_try;
1140
+ int old_diag, old_itmax;
1141
+ LDBLE old_tol, old_min_value, old_step, old_pe, old_pp_column_scale;
1142
+ LDBLE small_pe_step, small_step;
1143
+ #if (__GNUC__ && (__cplusplus >= 201103L)) || (_MSC_VER >= 1600)
1144
+ std::unique_ptr<cxxPPassemblage> pp_assemblage_save=NULL;
1145
+ std::unique_ptr<cxxSSassemblage> ss_assemblage_save=NULL;
1146
+ std::unique_ptr<cxxKinetics> kinetics_save=NULL;
1147
+ #else
1148
+ std::auto_ptr<cxxPPassemblage> pp_assemblage_save(NULL);
1149
+ std::auto_ptr<cxxSSassemblage> ss_assemblage_save(NULL);
1150
+ std::auto_ptr<cxxKinetics> kinetics_save(NULL);
1151
+ #endif
1152
+ int restart = 0;
1153
+
1154
+ small_pe_step = 5.;
1155
+ small_step = 10.;
1156
+ converge = FALSE;
1157
+
1158
+ old_diag = diagonal_scale;
1159
+ old_itmax = itmax;
1160
+ old_tol = ineq_tol;
1161
+ old_step = step_size;
1162
+ old_pe = pe_step_size;
1163
+ old_min_value = min_value;
1164
+ old_pp_column_scale = pp_column_scale;
1165
+ int old_equi_delay = equi_delay;
1166
+
1167
+ if (state == TRANSPORT || state == PHAST)
1168
+ {
1169
+ set_transport(i, use_mix, use_kinetics, i);
1170
+ }
1171
+ else if (state == ADVECTION)
1172
+ {
1173
+ set_advection(i, use_mix, use_kinetics, i);
1174
+ }
1175
+ else if (state == REACTION)
1176
+ {
1177
+ set_reaction(i, use_mix, use_kinetics);
1178
+ }
1179
+ if (use.Get_pp_assemblage_ptr() != NULL)
1180
+ {
1181
+ cxxPPassemblage * pp_assemblage_ptr = use.Get_pp_assemblage_ptr();
1182
+ pp_assemblage_save.reset(new cxxPPassemblage(*pp_assemblage_ptr));
1183
+ }
1184
+ if (use.Get_ss_assemblage_ptr() != NULL)
1185
+ {
1186
+ cxxSSassemblage * ss_assemblage_ptr = use.Get_ss_assemblage_ptr();
1187
+ ss_assemblage_save.reset(new cxxSSassemblage(*ss_assemblage_ptr));
1188
+ }
1189
+ if (use.Get_kinetics_ptr() != NULL)
1190
+ {
1191
+ kinetics_save.reset(new cxxKinetics(*use.Get_kinetics_ptr()));
1192
+ }
1193
+
1194
+ if (pitzer_model == TRUE || sit_model == TRUE)
1195
+ {
1196
+ diagonal_scale = TRUE;
1197
+ always_full_pitzer = FALSE;
1198
+ max_try = 14;
1199
+ }
1200
+ else
1201
+ {
1202
+ max_try = 14;
1203
+ }
1204
+ max_try = (max_tries < max_try) ? max_tries : max_try;
1205
+ /*max_try = 1; */
1206
+
1207
+ restart:
1208
+ for (j = 0; j < max_try; j++)
1209
+ {
1210
+ if (j == 1)
1211
+ {
1212
+ /*always_full_pitzer = TRUE;*/
1213
+ if (pe_step_size <= small_pe_step && step_size <= small_step)
1214
+ continue;
1215
+ itmax *= 2;
1216
+ step_size = small_step;
1217
+ pe_step_size = small_pe_step;
1218
+ error_string = sformatf(
1219
+ "Trying smaller step size, pe step size %g, %g ... \n",
1220
+ (double) step_size, (double) pe_step_size);
1221
+ warning_msg(error_string);
1222
+ }
1223
+ else if (j == 2)
1224
+ {
1225
+ itmax *= 2;
1226
+ ineq_tol /= 10.;
1227
+ error_string = sformatf( "Trying reduced tolerance %g ...\n",
1228
+ (double) ineq_tol);
1229
+ warning_msg(error_string);
1230
+ }
1231
+ else if (j == 3)
1232
+ {
1233
+ itmax *= 2;
1234
+ ineq_tol *= 10.;
1235
+ error_string = sformatf( "Trying increased tolerance %g ...\n",
1236
+ (double) ineq_tol);
1237
+ warning_msg(error_string);
1238
+ }
1239
+ else if (j == 4)
1240
+ {
1241
+ always_full_pitzer = TRUE;
1242
+ itmax *= 2;
1243
+ if (diagonal_scale == TRUE)
1244
+ {
1245
+ diagonal_scale = FALSE;
1246
+ }
1247
+ else
1248
+ {
1249
+ diagonal_scale = TRUE;
1250
+ }
1251
+ error_string = sformatf( "Trying diagonal scaling ...\n");
1252
+ warning_msg(error_string);
1253
+ }
1254
+ else if (j == 5)
1255
+ {
1256
+ itmax *= 2;
1257
+ if (diagonal_scale == TRUE)
1258
+ {
1259
+ diagonal_scale = FALSE;
1260
+ }
1261
+ else
1262
+ {
1263
+ diagonal_scale = TRUE;
1264
+ }
1265
+ ineq_tol /= 10.;
1266
+ error_string = sformatf(
1267
+ "Trying diagonal scaling and reduced tolerance %g ...\n",
1268
+ (double) ineq_tol);
1269
+ warning_msg(error_string);
1270
+ }
1271
+ else if (j == 6)
1272
+ {
1273
+ if (pitzer_model == TRUE || sit_model == TRUE) continue;
1274
+ itmax *= 2;
1275
+ pp_column_scale = 1e-10;
1276
+ error_string = sformatf(
1277
+ "Trying scaling pure_phase columns %g ...\n",
1278
+ (double) pp_column_scale);
1279
+ warning_msg(error_string);
1280
+ }
1281
+ else if (j == 7)
1282
+ {
1283
+ if (pitzer_model == TRUE || sit_model == TRUE) continue;
1284
+ itmax *= 2;
1285
+ pp_column_scale = 1e-10;
1286
+ if (diagonal_scale == TRUE)
1287
+ {
1288
+ diagonal_scale = FALSE;
1289
+ }
1290
+ else
1291
+ {
1292
+ diagonal_scale = TRUE;
1293
+ }
1294
+ error_string = sformatf(
1295
+ "Trying scaling pure_phase columns and diagonal scale %g ...\n",
1296
+ (double) pp_column_scale);
1297
+ warning_msg(error_string);
1298
+ }
1299
+ else if (j == 8)
1300
+ {
1301
+ if (use.Get_pp_assemblage_ptr() == NULL) continue;
1302
+ if (equi_delay > 0)
1303
+ {
1304
+ equi_delay = 0;
1305
+ }
1306
+ else
1307
+ {
1308
+ equi_delay = 1;
1309
+ }
1310
+ error_string = sformatf( "Trying delay removal of equilibrium phases %g ...\n",
1311
+ (double) equi_delay);
1312
+ warning_msg(error_string);
1313
+ }
1314
+
1315
+ else if (j == 9)
1316
+ {
1317
+ if (pitzer_model == TRUE || sit_model == TRUE) continue;
1318
+ itmax *= 2;
1319
+ min_value *= 10;
1320
+ error_string = sformatf( "Trying increased scaling %g ...\n",
1321
+ (double) min_value);
1322
+ warning_msg(error_string);
1323
+ }
1324
+ else if (j == 10)
1325
+ {
1326
+ if (pitzer_model == TRUE || sit_model == TRUE) continue;
1327
+ aqueous_only = 5;
1328
+ error_string = sformatf(
1329
+ "Skipping optimize equations for first %d iterations ...\n",
1330
+ aqueous_only);
1331
+ warning_msg(error_string);
1332
+ }
1333
+ else if (j == 11)
1334
+ {
1335
+ if (pitzer_model == TRUE || sit_model == TRUE) continue;
1336
+ negative_concentrations = TRUE;
1337
+ error_string = sformatf(
1338
+ "Adding inequality to make concentrations greater than zero.\n");
1339
+ warning_msg(error_string);
1340
+ }
1341
+ else if (j == 12)
1342
+ {
1343
+ itmax *= 2;
1344
+ ineq_tol /= 100.;
1345
+ error_string = sformatf( "Trying reduced tolerance %g ...\n",
1346
+ (double) ineq_tol);
1347
+ warning_msg(error_string);
1348
+ }
1349
+ else if (j == 13)
1350
+ {
1351
+ itmax *= 2;
1352
+ ineq_tol /= 1000.;
1353
+ error_string = sformatf( "Trying reduced tolerance %g ...\n",
1354
+ (double) ineq_tol);
1355
+ warning_msg(error_string);
1356
+ }
1357
+ else if (j == 14 && use.Get_ss_assemblage_in())
1358
+ {
1359
+ //cxxStorageBin error_bin;
1360
+ //Use2cxxStorageBin(error_bin);
1361
+ //std::ostringstream error_input;
1362
+ //error_bin.dump_raw(error_input, 0);
1363
+ //cxxStorageBin reread;
1364
+ //std::istringstream is(error_input.str());
1365
+ //CParser cp(is);
1366
+ //cp.set_echo_stream(CParser::EO_NONE);
1367
+ //reread.read_raw(cp);
1368
+ //cxxStorageBin2phreeqc(reread);
1369
+ //error_string = sformatf("Trying restarting ...\n");
1370
+ //warning_msg(error_string);
1371
+ //if (restart < 2)
1372
+ //{
1373
+ // restart++;
1374
+ // goto restart;
1375
+ //}
1376
+ }
1377
+ if (j > 0)
1378
+ {
1379
+ if (pp_assemblage_save.get() != NULL)
1380
+ {
1381
+ Rxn_pp_assemblage_map[pp_assemblage_save->Get_n_user()] = *pp_assemblage_save;
1382
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, pp_assemblage_save->Get_n_user()));
1383
+ }
1384
+ if (ss_assemblage_save.get() != NULL)
1385
+ {
1386
+ Rxn_ss_assemblage_map[ss_assemblage_save->Get_n_user()] = *ss_assemblage_save;
1387
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, ss_assemblage_save->Get_n_user()));
1388
+ }
1389
+ if (kinetics_save.get() != NULL)
1390
+ {
1391
+ Rxn_kinetics_map[kinetics_save->Get_n_user()] = *kinetics_save;
1392
+ use.Set_kinetics_ptr(Utilities::Rxn_find(Rxn_kinetics_map, kinetics_save->Get_n_user()));
1393
+ }
1394
+ }
1395
+ if (j == 14)
1396
+ {
1397
+ cxxStorageBin error_bin(this->Get_phrq_io());
1398
+ Use2cxxStorageBin(error_bin);
1399
+ std::ostringstream error_input;
1400
+ error_bin.dump_raw(error_input, 0);
1401
+ cxxStorageBin reread(this->Get_phrq_io());
1402
+ std::istringstream is(error_input.str());
1403
+ CParser cp(is);
1404
+ cp.set_echo_stream(CParser::EO_NONE);
1405
+ cp.set_echo_file(CParser::EO_NONE);
1406
+ reread.read_raw(cp);
1407
+ cxxStorageBin2phreeqc(reread);
1408
+ error_string = sformatf("Trying restarting ...\n");
1409
+ warning_msg(error_string);
1410
+
1411
+ step_size = 1.0 + (small_step - 1.0)/((double) restart + 1.0);
1412
+ pe_step_size = 1.0 + (small_pe_step - 1)/ ((double)restart + 1.0);
1413
+ if (restart < 2)
1414
+ {
1415
+ restart++;
1416
+ goto restart;
1417
+ }
1418
+ }
1419
+ set_and_run_attempt = j;
1420
+
1421
+ converge =
1422
+ set_and_run(i, use_mix, use_kinetics, nsaver, step_fraction);
1423
+ /* reset values */
1424
+ diagonal_scale = old_diag;
1425
+ itmax = old_itmax;
1426
+ ineq_tol = old_tol;
1427
+ step_size = old_step;
1428
+ pe_step_size = old_pe;
1429
+ min_value = old_min_value;
1430
+ pp_column_scale = old_pp_column_scale;
1431
+ equi_delay = old_equi_delay;
1432
+ aqueous_only = 0;
1433
+ negative_concentrations = FALSE;
1434
+ always_full_pitzer = FALSE;
1435
+ if (converge == TRUE)
1436
+ {
1437
+ break;
1438
+ }
1439
+ else if (converge == MASS_BALANCE)
1440
+ {
1441
+ break;
1442
+ }
1443
+ warning_msg
1444
+ ("Numerical method failed with this set of convergence parameters.\n");
1445
+ }
1446
+ if (converge == FALSE && use.Get_kinetics_ptr() != NULL
1447
+ && use.Get_kinetics_ptr()->Get_use_cvode())
1448
+ {
1449
+ error_string = sformatf(
1450
+ "Numerical method failed on all parameter combinations, retrying integration, cell/soln %d", this->solution_number());
1451
+ warning_msg(error_string);
1452
+ converge = MASS_BALANCE;
1453
+ }
1454
+ if (converge == FALSE)
1455
+ {
1456
+ /*
1457
+ * write to error.inp what failed to converge.
1458
+ */
1459
+ std::ofstream error_input("error.inp");
1460
+ cxxStorageBin error_bin(this->Get_phrq_io());
1461
+ Use2cxxStorageBin(error_bin);
1462
+ error_bin.dump_raw(error_input, 0);
1463
+ error_input.close();
1464
+
1465
+ /* if (state == TRANSPORT && dump_modulus == 0) dump(); */
1466
+ check_residuals();
1467
+ pr.all = TRUE;
1468
+ pr.gas_phase = use.Get_gas_phase_in();
1469
+ pr.pp_assemblage = use.Get_pp_assemblage_in();
1470
+ pr.ss_assemblage = use.Get_ss_assemblage_in();
1471
+ pr.surface = use.Get_surface_in();
1472
+ pr.exchange = use.Get_exchange_in();
1473
+ pr.totals = TRUE;
1474
+ pr.species = TRUE;
1475
+ pr.saturation_indices = TRUE;
1476
+ pr.irrev = use.Get_reaction_in();
1477
+ pr.mix = use.Get_mix_in();
1478
+ pr.reaction = TRUE;
1479
+ pr.use = TRUE;
1480
+ sum_species();
1481
+ print_all();
1482
+ error_string = sformatf(
1483
+ "Numerical method failed on all combinations of convergence parameters, cell/soln/mix %d", this->solution_number());
1484
+ error_msg(error_string, STOP);
1485
+ }
1486
+ numerical_fixed_volume = false;
1487
+ if (converge == MASS_BALANCE)
1488
+ {
1489
+ return (MASS_BALANCE);
1490
+ }
1491
+ return (OK);
1492
+ }
1493
+
1494
+ /* ---------------------------------------------------------------------- */
1495
+ int Phreeqc::
1496
+ set_and_run(int i, int use_mix, int use_kinetics, int nsaver,
1497
+ LDBLE step_fraction)
1498
+ /* ---------------------------------------------------------------------- */
1499
+ {
1500
+ /*
1501
+ * i --user number for soln, reaction, etc.
1502
+ * use_mix --integer flag
1503
+ state == TRANSPORT: DISP, STAG, NOMIX
1504
+ state == REACTION: TRUE, FALSE
1505
+ * use_kinetics --true or false flag to calculate kinetic reactions
1506
+ * nsaver --user number to store solution
1507
+ * step_fraction--fraction of irreversible reaction to add
1508
+ */
1509
+ int converge;
1510
+ if (state == TRANSPORT || state == PHAST)
1511
+ {
1512
+ set_transport(i, use_mix, use_kinetics, nsaver);
1513
+ }
1514
+ else if (state == ADVECTION)
1515
+ {
1516
+ set_advection(i, use_mix, use_kinetics, nsaver);
1517
+ }
1518
+ else if (state == REACTION)
1519
+ {
1520
+ set_reaction(i, use_mix, use_kinetics);
1521
+ }
1522
+ cell = i;
1523
+ /*
1524
+ * Take step
1525
+ */
1526
+ if (state >= REACTION)
1527
+ {
1528
+ if (step(step_fraction) == MASS_BALANCE)
1529
+ {
1530
+ return (MASS_BALANCE);
1531
+ }
1532
+ /*
1533
+ * Always use solution, exchange, and surface -1
1534
+ */
1535
+ use.Set_solution_ptr(Utilities::Rxn_find(Rxn_solution_map, -1));
1536
+ /* new */
1537
+ if (use.Get_exchange_ptr() != NULL)
1538
+ {
1539
+ use.Set_exchange_ptr(Utilities::Rxn_find(Rxn_exchange_map, -1));
1540
+ }
1541
+ if (use.Get_surface_ptr() != NULL)
1542
+ {
1543
+ use.Set_surface_ptr(Utilities::Rxn_find(Rxn_surface_map, -1));
1544
+ }
1545
+
1546
+ /*
1547
+ * Adjust the total pressure to the gas pressure
1548
+ */
1549
+ if (use.Get_gas_phase_ptr() != NULL)
1550
+ {
1551
+ cxxGasPhase *gas_phase_ptr = use.Get_gas_phase_ptr();
1552
+ if (gas_phase_ptr->Get_type() == cxxGasPhase::GP_PRESSURE)
1553
+ {
1554
+ /*
1555
+ * Fixed-pressure Gas phase and solution will react
1556
+ * Change total pressure of current simulation to pressure
1557
+ * of gas phase
1558
+ */
1559
+ patm_x = gas_phase_ptr->Get_total_p();
1560
+ }
1561
+ /* fixed volume gas phase is handled in calc_gas_pressures */
1562
+
1563
+ }
1564
+ }
1565
+ /* end new */
1566
+ if (use.Get_surface_ptr() != NULL)
1567
+ {
1568
+ dl_type_x = use.Get_surface_ptr()->Get_dl_type();
1569
+ }
1570
+ if (use.Get_surface_ptr() != NULL && dl_type_x != cxxSurface::NO_DL)
1571
+ {
1572
+ converge = surface_model();
1573
+ }
1574
+ else
1575
+ {
1576
+ prep();
1577
+ k_temp(use.Get_solution_ptr()->Get_tc(), use.Get_solution_ptr()->Get_patm());
1578
+ set(FALSE);
1579
+ converge = model();
1580
+ }
1581
+ sum_species();
1582
+ viscos = viscosity(NULL);
1583
+ use.Get_solution_ptr()->Set_viscosity(viscos);
1584
+ use.Get_solution_ptr()->Set_viscos_0(viscos_0);
1585
+ if (use.Get_surface_ptr() != NULL && dl_type_x != cxxSurface::NO_DL && use.Get_surface_ptr()->Get_calc_viscosity())
1586
+ use.Get_surface_ptr()->Set_DDL_viscosity(viscosity(use.Get_surface_ptr()));
1587
+ return (converge);
1588
+ }
1589
+
1590
+ /* ---------------------------------------------------------------------- */
1591
+ int Phreeqc::
1592
+ set_transport(int i, int use_mix, int use_kinetics, int nsaver)
1593
+ /* ---------------------------------------------------------------------- */
1594
+ {
1595
+ /*
1596
+ * i --user number for soln, reaction, etc.
1597
+ * use_mix --integer flag
1598
+ state == TRANSPORT: DISP, STAG, NOMIX, MIX_BS
1599
+ state == REACTION: TRUE, FALSE
1600
+ * use_kinetics --true or false flag to calculate kinetic reactions
1601
+ * nsaver --user number to store solution
1602
+ */
1603
+ cell = i;
1604
+ reaction_step = 1;
1605
+ /*
1606
+ * Find mixture or solution
1607
+ */
1608
+
1609
+ use.Set_mix_ptr(NULL);
1610
+ use.Set_mix_in(false);
1611
+ if (use_mix == DISP)
1612
+ {
1613
+ use.Set_mix_ptr(Utilities::Rxn_find(Dispersion_mix_map, i));
1614
+ use.Set_mix_in(true);
1615
+ use.Set_n_mix_user(i);
1616
+ use.Set_n_mix_user_orig(i);
1617
+ }
1618
+ else if ((use_mix == STAG && multi_Dflag != TRUE) || use_mix == MIX_BS)
1619
+ {
1620
+ use.Set_mix_ptr(Utilities::Rxn_find(Rxn_mix_map, i));
1621
+ if (use.Get_mix_ptr() != NULL)
1622
+ {
1623
+ use.Set_mix_in(true);
1624
+ use.Set_n_mix_user(i);
1625
+ use.Set_n_mix_user_orig(i);
1626
+ }
1627
+ else
1628
+ {
1629
+ use.Set_solution_ptr(Utilities::Rxn_find(Rxn_solution_map, i));
1630
+ if (use.Get_solution_ptr() == NULL)
1631
+ {
1632
+ error_string = sformatf( "Solution %d not found, while searching mix structure for solution %d.",
1633
+ i, use.Get_n_solution_user());
1634
+ error_msg(error_string, STOP);
1635
+ }
1636
+ use.Set_n_solution_user(i);
1637
+ use.Set_solution_in(true);
1638
+ }
1639
+ }
1640
+ else
1641
+ {
1642
+ use.Set_solution_ptr(Utilities::Rxn_find(Rxn_solution_map, i));
1643
+ if (use.Get_solution_ptr() == NULL)
1644
+ {
1645
+ error_string = sformatf( "Solution %d not found, while searching mix structure for solution %d.",
1646
+ i, use.Get_n_solution_user());
1647
+ error_msg(error_string, STOP);
1648
+ }
1649
+ use.Set_n_solution_user(i);
1650
+ use.Set_solution_in(true);
1651
+ }
1652
+ save.solution = TRUE;
1653
+ save.n_solution_user = nsaver;
1654
+ save.n_solution_user_end = nsaver;
1655
+ /*
1656
+ * Find pure phase assemblage
1657
+ */
1658
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, i));
1659
+ if (use.Get_pp_assemblage_ptr() != NULL)
1660
+ {
1661
+ use.Set_pp_assemblage_in(true);
1662
+ use.Set_n_pp_assemblage_user(i);
1663
+ save.pp_assemblage = TRUE;
1664
+ save.n_pp_assemblage_user = i;
1665
+ save.n_pp_assemblage_user_end = i;
1666
+ }
1667
+ else
1668
+ {
1669
+ use.Set_pp_assemblage_in(false);
1670
+ save.pp_assemblage = FALSE;
1671
+ }
1672
+ /*
1673
+ * Find irreversible reaction
1674
+ */
1675
+ use.Set_reaction_ptr(Utilities::Rxn_find(Rxn_reaction_map, i));
1676
+ if (use.Get_reaction_ptr() != NULL)
1677
+ {
1678
+ use.Set_reaction_in(true);
1679
+ use.Set_n_reaction_user(i);
1680
+ }
1681
+ else
1682
+ {
1683
+ use.Set_reaction_in(false);
1684
+ }
1685
+ /*
1686
+ * Find exchange
1687
+ */
1688
+ use.Set_exchange_ptr(Utilities::Rxn_find(Rxn_exchange_map, i));
1689
+ if (use.Get_exchange_ptr() != NULL)
1690
+ {
1691
+ use.Set_exchange_in(true);
1692
+ use.Set_n_exchange_user(i);
1693
+ save.exchange = TRUE;
1694
+ save.n_exchange_user = i;
1695
+ save.n_exchange_user_end = i;
1696
+ }
1697
+ else
1698
+ {
1699
+ use.Set_exchange_in(false);
1700
+ save.exchange = FALSE;
1701
+ }
1702
+
1703
+ /*
1704
+ * Find surface
1705
+ */
1706
+ use.Set_surface_ptr(Utilities::Rxn_find(Rxn_surface_map, i));
1707
+ if (use.Get_surface_ptr() != NULL)
1708
+ {
1709
+ use.Set_surface_in(true);
1710
+ use.Set_n_surface_user(i);
1711
+ save.surface = TRUE;
1712
+ save.n_surface_user = i;
1713
+ save.n_surface_user_end = i;
1714
+ }
1715
+ else
1716
+ {
1717
+ use.Set_surface_in(false);
1718
+ save.surface = FALSE;
1719
+ dl_type_x = cxxSurface::NO_DL;
1720
+ }
1721
+ /*
1722
+ * Find temperature; temp retardation is done in step
1723
+ */
1724
+ use.Set_temperature_ptr(Utilities::Rxn_find(Rxn_temperature_map, i));
1725
+ if (use.Get_temperature_ptr() != NULL)
1726
+ {
1727
+ use.Set_temperature_in(true);
1728
+ use.Set_n_temperature_user(i);
1729
+ }
1730
+ else
1731
+ {
1732
+ use.Set_temperature_in(false);
1733
+ }
1734
+ /*
1735
+ * Find pressure
1736
+ */
1737
+ use.Set_pressure_ptr(Utilities::Rxn_find(Rxn_pressure_map, i));
1738
+ if (use.Get_pressure_ptr() != NULL)
1739
+ {
1740
+ use.Set_pressure_in(true);
1741
+ use.Set_n_pressure_user(i);
1742
+ }
1743
+ else
1744
+ {
1745
+ use.Set_pressure_in(false);
1746
+ }
1747
+ /*
1748
+ * Find gas
1749
+ */
1750
+ use.Set_gas_phase_ptr(Utilities::Rxn_find(Rxn_gas_phase_map, i));
1751
+ if (use.Get_gas_phase_ptr() != NULL)
1752
+ {
1753
+ use.Set_gas_phase_in(true);
1754
+ use.Set_n_gas_phase_user(i);
1755
+ save.gas_phase = TRUE;
1756
+ save.n_gas_phase_user = i;
1757
+ save.n_gas_phase_user_end = i;
1758
+ }
1759
+ else
1760
+ {
1761
+ use.Set_gas_phase_in(false);
1762
+ save.gas_phase = FALSE;
1763
+ }
1764
+ /*
1765
+ * Find ss_assemblage
1766
+ */
1767
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, i));
1768
+ if (use.Get_ss_assemblage_ptr() != NULL)
1769
+ {
1770
+ use.Set_ss_assemblage_in(true);
1771
+ use.Set_n_ss_assemblage_user(i);
1772
+ save.ss_assemblage = TRUE;
1773
+ save.n_ss_assemblage_user = i;
1774
+ save.n_ss_assemblage_user_end = i;
1775
+ }
1776
+ else
1777
+ {
1778
+ use.Set_ss_assemblage_in(false);
1779
+ save.ss_assemblage = FALSE;
1780
+ }
1781
+ /*
1782
+ * Find kinetics
1783
+ */
1784
+ use.Set_kinetics_ptr(NULL);
1785
+ use.Set_kinetics_in(false);
1786
+ save.kinetics = FALSE;
1787
+ if (use_kinetics == TRUE)
1788
+ {
1789
+ use.Set_kinetics_ptr(Utilities::Rxn_find(Rxn_kinetics_map, i));
1790
+ if (use.Get_kinetics_ptr() != NULL)
1791
+ {
1792
+ use.Set_n_kinetics_user(i);
1793
+ use.Set_kinetics_in(true);
1794
+ save.kinetics = TRUE;
1795
+ save.n_kinetics_user = i;
1796
+ save.n_kinetics_user_end = i;
1797
+ }
1798
+ }
1799
+ /*
1800
+ if (use.irrev_ptr != NULL && use.Get_kinetics_ptr() != NULL)
1801
+ {
1802
+ warning_msg("Should not use REACTION in same simulation with KINETICS.");
1803
+ }
1804
+ */
1805
+ return (OK);
1806
+ }
1807
+
1808
+ /* ---------------------------------------------------------------------- */
1809
+ int Phreeqc::
1810
+ set_reaction(int i, int use_mix, int use_kinetics)
1811
+ /* ---------------------------------------------------------------------- */
1812
+ {
1813
+ /*
1814
+ * i --user number for soln, reaction, etc.
1815
+ * use_mix --integer flag
1816
+ state == TRANSPORT: DISP, STAG, NOMIX
1817
+ state == REACTION: TRUE, FALSE
1818
+ * use_kinetics --true or false flag to calculate kinetic reactions
1819
+ */
1820
+ /*
1821
+ * Find mixture or solution
1822
+ */
1823
+ use.Set_mix_ptr(NULL);
1824
+ use.Set_solution_ptr(NULL);
1825
+ if (use_mix == TRUE && use.Get_mix_in() == TRUE)
1826
+ {
1827
+ use.Set_mix_ptr(Utilities::Rxn_find(Rxn_mix_map, i));
1828
+ if (use.Get_mix_ptr() == NULL)
1829
+ {
1830
+ error_string = sformatf( "MIX %d not found.", i);
1831
+ error_msg(error_string, STOP);
1832
+ }
1833
+ }
1834
+ else
1835
+ {
1836
+ use.Set_solution_ptr(Utilities::Rxn_find(Rxn_solution_map, i));
1837
+ if (use.Get_solution_ptr() == NULL)
1838
+ {
1839
+ error_string = sformatf( "Solution %d not found.", i);
1840
+ error_msg(error_string, STOP);
1841
+ }
1842
+ }
1843
+ /*
1844
+ * Find pure phase assemblage
1845
+ */
1846
+ if (use.Get_pp_assemblage_in() == TRUE)
1847
+ {
1848
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, i));
1849
+ if (use.Get_pp_assemblage_ptr() == NULL)
1850
+ {
1851
+ error_string = sformatf( "PP_ASSEMBLAGE %d not found.", i);
1852
+ error_msg(error_string, STOP);
1853
+ }
1854
+ }
1855
+
1856
+ /*
1857
+ * Find irreversible reaction
1858
+ */
1859
+ if (use.Get_reaction_in() == TRUE)
1860
+ {
1861
+ use.Set_reaction_ptr(Utilities::Rxn_find(Rxn_reaction_map, i));
1862
+ if (use.Get_reaction_ptr() == NULL)
1863
+ {
1864
+ error_string = sformatf( "REACTION %d not found.", i);
1865
+ error_msg(error_string, STOP);
1866
+ }
1867
+ }
1868
+ /*
1869
+ * Find exchange
1870
+ */
1871
+ if (use.Get_exchange_in() == TRUE)
1872
+ {
1873
+ use.Set_exchange_ptr(Utilities::Rxn_find(Rxn_exchange_map, i));
1874
+ if (use.Get_exchange_ptr() == NULL)
1875
+ {
1876
+ error_string = sformatf( "EXCHANGE %d not found.", i);
1877
+ error_msg(error_string, STOP);
1878
+ }
1879
+ }
1880
+ /*
1881
+ * Find surface
1882
+ */
1883
+ //if (use.Get_surface_in() && use.Get_kinetics_in() && use.Get_kinetics_ptr() && !use.Get_kinetics_ptr()->Get_use_cvode() && reaction_step > 1)
1884
+ //{
1885
+ // // use.Set_surface_ptr(Utilities::Rxn_find(Rxn_surface_map, i));
1886
+ // // appt: we may come here with zero kinetic reaction, but surface may have to keep DONNAN_DL
1887
+ //}
1888
+ //else
1889
+ // dl_type_x = cxxSurface::NO_DL;
1890
+ if (use.Get_surface_in() == TRUE)
1891
+ {
1892
+ use.Set_surface_ptr(Utilities::Rxn_find(Rxn_surface_map, i));
1893
+ if (use.Get_surface_ptr() == NULL)
1894
+ {
1895
+ error_string = sformatf( "SURFACE %d not found.", i);
1896
+ error_msg(error_string, STOP);
1897
+ }
1898
+ }
1899
+ /*
1900
+ * Find temperature; temp retardation is done in step
1901
+ */
1902
+ if (use.Get_temperature_in() == TRUE)
1903
+ {
1904
+ use.Set_temperature_ptr(Utilities::Rxn_find(Rxn_temperature_map, i));
1905
+ if (use.Get_temperature_ptr() == NULL)
1906
+ {
1907
+ error_string = sformatf( "TEMPERATURE %d not found.", i);
1908
+ error_msg(error_string, STOP);
1909
+ }
1910
+ }
1911
+ /*
1912
+ * Find pressure
1913
+ */
1914
+ if (use.Get_pressure_in() == TRUE)
1915
+ {
1916
+ use.Set_pressure_ptr(Utilities::Rxn_find(Rxn_pressure_map, i));
1917
+ if (use.Get_pressure_ptr() == NULL)
1918
+ {
1919
+ error_string = sformatf( "PRESSURE %d not found.", i);
1920
+ error_msg(error_string, STOP);
1921
+ }
1922
+ }
1923
+ /*
1924
+ * Find gas
1925
+ */
1926
+ if (use.Get_gas_phase_in() == TRUE)
1927
+ {
1928
+ use.Set_gas_phase_ptr(Utilities::Rxn_find(Rxn_gas_phase_map, i));
1929
+ if (use.Get_gas_phase_ptr() == NULL)
1930
+ {
1931
+ error_string = sformatf( "GAS_PHASE %d not found.", i);
1932
+ error_msg(error_string, STOP);
1933
+ }
1934
+ }
1935
+ /*
1936
+ * Find ss_assemblage
1937
+ */
1938
+ if (use.Get_ss_assemblage_in() == TRUE)
1939
+ {
1940
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, i));
1941
+ if (use.Get_ss_assemblage_ptr() == NULL)
1942
+ {
1943
+ error_string = sformatf( "Solid-solution Assemblage %d not found.",
1944
+ i);
1945
+ error_msg(error_string, STOP);
1946
+ }
1947
+ }
1948
+ /*
1949
+ * Find kinetics
1950
+ */
1951
+ if (use_kinetics == TRUE && use.Get_kinetics_in() == TRUE)
1952
+ {
1953
+ use.Set_kinetics_ptr(Utilities::Rxn_find(Rxn_kinetics_map, i));
1954
+ if (use.Get_kinetics_ptr() == NULL)
1955
+ {
1956
+ error_string = sformatf( "KINETICS %d not found.", i);
1957
+ error_msg(error_string, STOP);
1958
+ }
1959
+ }
1960
+ else
1961
+ {
1962
+ use.Set_kinetics_ptr(NULL);
1963
+ }
1964
+ /*
1965
+ if (use.irrev_ptr != NULL && use.Get_kinetics_ptr() != NULL)
1966
+ {
1967
+ warning_msg("Should not use REACTION in same simulation with KINETICS.");
1968
+ }
1969
+ */
1970
+ return (OK);
1971
+ }
1972
+ /* ---------------------------------------------------------------------- */
1973
+ int Phreeqc::
1974
+ run_reactions(int i, LDBLE kin_time, int use_mix, LDBLE step_fraction)
1975
+ /* ---------------------------------------------------------------------- */
1976
+ {
1977
+ /*
1978
+ * Kinetics calculations
1979
+ * Rates and moles of each reaction are calculated in calc_kinetic_reaction
1980
+ * Total number of moles in reaction is stored in kinetics[i].totals
1981
+ */
1982
+ //int increase_tol = 0; // appt
1983
+ int converge, m_iter;
1984
+ int pr_all_save;
1985
+ int nsaver;
1986
+ cxxKinetics *kinetics_ptr;
1987
+ cxxPPassemblage *pp_assemblage_ptr;
1988
+ cxxSSassemblage *ss_assemblage_ptr;
1989
+ cxxUse use_save;
1990
+ int save_old, n_reactions /*, nok, nbad */ ;
1991
+
1992
+ /* CVODE definitions */
1993
+ realtype ropt[OPT_SIZE], reltol, t, tout, tout1, sum_t;
1994
+ long int iopt[OPT_SIZE];
1995
+ int flag;
1996
+ /*
1997
+ * Set nsaver
1998
+ */
1999
+ run_reactions_iterations = 0;
2000
+ overall_iterations = 0;
2001
+ kin_time_x = kin_time;
2002
+ rate_kin_time = kin_time;
2003
+ nsaver = i;
2004
+ if (state == TRANSPORT || state == PHAST)
2005
+ {
2006
+ if (use_mix == DISP)
2007
+ {
2008
+ nsaver = -2;
2009
+ }
2010
+ else if (use_mix == STAG)
2011
+ {
2012
+ nsaver = -2 - i;
2013
+ }
2014
+ }
2015
+ if (state == ADVECTION)
2016
+ {
2017
+ nsaver = -2;
2018
+ }
2019
+ /*
2020
+ * Check that reaction exists for this cell ..
2021
+ */
2022
+ kinetics_ptr = Utilities::Rxn_find(Rxn_kinetics_map, i);
2023
+ if (kin_time <= 0 ||
2024
+ (kinetics_ptr && kinetics_ptr->Get_kinetics_comps().size() == 0) ||
2025
+ (state == REACTION && use.Get_kinetics_in() == FALSE) ||
2026
+ (state == TRANSPORT && kinetics_ptr == NULL) ||
2027
+ (state == PHAST && kinetics_ptr == NULL) ||
2028
+ (state == ADVECTION && kinetics_ptr == NULL))
2029
+ {
2030
+ converge =
2031
+ set_and_run_wrapper(i, use_mix, FALSE, nsaver, step_fraction);
2032
+ if (converge == MASS_BALANCE)
2033
+ {
2034
+ error_string = sformatf("Negative concentration in solution %d. Stopping calculation.", cell_no);
2035
+ error_msg(error_string, STOP);
2036
+ }
2037
+ run_reactions_iterations += iterations;
2038
+ }
2039
+ else
2040
+ {
2041
+ /*
2042
+ * Save moles of kinetic reactants for printout...
2043
+ */
2044
+ size_t count_comps = kinetics_ptr->Get_kinetics_comps().size();
2045
+ m_temp.resize(count_comps);
2046
+ m_original.resize(count_comps);
2047
+
2048
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2049
+ {
2050
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2051
+ m_original[j] = kinetics_comp_ptr->Get_m();
2052
+ m_temp[j] = kinetics_comp_ptr->Get_m();
2053
+ }
2054
+ /*
2055
+ * Start the loop for timestepping ...
2056
+ * Use either Runge-Kutta-Fehlberg, or final result extrapolation
2057
+ */
2058
+ pr_all_save = pr.all;
2059
+ pr.all = FALSE;
2060
+ /*
2061
+ * This condition makes output equal for incremental_reactions TRUE/FALSE...
2062
+ * (if (incremental_reactions == FALSE || reaction_step == 1)
2063
+ */
2064
+ store_get_equi_reactants(i, FALSE);
2065
+ if (!kinetics_ptr->Get_use_cvode())
2066
+ {
2067
+ /* in case dispersivity is not wanted..
2068
+ if (multi_Dflag)
2069
+ rk_kinetics(i, kin_time, NOMIX, nsaver, step_fraction);
2070
+ else
2071
+ */
2072
+ rk_kinetics(i, kin_time, use_mix, nsaver, step_fraction);
2073
+ }
2074
+ else
2075
+ {
2076
+ save_old = -2 - (count_cells * (1 + stag_data.count_stag) + 2);
2077
+ if (nsaver != i)
2078
+ {
2079
+ Utilities::Rxn_copy(Rxn_solution_map, i, save_old);
2080
+ }
2081
+ for (int j = 0; j < OPT_SIZE; j++)
2082
+ {
2083
+ iopt[j] = 0;
2084
+ ropt[j] = 0;
2085
+ }
2086
+ /*
2087
+ * Do mix first
2088
+ */
2089
+ kinetics_ptr = Utilities::Rxn_find(Rxn_kinetics_map, i);
2090
+ n_reactions = (int) kinetics_ptr->Get_kinetics_comps().size();
2091
+ cvode_n_user = i;
2092
+ cvode_kinetics_ptr = (void *) kinetics_ptr;
2093
+ cvode_n_reactions = n_reactions;
2094
+ cvode_rate_sim_time_start = rate_sim_time_start;
2095
+ cvode_rate_sim_time = rate_sim_time;
2096
+
2097
+ if (multi_Dflag)
2098
+ converge = set_and_run_wrapper(i, NOMIX, FALSE, i, step_fraction);
2099
+ else
2100
+ converge = set_and_run_wrapper(i, use_mix, FALSE, i, step_fraction);
2101
+ if (converge == MASS_BALANCE)
2102
+ {
2103
+ error_string = sformatf("Negative concentration in solution %d. Stopping calculation.", cell_no);
2104
+ error_msg(error_string, STOP);
2105
+ }
2106
+ saver();
2107
+ pp_assemblage_ptr = Utilities::Rxn_find(Rxn_pp_assemblage_map, i);
2108
+ ss_assemblage_ptr = Utilities::Rxn_find(Rxn_ss_assemblage_map, i);
2109
+ if (pp_assemblage_ptr != NULL)
2110
+ {
2111
+ cvode_pp_assemblage_save = new cxxPPassemblage(*pp_assemblage_ptr);
2112
+ }
2113
+ if (ss_assemblage_ptr != NULL)
2114
+ {
2115
+ cvode_ss_assemblage_save = new cxxSSassemblage(*ss_assemblage_ptr);
2116
+ }
2117
+ /* allocate space for CVODE */
2118
+ kinetics_machEnv = M_EnvInit_Serial(n_reactions);
2119
+ kinetics_machEnv->phreeqc_ptr = this;
2120
+ kinetics_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */
2121
+ if (kinetics_y == NULL)
2122
+ malloc_error();
2123
+ cvode_last_good_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */
2124
+ if (cvode_last_good_y == NULL)
2125
+ malloc_error();
2126
+ cvode_prev_good_y = N_VNew(n_reactions, kinetics_machEnv); /* Allocate y, abstol vectors */
2127
+ if (cvode_prev_good_y == NULL)
2128
+ malloc_error();
2129
+ kinetics_abstol = N_VNew(n_reactions, kinetics_machEnv);
2130
+ if (kinetics_abstol == NULL)
2131
+ malloc_error();
2132
+ for (int j = 0; j < n_reactions; j++)
2133
+ {
2134
+ Ith(cvode_last_good_y, j + 1) = 0.0;
2135
+ Ith(cvode_prev_good_y, j + 1) = 0.0;
2136
+ Ith(kinetics_abstol, j + 1) = 0.0;
2137
+ }
2138
+ /*
2139
+ * Set y to 0.0
2140
+ */
2141
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2142
+ {
2143
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2144
+ kinetics_comp_ptr->Set_moles(0.0);
2145
+ Ith(kinetics_y, j + 1) = 0.0;
2146
+ Ith(kinetics_abstol, j + 1) = kinetics_comp_ptr->Get_tol();
2147
+ /*Ith(abstol,j+1) = 1e-8; */
2148
+ /* m_temp[j] = kinetics_ptr->comps[j].m; */
2149
+ }
2150
+ reltol = 0.0;
2151
+
2152
+ /* Call CVodeMalloc to initialize CVODE:
2153
+
2154
+ NEQ is the problem size = number of equations
2155
+ f is the user's right hand side function in y'=f(t,y)
2156
+ T0 is the initial time
2157
+ y is the initial dependent variable vector
2158
+ BDF specifies the Backward Differentiation Formula
2159
+ NEWTON specifies a Newton iteration
2160
+ SV specifies scalar relative and vector absolute tolerances
2161
+ &reltol is a pointer to the scalar relative tolerance
2162
+ abstol is the absolute tolerance vector
2163
+ FALSE indicates there are no optional inputs in iopt and ropt
2164
+ iopt is an array used to communicate optional integer input and output
2165
+ ropt is an array used to communicate optional real input and output
2166
+
2167
+ A pointer to CVODE problem memory is returned and stored in cvode_mem. */
2168
+ /* Don`t know what this does */
2169
+ /*
2170
+ iopt[SLDET] = TRUE;
2171
+ cvode_mem = CVodeMalloc(n_reactions, f, 0.0, y, BDF, NEWTON, SV, &reltol, abstol, NULL, NULL, TRUE, iopt, ropt, machEnv);
2172
+ cvode_mem = CVodeMalloc(n_reactions, f, 0.0, y, ADAMS, FUNCTIONAL, SV, &reltol, abstol, NULL, NULL, FALSE, iopt, ropt, machEnv);
2173
+ iopt[MXSTEP] is maximum number of steps that CVODE tries.
2174
+ */
2175
+ //iopt[SLDET] = TRUE; // appt
2176
+ iopt[MXSTEP] = kinetics_ptr->Get_cvode_steps();
2177
+ iopt[MAXORD] = kinetics_ptr->Get_cvode_order();
2178
+ kinetics_cvode_mem =
2179
+ CVodeMalloc(n_reactions, f, 0.0, kinetics_y, BDF, NEWTON, SV,
2180
+ &reltol, kinetics_abstol, this, NULL, TRUE, iopt,
2181
+ ropt, kinetics_machEnv);
2182
+ if (kinetics_cvode_mem == NULL)
2183
+ malloc_error();
2184
+
2185
+ /* Call CVDense to specify the CVODE dense linear solver with the
2186
+ user-supplied Jacobian routine Jac. */
2187
+ flag = CVDense(kinetics_cvode_mem, Jac, this);
2188
+ if (flag != SUCCESS)
2189
+ {
2190
+ error_msg("CVDense failed.", STOP);
2191
+ }
2192
+ t = 0;
2193
+ tout = kin_time;
2194
+ /*ropt[HMAX] = tout/10.; */
2195
+ /*ropt[HMIN] = 1e-17; */
2196
+ use_save = use;
2197
+ flag = CVode(kinetics_cvode_mem, tout, kinetics_y, &t, NORMAL);
2198
+ rate_sim_time = rate_sim_time_start + t;
2199
+ /*
2200
+ printf("At t = %0.4e y =%14.6e %14.6e %14.6e\n",
2201
+ t, Ith(y,1), Ith(y,2), Ith(y,3));
2202
+ */
2203
+ m_iter = 0;
2204
+ sum_t = 0;
2205
+ RESTART:
2206
+ while (flag != SUCCESS)
2207
+ {
2208
+ sum_t += cvode_last_good_time;
2209
+ {
2210
+ error_string = sformatf("CV_ODE: Time: %8.2e s. Delta t: %8.2e s. Calls: %d.", (double)(sum_t), (double) cvode_last_good_time, m_iter);
2211
+ status(0, error_string, true);
2212
+ }
2213
+ //if (state != TRANSPORT)
2214
+ //{
2215
+ // error_string = sformatf(
2216
+ // "CVode incomplete at cvode_steps %d. Cell: %d. Time: %8.2e s. Cvode calls: %d, continuing...\n",
2217
+ // (int)iopt[NST], cell_no, (double)sum_t, m_iter + 1);
2218
+ // warning_msg(error_string);
2219
+ //}
2220
+ #ifdef DEBUG_KINETICS
2221
+ if (m_iter > 5)
2222
+ dump_kinetics_stderr(cell_no);
2223
+ #endif
2224
+
2225
+ //if (m_iter > 0.5 * kinetics_ptr->Get_bad_step_max() &&
2226
+ // (cvode_last_good_time < 1e-6 || cvode_last_good_time < 1e-6 * tout)) // appt
2227
+ //{
2228
+ // if (increase_tol < 3)
2229
+ // {
2230
+ // increase_tol += 1;
2231
+ // for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2232
+ // {
2233
+ // cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2234
+ // LDBLE tr = kinetics_comp_ptr->Get_tol() * 10.0;
2235
+ // kinetics_comp_ptr->Set_tol(tr);
2236
+ // tr += 0;
2237
+ // }
2238
+ // }
2239
+ //}
2240
+ cvode_last_good_time = 0;
2241
+ if (++m_iter >= kinetics_ptr->Get_bad_step_max())
2242
+ {
2243
+ m_temp.clear();
2244
+ m_original.clear();
2245
+ error_string = sformatf(
2246
+ "CVode is at maximum calls: %d. Cell: %d. Time: %8.2e s\nERROR: Please increase the maximum calls with -bad_step_max.",
2247
+ m_iter, cell_no, (double)sum_t);
2248
+ error_msg(error_string, STOP);
2249
+ }
2250
+ tout1 = tout - sum_t;
2251
+ t = 0;
2252
+ N_VScale(1.0, cvode_last_good_y, kinetics_y);
2253
+ for (int j = 0; j < OPT_SIZE; j++)
2254
+ {
2255
+ iopt[j] = 0;
2256
+ ropt[j] = 0;
2257
+ }
2258
+ CVodeFree(kinetics_cvode_mem); /* Free the CVODE problem memory */
2259
+ iopt[MXSTEP] = kinetics_ptr->Get_cvode_steps();
2260
+ iopt[MAXORD] = kinetics_ptr->Get_cvode_order();
2261
+ kinetics_cvode_mem =
2262
+ CVodeMalloc(n_reactions, f, 0.0, kinetics_y, BDF, NEWTON,
2263
+ SV, &reltol, kinetics_abstol, this, NULL,
2264
+ TRUE, iopt, ropt, kinetics_machEnv);
2265
+ if (kinetics_cvode_mem == NULL)
2266
+ malloc_error();
2267
+
2268
+ /* Call CVDense to specify the CVODE dense linear solver with the
2269
+ user-supplied Jacobian routine Jac. */
2270
+ flag = CVDense(kinetics_cvode_mem, Jac, this);
2271
+ if (flag != SUCCESS)
2272
+ {
2273
+ error_msg("CVDense failed.", STOP);
2274
+ }
2275
+ flag =
2276
+ CVode(kinetics_cvode_mem, tout1, kinetics_y, &t, NORMAL);
2277
+ /*
2278
+ error_string = sformatf( "CVode failed, flag=%d.\n", flag);
2279
+ error_msg(error_string, STOP);
2280
+ */
2281
+ }
2282
+ /*
2283
+ 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 );
2284
+ */
2285
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2286
+ {
2287
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2288
+ kinetics_comp_ptr->Set_moles(Ith(kinetics_y, j + 1));
2289
+ kinetics_comp_ptr->Set_m(m_original[j] - kinetics_comp_ptr->Get_moles());
2290
+ if (kinetics_comp_ptr->Get_m() < 0)
2291
+ {
2292
+ kinetics_comp_ptr->Set_moles(m_original[j]);
2293
+ kinetics_comp_ptr->Set_m(0.0);
2294
+ }
2295
+ }
2296
+ if (use.Get_pp_assemblage_ptr() != NULL)
2297
+ {
2298
+ Rxn_pp_assemblage_map[cvode_pp_assemblage_save->Get_n_user()] = *cvode_pp_assemblage_save;
2299
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, cvode_pp_assemblage_save->Get_n_user()));
2300
+ }
2301
+ if (use.Get_ss_assemblage_ptr() != NULL)
2302
+ {
2303
+ Rxn_ss_assemblage_map[cvode_ss_assemblage_save->Get_n_user()] = *cvode_ss_assemblage_save;
2304
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, cvode_ss_assemblage_save->Get_n_user()));
2305
+ }
2306
+ calc_final_kinetic_reaction(kinetics_ptr);
2307
+ if (set_and_run_wrapper(i, NOMIX, TRUE, nsaver, 0) ==
2308
+ MASS_BALANCE)
2309
+ {
2310
+ /*error_msg("FAIL 2 after successful integration in CVode", CONTINUE); */
2311
+ warning_msg("FAIL 2 after successful integration in CVode");
2312
+ flag = -1;
2313
+ goto RESTART;
2314
+ }
2315
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2316
+ {
2317
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2318
+ kinetics_comp_ptr->Set_m(m_original[j] - kinetics_comp_ptr->Get_moles());
2319
+ }
2320
+ /*
2321
+ * Restore solution i, if necessary
2322
+ */
2323
+ if (nsaver != i)
2324
+ {
2325
+ Utilities::Rxn_copy(Rxn_solution_map, save_old, i);
2326
+ }
2327
+ free_cvode();
2328
+ use.Set_mix_in(use_save.Get_mix_in());
2329
+ use.Set_mix_ptr(use_save.Get_mix_ptr());
2330
+
2331
+ error_string = sformatf("CV_ODE: Final Delta t: %8.2e s. Calls: %d. ", (double)cvode_last_good_time, m_iter);
2332
+ status(0, error_string, true);
2333
+
2334
+ //status(0, NULL);
2335
+ }
2336
+
2337
+ rate_sim_time = rate_sim_time_start + kin_time;
2338
+ store_get_equi_reactants(i, TRUE);
2339
+ pr.all = pr_all_save;
2340
+
2341
+ kinetics_ptr = Utilities::Rxn_find(Rxn_kinetics_map, i);
2342
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2343
+ {
2344
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2345
+ kinetics_comp_ptr->Set_moles(m_original[j] - kinetics_comp_ptr->Get_m());
2346
+ /* if (kinetics_ptr->comps[j].moles < 1.e-15) kinetics_ptr->comps[j].moles = 0.0;
2347
+ */ }
2348
+ m_temp.clear();
2349
+ m_original.clear();
2350
+ }
2351
+ iterations = run_reactions_iterations;
2352
+ if (cvode_pp_assemblage_save != NULL)
2353
+ {
2354
+ delete cvode_pp_assemblage_save;
2355
+ cvode_pp_assemblage_save = NULL;
2356
+ }
2357
+ if (cvode_ss_assemblage_save != NULL)
2358
+ {
2359
+ delete cvode_ss_assemblage_save;
2360
+ cvode_ss_assemblage_save = NULL;
2361
+ }
2362
+ return (OK);
2363
+ }
2364
+
2365
+ /* ---------------------------------------------------------------------- */
2366
+ int Phreeqc::
2367
+ free_cvode(void)
2368
+ /* ---------------------------------------------------------------------- */
2369
+ {
2370
+ if (kinetics_y != NULL)
2371
+ N_VFree(kinetics_y); /* Free vector */
2372
+ kinetics_y = NULL;
2373
+ if (cvode_last_good_y != NULL)
2374
+ N_VFree(cvode_last_good_y); /* Free vector */
2375
+ cvode_last_good_y = NULL;
2376
+ if (cvode_prev_good_y != NULL)
2377
+ N_VFree(cvode_prev_good_y); /* Free vector */
2378
+ cvode_prev_good_y = NULL;
2379
+ if (kinetics_abstol != NULL)
2380
+ N_VFree(kinetics_abstol); /* Free vector */
2381
+ kinetics_abstol = NULL;
2382
+ if (kinetics_cvode_mem != NULL)
2383
+ CVodeFree(kinetics_cvode_mem); /* Free the CVODE problem memory */
2384
+ kinetics_cvode_mem = NULL;
2385
+ if (kinetics_machEnv != NULL)
2386
+ M_EnvFree_Serial(kinetics_machEnv); /* Free the machine environment memory */
2387
+ kinetics_machEnv = NULL;
2388
+ if (cvode_pp_assemblage_save != NULL)
2389
+ {
2390
+ delete cvode_pp_assemblage_save;
2391
+ cvode_pp_assemblage_save = NULL;
2392
+ }
2393
+ if (cvode_ss_assemblage_save != NULL)
2394
+ {
2395
+ delete cvode_ss_assemblage_save;
2396
+ cvode_ss_assemblage_save = NULL;
2397
+ }
2398
+ return (OK);
2399
+ }
2400
+
2401
+ /* ---------------------------------------------------------------------- */
2402
+ int Phreeqc::
2403
+ set_advection(int i, int use_mix, int use_kinetics, int nsaver)
2404
+ /* ---------------------------------------------------------------------- */
2405
+ {
2406
+ /*
2407
+ * i --user number for soln, reaction, etc.
2408
+ * use_mix --integer flag
2409
+ state == TRANSPORT: DISP, STAG, NOMIX
2410
+ state == REACTION: TRUE, FALSE
2411
+ state == ADVECTION: TRUE, FALSE
2412
+ * use_kinetics --true or false flag to calculate kinetic reactions
2413
+ * nsaver --user number to store solution
2414
+ */
2415
+
2416
+ cell = i;
2417
+ reaction_step = 1;
2418
+ /*
2419
+ * Find mixture or solution
2420
+ */
2421
+
2422
+ use.Set_mix_ptr(NULL);
2423
+ use.Set_mix_in(false);
2424
+ use.Set_mix_ptr(Utilities::Rxn_find(Rxn_mix_map, i));
2425
+ if (use_mix == TRUE && use.Get_mix_ptr() != NULL)
2426
+ {
2427
+ use.Set_mix_in(true);
2428
+ use.Set_n_mix_user(i);
2429
+ use.Set_n_mix_user_orig(i);
2430
+ use.Set_n_solution_user(i);
2431
+ }
2432
+ else
2433
+ {
2434
+ use.Set_solution_ptr(Utilities::Rxn_find(Rxn_solution_map, i));
2435
+ if (use.Get_solution_ptr() == NULL)
2436
+ {
2437
+ error_string = sformatf( "Solution %d not found.",
2438
+ use.Get_n_solution_user());
2439
+ error_msg(error_string, STOP);
2440
+ }
2441
+ use.Set_n_solution_user(i);
2442
+ use.Set_solution_in(true);
2443
+ }
2444
+ save.solution = TRUE;
2445
+ save.n_solution_user = nsaver;
2446
+ save.n_solution_user_end = nsaver;
2447
+ /*
2448
+ * Find pure phase assemblage
2449
+ */
2450
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, i));
2451
+ if (use.Get_pp_assemblage_ptr() != NULL)
2452
+ {
2453
+ use.Set_pp_assemblage_in(true);
2454
+ use.Set_n_pp_assemblage_user(i);
2455
+ save.pp_assemblage = TRUE;
2456
+ save.n_pp_assemblage_user = i;
2457
+ save.n_pp_assemblage_user_end = i;
2458
+ }
2459
+ else
2460
+ {
2461
+ use.Set_pp_assemblage_in(false);
2462
+ save.pp_assemblage = FALSE;
2463
+ }
2464
+ /*
2465
+ * Find irreversible reaction
2466
+ */
2467
+ use.Set_reaction_ptr(Utilities::Rxn_find(Rxn_reaction_map, i));
2468
+ if (use.Get_reaction_ptr() != NULL)
2469
+ {
2470
+ use.Set_reaction_in(true);
2471
+ use.Set_n_reaction_user(i);
2472
+ }
2473
+ else
2474
+ {
2475
+ use.Set_reaction_in(false);
2476
+ }
2477
+ /*
2478
+ * Find exchange
2479
+ */
2480
+ use.Set_exchange_ptr(Utilities::Rxn_find(Rxn_exchange_map, i));
2481
+ if (use.Get_exchange_ptr() != NULL)
2482
+ {
2483
+ use.Set_exchange_in(true);
2484
+ use.Set_n_exchange_user(i);
2485
+ save.exchange = TRUE;
2486
+ save.n_exchange_user = i;
2487
+ save.n_exchange_user_end = i;
2488
+ }
2489
+ else
2490
+ {
2491
+ use.Set_exchange_in(false);
2492
+ save.exchange = FALSE;
2493
+ }
2494
+
2495
+ /*
2496
+ * Find surface
2497
+ */
2498
+ use.Set_surface_ptr(Utilities::Rxn_find(Rxn_surface_map, i));
2499
+ if (use.Get_surface_ptr() != NULL)
2500
+ {
2501
+ use.Set_surface_in(true);
2502
+ use.Set_n_surface_user(i);
2503
+ save.surface = TRUE;
2504
+ save.n_surface_user = i;
2505
+ save.n_surface_user_end = i;
2506
+ }
2507
+ else
2508
+ {
2509
+ use.Set_surface_in(false);
2510
+ save.surface = FALSE;
2511
+ dl_type_x = cxxSurface::NO_DL;
2512
+ }
2513
+ /*
2514
+ * Find temperature; temp retardation is done in step
2515
+ */
2516
+ use.Set_temperature_ptr(Utilities::Rxn_find(Rxn_temperature_map, i));
2517
+ if (use.Get_temperature_ptr() != NULL)
2518
+ {
2519
+ use.Set_temperature_in(true);
2520
+ use.Set_n_temperature_user(i);
2521
+ }
2522
+ else
2523
+ {
2524
+ use.Set_temperature_in(false);
2525
+ }
2526
+ /*
2527
+ * Find pressure
2528
+ */
2529
+ use.Set_pressure_ptr(Utilities::Rxn_find(Rxn_pressure_map, i));
2530
+ if (use.Get_pressure_ptr() != NULL)
2531
+ {
2532
+ use.Set_pressure_in(true);
2533
+ use.Set_n_pressure_user(i);
2534
+ }
2535
+ else
2536
+ {
2537
+ use.Set_pressure_in(false);
2538
+ }
2539
+ /*
2540
+ * Find gas
2541
+ */
2542
+ use.Set_gas_phase_ptr(Utilities::Rxn_find(Rxn_gas_phase_map, i));
2543
+ if (use.Get_gas_phase_ptr() != NULL)
2544
+ {
2545
+ use.Set_gas_phase_in(true);
2546
+ use.Set_n_gas_phase_user(i);
2547
+ save.gas_phase = TRUE;
2548
+ save.n_gas_phase_user = i;
2549
+ save.n_gas_phase_user_end = i;
2550
+ }
2551
+ else
2552
+ {
2553
+ use.Set_gas_phase_in(false);
2554
+ save.gas_phase = FALSE;
2555
+ }
2556
+ /*
2557
+ * Find ss_assemblage
2558
+ */
2559
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, i));
2560
+ if (use.Get_ss_assemblage_ptr() != NULL)
2561
+ {
2562
+ use.Set_ss_assemblage_in(true);
2563
+ use.Set_n_ss_assemblage_user(i);
2564
+ save.ss_assemblage = TRUE;
2565
+ save.n_ss_assemblage_user = i;
2566
+ save.n_ss_assemblage_user_end = i;
2567
+ }
2568
+ else
2569
+ {
2570
+ use.Set_ss_assemblage_in(false);
2571
+ save.ss_assemblage = FALSE;
2572
+ }
2573
+ /*
2574
+ * Find kinetics
2575
+ */
2576
+ use.Set_kinetics_ptr(NULL);
2577
+ use.Set_kinetics_in(false);
2578
+ save.kinetics = FALSE;
2579
+ if (use_kinetics == TRUE)
2580
+ {
2581
+ use.Set_kinetics_ptr(Utilities::Rxn_find(Rxn_kinetics_map, i));
2582
+ if (use.Get_kinetics_ptr() != NULL)
2583
+ {
2584
+ use.Set_n_kinetics_user(i);
2585
+ use.Set_kinetics_in(true);
2586
+ save.kinetics = TRUE;
2587
+ save.n_kinetics_user = i;
2588
+ save.n_kinetics_user_end = i;
2589
+ }
2590
+ }
2591
+ /*
2592
+ if (use.irrev_ptr != NULL && use.Get_kinetics_ptr() != NULL)
2593
+ {
2594
+ warning_msg("Should not use REACTION in same simulation with KINETICS.");
2595
+ }
2596
+ */
2597
+ return (OK);
2598
+ }
2599
+
2600
+ /* ---------------------------------------------------------------------- */
2601
+ int Phreeqc::
2602
+ store_get_equi_reactants(int l, int kin_end)
2603
+ /* ---------------------------------------------------------------------- */
2604
+ {
2605
+ int i, k;
2606
+
2607
+ if (use.Get_pp_assemblage_in() == TRUE)
2608
+ {
2609
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, l));
2610
+ }
2611
+ else
2612
+ use.Set_pp_assemblage_ptr(NULL);
2613
+ cxxPPassemblage * pp_assemblage_ptr = use.Get_pp_assemblage_ptr();
2614
+ if (use.Get_gas_phase_in() == TRUE)
2615
+ {
2616
+ use.Set_gas_phase_ptr(Utilities::Rxn_find(Rxn_gas_phase_map, l));
2617
+ }
2618
+ else
2619
+ use.Set_gas_phase_ptr(NULL);
2620
+ if (use.Get_ss_assemblage_in() == TRUE)
2621
+ {
2622
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, l));
2623
+ }
2624
+ else
2625
+ use.Set_ss_assemblage_ptr(NULL);
2626
+
2627
+ if (kin_end == FALSE)
2628
+ {
2629
+ count_pp = count_ss = count_pg = 0;
2630
+ if (use.Get_pp_assemblage_ptr() != NULL)
2631
+ count_pp = (int) pp_assemblage_ptr->Get_pp_assemblage_comps().size();
2632
+ if (use.Get_gas_phase_ptr() != NULL)
2633
+ {
2634
+ cxxGasPhase *gas_phase_ptr = use.Get_gas_phase_ptr();
2635
+ count_pg = (int) gas_phase_ptr->Get_gas_comps().size();
2636
+ }
2637
+ if (use.Get_ss_assemblage_ptr() != NULL)
2638
+ {
2639
+ std::vector<cxxSS *> ss_ptrs = use.Get_ss_assemblage_ptr()->Vectorize();
2640
+ for (size_t i = 0; i < ss_ptrs.size(); i++)
2641
+ {
2642
+ cxxSS *ss_ptr = ss_ptrs[i];
2643
+ count_ss += (int) ss_ptr->Get_ss_comps().size();
2644
+ }
2645
+ }
2646
+ k = count_pp + count_ss + count_pg;
2647
+
2648
+ if (k == 0)
2649
+ return (OK);
2650
+ x0_moles.resize(k);
2651
+ for (i = 0; i < k; i++) x0_moles[i] = 0.0;
2652
+ k = -1;
2653
+ if (pp_assemblage_ptr)
2654
+ {
2655
+ std::map<std::string, cxxPPassemblageComp>::iterator it;
2656
+ it = pp_assemblage_ptr->Get_pp_assemblage_comps().begin();
2657
+ for ( ; it != pp_assemblage_ptr->Get_pp_assemblage_comps().end(); it++)
2658
+ {
2659
+ x0_moles[++k] = it->second.Get_moles();
2660
+ }
2661
+ }
2662
+
2663
+ {
2664
+ cxxGasPhase *gas_phase_ptr = use.Get_gas_phase_ptr();
2665
+ if (gas_phase_ptr)
2666
+ {
2667
+ for (size_t l = 0; l < gas_phase_ptr->Get_gas_comps().size(); l++)
2668
+ {
2669
+ x0_moles[++k] += gas_phase_ptr->Get_gas_comps()[l].Get_moles();
2670
+ }
2671
+ }
2672
+ }
2673
+ if (count_ss != 0)
2674
+ {
2675
+ std::vector<cxxSS *> ss_ptrs = use.Get_ss_assemblage_ptr()->Vectorize();
2676
+ for (size_t i = 0; i < ss_ptrs.size(); i++)
2677
+ {
2678
+ cxxSS *ss_ptr = ss_ptrs[i];
2679
+ for (size_t j = 0; j < ss_ptr->Get_ss_comps().size(); j++)
2680
+ {
2681
+ cxxSScomp *comp_ptr = &(ss_ptr->Get_ss_comps()[j]);
2682
+ x0_moles[++k] = comp_ptr->Get_moles();
2683
+ }
2684
+ /*!!!! also miscibility gap comps ??
2685
+ */
2686
+ }
2687
+ }
2688
+ }
2689
+ else
2690
+ {
2691
+ k = -1;
2692
+ if (pp_assemblage_ptr && count_pp > 0)
2693
+ {
2694
+ std::map<std::string, cxxPPassemblageComp>::iterator it;
2695
+ it = pp_assemblage_ptr->Get_pp_assemblage_comps().begin();
2696
+ for ( ; it != pp_assemblage_ptr->Get_pp_assemblage_comps().end(); it++)
2697
+ {
2698
+ it->second.Set_moles(x0_moles[++k]);
2699
+ it->second.Set_delta(0.0);
2700
+ }
2701
+ }
2702
+
2703
+ {
2704
+ cxxGasPhase *gas_phase_ptr = use.Get_gas_phase_ptr();
2705
+ if (gas_phase_ptr && count_pg)
2706
+ {
2707
+ std::vector<cxxGasComp> temp_comps(gas_phase_ptr->Get_gas_comps());
2708
+ for (size_t l = 0; l < temp_comps.size(); l++)
2709
+ {
2710
+ temp_comps[l].Set_moles(x0_moles[++k]);
2711
+ }
2712
+ gas_phase_ptr->Set_gas_comps(temp_comps);
2713
+ }
2714
+ }
2715
+ if (count_ss != 0)
2716
+ {
2717
+ std::vector<cxxSS *> ss_ptrs = use.Get_ss_assemblage_ptr()->Vectorize();
2718
+ for (size_t i = 0; i < ss_ptrs.size(); i++)
2719
+ {
2720
+ cxxSS *ss_ptr = ss_ptrs[i];
2721
+ for (size_t j = 0; j < ss_ptr->Get_ss_comps().size(); j++)
2722
+ {
2723
+ cxxSScomp *comp_ptr = &(ss_ptr->Get_ss_comps()[j]);
2724
+ comp_ptr->Set_initial_moles(x0_moles[++k]);
2725
+ }
2726
+ /*!!!! also miscibility gap comps ??
2727
+ */
2728
+ }
2729
+ }
2730
+ /*
2731
+ * This condition makes output equal for incremental_reactions TRUE/FALSE...
2732
+ * if (incremental_reactions == FALSE || reaction_step == count_total_steps)
2733
+ */
2734
+ x0_moles.clear();
2735
+ }
2736
+ return (OK);
2737
+ }
2738
+ void Phreeqc::
2739
+ f(integertype N, realtype t, N_Vector y, N_Vector ydot,
2740
+ void *f_data)
2741
+ {
2742
+ int n_user;
2743
+ //LDBLE step_fraction;
2744
+ cxxKinetics *kinetics_ptr;
2745
+ Phreeqc *pThis = (Phreeqc *) f_data;
2746
+
2747
+ pThis->cvode_error = FALSE;
2748
+ n_user = pThis->cvode_n_user;
2749
+ kinetics_ptr = (cxxKinetics *) pThis->cvode_kinetics_ptr;
2750
+ //step_fraction = pThis->cvode_step_fraction;
2751
+ pThis->rate_sim_time = pThis->cvode_rate_sim_time;
2752
+
2753
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2754
+ {
2755
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2756
+ /*
2757
+ kinetics_ptr->comps[i].moles = y[i + 1];
2758
+ kinetics_ptr->comps[i].m = m_original[i] - y[i + 1];
2759
+ */
2760
+ kinetics_comp_ptr->Set_moles(Ith(y, i + 1));
2761
+ kinetics_comp_ptr->Set_m(pThis->m_original[i] - Ith(y, i + 1));
2762
+ if (kinetics_comp_ptr->Get_m() < 0)
2763
+ {
2764
+ /*
2765
+ NOTE: y is not correct if it is greater than m_original
2766
+ However, it seems to work to let y wander off, but use
2767
+ .moles as the correct integral.
2768
+ It does not work to reset Y to m_original, presumably
2769
+ because the rational extrapolation gets screwed up.
2770
+ */
2771
+
2772
+ /*
2773
+ Ith(y,i + 1) = m_original[i];
2774
+ */
2775
+ //if (kinetics_ptr->Get_use_cvode())
2776
+ //{
2777
+ // pThis->cvode_error = TRUE;
2778
+ // return;
2779
+ //}
2780
+ kinetics_comp_ptr->Set_moles(pThis->m_original[i]);
2781
+ kinetics_comp_ptr->Set_m(0.0);
2782
+ }
2783
+ }
2784
+ pThis->calc_final_kinetic_reaction(kinetics_ptr);
2785
+ /* if (set_and_run(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) { */
2786
+ if (pThis->use.Get_pp_assemblage_ptr() != NULL)
2787
+ {
2788
+ pThis->Rxn_pp_assemblage_map[pThis->cvode_pp_assemblage_save->Get_n_user()] = *pThis->cvode_pp_assemblage_save;
2789
+ pThis->use.Set_pp_assemblage_ptr(Utilities::Rxn_find(pThis->Rxn_pp_assemblage_map, pThis->cvode_pp_assemblage_save->Get_n_user()));
2790
+ }
2791
+ if (pThis->use.Get_ss_assemblage_ptr() != NULL)
2792
+ {
2793
+ pThis->Rxn_ss_assemblage_map[pThis->cvode_ss_assemblage_save->Get_n_user()] = *pThis->cvode_ss_assemblage_save;
2794
+ pThis->use.Set_ss_assemblage_ptr(Utilities::Rxn_find(pThis->Rxn_ss_assemblage_map, pThis->cvode_ss_assemblage_save->Get_n_user()));
2795
+ }
2796
+
2797
+ if (pThis->set_and_run_wrapper(n_user, FALSE, TRUE, n_user, 0.0) == MASS_BALANCE)
2798
+ {
2799
+ pThis->run_reactions_iterations += pThis->iterations;
2800
+ pThis->cvode_error = TRUE;
2801
+ /*
2802
+ error_msg("Mass balance error in f", CONTINUE);
2803
+ */
2804
+ return;
2805
+ }
2806
+ if (pThis->cvode_test == TRUE)
2807
+ {
2808
+ return;
2809
+ }
2810
+ pThis->run_reactions_iterations += pThis->iterations;
2811
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2812
+ {
2813
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2814
+ kinetics_comp_ptr->Set_moles(0.0);
2815
+ }
2816
+ pThis->calc_kinetic_reaction(kinetics_ptr, 1.0);
2817
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2818
+ {
2819
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2820
+ /*
2821
+ dydx[i + 1] = kinetics_ptr->comps[i].moles;
2822
+ */
2823
+ Ith(ydot, i + 1) = kinetics_comp_ptr->Get_moles();
2824
+ }
2825
+ return;
2826
+ }
2827
+
2828
+ /*
2829
+ static void Jac(integertype N, DenseMat J, RhsFn f, void *f_data, realtype t,
2830
+ N_Vector y, N_Vector fy, N_Vector ewt, realtype h,
2831
+ realtype uround, void *jac_data, long int *nfePtr,
2832
+ N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3);
2833
+ */
2834
+ void Phreeqc::
2835
+ Jac(integertype N, DenseMat J, RhsFn f, void *f_data,
2836
+ realtype t, N_Vector y, N_Vector fy, N_Vector ewt,
2837
+ realtype h, realtype uround, void *jac_data,
2838
+ long int *nfePtr, N_Vector vtemp1, N_Vector vtemp2,
2839
+ N_Vector vtemp3)
2840
+ {
2841
+ int count_cvode_errors;
2842
+ int n_reactions, n_user;
2843
+ LDBLE del;
2844
+ std::vector<double> initial_rates;
2845
+ cxxKinetics *kinetics_ptr;
2846
+ LDBLE step_fraction;
2847
+
2848
+ Phreeqc *pThis = (Phreeqc *) f_data;
2849
+
2850
+ pThis->cvode_error = FALSE;
2851
+ n_reactions = pThis->cvode_n_reactions;
2852
+ n_user = pThis->cvode_n_user;
2853
+ kinetics_ptr = (cxxKinetics *) pThis->cvode_kinetics_ptr;
2854
+ step_fraction = pThis->cvode_step_fraction;
2855
+ pThis->rate_sim_time = pThis->cvode_rate_sim_time;
2856
+
2857
+ initial_rates.resize(n_reactions);
2858
+
2859
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2860
+ {
2861
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2862
+ /*
2863
+ kinetics_ptr->comps[i].moles = y[i + 1];
2864
+ kinetics_ptr->comps[i].m = m_original[i] - y[i + 1];
2865
+ */
2866
+ kinetics_comp_ptr->Set_moles(Ith(y, i + 1));
2867
+ kinetics_comp_ptr->Set_m(pThis->m_original[i] - Ith(y, i + 1));
2868
+ if (kinetics_comp_ptr->Get_m() < 0)
2869
+ {
2870
+ /*
2871
+ NOTE: y is not correct if it is greater than m_original
2872
+ However, it seems to work to let y wander off, but use
2873
+ .moles as the correct integral.
2874
+ It does not work to reset Y to m_original, presumably
2875
+ because the rational extrapolation gets screwed up.
2876
+ */
2877
+
2878
+ /*
2879
+ Ith(y,i + 1) = m_original[i];
2880
+ */
2881
+ kinetics_comp_ptr->Set_moles(pThis->m_original[i]);
2882
+ kinetics_comp_ptr->Set_m(0.0);
2883
+ }
2884
+ }
2885
+ pThis->calc_final_kinetic_reaction(kinetics_ptr);
2886
+ /* if (set_and_run(n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE) { */
2887
+ if (pThis->use.Get_pp_assemblage_ptr() != NULL)
2888
+ {
2889
+ pThis->Rxn_pp_assemblage_map[pThis->cvode_pp_assemblage_save->Get_n_user()] = *pThis->cvode_pp_assemblage_save;
2890
+ pThis->use.Set_pp_assemblage_ptr(Utilities::Rxn_find(pThis->Rxn_pp_assemblage_map, pThis->cvode_pp_assemblage_save->Get_n_user()));
2891
+ }
2892
+ if (pThis->set_and_run_wrapper(n_user, FALSE, TRUE, n_user, 0.0) == MASS_BALANCE)
2893
+ {
2894
+ pThis->run_reactions_iterations += pThis->iterations;
2895
+ pThis->cvode_error = TRUE;
2896
+ /*
2897
+ error_msg("Mass balance error in jacobian", CONTINUE);
2898
+ */
2899
+ initial_rates.clear();
2900
+ return;
2901
+ }
2902
+ pThis->run_reactions_iterations += pThis->iterations;
2903
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2904
+ {
2905
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2906
+ kinetics_comp_ptr->Set_moles(0.0);
2907
+ }
2908
+ pThis->calc_kinetic_reaction(kinetics_ptr, 1.0);
2909
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2910
+ {
2911
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2912
+ initial_rates[i] = kinetics_comp_ptr->Get_moles();
2913
+ }
2914
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2915
+ {
2916
+ cxxKineticsComp * kinetics_comp_i_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
2917
+ /* calculate reaction up to current time */
2918
+ del = 1e-12;
2919
+ pThis->cvode_error = TRUE;
2920
+ count_cvode_errors = 0;
2921
+ while (pThis->cvode_error == TRUE)
2922
+ {
2923
+ del /= 10.;
2924
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2925
+ {
2926
+ cxxKineticsComp * kinetics_comp_j_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2927
+ /*
2928
+ kinetics_ptr->comps[j].moles = y[j + 1];
2929
+ kinetics_ptr->comps[j].m = m_original[j] - y[j + 1];
2930
+ */
2931
+ kinetics_comp_j_ptr->Set_moles(Ith(y, j + 1));
2932
+ kinetics_comp_j_ptr->Set_m(pThis->m_original[j] - Ith(y, j + 1));
2933
+ if (kinetics_comp_i_ptr->Get_m() < 0)
2934
+ {
2935
+ /*
2936
+ NOTE: y is not correct if it is greater than m_original
2937
+ However, it seems to work to let y wander off, but use
2938
+ .moles as the correct integral.
2939
+ It does not work to reset Y to m_original, presumably
2940
+ because the rational extrapolation gets screwed up.
2941
+ */
2942
+
2943
+ /*
2944
+ Ith(y,i + 1) = m_original[i];
2945
+ */
2946
+ kinetics_comp_i_ptr->Set_moles(pThis->m_original[i]);
2947
+ kinetics_comp_i_ptr->Set_m(0.0);
2948
+ }
2949
+ }
2950
+
2951
+ /* Add small amount of ith reaction */
2952
+ kinetics_comp_i_ptr->Set_m(kinetics_comp_i_ptr->Get_m() - del);
2953
+ if (kinetics_comp_i_ptr->Get_m() < 0)
2954
+ {
2955
+ kinetics_comp_i_ptr->Set_m(0);
2956
+ }
2957
+ kinetics_comp_i_ptr->Set_moles(kinetics_comp_i_ptr->Get_moles() + del);
2958
+ pThis->calc_final_kinetic_reaction(kinetics_ptr);
2959
+ if (pThis->use.Get_pp_assemblage_ptr() != NULL)
2960
+ {
2961
+ pThis->Rxn_pp_assemblage_map[pThis->cvode_pp_assemblage_save->Get_n_user()] = *pThis->cvode_pp_assemblage_save;
2962
+ pThis->use.Set_pp_assemblage_ptr(Utilities::Rxn_find(pThis->Rxn_pp_assemblage_map, pThis->cvode_pp_assemblage_save->Get_n_user()));
2963
+ }
2964
+ if (pThis->set_and_run_wrapper
2965
+ (n_user, FALSE, TRUE, n_user, step_fraction) == MASS_BALANCE)
2966
+ {
2967
+ count_cvode_errors++;
2968
+ pThis->cvode_error = TRUE;
2969
+ if (count_cvode_errors > 30)
2970
+ {
2971
+ initial_rates.clear();
2972
+ return;
2973
+ }
2974
+ pThis->run_reactions_iterations += pThis->iterations;
2975
+ continue;
2976
+ }
2977
+ pThis->cvode_error = FALSE;
2978
+ pThis->run_reactions_iterations += pThis->iterations;
2979
+ /*kinetics_ptr->comps[i].moles -= del; */
2980
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2981
+ {
2982
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2983
+ kinetics_comp_ptr->Set_moles(0.0);
2984
+ }
2985
+ pThis->calc_kinetic_reaction(kinetics_ptr, 1.0);
2986
+
2987
+ /* calculate new rates for df/dy[i] */
2988
+ /* dfdx[i + 1] = 0.0; */
2989
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
2990
+ {
2991
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
2992
+ IJth(J, j + 1, i + 1) =
2993
+ (kinetics_comp_ptr->Get_moles() - initial_rates[j]) / del;
2994
+ }
2995
+ }
2996
+ }
2997
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
2998
+ {
2999
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
3000
+ kinetics_comp_ptr->Set_moles(0);
3001
+ }
3002
+ initial_rates.clear();
3003
+ return;
3004
+ }
3005
+
3006
+ void Phreeqc::
3007
+ cvode_init(void)
3008
+ {
3009
+ cvode_kinetics_ptr = NULL;
3010
+ cvode_test = 0;
3011
+ cvode_error = 0;
3012
+ cvode_n_user = -99;
3013
+ cvode_n_reactions = -99;
3014
+ cvode_step_fraction = 0.0;
3015
+ cvode_rate_sim_time = 0.0;
3016
+ cvode_rate_sim_time_start = 0.0;
3017
+ cvode_last_good_time = 0.0;
3018
+ cvode_prev_good_time = 0.0;
3019
+ cvode_last_good_y = NULL;
3020
+ cvode_prev_good_y = NULL;
3021
+ kinetics_machEnv = NULL;
3022
+ kinetics_y = kinetics_abstol = NULL;
3023
+ kinetics_cvode_mem = NULL;
3024
+ cvode_pp_assemblage_save = NULL;
3025
+ cvode_ss_assemblage_save = NULL;
3026
+ return;
3027
+ }
3028
+ bool Phreeqc::
3029
+ cvode_update_reactants(int i, int nsaver, bool save_it)
3030
+ {
3031
+ cxxKinetics *kinetics_ptr = use.Get_kinetics_ptr();
3032
+ int n_reactions = (int) kinetics_ptr->Get_kinetics_comps().size();
3033
+
3034
+ for (size_t j = 0; j < kinetics_ptr->Get_kinetics_comps().size(); j++)
3035
+ {
3036
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
3037
+
3038
+ // Adds reaction defined by last_good_y
3039
+ kinetics_comp_ptr->Set_moles(Ith(cvode_last_good_y, j + 1));
3040
+ // Reduces m
3041
+ kinetics_comp_ptr->Set_m(m_original[j] - kinetics_comp_ptr->Get_moles());
3042
+ // Don't update until after calc_final_reaction
3043
+ //m_original[j] = kinetics_comp_ptr->Get_m();
3044
+ //m_temp[j] = kinetics_comp_ptr->Get_m();
3045
+ if (kinetics_comp_ptr->Get_m() < 0)
3046
+ {
3047
+ kinetics_comp_ptr->Set_moles(m_original[j]);
3048
+ kinetics_comp_ptr->Set_m(0.0);
3049
+ }
3050
+ }
3051
+ // calculates net reaction
3052
+ calc_final_kinetic_reaction(kinetics_ptr);
3053
+ if (use.Get_pp_assemblage_ptr() != NULL)
3054
+ {
3055
+ Rxn_pp_assemblage_map[cvode_pp_assemblage_save->Get_n_user()] = *cvode_pp_assemblage_save;
3056
+ use.Set_pp_assemblage_ptr(Utilities::Rxn_find(Rxn_pp_assemblage_map, cvode_pp_assemblage_save->Get_n_user()));
3057
+ }
3058
+ if (use.Get_ss_assemblage_ptr() != NULL)
3059
+ {
3060
+ Rxn_ss_assemblage_map[cvode_ss_assemblage_save->Get_n_user()] = *cvode_ss_assemblage_save;
3061
+ use.Set_ss_assemblage_ptr(Utilities::Rxn_find(Rxn_ss_assemblage_map, cvode_ss_assemblage_save->Get_n_user()));
3062
+ }
3063
+ // runs previous solution plus net reaction
3064
+ if (set_and_run_wrapper(i, NOMIX, TRUE, nsaver, 1.0) == MASS_BALANCE)
3065
+ {
3066
+ error_msg("CVODE step was bad", STOP);
3067
+ return false;
3068
+ }
3069
+
3070
+ // saves result to reactants defined by saver
3071
+ if (save_it)
3072
+ {
3073
+ saver();
3074
+
3075
+ cxxPPassemblage *pp_assemblage_ptr = Utilities::Rxn_find(Rxn_pp_assemblage_map, nsaver);
3076
+ cxxSSassemblage *ss_assemblage_ptr = Utilities::Rxn_find(Rxn_ss_assemblage_map, nsaver);
3077
+ if (cvode_pp_assemblage_save != NULL)
3078
+ {
3079
+ delete cvode_pp_assemblage_save;
3080
+ cvode_pp_assemblage_save = new cxxPPassemblage(*pp_assemblage_ptr);
3081
+ }
3082
+ if (cvode_ss_assemblage_save != NULL)
3083
+ {
3084
+ delete cvode_ss_assemblage_save;
3085
+ cvode_ss_assemblage_save = new cxxSSassemblage(*ss_assemblage_ptr);
3086
+ }
3087
+
3088
+ for (int j = 0; j < n_reactions; j++)
3089
+ {
3090
+ Ith(cvode_last_good_y, j + 1) = 0.0;
3091
+ Ith(cvode_prev_good_y, j + 1) = 0.0;
3092
+
3093
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[j]);
3094
+ m_original[j] = kinetics_comp_ptr->Get_m();
3095
+ m_temp[j] = kinetics_comp_ptr->Get_m();
3096
+ }
3097
+ }
3098
+ return true;
3099
+ }
3100
+ /* ---------------------------------------------------------------------- */
3101
+ bool Phreeqc::
3102
+ limit_rates(cxxKinetics *kinetics_ptr)
3103
+ /* ---------------------------------------------------------------------- */
3104
+ {
3105
+ /*
3106
+ * Go through kinetic components to
3107
+ * determine rates and
3108
+ * a list of elements and amounts in
3109
+ * the reaction.
3110
+ */
3111
+
3112
+ // check if any small concentrations with negative rates
3113
+ if (!use_kinetics_limiter)
3114
+ {
3115
+ return false;
3116
+ }
3117
+ std::vector<std::string> negative_rate;
3118
+ cxxNameDouble::iterator it = kinetics_ptr->Get_totals().begin();
3119
+ for ( ; it != kinetics_ptr->Get_totals().end(); it++)
3120
+ {
3121
+ if (total(it->first.c_str()) < 1e-10 && it->second < -1e-20)
3122
+ {
3123
+ //if (total(it->first.c_str()) > fabs(it->second))
3124
+ // continue;
3125
+ negative_rate.push_back(it->first);
3126
+ }
3127
+ }
3128
+ if (negative_rate.size() == 0) return false;
3129
+
3130
+ for (size_t j = 0; j < negative_rate.size(); j++)
3131
+ {
3132
+ std::string elt = negative_rate[j];
3133
+ LDBLE positive_rates = 0;
3134
+ LDBLE negative_rates = 0;
3135
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
3136
+ {
3137
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
3138
+ cxxNameDouble::iterator it = kinetics_comp_ptr->Get_moles_of_reaction().find(elt);
3139
+ if (it != kinetics_comp_ptr->Get_moles_of_reaction().end())
3140
+ {
3141
+ if (it->second >= 0.0)
3142
+ {
3143
+ positive_rates += it->second;
3144
+ }
3145
+ else
3146
+ {
3147
+ negative_rates += it->second;
3148
+ }
3149
+ }
3150
+ }
3151
+
3152
+ // factor to reduce precipitation to equal dissolution
3153
+ LDBLE limiter_fraction = 1.0;
3154
+ if (negative_rates < 0.0)
3155
+ {
3156
+ limiter_fraction = fabs(positive_rates / negative_rates);
3157
+ //limiter_fraction = fabs((0.9*total(elt.c_str()) + positive_rates) / negative_rates);
3158
+ }
3159
+ else
3160
+ {
3161
+ assert(false);
3162
+ }
3163
+
3164
+ // Now limit precipitation
3165
+ for (size_t i = 0; i < kinetics_ptr->Get_kinetics_comps().size(); i++)
3166
+ {
3167
+ cxxKineticsComp * kinetics_comp_ptr = &(kinetics_ptr->Get_kinetics_comps()[i]);
3168
+ cxxNameDouble::iterator it = kinetics_comp_ptr->Get_moles_of_reaction().find(elt);
3169
+ if (it != kinetics_comp_ptr->Get_moles_of_reaction().end())
3170
+ {
3171
+ if (it->second < 0.0)
3172
+ {
3173
+ kinetics_comp_ptr->Set_moles(kinetics_comp_ptr->Get_moles() * limiter_fraction);
3174
+ }
3175
+ }
3176
+ }
3177
+ }
3178
+
3179
+ return true;
3180
+ }