JuMP - variable constraint depending on variable

Hey,

I need some help with JuMP. I am trying to modell Liquid-Liquid Equilirum.

@variable(l, xp1[1:n_komp])

@constraint(l, gammap1 == GAMMAP1(n_komp, t, xp1))

To do this, I need an activity coeff., which is dependent on the composition xp1. The way this work is, you keep looking for two phase compositions xp1 and xp2, until xp1actcoeff1-xp2actcoeff2 = 0.
The activity coeff. is a function of the composition xp1 or xp2. Instead using Unifac/Uniquac/etc… to calculate the act. coeff., I am using a quantum chemical software, which can be triggered by command line with GAMMAP1().

The Problem is that this software needs a .inp file with the concentrations xp1 and xp2. When I ran my JuMP Model, the .inp file that was created had { xp1[1] xp1[2] } as concentration, instead of the values that the solver is currently using for this iteration step.

My question is: How do I get to the value that is currently being used by the solver on the current iteration step?

Thanks a lot.

Best regards,
Ulrich

Take a read of PSA: make it easier to help you.

Then, make a self-contained minimal working example and post it here. It’s hard to tell what you’re trying to do from the text.

You might be looking for JuMP.value http://www.juliaopt.org/JuMP.jl/v0.19.0/solutions/#Obtaining-solutions-1

Or you might be looking for JuMP.set_start_value http://www.juliaopt.org/JuMP.jl/dev/variables/#Start-values-1

1 Like
using JuMP


using Ipopt



m = Model(solver=IpoptSolver(print_level=0))


@variable(m, xp1[1:n_komp])
@variable(m, xp2[1:n_komp])
@variable(m, x[1:n_komp])
@variable(m, y[1:n_komp])
@variable(m, F)
@variable(m, V)
@variable(m, g1[1:n_komp], start =  GAMMAP1(t, n_komp, getvalue(xp1)))
@variable(m, g2[1:n_komp], start =  GAMMAP2(t, n_komp, getvalue(xp2)))


@NLobjective(m, Min, V+F-1)


@constraint(m, sum(x) == 1)
@constraint(m, sum(y) == 1)
@constraint(m, sum(xp1) == 1)
@constraint(m, sum(xp2) == 1)
@constraint(m, K.*x.-y .== 0)
@constraint(m, F.*x+V*y.-z .== 0)
@constraint(m, xp1.*g1 .==  xp2.*g2 )



solve(m)

global x = getvalue(x)
global y = getvalue(y)
global V =  getvalue(V)
global F = getvalue(F)

println("x = ", x)
println("y = ", y)
println("F = ", F)
println("V = ", V)

I need the solver to get the g1 and g2 values from the function. This function gets the value from an outside software (CosmoTherm). It need the concentration vector xp1 and xp2 as input to calculate g1 and g2.

A few points.

  1. You’re using JuMP 0.18. (Are you on Julia 0.6?) You should upgrade to Julia 1.0 and JuMP 0.19.

  2. Read the JuMP nonlinear documentation, particularly about user-defined functions http://www.juliaopt.org/JuMP.jl/v0.19.1/nlp/#User-defined-Functions-1
    You need to call JuMP.register in order to be able to use a user-defined function.

  3. start = only provides a primal start hint for the solver. It does not enforce a constraint. Is that what you want? See http://www.juliaopt.org/JuMP.jl/dev/variables/#Start-values-1

  4. It looks unlikely that you can get derivatives out of GAMMAP1? You might want to consider using https://github.com/JuliaOpt/NLopt.jl. It has some derivative-free methods.

Thanks. I just updates to 0.19 earlier. I was using JuliaPro 1.0.3 and it automatically installed v0.18.

I am not sure if I need derivatives. I guess g1 should be given as a constraint and not a variable.
What I need is to use the current value for the variables xp1 and xp2 to calculate g1 and g2 (activity coefficients) with CosmoTherm. The GAMMAP1 and GAMMAP2 are used to run CosmoTherm (quantum chemical software) from the command line.

I am not sure if I need derivatives

The solver you are using, Ipopt, does need them.

JuMP isn’t really suited for this problem. You should probably just use NLopt directly. There are a number of derivative-free algorithms: https://nlopt.readthedocs.io/en/latest/NLopt_Algorithms/#local-derivative-free-optimization

This documentation should get you started: https://github.com/JuliaOpt/NLopt.jl#the-nlopt-module-for-julia

I recommend solving some small problems without the call to CosmoTherm first (to get the hang of things) before launching into the full problem.