def test_equilibrate_overload_6(setup, num_regression):
    """
    An integration test that checks result's reproducibility of 
    the calculation of a problem using     
    equilibrate(ChemicalState& state, const Partition& partition, const EquilibriumOptions& options)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """
    (system, problem) = setup

    # find a state based on the equilibrium setup
    state = equilibrate(problem)

    # change pressure and temperature
    state.setTemperature(problem.temperature() + 5)
    state.setPressure(problem.pressure() + 5)

    options = EquilibriumOptions()
    partition = Partition(system)

    # compute equilibrium for state with new temperature and pressure
    equilibriumResult = equilibrate(state, partition, options)

    stateDict = convert_reaktoro_state_to_dict(state)

    num_regression.check(stateDict,
                         default_tolerance=dict(atol=1e-5, rtol=1e-16))
Ejemplo n.º 2
0
def test_equilibrium_solver_with_equilibrate(
        partition_with_inert_gaseous_phase, chemical_system):
    problem = _create_equilibrium_problem(partition_with_inert_gaseous_phase)
    state = _create_chemical_state(chemical_system)

    # Compute equilibrium state; the amounts of CO2(g) and H2O(g) should remain the same
    equilibrate(state, problem)

    # Assert the amounts of CO2(g) and H2O(g) are the same as initially set
    assert state.speciesAmount('CO2(g)') == 1.0
    assert state.speciesAmount('H2O(g)') == 0.001
Ejemplo n.º 3
0
def test_equilibrium_path(num_regression, tmpdir):
    """
    An integration test that checks result's reproducibility of 
    the calculation of an equilibrium path between two states   
    """

    database = Database("supcrt98.xml")

    editor = ChemicalEditor(database)
    editor.addAqueousPhase("H O C Na Cl")

    system = ChemicalSystem(editor)

    problem1 = EquilibriumProblem(system)
    problem1.add("H2O", 1, "kg")
    problem1.add("CO2", 0.5, "mol")
    problem1.add("HCl", 1, "mol")

    problem2 = EquilibriumProblem(system)
    problem2.add("H2O", 1, "kg")
    problem2.add("CO2", 0.5, "mol")
    problem2.add("NaOH", 2, "mol")

    state1 = equilibrate(problem1)
    state2 = equilibrate(problem2)

    path = EquilibriumPath(system)

    output = path.output()
    output.filename(tmpdir.dirname + "/equilibriumPathResult.txt")

    # Define which outputs will be written and checked
    output.add("t")
    output.add("pH")
    output.add("speciesMolality(HCO3-)")
    output.add("speciesMolality(CO2(aq))")
    output.add("speciesMolality(CO3--)")

    path.solve(state1, state2)

    pathTable = pd.read_csv(
        tmpdir.dirname + "/equilibriumPathResult.txt",
        index_col=None,
        delim_whitespace=True,
    )

    pathDict = convert_dataframe_to_dict(pathTable)

    num_regression.check(pathDict)
Ejemplo n.º 4
0
def test_kinetic_path_solve_final_state(state_regression, setup, time_span,
                                        minerals_to_add):
    """
    An integration test that checks result's reproducibility of
    the calculation of a kinetic problem and only check the
    final state
    @param setup
        a tuple that has some objects from kineticProblemSetup.py
        (problem, reactions, partition)
    @param time_span
        time information about the kinetic problem.
        time_span.ti = initial time
        time_span.tf = final time
        time_span.unit = ti and tf units
    """
    (problem, reactions, partition) = setup

    state = equilibrate(problem)

    for mineral in minerals_to_add:
        state.setSpeciesMass(mineral.mineral_name, mineral.amount,
                             mineral.unit)

    path = KineticPath(reactions)

    path.setPartition(partition)

    path.solve(state, time_span.ti, time_span.tf, time_span.unit)

    state_regression.check(state, default_tol=dict(atol=1e-5, rtol=1e-14))
Ejemplo n.º 5
0
def kinect_problem_with_h2o_hcl_caco3_mgco3_co2_calcite():

    database = Database("supcrt98.xml")

    editor = ChemicalEditor(database)
    editor.addAqueousPhase("H2O HCl CaCO3 MgCO3")
    editor.addGaseousPhase(["H2O(g)", "CO2(g)"])
    editor.addMineralPhase("Calcite")

    calciteReaction = editor.addMineralReaction("Calcite")
    calciteReaction.setEquation("Calcite = Ca++ + CO3--")
    calciteReaction.addMechanism("logk = -5.81 mol/(m2*s); Ea = 23.5 kJ/mol")
    calciteReaction.addMechanism(
        "logk = -0.30 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0"
    )
    calciteReaction.setSpecificSurfaceArea(10, "cm2/g")

    system = ChemicalSystem(editor)
    reactions = ReactionSystem(editor)

    partition = Partition(system)
    partition.setKineticPhases(["Calcite"])

    problem = EquilibriumProblem(system)
    problem.setPartition(partition)
    problem.add("H2O", 1, "kg")
    problem.add("HCl", 1, "mmol")

    state = equilibrate(problem)

    state.setSpeciesMass("Calcite", 100, "g")

    return (state, reactions, partition)
Ejemplo n.º 6
0
def kinect_problem_with_h2o_nacl_caco3_mgco3_hcl_co2_calcite_magnesite_dolomite_halite():

    database = Database("supcrt98.xml")

    editor = ChemicalEditor(database)

    editor.addAqueousPhase("H2O NaCl CaCO3 MgCO3 HCl")
    editor.addGaseousPhase(["H2O(g)", "CO2(g)"])
    editor.addMineralPhase("Calcite")
    editor.addMineralPhase("Magnesite")
    editor.addMineralPhase("Dolomite")
    editor.addMineralPhase("Halite")

    calciteReaction = editor.addMineralReaction("Calcite")
    calciteReaction.setEquation("Calcite = Ca++ + CO3--")
    calciteReaction.addMechanism("logk = -5.81 mol/(m2*s); Ea = 23.5 kJ/mol")
    calciteReaction.addMechanism(
        "logk = -0.30 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0"
    )
    calciteReaction.setSpecificSurfaceArea(10, "cm2/g")

    magnesiteReaction = editor.addMineralReaction("Magnesite")
    magnesiteReaction.setEquation("Magnesite = Mg++ + CO3--")
    magnesiteReaction.addMechanism("logk = -9.34 mol/(m2*s); Ea = 23.5 kJ/mol")
    magnesiteReaction.addMechanism(
        "logk = -6.38 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0"
    )
    magnesiteReaction.setSpecificSurfaceArea(10, "cm2/g")

    dolomiteReaction = editor.addMineralReaction("Dolomite")
    dolomiteReaction.setEquation("Dolomite = Ca++ + Mg++ + 2*CO3--")
    dolomiteReaction.addMechanism("logk = -7.53 mol/(m2*s); Ea = 52.2 kJ/mol")
    dolomiteReaction.addMechanism(
        "logk = -3.19 mol/(m2*s); Ea = 36.1 kJ/mol; a[H+] = 0.5"
    )
    dolomiteReaction.setSpecificSurfaceArea(10, "cm2/g")

    system = ChemicalSystem(editor)
    reactions = ReactionSystem(editor)

    partition = Partition(system)
    partition.setKineticSpecies(["Calcite", "Magnesite", "Dolomite"])

    problem = EquilibriumProblem(system)
    problem.setPartition(partition)
    problem.add("H2O", 1, "kg")
    problem.add("NaCl", 1, "mol")
    problem.add("CO2", 1, "mol")

    state = equilibrate(problem)

    state.setSpeciesMass("Calcite", 100, "g")
    state.setSpeciesMass("Dolomite", 50, "g")

    return (state, reactions, partition)
Ejemplo n.º 7
0
def brine_co2_path():
    editor = ChemicalEditor()
    editor.addAqueousPhaseWithElementsOf("H2O NaCl CaCO3 MgCO3")
    editor.addGaseousPhase(["H2O(g)", "CO2(g)"])
    editor.addMineralPhase("Calcite")
    editor.addMineralPhase("Magnesite")
    editor.addMineralPhase("Dolomite")
    editor.addMineralPhase("Halite")

    editor.addMineralReaction("Calcite") \
        .setEquation("Calcite = Ca++ + CO3--") \
        .addMechanism("logk = -5.81 mol/(m2*s); Ea = 23.5 kJ/mol") \
        .addMechanism("logk = -0.30 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0") \
        .setSpecificSurfaceArea(10, "cm2/g")

    editor.addMineralReaction("Magnesite") \
        .setEquation("Magnesite = Mg++ + CO3--") \
        .addMechanism("logk = -9.34 mol/(m2*s); Ea = 23.5 kJ/mol") \
        .addMechanism("logk = -6.38 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0") \
        .setSpecificSurfaceArea(10, "cm2/g")

    editor.addMineralReaction("Dolomite") \
        .setEquation("Dolomite = Ca++ + Mg++ + 2*CO3--") \
        .addMechanism("logk = -7.53 mol/(m2*s); Ea = 52.2 kJ/mol") \
        .addMechanism("logk = -3.19 mol/(m2*s); Ea = 36.1 kJ/mol; a[H+] = 0.5") \
        .setSpecificSurfaceArea(10, "cm2/g")

    system = ChemicalSystem(editor)
    reactions = ReactionSystem(editor)

    partition = Partition(system)
    partition.setKineticSpecies(["Calcite", "Magnesite", "Dolomite"])

    problem = EquilibriumProblem(system)
    problem.setPartition(partition)
    problem.setTemperature(60, "celsius")
    problem.setPressure(100, "bar")
    problem.add("H2O", 1, "kg")
    problem.add("NaCl", 0.5, "mol")
    problem.add("CO2", 1, "mol")

    state = equilibrate(problem)

    state.setSpeciesMass("Calcite", 100, "g")
    state.setSpeciesMass("Dolomite", 50, "g")

    path = KineticPath(reactions)
    path.setPartition(partition)

    return path, state
Ejemplo n.º 8
0
def test_equilibrate_overload_5(setup, state_regression):
    """
    An integration test that checks result's reproducibility of
    the calculation of a problem using
    equilibrate(ChemicalState& state, const EquilibriumOptions& options)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """
    (system, problem) = setup

    # Find a state based on the equilibrium setup
    state = equilibrate(problem)

    # Change pressure and temperature
    state.setTemperature(problem.temperature() + 5)
    state.setPressure(problem.pressure() + 5)

    options = EquilibriumOptions()

    # Compute equilibrium for state with new temperature and pressure
    equilibriumResult = equilibrate(state, options)

    state_regression.check(state, default_tol=dict(atol=1e-5, rtol=1e-16))
Ejemplo n.º 9
0
def test_kinetic_path_solve_complete_path(table_regression, tmpdir, setup,
                                          time_span, checked_variables,
                                          minerals_to_add):
    """
    An integration test that checks result's reproducibility of
    the calculation of a kinetic problem and check all the path
    @param setup
        a tuple that has some objects from kineticProblemSetup.py
        (problem, reactions, partition)
    @param time_span
        time information about the kinetic problem.
        time_span.ti = initial time
        time_span.tf = final time
        time_span.unit = ti and tf units
    @param checked_variables
        a list that has all the variables that will be tested
    """
    (problem, reactions, partition) = setup

    state = equilibrate(problem)

    for mineral in minerals_to_add:
        state.setSpeciesMass(mineral.mineral_name, mineral.amount,
                             mineral.unit)

    path = KineticPath(reactions)

    path.setPartition(partition)

    output = path.output()
    output.precision(16)
    output.filename(tmpdir.dirname + "/kinetictPathResult.txt")
    for checked_variable in checked_variables:
        output.add(checked_variable)

    path.solve(state, time_span.ti, time_span.tf, time_span.unit)

    path_kinetic_table = pd.read_csv(
        tmpdir.dirname + "/kinetictPathResult.txt",
        index_col=None,
        skiprows=1,
        delim_whitespace=True,
    )

    path_kinetic_table.columns = checked_variables

    table_regression.check(path_kinetic_table,
                           default_tol=dict(atol=1e-3, rtol=1e-14))
Ejemplo n.º 10
0
def test_equilibrate_overload_1(setup, state_regression):
    """
    An integration test that checks result's reproducibility of
    the calculation of a problem using
    equilibrate(const EquilibriumProblem& problem)
    and
    equilibrate(const EquilibriumInverseProblem& problem)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """

    (system, problem) = setup

    equilibriumState = equilibrate(problem)

    state_regression.check(equilibriumState,
                           default_tol=dict(atol=1e-5, rtol=1e-16))
Ejemplo n.º 11
0
def test_equilibrium_solver_solve_overload_1(setup, state_regression):
    """
    An integration test that checks result's reproducibility of 
    the calculation of an equilibrium of a state using 
    EquilibriumSolver::solve(ChemicalState& state)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """
    (system, problem) = setup

    state = equilibrate(problem)
    state.setTemperature(problem.temperature() + 30)
    state.setPressure(problem.pressure() + 40)

    solver = EquilibriumSolver(system)

    solver.solve(state)

    state_regression.check(state, default_tol=dict(atol=1e-5, rtol=1e-16))
Ejemplo n.º 12
0
def test_equilibrate_overload_8(setup, state_regression):
    """
    An integration test that checks result's reproducibility of
    the calculation of a problem using
    equilibrate(ChemicalState& state, const EquilibriumProblem& problem, const EquilibriumOptions& options)
    and
    equilibrate(ChemicalState& state, const EquilibriumInverseProblem& problem, const EquilibriumOptions& options)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """
    (system, problem) = setup

    state = ChemicalState(system)

    options = EquilibriumOptions()

    equilibriumResult = equilibrate(state, problem, options)

    state_regression.check(state, default_tol=dict(atol=1e-5, rtol=1e-16))
def test_equilibrate_overload_7(setup, num_regression):
    """
    An integration test that checks result's reproducibility of 
    the calculation of a problem using       
    equilibrate(ChemicalState& state, const EquilibriumProblem& problem)
    and
    equilibrate(ChemicalState& state, const EquilibriumInverseProblem& problem)
    @param setup
        a tuple that has some objects from problem setup
        (system, problem)
    """
    (system, problem) = setup

    state = ChemicalState(system)

    equilibriumResult = equilibrate(state, problem)

    stateDict = convert_reaktoro_state_to_dict(state)

    num_regression.check(stateDict,
                         default_tolerance=dict(atol=1e-5, rtol=1e-16))
Ejemplo n.º 14
0
def test_chemicaltransport_step(num_regression):

    nx, ny, nz = 5, 5, 5  # number of cells along x, y, and z
    nsteps = 10  # number of time steps

    velocity = fire.Constant([1.0e-2, 0.0,
                              0.0])  # the velocity (in units of m/s)
    diffusion = fire.Constant(
        1.0e-4)  # the diffusion coefficient (in units of m2/s)
    dt = 1.0  # the time step (in units of s)
    T = 60.0 + 273.15  # the temperature (in units of K)
    P = 100 * 1e5  # the pressure (in units of Pa)

    mesh = fire.UnitCubeMesh(nx, ny, nz)
    V = fire.FunctionSpace(mesh, "CG", 1)

    # Initialise the database
    database = rkt.Database("supcrt98.xml")

    # Initialise the chemical editor
    editor = rkt.ChemicalEditor(database)
    editor.addAqueousPhase(
        "H2O(l) H+ OH- Na+ Cl- Ca++ Mg++ HCO3- CO2(aq) CO3--")
    editor.addMineralPhase("Quartz")
    editor.addMineralPhase("Calcite")
    editor.addMineralPhase("Dolomite")

    # Initialise the chemical system
    system = rkt.ChemicalSystem(editor)

    # Define the initial condition of the reactive transport modeling problem
    problem_ic = rkt.EquilibriumProblem(system)
    problem_ic.setTemperature(T)
    problem_ic.setPressure(P)
    problem_ic.add("H2O", 1.0, "kg")
    problem_ic.add("NaCl", 0.7, "mol")
    problem_ic.add("CaCO3", 10, "mol")
    problem_ic.add("SiO2", 10, "mol")

    # Define the boundary condition of the reactive transport modeling problem
    problem_bc = rkt.EquilibriumProblem(system)
    problem_bc.setTemperature(T)
    problem_bc.setPressure(P)
    problem_bc.add("H2O", 1.0, "kg")
    problem_bc.add("NaCl", 0.90, "mol")
    problem_bc.add("MgCl2", 0.05, "mol")
    problem_bc.add("CaCl2", 0.01, "mol")
    problem_bc.add("CO2", 0.75, "mol")

    # Calculate the equilibrium states for the initial and boundary conditions
    state_ic = rkt.equilibrate(problem_ic)
    state_bc = rkt.equilibrate(problem_bc)

    # Scale the volumes of the phases in the initial condition such that their sum is 1 m3
    state_ic.scalePhaseVolume("Aqueous", 0.1, "m3")
    state_ic.scalePhaseVolume("Quartz", 0.882, "m3")
    state_ic.scalePhaseVolume("Calcite", 0.018, "m3")

    # Scale the volume of the boundary equilibrium state to 1 m3
    state_bc.scaleVolume(1.0)

    # Initialise the chemical field
    field = rok.ChemicalField(system, V)
    field.fill(state_ic)

    # Initialize the chemical transport solver
    transport = rok.ChemicalTransportSolver(field)
    transport.addBoundaryCondition(state_bc, 1)  # 1 means left side
    transport.setVelocity([velocity])
    transport.setDiffusion([diffusion])

    species_names_for_output = [
        "Ca++",
        "Mg++",
        "Calcite",
        "Dolomite",
        "CO2(aq)",
        "HCO3-",
        "Cl-",
        "H2O(l)",
    ]
    element_names_for_output = ["H", "O", "C", "Ca", "Mg", "Na", "Cl"]

    species_amount_functions = [
        fire.Function(V, name=name) for name in species_names_for_output
    ]
    element_amount_functions = [
        fire.Function(V, name=name) for name in element_names_for_output
    ]

    step = 0

    species_data = []
    element_data = []

    while step <= nsteps:
        transport.step(field, dt)

        # For each selected species, output its molar amounts
        for f in species_amount_functions:
            f.assign(field.speciesAmount(f.name()))
            species_data.append(f.dat.data)

        # For each selected species, output its molar amounts
        for f in element_amount_functions:
            f.assign(field.elementAmountInPhase(f.name(), "Aqueous"))
            element_data.append(f.dat.data)

        step += 1

    species_data = {
        "n({})(step={})".format(name, i): u
        for i, (name,
                u) in enumerate(zip(species_names_for_output, species_data))
    }
    element_data = {
        "b({})(step={})".format(name, i): u
        for i, (name,
                u) in enumerate(zip(element_names_for_output, element_data))
    }
    data = {**species_data, **element_data}

    num_regression.check(data)
Ejemplo n.º 15
0
problem_ic.add("NaCl", 0.7, "mol")
problem_ic.add("CaCO3", 10, "mol")
problem_ic.add("SiO2", 10, "mol")

# Define the boundary condition of the reactive transport modeling problem
problem_bc = rkt.EquilibriumProblem(system)
problem_bc.setTemperature(T)
problem_bc.setPressure(P)
problem_bc.add("H2O", 1.0, "kg")
problem_bc.add("NaCl", 0.90, "mol")
problem_bc.add("MgCl2", 0.05, "mol")
problem_bc.add("CaCl2", 0.01, "mol")
problem_bc.add("CO2", 0.75, "mol")

# Calculate the equilibrium states for the initial and boundary conditions
state_ic = rkt.equilibrate(problem_ic)
state_bc = rkt.equilibrate(problem_bc)

# Scale the volumes of the phases in the initial condition such that their sum is 1 m3
state_ic.scalePhaseVolume("Aqueous", 0.1, "m3")
state_ic.scalePhaseVolume("Quartz", 0.882, "m3")
state_ic.scalePhaseVolume("Calcite", 0.018, "m3")

# Scale the volume of the boundary equilibrium state to 1 m3
state_bc.scaleVolume(1.0)

# Initialise the chemical field
field = rok.ChemicalField(system, V)
field.fill(state_ic)

# Initialize the chemical transport solver