Vitens / phreeqpython

Object-oriented python wrapper for the VIPhreeqc module
Apache License 2.0
68 stars 19 forks source link

Changes to solutions with run_string #9

Closed ahockin closed 4 years ago

ahockin commented 4 years ago

Hi,

I have a question about the run_string() function. I would like to use some features which are not yet in PhreeqPython (e.g. Exchange and Transport) and will need to use pp.ip.run_string() to run them.

However, when testing using it on a built in function like solution.equalize, I do not get the same results as when I try and run 'Equilibrium Phases' in the use pp.ip.run_string(). The solution is missing phases and I am not sure what I am doing wrong?

Thanks for any help!

##################################

Github example 2

from phreeqpython import PhreeqPython

pp = PhreeqPython()

pp.add_master_species( element = 'Doc', master_species = 'Doc', alkalinity = 0, egfw = 12)

pp.add_species(reaction = 'Doc = Doc', log_k= 0)

Add Jurbanite to the database

str_to_run = """ PHASES # Taken from WATEQ4f database as not present in phreeqc.dat Jurbanite AlOHSO4 + H+ = Al+3 + SO4-2 + H2O log_k -3.230 """

pp.ip.run_string(str_to_run)

solution0 = pp.add_solution({'temp' : 8.9, 'pH': 5.75, 'Ca': 0.9, 'Mg': 0.16, 'Na':0.65, 'K':0.05, 'Al':0, 'Fe(+2)': 0.19, 'Cl':0.76, 'C(+4)':3.5, #TIC 'S(6)':0.6, 'Si':0.1, 'DOC':0, })

str_to_run ="""

EQUILIBRIUM_PHASES 0 Jurbanite 0 1

""" pp.ip.run_string(str_to_run)

print(solution0.phases)

solution1 = solution0.copy()

EQUILLIBRIUM PHASES

solution1.equalize(['Jurbanite'], [0], [1])

print(solution1.phases)

AbelHeinsbroek commented 4 years ago

Hi!

You need to tell PHREEQC which solution to use, and to store the changes:

I think this should work:

str_to_run ="""
USE SOLUTION 0
EQUILIBRIUM_PHASES 0
Jurbanite 0 1
SAVE SOLUTION 0
END
"""

Also, keep in mind that changes to PhreeqPython solutions are persistent. You copy solution1 from solution0, after equalizing with Jurbanite, only to equalize again. You should make a copy of solution0 directly after the add_solution block

AbelHeinsbroek commented 4 years ago

In addition, if you want to know what PhreeqPython is doing 'under the hood', you can enable debug mode using:

pp.ip.debug = True

PhreeqPython will then print all the strings sent to phreeqc

ahockin commented 4 years ago

Hi Abel,

The pp.ip.debug = True code has been SUPER helpful, thank you!

In order to get the TRANSPORT function to work I found in running my own code I had to modify the source code at line 186;

from: inputstr += "EQUILIBRIUM PHASES 1 \n" to: inputstr += "EQUILIBRIUM_PHASES "+str(solution_number) + "\n"

or else the code wouldn't use the correct phase assemblage in the transport function. Hope that makes sense.

Unrelated, but is there an easy way to create multiple of the same solutions? For example, in PHREEQC you can use "SOLUTION 1-15 " and then specify the contents. In PhreeqPython for now I am creating one solution and then copying it 15 times (solution2 = solution1.copy()), but I would guess there is a more elegant way of doing this?

Thanks!

AbelHeinsbroek commented 4 years ago

Unrelated, but is there an easy way to create multiple of the same solutions? For example, in PHREEQC you can use "SOLUTION 1-15 " and then specify the contents. In PhreeqPython for now I am creating one solution and then copying it 15 times (solution2 = solution1.copy()), but I would guess there is a more elegant way of doing this?

We could modify the add_solution method to support returning multiple solutions. Otherwise, a simple list comprehension works fine as well:

[sol.copy() for _ in range(10)]
ahockin commented 4 years ago

Great, the list works perfect, thank you!