Does GEKKO have a method to import Global, MV an CV options from JSON?

Viewed 17

For my GEKKO models, I would like to maintain global option settings for the model, MV's and CV in an external file (CSV or JSON) and assign it to the model before solving. I notice in the model output directory that there is a file options.json that represent what I am after. Is this only and output file or is there a shortcut to import options settings as well?

1 Answers

There is no shortcut to write the options.json back to the application. However, the overrides.dbs file allows any parameter to be fixed at a specified value. Try the following to read the options.json file, make changes, and then write everything to an overrides.dbs file. This should work for every Gekko application.

# Read options as dictionary
with open(m.path+'//options.json') as f:
    d = json.load(f)

# Make changes
d['u']['DCOST'] = 0.2
d['y']['STATUS'] = 1

# Write options
with open(m.path+'/overrides.dbs', 'w') as f:
    for key in d['APM'].keys():
        f.write("APM.%s=%s\n"%(key,d['APM'][key]))
    for i in range(d['INFO']['N_FV']):
        n = d['INFO']['FV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_MV']):
        n = d['INFO']['MV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_SV']):
        n = d['INFO']['SV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_CV']):
        n = d['INFO']['CV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))

This creates an overrides.dbs text file in the local run directory (remote=False) with the Global (APM), Parameter (FV,MV), and Variable (SV,CV) options. This overrides.dbs file replaces any values in the gk0_model.dbs file as described in the documentation.

APM.APPINFO=0
APM.APPINFOCHG=0
APM.APPSTATUS=1
APM.AUTO_COLD=0
APM.BAD_CYCLES=0
APM.BNDS_CHK=1
APM.COLDSTART=0
APM.CSV_READ=2
APM.CSV_WRITE=1
APM.CTRL_HOR=40
APM.CTRL_TIME=0.5
APM.CTRL_UNITS=1
APM.CTRLMODE=3
APM.CV_WGT_SLOPE=0.0
APM.CV_WGT_START=0
APM.CV_TYPE=2
APM.CYCLECOUNT=1
APM.DBS_LEVEL=1
APM.DBS_READ=1
APM.DBS_WRITE=1
APM.DIAGLEVEL=0
APM.EV_WGT_SLOPE=0.0
APM.EV_TYPE=1
APM.FILTER=1.0
APM.FRZE_CHK=1
APM.HIST_HOR=0
APM.HIST_UNITS=0
APM.ICD_CALC=0
APM.IMODE=6
APM.ITERATIONS=0
APM.LINEAR=0
APM.MAX_ITER=250
APM.MAX_MEMORY=4
APM.MAX_TIME=1e+20
APM.MEAS_CHK=1
APM.MV_DCOST_SLOPE=0.1
APM.MV_STEP_HOR=1
APM.MV_TYPE=0
APM.NODES=2
APM.OBJFCNVAL=2.2153332782e-10
APM.OTOL=1e-06
APM.PRED_HOR=40
APM.PRED_TIME=0.5
APM.REDUCE=0
APM.REPLAY=0
APM.REQCTRLMODE=3
APM.RTOL=1e-06
APM.SCALING=1
APM.SENSITIVITY=0
APM.SEQUENTIAL=0
APM.SOLVER=3
APM.SOLVESTATUS=1
APM.SOLVETIME=0.112
APM.SPECS=1
APM.SPC_CHART=0
APM.STREAM_LEVEL=0
APM.TIME_SHIFT=1
APM.WEB=0
APM.WEB_MENU=1
APM.WEB_REFRESH=10
APM.WEB_PLOT_FREQ=1
u.AWS=0
u.COST=0.0
u.CRITICAL=0
u.DCOST=0.2
u.DMAX=20.0
u.DMAXHI=1e+20
u.DMAXLO=-1e+20
u.DPRED[1]=2.0723799252e-05
u.DPRED[2]=1.6411259174e-05
u.DPRED[3]=1.3801035879e-05
u.DPRED[4]=1.1903110675e-05
u.DPRED[5]=1.042339369e-05
u.DPRED[6]=9.224551212e-06
u.DPRED[7]=8.2283921352e-06
u.DPRED[8]=7.3852475973e-06
u.DPRED[9]=6.6613167029e-06
u.DPRED[10]=6.0324804645e-06
u.FSTATUS=1.0
u.LOWER=0.0
u.LSTVAL=0.0
u.MEAS=0.0
u.MV_STEP_HOR=0
u.NEWVAL=2.0723799252e-05
u.NXTVAL=3.7135058426e-05
u.OSTATUS[1]=4
u.OSTATUS[2]=1
u.OSTATUSCHG[1]=4
u.OSTATUSCHG[2]=1
u.PRED[0]=0.0
u.PRED[1]=2.0723799252e-05
u.PRED[2]=3.7135058426e-05
u.PRED[3]=5.0936094305e-05
u.PRED[4]=6.2839204981e-05
u.PRED[5]=7.3262598671e-05
u.PRED[6]=8.2487149883e-05
u.PRED[7]=9.0715542018e-05
u.PRED[8]=9.8100789615e-05
u.PRED[9]=0.00010476210632
u.PRED[10]=0.00011079458678
u.PSTATUS=1
u.REQONCTRL=0
u.STATUS=1
u.TIER=1
u.UPPER=100.0
u.VDVL=1e+20
u.VLACTION=0
u.VLHI=1e+20
u.VLLO=-1e+20
y.BIAS=0.0
y.COST=0.0
y.CRITICAL=0
y.FSTATUS=0.0
y.FDELAY=0
y.LOWER=-1.23456789e+20
y.LSTVAL=0.0
y.MEAS=0.0
y.MEAS_GAP=0.001
y.MODEL=0.0
y.OSTATUS[1]=0
y.OSTATUS[2]=5
y.OSTATUSCHG[1]=0
y.OSTATUSCHG[2]=5
y.PRED[0]=0.0
y.PRED[1]=6.9079330839e-05
y.PRED[2]=0.00016983641531
y.PRED[3]=0.00028301125789
y.PRED[4]=0.00039813818853
y.PRED[5]=0.00050963412126
y.PRED[6]=0.00061471324711
y.PRED[7]=0.00071219397147
y.PRED[8]=0.00080179861303
y.PRED[9]=0.00088373942975
y.PRED[10]=0.00095847490911
y.PSTATUS=1
y.SP=0.0
y.SPHI=1.23456789e-40
y.SPLO=1.23456789e-40
y.STATUS=1
y.TAU=1.0
y.TIER=1
y.TR_INIT=0
y.TR_OPEN=1.0
y.UPPER=1.23456789e+20
y.VDVL=1e+20
y.VLACTION=0
y.VLHI=1e+20
y.VLLO=-1e+20
y.WMEAS=20.0
y.WMODEL=2.0
y.WSP=20.0
y.WSPHI=20.0
y.WSPLO=20.0

A complete script validates the changes in m.path with a new options.json file that has the changes. This method of writing options overrides anything that is in m.options that is written to gk0_model.dbs.

New u.DCOST:  0.2
New y.STATUS:  1
from gekko import GEKKO
import numpy as np
import json
m = GEKKO(remote=False) # local mode
m.time = np.linspace(0,20,41)

# Manipulated variable
u = m.MV(value=0, lb=0, ub=100,name='u')
u.STATUS = 1  # allow optimizer to change
u.DCOST = 0.1 # smooth out MV
u.DMAX = 20   # slow down change

# Controlled Variable
y = m.CV(value=0,name='y')
y.STATUS = 0

# Model equation
m.Equation(y.dt() == -y + 10*u)

# Global options
m.options.IMODE = 6   # control
m.options.CV_TYPE = 2 # squared error

# Solve
m.solve(disp=False)

# Read options as dictionary
with open(m.path+'//options.json') as f:
    d = json.load(f)

# Make changes
d['u']['DCOST'] = 0.2
d['y']['STATUS'] = 1

# Write options
with open(m.path+'/overrides.dbs', 'w') as f:
    for key in d['APM'].keys():
        f.write("APM.%s=%s\n"%(key,d['APM'][key]))
    for i in range(d['INFO']['N_FV']):
        n = d['INFO']['FV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_MV']):
        n = d['INFO']['MV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_SV']):
        n = d['INFO']['SV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))
    for i in range(d['INFO']['N_CV']):
        n = d['INFO']['CV'][i] # get name
        for key in d[n]:
            f.write(n+".%s=%s\n"%(key,d[n][key]))

# Solve again
m.solve(disp=False)

# Verify configuration
with open(m.path+'//options.json') as f:
    d = json.load(f)
print('New u.DCOST: ',d['u']['DCOST'])
print('New y.STATUS: ',d['y']['STATUS'])

# Open run directory to see files (optional)
#m.open_folder()
Related