# Floudas, C.A., Pardalos, P.M., et al. Handbook of test problems in local and global#

`phase.py`

```"""
## MODELTYPE: NLP

Floudas, C.A., Pardalos, P.M., et al. Handbook of test problems in local and global
optimization. Kluwer Academic Publishers, Dordrecht, 1999
Chapter 8. Section: Phase and Chemical Equilibrium Problems-Equations of State
Test Problem 1, pp. 180-181.

Van der Waals equation, Tangent Plane distance minimization
Ternary System
"""

from __future__ import annotations

import os

import gamspy.math as gams_math
from gamspy import (
Alias,
Container,
Equation,
Model,
Parameter,
Set,
Sum,
Variable,
)

def main():
m = Container(
system_directory=os.getenv("SYSTEM_DIRECTORY", None),
)

# SET #
i = Set(m, name="i", records=["1", "2", "3"], description="components")

# ALIAS #
j = Alias(m, name="j", alias_with=i)

# PARAMETERS #
feedmf = Parameter(
m,
name="feedmf",
domain=i,
description="mole fraction of component i in candidate phase",
)
feedz = Parameter(
m, name="feedz", description="compressibility of candidate phase"
)
feedfc = Parameter(
m,
name="feedfc",
domain=i,
description="fugacity coefficient of component i in candidate phase",
)
b = Parameter(
m,
name="b",
domain=i,
description="Van der Waals pure-component parameter",
)
a = Parameter(
m,
name="a",
domain=[i, j],
description="Van der Waals mixture parameter",
)

feedmf["1"] = 0.83
feedmf["2"] = 0.085
feedmf["3"] = 0.085

feedz[...] = 0.55716

feedfc["1"] = -0.244654
feedfc["2"] = -1.33572
feedfc["3"] = -0.457869

b["1"] = 0.14998
b["2"] = 0.14998
b["3"] = 0.14998

a["1", "1"] = 0.37943
a["1", "2"] = 0.75885
a["1", "3"] = 0.48991
a["2", "1"] = 0.75885
a["2", "2"] = 0.88360
a["2", "3"] = 0.23612
a["3", "1"] = 0.48991
a["3", "2"] = 0.23612
a["3", "3"] = 0.63263

# VARIABLES #
x = Variable(
m,
name="x",
domain=i,
description="mole fractio of component i in incipient phase",
)
z = Variable(m, name="z", description="compressibility of incipient phase")
amix = Variable(
m,
name="amix",
description="mixture A parameter (function of composition)",
)
bmix = Variable(
m,
name="bmix",
description="mixture B parameter (function of composition)",
)

# EQUATIONS #
eos = Equation(
m,
name="eos",
type="regular",
description="equation of state constraint",
)
defa = Equation(
m, name="defa", type="regular", description="definition of Amix"
)
defb = Equation(
m, name="defb", type="regular", description="definition of Bmix"
)
molesum = Equation(
m,
name="molesum",
type="regular",
description="mole fractions sum to 1",
)

# Objective function to be minimized: tangent plane distance
dist = (
Sum(i, x[i] * gams_math.log(x[i]))
+ bmix / (z - bmix)
- gams_math.log(z - bmix)
- 2.0 * amix / z
- Sum(i, x[i] * (gams_math.log(feedmf[i]) + feedfc[i]))
)

# Constraints:
eos[...] = (
gams_math.power(z, 3)
- (bmix + 1) * gams_math.power(z, 2)
+ amix * z
- amix * bmix
== 0
)

defa[...] = amix - Sum(i, Sum(j, a[i, j] * x[i] * x[j])) == 0

defb[...] = bmix - Sum(i, b[i] * x[i]) == 0

molesum[...] = Sum(i, x[i]) == 1.0

# Simple Bounds of variables
z.lo[...] = 0.001
x.lo["1"] = 0.001
x.lo["2"] = 0.001
x.lo["3"] = 0.001

phase = Model(
m,
name="phase",
equations=m.getEquations(),
problem="nlp",
sense="min",
objective=dist,
)
phase.solve()

print("x:  \n", x.toDict(), "\n")
print("z:  \n", round(z.toValue(), 4), "\n")

# End phase

if __name__ == "__main__":
main()
```