Evaluating numerical value of variable at runtime

Dear GAMSPy Community,

I am new to GAMSPy and set-based declarative algebraic modeling in general so please forgive the potentially silly question. I would like to use GAMSPy in place of SciPy solvers like minimize(), which is not very robust and requires a good initial guess, to optimise thermodynamic cycles. In order to calculate the fluid properties at different stations around my cycle, I need to call the Python library CoolProp, whose methods naturally accept only numerical inputs, e.g. temperature and pressure. To use GAMSPy, I would have to evaluate my variables, i.e. extract their numerical values, during each iteration of the optimisation process.

I read the sections “External Equations” and “Extrinsic Functions” of the documentation, but before delving into this (I am not very familiar with C/FORTRAN) I was wondering whether there is an easier way of evaluating the variables at runtime (at the cost of performance, of course). To give you an idea of what I am after, below is a short code showing how I envisage to iterate the total-total pressure ratio pi_tt across a compressor to obtain a desired total-static pressure ratio pi_ts_req.

from gamspy import Container, Equation, Model, Variable, Parameter
from ... import model_meanline

inlet_stagnation_state = ...

def calculate_pi_ts(pi_tt):
    
    # Evaluate mean-line model
    outlet_static_state = \
        model_meanline(
            inlet_stagnation_state, #  constant input
            pi_tt, # THIS SHOULD BE A NUMERICAL VALUE BUT IS CURRENTLY A SYMBOLIC EXPRESSION
            ... #  other constant inputs
        )
    
    # Calculate total-static pressure ratio
    pi_ts = outlet_state.p/inlet_stagnation_state.p
    
    return pi_ts

m = Container()

pi_ts_req = Parameter(m, name="pi_ts_req", records=2.5)

pi_tt = Variable(m, name="pi_tt", type="positive")
var_obj = Variable(m, name="var_obj")

eq_obj = Equation(m, name="eq_obj", type="regular")
eq = Equation(m, name="eq", type="regular")

# Objective function
eequ[...] = calculate_pi_ts(pi_tt) - pi_ts_req == 0
eq_obj[...] = var_obj == 1

# Variable bounds
pi_tt.lo = pi_ts_req
pi_tt.up = 100
# Initial guess
pi_tt.l = pi_ts_req + 0.1

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

Many thanks in advance for your help,
Nils

Update: in the API reference I found that Variable.toValue() is supposed to “[…] return symbol records as a Python float”. This indeed works after the model has been solved successfully, but when I type print(Variable.toValue()) inside the calculate_pi_ts() function in my initial post I get None. What is it that fundamentally prevents the conversion from symbolic expression to float under those conditions?