impl mixed langprog

33
Mixed-Language Programming in IMPL (IMPL-MixedLangProg) i n d u s t r IAL g o r i t h m s LLC. (IAL) www.industrialgorithms.com June 2015 Introduction Presented in this short document is a description of how to use IMPL in a “mixed-language programming” (MLP) concept i.e., using IML (Industrial Modeling Language) and IPL (Industrial Programming Language). We also demonstrate how IMPL can be called from Excel/VBA which is another example of MLP. The notion of mixed-language programming is to employ the best programming language for each specific part of the overall problem solution. Though IML and IPL can configure identical problems with both logistics and quality phenomenological characteristics, it is useful, for example, to configure static or time-invariant data in IML and dynamic or time- variant data in IPL. The system architecture of IMPL which enables MLP is a “global address space” (GAS) memory for all of its sets, lists, parameters, formulas, variables, constraints and derivatives. This is the same enabling technology used for conventional MLP when binding C/C++ to Java/Julia for instance. This ultimately means that an insert, update, view and delete occurs globally within the IMPL data-bank so any interfacing and/or interaction that occurs after that point has maximal consistency and integrity as well as minimal redundancy since there is only one data repository or store. It should also be mentioned however that this is global or common memory within an IMPL instance or image only. If multiple IMPL images are spawned simultaneously or concurrently on different processors or threads, the IMPL memory address space is local to each image. More specifically, how IMPL implements this system architecture is through IMPL’s SSIIMPLE (Server, Solvers, Interfacer, Interacter, Modeler, Presolver Libraries and Executable) system architecture where the Server shown in Figure 1 is at the center. Both the Interfacer (IML) and Interacter (IPL) bind, connect or link to the Server which stores and manages the IMPL data. Once the problem data has been created and contained, then the Modeler, Presolver and Solvers can access the data quickly and efficiently.

Upload: alkis-vazacopoulos

Post on 03-Aug-2015

46 views

Category:

Data & Analytics


0 download

TRANSCRIPT

Mixed-Language Programming in IMPL (IMPL-MixedLangProg)

i n d u s t r IAL g o r i t h m s LLC. (IAL)www.industrialgorithms.com

June 2015

Introduction

Presented in this short document is a description of how to use IMPL in a “mixed-language programming” (MLP) concept i.e., using IML (Industrial Modeling Language) and IPL (Industrial Programming Language). We also demonstrate how IMPL can be called from Excel/VBA which is another example of MLP. The notion of mixed-language programming is to employ the best programming language for each specific part of the overall problem solution. Though IML and IPL can configure identical problems with both logistics and quality phenomenological characteristics, it is useful, for example, to configure static or time-invariant data in IML and dynamic or time-variant data in IPL.

The system architecture of IMPL which enables MLP is a “global address space” (GAS) memory for all of its sets, lists, parameters, formulas, variables, constraints and derivatives. This is the same enabling technology used for conventional MLP when binding C/C++ to Java/Julia for instance. This ultimately means that an insert, update, view and delete occurs globally within the IMPL data-bank so any interfacing and/or interaction that occurs after that point has maximal consistency and integrity as well as minimal redundancy since there is only one data repository or store. It should also be mentioned however that this is global or common memory within an IMPL instance or image only. If multiple IMPL images are spawned simultaneously or concurrently on different processors or threads, the IMPL memory address space is local to each image.

More specifically, how IMPL implements this system architecture is through IMPL’s SSIIMPLE (Server, Solvers, Interfacer, Interacter, Modeler, Presolver Libraries and Executable) system architecture where the Server shown in Figure 1 is at the center. Both the Interfacer (IML) and Interacter (IPL) bind, connect or link to the Server which stores and manages the IMPL data. Once the problem data has been created and contained, then the Modeler, Presolver and Solvers can access the data quickly and efficiently.

Figure 1. IMPL’s SSIIMPLE System Architecture.

IMPLServer

IMPLPresolver

IMPLModeler

IMPLSolversIMPLInterface

r

IMPLInteracter

To demonstrate these concepts, we highlight a small but representative gasoline blendshop quality optimization problem coded in Excel/VBA and IMPL where there is a mix of IML and IPL configured data.

Small Gasoline Blendshop Quality Optimization Synopsis

Here we focus only on the nonlinear quantity and quality details where the flowsheet is presented in Figure 1 and uses our Unit-Operation-Port-State Superstructure (UOPSS) as discussed in Kelly (2004), Kelly (2005) and Zyngier and Kelly (2012). Other blending specific aspects can be found in Kelly and Mann (2003), Kelly (2006) and Kelly, Menezes and Grossmann (2014).

Figure 2. Small Gasoline Blendshop Flowsheet in UOPSS.

The static construction data of this UOPSS flowsheet can be found in the UPS file of Appendix A (note that the UPS file is generated by our GNOME Dia/Python drawing prototype).

This problem has five (5) components each with two (2) tanks and two (2) products or grades also with two (2) tanks each. There is a single blend header with two (2) operations of Regular and Premium. There is one (1) density and twelve (12) properties (RON, MON, ROAD, RVP, ARO, BEN, E70, E100, E150, E225, SUL and VLI). The SUL property is a mass-based property, RVP is a blending-index (property-transform) where ROAD and VLI are derived-properties (properties-property). All of the static capacity and capability data are found in the IML file of Appendix B.

The IML file has the UPS file embedded as an include-file and is called by the Excel/VBA application code found in Appendix C where its corresponding module code is found in Appendix D. All of the IMPL and IPL 64-bit procedure declarations are found in the Excel/VBA module code using 64-bit pointer addresses (VBA LongPtr and C LongLong integer types) when passing procedure, function or subroutine pointers. The IMPL Interfacer inputs the static configuration data found in the IML file which constructs the UOPS structures, shapes or objects whereby all static and dynamic data can be properly and uniquely addressed, indexed, pointed to or referenced.

Figure 2 shows the user interface programmed in 64-bit Excel/VBA Office 2013 where the “Blendshop” sheet is interactive allowing the quantity and quality variable bounds to be changed i.e., “~” is equals, “<” is less-than or equal and “>” is greater than or equal. The “Rundown” and “Inventory” sheets contain the optimized component flows and tank holdups respectively where the “Log” sheet displays the callback or feedback log from IMPL’s Presolver back to VBA (cf. function “summons” in Appendix D). Note that “callbacks” are well-known in MLP because they provide the necessary interaction between one system and the other especially when one of the systems takes longer to run than the other and notifications of its progress is prudent.

Figure 3. Small Gasoline Blendshop in Excel/VBA (Office 2013 64-Bit) and IMPL.

To manage the dynamic and user data, IPL is employed to interactively modify and/or over-load the static data as required using several IPL routines listed below which can be seen in Appendix C using the concept of orders, transactions, commands or provisos:

rtn = IMPLreceiveUOPSflowweight(uname, oname, pname, sname, prowt, _per1wt, per2wt, penwt, IMPLkeep)

rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, _lower, upper, target, begintime, endtime, IMPLkeep)

rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, _lower, upper, target, begintime, endtime, IMPLkeep)

rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, _lower, upper, target, begintime, endtime, IMPLkeep)

These IPL “receive” functions allow the application code to insert and/or update any of the problem static and dynamic data before the IMPL Modeler is called to configure the dependent sets, lists and parameters as well as to create the variables, constraints and derivatives before the IMPL Presolver is called to presolve and solve the problem. For this implementation, we can call IPOPT or IMPL’s SLPQPE nonlinear solver which uses CPLEX, COINMP, GLPK and LPSOLVE as the LP sub-solver.

Once the problem has been solved i.e., converged all variables and constraints to an acceptable level of tolerance, IPL subroutines and functions can be called to “retrieve” or view the solution-data as follows:

Call IMPLretrieveOBJterms2(profit, performance1, performance2, penalty, total)

Call IMPLretrieveT(tpn, tfn)

Call IMPLretrieveUOflow2(uname, oname, tpn, tfn, value(1))

Call IMPLretrieveUOPSyield2(uname, oname, pname, sname, tpn, tfn, value(1))

Call IMPLretrieveUOPSproperty2(uname, oname, pname, sname, bname, tpn, tfn, value(1))

Call IMPLretrieveUOPSflow2(uname, oname, pname, sname, tpn, tfn, value(1))

Call IMPLretrieveUOholdup2(uname, oname, tpn, tfn, value(1))

When the known or valid UOPS names are used to call these routines then multiple time-periods can be retrieved from IMPL to Excel/VBA using a one-dimensional (1D) array (Value(1)) pointing to its first array index. The integers “tpn” and “tfn” are required by IMPL to specify the number of time-periods in the past/present and the number of time-periods in the future. For those computer programming languages where it is difficult to access vector or 1D array data, IPL has corresponding retrieve functions which passes back one value only for the specified time-period index.

In summary, we have shown how to configure a small gasoline blending optimization problem using some mix of IMPL’s IML (usually static or model-data) and IPL (usually dynamic or cycle-data) as well as being interfaced and interacted with Excel/VBA which is also an example of MLP.

Please contact Alkis Vazacopoulos ([email protected]) to obtain a trial evaluation license of IMPL and the Excel workbook described.

References

Kelly, J.D., "Production modeling for multimodal operations", Chemical Engineering Progress, February, 44, (2004).

Kelly, J.D., "The unit-operation-stock superstructure (UOSS) and the quantity-logic-quality paradigm (QLQP) for production scheduling in the process industries", In: MISTA 2005 Conference Proceedings, 327, (2005).

Zyngier, D., Kelly, J.D., "UOPSS: a new paradigm for modeling production planning and scheduling systems", ESCAPE 22, June, (2012).

Kelly, J.D., Mann, J.M., "Crude-oil blend scheduling optimization: an application with multi-million dollar benefits", Hydrocarbon Processing, June, 47, July, 72, (2003).

Kelly, J.D., "Logistics: the missing link in blend scheduling optimization", Hydrocarbon Processing, June, 45, (2006).

Kelly, J.D., Menezes, B.C., Grossmann, I.E., “Distillation blending and cutpoint temperature optimization using monotonic interpolation”, Industrial and Engineering Chemistry Research, 53, 15146-15156, (2014).

Appendix A – IMPL-Blendshop-QQ.UPS File i M P l (c)

Copyright and Property of i n d u s t r I A L g o r i t h m s LLC.

checksum,242!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Unit-Operation-Port-State-Superstructure (UOPSS) *.UPS File.! (This file is automatically generated from the Python program IALConstructer.py)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sUnit,&sOperation,@sType,@sSubtype,@sUseBlender,Premium,processc,blender%,Blender,Regular,processc,blender%,Butane,,perimeter,,MTBE,,perimeter,,Naphtha,,perimeter,,Pentane,,perimeter,,Premium,,perimeter,,Reformate,,perimeter,,Regular,,perimeter,,TK1,Butane,pool,,TK10,MTBE,pool,,TK11,Regular,pool,,TK12,Regular,pool,,TK13,Premium,pool,,TK14,Premium,pool,,TK2,Butane,pool,,TK3,Pentane,pool,,TK4,Pentane,pool,,TK5,Naphtha,pool,,TK6,Naphtha,pool,,TK7,Reformate,pool,,TK8,Reformate,pool,,TK9,MTBE,pool,,&sUnit,&sOperation,@sType,@sSubtype,@sUse

! Number of UO shapes = 23

&sAlias,&sUnit,&sOperationALLPARTS,Blender,PremiumALLPARTS,Blender,RegularALLPARTS,Butane,ALLPARTS,MTBE,ALLPARTS,Naphtha,ALLPARTS,Pentane,ALLPARTS,Premium,ALLPARTS,Reformate,ALLPARTS,Regular,ALLPARTS,TK1,ButaneALLPARTS,TK10,MTBEALLPARTS,TK11,RegularALLPARTS,TK12,RegularALLPARTS,TK13,PremiumALLPARTS,TK14,PremiumALLPARTS,TK2,ButaneALLPARTS,TK3,PentaneALLPARTS,TK4,PentaneALLPARTS,TK5,NaphthaALLPARTS,TK6,NaphthaALLPARTS,TK7,ReformateALLPARTS,TK8,ReformateALLPARTS,TK9,MTBE&sAlias,&sUnit,&sOperation

&sUnit,&sOperation,&sPort,&sState,@sType,@sSubtypeBlender,Premium,i1,,in,Blender,Premium,i2,,in,Blender,Premium,i3,,in,Blender,Premium,i4,,in,Blender,Premium,i5,,in,Blender,Premium,o,,out,Blender,Regular,i1,,in,Blender,Regular,i2,,in,Blender,Regular,i3,,in,Blender,Regular,i4,,in,Blender,Regular,i5,,in,Blender,Regular,o,,out,Butane,,o,,out,MTBE,,o,,out,Naphtha,,o,,out,Pentane,,o,,out,Premium,,i,,in,Reformate,,o,,out,Regular,,i,,in,TK1,Butane,i,,in,TK1,Butane,o,,out,TK10,MTBE,i,,in,TK10,MTBE,o,,out,TK11,Regular,i,,in,TK11,Regular,o,,out,TK12,Regular,i,,in,TK12,Regular,o,,out,

TK13,Premium,i,,in,TK13,Premium,o,,out,TK14,Premium,i,,in,TK14,Premium,o,,out,TK2,Butane,i,,in,TK2,Butane,o,,out,TK3,Pentane,i,,in,TK3,Pentane,o,,out,TK4,Pentane,i,,in,TK4,Pentane,o,,out,TK5,Naphtha,i,,in,TK5,Naphtha,o,,out,TK6,Naphtha,i,,in,TK6,Naphtha,o,,out,TK7,Reformate,i,,in,TK7,Reformate,o,,out,TK8,Reformate,i,,in,TK8,Reformate,o,,out,TK9,MTBE,i,,in,TK9,MTBE,o,,out,&sUnit,&sOperation,&sPort,&sState,@sType,@sSubtype

! Number of UOPS shapes = 47

&sAlias,&sUnit,&sOperation,&sPort,&sStateALLINPORTS,Blender,Premium,i1,ALLINPORTS,Blender,Premium,i2,ALLINPORTS,Blender,Premium,i3,ALLINPORTS,Blender,Premium,i4,ALLINPORTS,Blender,Premium,i5,ALLINPORTS,Blender,Regular,i1,ALLINPORTS,Blender,Regular,i2,ALLINPORTS,Blender,Regular,i3,ALLINPORTS,Blender,Regular,i4,ALLINPORTS,Blender,Regular,i5,ALLINPORTS,Premium,,i,ALLINPORTS,Regular,,i,ALLINPORTS,TK1,Butane,i,ALLINPORTS,TK10,MTBE,i,ALLINPORTS,TK11,Regular,i,ALLINPORTS,TK12,Regular,i,ALLINPORTS,TK13,Premium,i,ALLINPORTS,TK14,Premium,i,ALLINPORTS,TK2,Butane,i,ALLINPORTS,TK3,Pentane,i,ALLINPORTS,TK4,Pentane,i,ALLINPORTS,TK5,Naphtha,i,ALLINPORTS,TK6,Naphtha,i,ALLINPORTS,TK7,Reformate,i,ALLINPORTS,TK8,Reformate,i,ALLINPORTS,TK9,MTBE,i,ALLOUTPORTS,Blender,Premium,o,ALLOUTPORTS,Blender,Regular,o,ALLOUTPORTS,Butane,,o,ALLOUTPORTS,MTBE,,o,ALLOUTPORTS,Naphtha,,o,ALLOUTPORTS,Pentane,,o,ALLOUTPORTS,Reformate,,o,ALLOUTPORTS,TK1,Butane,o,ALLOUTPORTS,TK10,MTBE,o,ALLOUTPORTS,TK11,Regular,o,ALLOUTPORTS,TK12,Regular,o,ALLOUTPORTS,TK13,Premium,o,ALLOUTPORTS,TK14,Premium,o,ALLOUTPORTS,TK2,Butane,o,ALLOUTPORTS,TK3,Pentane,o,ALLOUTPORTS,TK4,Pentane,o,ALLOUTPORTS,TK5,Naphtha,o,ALLOUTPORTS,TK6,Naphtha,o,ALLOUTPORTS,TK7,Reformate,o,ALLOUTPORTS,TK8,Reformate,o,ALLOUTPORTS,TK9,MTBE,o,&sAlias,&sUnit,&sOperation,&sPort,&sState

&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sStateBlender,Premium,o,,TK13,Premium,i,Blender,Premium,o,,TK14,Premium,i,Blender,Regular,o,,TK11,Regular,i,Blender,Regular,o,,TK12,Regular,i,Butane,,o,,TK1,Butane,i,Butane,,o,,TK2,Butane,i,MTBE,,o,,TK10,MTBE,i,MTBE,,o,,TK9,MTBE,i,Naphtha,,o,,TK5,Naphtha,i,Naphtha,,o,,TK6,Naphtha,i,Pentane,,o,,TK3,Pentane,i,Pentane,,o,,TK4,Pentane,i,Reformate,,o,,TK7,Reformate,i,Reformate,,o,,TK8,Reformate,i,TK1,Butane,o,,Blender,Premium,i1,TK1,Butane,o,,Blender,Regular,i1,TK10,MTBE,o,,Blender,Premium,i5,TK10,MTBE,o,,Blender,Regular,i5,TK11,Regular,o,,Regular,,i,TK12,Regular,o,,Regular,,i,

TK13,Premium,o,,Premium,,i,TK14,Premium,o,,Premium,,i,TK2,Butane,o,,Blender,Premium,i1,TK2,Butane,o,,Blender,Regular,i1,TK3,Pentane,o,,Blender,Premium,i2,TK3,Pentane,o,,Blender,Regular,i2,TK4,Pentane,o,,Blender,Premium,i2,TK4,Pentane,o,,Blender,Regular,i2,TK5,Naphtha,o,,Blender,Premium,i3,TK5,Naphtha,o,,Blender,Regular,i3,TK6,Naphtha,o,,Blender,Premium,i3,TK6,Naphtha,o,,Blender,Regular,i3,TK7,Reformate,o,,Blender,Premium,i4,TK7,Reformate,o,,Blender,Regular,i4,TK8,Reformate,o,,Blender,Premium,i4,TK8,Reformate,o,,Blender,Regular,i4,TK9,MTBE,o,,Blender,Premium,i5,TK9,MTBE,o,,Blender,Regular,i5,&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sState

! Number of UOPSPSUO shapes = 38

&sAlias,&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sStateALLPATHS,TK1,Butane,o,,Blender,Premium,i1,ALLPATHS,TK2,Butane,o,,Blender,Premium,i1,ALLPATHS,TK3,Pentane,o,,Blender,Premium,i2,ALLPATHS,TK4,Pentane,o,,Blender,Premium,i2,ALLPATHS,TK5,Naphtha,o,,Blender,Premium,i3,ALLPATHS,TK6,Naphtha,o,,Blender,Premium,i3,ALLPATHS,TK7,Reformate,o,,Blender,Premium,i4,ALLPATHS,TK8,Reformate,o,,Blender,Premium,i4,ALLPATHS,TK10,MTBE,o,,Blender,Premium,i5,ALLPATHS,TK9,MTBE,o,,Blender,Premium,i5,ALLPATHS,TK1,Butane,o,,Blender,Regular,i1,ALLPATHS,TK2,Butane,o,,Blender,Regular,i1,ALLPATHS,TK3,Pentane,o,,Blender,Regular,i2,ALLPATHS,TK4,Pentane,o,,Blender,Regular,i2,ALLPATHS,TK5,Naphtha,o,,Blender,Regular,i3,ALLPATHS,TK6,Naphtha,o,,Blender,Regular,i3,ALLPATHS,TK7,Reformate,o,,Blender,Regular,i4,ALLPATHS,TK8,Reformate,o,,Blender,Regular,i4,ALLPATHS,TK10,MTBE,o,,Blender,Regular,i5,ALLPATHS,TK9,MTBE,o,,Blender,Regular,i5,ALLPATHS,TK13,Premium,o,,Premium,,i,ALLPATHS,TK14,Premium,o,,Premium,,i,ALLPATHS,TK11,Regular,o,,Regular,,i,ALLPATHS,TK12,Regular,o,,Regular,,i,ALLPATHS,Butane,,o,,TK1,Butane,i,ALLPATHS,MTBE,,o,,TK10,MTBE,i,ALLPATHS,Blender,Regular,o,,TK11,Regular,i,ALLPATHS,Blender,Regular,o,,TK12,Regular,i,ALLPATHS,Blender,Premium,o,,TK13,Premium,i,ALLPATHS,Blender,Premium,o,,TK14,Premium,i,ALLPATHS,Butane,,o,,TK2,Butane,i,ALLPATHS,Pentane,,o,,TK3,Pentane,i,ALLPATHS,Pentane,,o,,TK4,Pentane,i,ALLPATHS,Naphtha,,o,,TK5,Naphtha,i,ALLPATHS,Naphtha,,o,,TK6,Naphtha,i,ALLPATHS,Reformate,,o,,TK7,Reformate,i,ALLPATHS,Reformate,,o,,TK8,Reformate,i,ALLPATHS,MTBE,,o,,TK9,MTBE,i,&sAlias,&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sState

Appendix B – IMPL-Blendshop-QQ.IML File i M P l (c) Copyright and Property of i n d u s t r I A L g o r i t h m s LLC. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Calculation Data (Parameters)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sCalc,@sValue

START,0.0BEGIN,0.0END,1.0PERIOD,1.0

! Basis: flow UoM = KB, time UoM = day

! Conversion from m3 to US barrel.M32B,1.0/0.1589873

! Conversion from US barrel to thousand US barrel (KB).B2KB,1.0/1000.0

! Conversion from hour to day.H2D,24.0

! Rates in (m3/hour converted to KB/day).

ButaneL,25.0*M32B*B2KB*H2DButaneU,25.0*M32B*B2KB*H2D

PentaneL,15.0*M32B*B2KB*H2DPentaneU,15.0*M32B*B2KB*H2D

NaphthaL,45.0*M32B*B2KB*H2DNaphthaU,45.0*M32B*B2KB*H2D

ReformateL,105.0*M32B*B2KB*H2DReformateU,105.0*M32B*B2KB*H2D

MTBEL,0.0*M32B*B2KB*H2DMTBEU,15.0*M32B*B2KB*H2D

BlenderL,25.0*M32B*B2KB*H2DBlenderU,250.0*M32B*B2KB*H2D

&sCalc,@sValue

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Chronological Data (Periods)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@rPastTHD,@rFutureTHD,@rTPDSTART,END,PERIOD@rPastTHD,@rFutureTHD,@rTPD

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Construction Data (Pointers)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Include-@sFile_NameIMPL-Blendshop-QQ.upsInclude-@sFile_Name

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Capacity Data (Prototypes)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sUnit,&sOperation,@rRate_Lower,@rRate_UpperALLPARTS,0.0,1000.0Blender,Regular,BlenderL,BlenderUBlender,Premium,BlenderL,BlenderU&sUnit,&sOperation,@rRate_Lower,@rRate_Upper

&sUnit,&sOperation,@rHoldup_Lower,@rHoldup_UpperTK1,Butane,4500*B2KB,25000*B2KBTK2,Butane,4500*B2KB,25000*B2KBTK3,Pentane,4000*B2KB,50000*B2KBTK4,Pentane,4000*B2KB,50000*B2KBTK5,Naphtha,2500*B2KB,35000*B2KBTK6,Naphtha,2500*B2KB,35000*B2KBTK7,Reformate,5000*B2KB,100000*B2KBTK8,Reformate,5000*B2KB,100000*B2KBTK9,MTBE,5000*B2KB,25000*B2KBTK10,MTBE,5000*B2KB,25000*B2KBTK11,Regular,20000*B2KB,200000*B2KBTK12,Regular,20000*B2KB,200000*B2KBTK13,Premium,10000*B2KB,100000*B2KBTK14,Premium,10000*B2KB,100000*B2KB&sUnit,&sOperation,@rHoldup_Lower,@rHoldup_Upper

&sUnit,&sOperation,&sPort,&sState,@rTeeRate_Lower,@rTeeRate_UpperALLINPORTS,0.0,1000.0ALLOUTPORTS,0.0,1000.0&sUnit,&sOperation,&sPort,&sState,@rTeeRate_Lower,@rTeeRate_Upper

&sUnit,&sOperation,&sPort,&sState,@rTotalRate_Lower,@rTotalRate_UpperALLINPORTS,0.0,1000.0ALLOUTPORTS,0.0,1000.0&sUnit,&sOperation,&sPort,&sState,@rTotalRate_Lower,@rTotalRate_Upper

&sUnit,&sOperation,&sPort,&sState,@rYield_Lower,@rYield_Upper,@rYield_FixedBlender,Regular,i1,,0.05,0.15,Blender,Regular,i2,,0.05,0.5,Blender,Regular,i3,,0.05,0.5,Blender,Regular,i4,,0.05,0.5,Blender,Regular,i5,,0.05,0.15,Blender,Regular,o,,1.0,1.0,Blender,Premium,i1,,0.05,0.15,Blender,Premium,i2,,0.05,0.5,Blender,Premium,i3,,0.05,0.5,Blender,Premium,i4,,0.05,0.5,Blender,Premium,i5,,0.05,0.15,Blender,Premium,o,,1.0,1.0,&sUnit,&sOperation,&sPort,&sState,@rYield_Lower,@rYield_Upper,@rYield_Fixed

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Constituent Data (Properties)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sDensitySG&sDensity

&sPropertyRONMONROADRVPAROBENE70E100E150E225SULVLI&sProperty

Mask-&sPropertyVLIMask-&sProperty

&sProperty,@sDensitySUL,SG&sProperty,@sDensity

Properties-&sMacro,@sValueRVPIndex,RVP^1.25RVPInverse,RVP^0.8ROAD,(RON+MON)/2.0VLI,10.0*(RVP^0.8) + 7.0*E70Properties-&sMacro,@sValue

PropertyTransform-&sProperty,@sType,@rValue,@sValueRVP,$,1,RVPIndexRVP,$,2,RVPInversePropertyTransform-&sProperty,@sType,@rValue,@sValue

PropertiesProperty-&sProperty,@sType,@rValue,@sValueROAD,?,3,ROADVLI,?,3,VLIPropertiesProperty-&sProperty,@sType,@rValue,@sValue

&sUnit,&sOperation,&sPort,&sState,&sDensity,@rDensity_Lower,@rDensity_Upper,@rDensity_TargetALLINPORTS,SG,0.0,2.0,ALLOUTPORTS,SG,0.0,2.0,&sUnit,&sOperation,&sPort,&sState,&sDensity,@rDensity_Lower,@rDensity_Upper,@rDensity_Target

&sTemplate,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_TargetPT,RON,0.0,150.0,,MON,0.0,150.0,,ROAD,0.0,150.0,,RVP,0.0,80.0,,ARO,0.0,100.0,,BEN,0.0,10.0,,E70,0.0,100.0,,E100,0.0,100.0,,E150,0.0,100.0,,E225,0.0,100.0,,SUL,0.0,10.0,,VLI,0.0,5000.0,&sTemplate,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_Target

&sUnit,&sOperation,&sPort,&sState,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_TargetALLINPORTS,PTALLOUTPORTS,PT&sUnit,&sOperation,&sPort,&sState,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_Target

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Cost Data (Pricing)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sUnit,&sOperation,&sPort,&sState,@rFlowPro_Weight,@rFlowPer1_Weight,@rFlowPer2_Weight,@rFlowPen_WeightRegular,,i,,1.0,Premium,,i,,1.0,&sUnit,&sOperation,&sPort,&sState,@rFlowPro_Weight,@rFlowPer1_Weight,@rFlowPer2_Weight,@rFlowPen_Weight

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Content/Current Data (Past, Present Provisos)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sUnit,&sOperation,@rHoldup_Value,@rStart_TimeTK1,Butane,4500*B2KB,STARTTK2,Butane,4500*B2KB,STARTTK3,Pentane,4000*B2KB,STARTTK4,Pentane,4000*B2KB,STARTTK5,Naphtha,2500*B2KB,STARTTK6,Naphtha,2500*B2KB,STARTTK7,Reformate,5000*B2KB,STARTTK8,Reformate,5000*B2KB,STARTTK9,MTBE,5000*B2KB,STARTTK10,MTBE,5000*B2KB,STARTTK11,Regular,20000*B2KB,STARTTK12,Regular,20000*B2KB,STARTTK13,Premium,10000*B2KB,STARTTK14,Premium,10000*B2KB,START&sUnit,&sOperation,@rHoldup_Value,@rStart_Time

&sUnit,&sDensity,@rDensity_Value,@rStart_TimeTK1,SG,0.5812,STARTTK2,SG,0.5812,STARTTK3,SG,0.6780,STARTTK4,SG,0.6780,STARTTK5,SG,0.6498,STARTTK6,SG,0.6498,STARTTK7,SG,0.781,STARTTK8,SG,0.781,STARTTK9,SG,0.7400,STARTTK10,SG,0.7400,STARTTK11,SG,0.0,STARTTK12,SG,0.0,STARTTK13,SG,0.0,STARTTK14,SG,0.0,START&sUnit,&sDensity,@rDensity_Value,@rStart_Time

&sUnit,&sProperty,@rProperty_Value,@rStart_TimeTK1,RON,94.8321,START,MON,89.8026,START,RVP,60.4545,START,ARO,0.0,START,BEN,0.0,START,E70,100.0,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.0,STARTTK2,RON,94.8321,START,MON,89.8026,START,RVP,60.4545,START,ARO,0.0,START,BEN,0.0,START,E70,100.0,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.0,STARTTK3,RON,71.0000,START,MON,61.0000,START,RVP,12.5000,START,ARO,0.0,START,BEN,1.0,START,E70,97.85,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.01,STARTTK4,RON,71.0000,START,MON,61.0000,START,RVP,12.5000,START,ARO,0.0,START,BEN,1.0,START,E70,97.85,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.01,STARTTK5,RON,62.8508,START,MON,57.9080,START,RVP,10.3584,START,ARO,0.5583,START,BEN,0.5583,START,E70,52.2870,START,E100,75.8432,START,E150,98.6460,START,E225,100.0,START,SUL,0.0122,STARTTK6,RON,62.8508,START,MON,57.9080,START,RVP,10.3584,START,ARO,0.5583,START,BEN,0.5583,START,E70,52.2870,START,E100,75.8432,START,E150,98.6460,START,E225,100.0,START,SUL,0.0122,STARTTK7,RON,95.0,START,MON,84.4,START,RVP,4.0,START,ARO,50.8,START,BEN,6.0,START,E70,6.1,START,E100,30.6,START,E150,98.9,START,E225,100.0,START,SUL,0.0,STARTTK8,RON,95.0,START,MON,84.4,START,RVP,4.0,START,ARO,50.8,START,BEN,6.0,START,E70,6.1,START

,E100,30.6,START,E150,98.9,START,E225,100.0,START,SUL,0.0,STARTTK9,RON,118.0000,START,MON,108.0000,START,RVP,7.8000,START,ARO,0.0,START,BEN,0.0,START,E70,100.0,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.0001,STARTTK10,RON,118.0000,START,MON,108.0000,START,RVP,7.8000,START,ARO,0.0,START,BEN,0.0,START,E70,100.0,START,E100,100.0,START,E150,100.0,START,E225,100.0,START,SUL,0.0001,STARTTK11,RON,0.0,START,MON,0.0,START,RVP,0.0,START,ARO,0.0,START,BEN,0.0,START,E70,0.0,START,E100,0.0,START,E150,0.0,START,E225,0.0,START,SUL,0.0,STARTTK12,RON,0.0,START,MON,0.0,START,RVP,0.0,START,ARO,0.0,START,BEN,0.0,START,E70,0.0,START,E100,0.0,START,E150,0.0,START,E225,0.0,START,SUL,0.0,STARTTK13,RON,0.0,START,MON,0.0,START,RVP,0.0,START,ARO,0.0,START,BEN,0.0,START,E70,0.0,START,E100,0.0,START,E150,0.0,START,E225,0.0,START,SUL,0.0,STARTTK14,RON,0.0,START,MON,0.0,START,RVP,0.0,START,ARO,0.0,START,BEN,0.0,START,E70,0.0,START,E100,0.0,START,E150,0.0,START,E225,0.0,START,SUL,0.0,START&sUnit,&sProperty,@rProperty_Value,@rStart_Time

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Command Data (Future Provisos)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&sUnit,&sOperation,@rSetup_Lower,@rSetup_Upper,@rBegin_Time,@rEnd_TimeALLPARTS,1,1,BEGIN,END&sUnit,&sOperation,@rSetup_Lower,@rSetup_Upper,@rBegin_Time,@rEnd_Time

&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sState,@rSetup_Lower,@rSetup_Upper,@rBegin_Time,@rEnd_TimeALLPATHS,1,1,BEGIN,END&sUnit,&sOperation,&sPort,&sState,&sUnit,&sOperation,&sPort,&sState,@rSetup_Lower,@rSetup_Upper,@rBegin_Time,@rEnd_Time

&sUnit,&sOperation,&sPort,&sState,@rTotalRate_Lower,@rTotalRate_Upper,@rTotalRate_Target,@rBegin_Time,@rEnd_TimeButane,,o,,ButaneL,ButaneU,,BEGIN,ENDPentane,,o,,PentaneL,PentaneU,,BEGIN,ENDNaphtha,,o,,NaphthaL,NaphthaU,,BEGIN,ENDReformate,,o,,ReformateL,ReformateU,,BEGIN,ENDMTBE,,o,,MTBEL,MTBEU,,BEGIN,END&sUnit,&sOperation,&sPort,&sState,@rTotalRate_Lower,@rTotalRate_Upper,@rTotalRate_Target,@rBegin_Time,@rEnd_Time

&sUnit,&sOperation,&sPort,&sState,&sDensity,@rDensity_Lower,@rDensity_Upper,@rDensity_Target,@rBegin_Time,@rEnd_TimeButane,,o,,SG,0.5812,0.5812,,BEGIN,ENDPentane,,o,,SG,0.6780,0.6780,,BEGIN,ENDNaphtha,,o,,SG,0.6498,0.6498,,BEGIN,ENDReformate,,o,,SG,0.7298,0.7298,,BEGIN,ENDMTBE,,o,,SG,0.7400,0.7400,,BEGIN,ENDBlender,Regular,o,,SG,0.0,2.0,,BEGIN,ENDBlender,Premium,o,,SG,0.0,2.0,,BEGIN,END&sUnit,&sOperation,&sPort,&sState,&sDensity,@rDensity_Lower,@rDensity_Upper,@rDensity_Target,@rBegin_Time,@rEnd_Time

&sUnit,&sOperation,&sPort,&sState,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_Target,@rBegin_Time,@rEnd_TimeButane,,o,,RON,94.8321,94.8321,,BEGIN,END,,,,MON,89.8026,89.8026,,BEGIN,END,,,,RVP,60.4545,60.4545,,BEGIN,END,,,,ARO,0.0,0.0,,BEGIN,END,,,,BEN,0.0,0.0,,BEGIN,END,,,,E70,100.0,100.0,,BEGIN,END,,,,E100,100.0,100.0,,BEGIN,END,,,,E150,100.0,100.0,,BEGIN,END,,,,E225,100.0,100.0,,BEGIN,END,,,,SUL,0.0,0.0,,BEGIN,ENDPentane,,o,,RON,71.0000,71.0000,,BEGIN,END,,,,MON,61.0000,61.0000,,BEGIN,END,,,,RVP,12.5000,12.5000,,BEGIN,END,,,,ARO,2.0,2.0,,BEGIN,END,,,,BEN,1.0,1.0,,BEGIN,END,,,,E70,97.85,97.85,,BEGIN,END,,,,E100,100.0,100.0,,BEGIN,END,,,,E150,100.0,100.0,,BEGIN,END,,,,E225,100.0,100.0,,BEGIN,END,,,,SUL,0.01,0.01,,BEGIN,ENDNaphtha,,o,,RON,62.8508,62.8508,,BEGIN,END,,,,MON,57.9080,57.9080,,BEGIN,END,,,,RVP,10.3584,10.3584,,BEGIN,END,,,,ARO,0.5583,0.5583,,BEGIN,END,,,,BEN,0.5583,0.5583,,BEGIN,END,,,,E70,52.2870,52.2870,,BEGIN,END,,,,E100,75.8432,75.8432,,BEGIN,END,,,,E150,98.6460,98.6460,,BEGIN,END,,,,E225,100.0,100.0,,BEGIN,END,,,,SUL,0.0122,0.0122,,BEGIN,ENDReformate,,o,,RON,95.0,95.0,,BEGIN,END,,,,MON,90.0,90.0,,BEGIN,END,,,,RVP,2.6540,2.6540,,BEGIN,END,,,,ARO,12.8702,12.8702,,BEGIN,END,,,,BEN,0.0,0.0,,BEGIN,END,,,,E70,50.0,50.0,,BEGIN,END,,,,E100,75.0,75.0,,BEGIN,END,,,,E150,100.0,100.0,,BEGIN,END,,,,E225,100.0,100.0,,BEGIN,END,,,,SUL,0.0479,0.0479,,BEGIN,ENDMTBE,,o,,RON,118.0000,118.0000,,BEGIN,END,,,,MON,108.0000,108.0000,,BEGIN,END,,,,RVP,7.8000,7.8000,,BEGIN,END,,,,ARO,0.0,0.0,,BEGIN,END,,,,BEN,0.0,0.0,,BEGIN,END,,,,E70,100.0,100.0,,BEGIN,END,,,,E100,100.0,100.0,,BEGIN,END,,,,E150,100.0,100.0,,BEGIN,END,,,,E225,100.0,100.0,,BEGIN,END,,,,SUL,0.0001,0.0001,,BEGIN,END&sUnit,&sOperation,&sPort,&sState,&sProperty,@rProperty_Lower,@rProperty_Upper,@rProperty_Target,@rBegin_Time,@rEnd_Time

Appendix C – IMPL-Blendshop-QQ.XLS File (Excel/VBA IPL Application Code)' i M P l (c)'' Copyright and Property of i n d u s t r I A L g o r i t h m s LLC.

Option Explicit

Sub IMPL_Blendshop_QQ() Dim path As String * IMPLlinestringlen Dim fact As String * IMPLlinestringlen Dim form As Long Dim fit As Long Dim filter As Long Dim focus As Long Dim face As Long Dim factor As Double Dim fob As Currency Dim frames As String * IMPLpagestringlen Dim filler As LongPtr Dim foreign As String * IMPLlinestringlen Dim force As Long Dim factorizer As Long Dim fork As Long Dim fresh As Long Dim flashback As Long Dim feedback As LongPtr Dim flag As Long Dim msg As String * IMPLlinestringlen Dim setting As Double Dim signal As Double Dim solver As String Dim name As String * IMPLbasestringlen Dim uname As String * IMPLbasestringlen

Dim oname As String * IMPLbasestringlen Dim pname As String * IMPLbasestringlen Dim sname As String * IMPLbasestringlen Dim bname As String * IMPLbasestringlen Dim dthp, dthf, dtp As Double Dim lower, upper, target As Double Dim prowt, per1wt, per2wt, penwt As Double Dim starttime, begintime, endtime As Double Dim ptr_dll As LongLong Dim ptr_mdl As LongLong Dim rtn As Long Dim profit, performance1, performance2, penalty, total As Double Dim tpn, tfn As Long Dim value(1 To 1000) As Double

Dim i, j, k, m, n, t As Long Dim nprops, nrundowns, ntanks As Long Dim propnames(1 To 100) As String * IMPLbasestringlen Dim rundownnames(1 To 100) As String * IMPLbasestringlen Dim tanknames(1 To 100) As String * IMPLbasestringlen Dim matnames(1 To 100) As String * IMPLbasestringlen ' Select the Blendshop worksheet to start.

Worksheets("Blendshop").Select ' Get the problem path where the IMPL DLL files are available.

Range("B1").Select path = Selection.value ' Change the directory to a location where the IMPL DLL's are available. ChDir Trim$(path) ' Get the problem name with its path included.

Range("B2").Select fact = Selection.value Range("I5").Select Selection.value = "" ' Set the "use log file" setting (USELOGFILE).

name = "USELOGFILE" rtn = IMPLreceiveSETTING(name, IMPLyes) ' Set the "non-naturally occurring number" setting (RNNON).

name = "RNNON" rtn = IMPLreceiveSETTING(name, IMPLrnnon) ' "Initialize" the problem environment.

rtn = IMPLroot(fact) If rtn = Int(IMPLrnnon) Then Selection.value = "%ERROR% - Invalid or missing license file." End ElseIf rtn > 0 Then Selection.value = "%ERROR% - Missing settings file." End ElseIf rtn < 0 Then Selection.value = "%WARNING% - Number of missing settings = " + Str$(-rtn) End End If

name = "USELOGFILE" setting = IMPLretrieveSETTING(name) msg = Trim(name) + " = " + Str$(Int(setting)) rtn = IMPLwritelog(msg) name = "RNNON" setting = IMPLretrieveSETTING(name) msg = Trim(name) + " = " + Str$(setting) rtn = IMPLwritelog(msg)

' Set the "remove floater" variables to "no".

name = "REMOVEFLOATERS" rtn = IMPLreceiveSETTING(name, IMPLno) setting = IMPLretrieveSETTING(name) msg = Trim(name) + " = " + Str$(Int(setting)) rtn = IMPLwritelog(msg)

' "Initialize" the problem memory.

rtn = IMPLreserve(fact, IMPLall) If rtn = Int(IMPLrnnon) Then Selection.value = "%ERROR% - Invalid or missing license file."

End ElseIf rtn > 0 Then Selection.value = "%ERROR% - Missing memory file." End ElseIf rtn < 0 Then Selection.value = "%WARNING% - Missing missing setting." End End If

' "Interface" the problem data using the *.IML and *.UPS files.

form = IMPLsparsic fit = IMPLdiscrete filter = IMPLquality focus = IMPLoptimization face = IMPLimport factor = 1# fob = 0 frames = Chr$(0) rtn = IMPLinterfaceri(fact, form, fit, filter, focus, face, factor, fob, frames) If rtn = Int(IMPLrnnon) Then Selection.value = "%ERROR% - Invalid arguments." End ElseIf rtn > 0 Then Selection.value = "%ERROR% - Issue parsing import-file on line = " + Str$(rtn) End ElseIf rtn < 0 Then Selection.value = "%WARNING% - Issue parsing import-file on line = " + Str$(Abs(rtn)) End End If ' "Interact" with the problem data. ' PRICE weights.

Range("C8").Select uname = "Regular" oname = "" pname = "i" sname = "" prowt = Selection.value per1wt = 0# per2wt = 0# penwt = 0# rtn = IMPLreceiveUOPSflowweight(uname, oname, pname, sname, prowt, per1wt, per2wt, penwt, IMPLkeep)

Range("E8").Select uname = "Premium" oname = "" pname = "i" sname = "" prowt = Selection.value per1wt = 0# per2wt = 0# penwt = 0# rtn = IMPLreceiveUOPSflowweight(uname, oname, pname, sname, prowt, per1wt, per2wt, penwt, IMPLkeep)

' VOLUME (flows) orders.

begintime = 0# endtime = 1#

Range("C9").Select uname = "Blender" oname = "Regular" pname = "o" sname = "" lower = 0# upper = 1000# target = IMPLrnnon name = Selection.value If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) upper = lower rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) End If Range("E9").Select uname = "Blender" oname = "Premium" pname = "o" sname = "" lower = 0# upper = 1000# target = IMPLrnnon name = Selection.value

If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) upper = lower rtn = IMPLreceiveUOPSrateorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) End If ' RECIPES (yields) orders. Range("C11").Select uname = "Blender" oname = "Regular" sname = "" target = IMPLrnnon For i = 1 To 5 pname = "i" + Trim$(Str$(i)) name = Selection.value lower = 0# upper = 1# If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# upper = lower rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) End If ActiveCell.Offset(1, 0).Select Next i Range("E11").Select uname = "Blender" oname = "Premium" sname = "" target = IMPLrnnon For i = 1 To 5 pname = "i" + Trim$(Str$(i)) name = Selection.value lower = 0# upper = 1# If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) / 100# upper = lower rtn = IMPLreceiveUOPSyieldorder(uname, oname, pname, sname, lower, upper, target, begintime, endtime, IMPLkeep) End If ActiveCell.Offset(1, 0).Select Next i ' PROPERTIES orders. nprops = 11 propnames(1) = "RON" propnames(2) = "MON" propnames(3) = "ROAD" propnames(4) = "RVP" propnames(5) = "ARO" propnames(6) = "BEN" propnames(7) = "E70" propnames(8) = "E100" propnames(9) = "E150" propnames(10) = "E225" propnames(11) = "SUL" Range("C18").Select uname = "Blender" oname = "Regular" pname = "o" sname = "" target = IMPLrnnon For i = 1 To nprops bname = propnames(i) name = Selection.value

lower = 0# upper = 150# If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) upper = lower rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) End If ActiveCell.Offset(1, 0).Select Next i Range("E18").Select uname = "Blender" oname = "Premium" pname = "o" sname = "" target = IMPLrnnon For i = 1 To nprops bname = propnames(i) name = Selection.value lower = 0# upper = 150# If InStr(name, ">") Then j = InStr(name, ">") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "<") Then j = InStr(name, "<") upper = Val(Mid(name, j + 1, IMPLbasestringlen)) rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) ElseIf InStr(name, "~") Then j = InStr(name, "~") lower = Val(Mid(name, j + 1, IMPLbasestringlen)) upper = lower rtn = IMPLreceiveUOPSpropertyorder(uname, oname, pname, sname, bname, lower, upper, target, begintime, endtime, IMPLkeep) End If ActiveCell.Offset(1, 0).Select Next i ' Update or modify the past and future time-horizon durations and the time-period duration.

dthp = -1# dthf = 1# dtp = 1# rtn = IMPLreceiveT(dthp, dthf, dtp) ' "Serialize" the problem data.

rtn = IMPLrender(fact, IMPLall) ' "Model" the problem.

filler = IMPLsupplementalless foreign = IMPLsupplementaryless force = IMPLparameter rtn = IMPLmodelerv(fact, form, fit, filter, focus, filler, foreign, force) force = IMPLvariable rtn = IMPLmodelerv(fact, form, fit, filter, focus, filler, foreign, force) force = IMPLconstraint rtn = IMPLmodelerc(fact, form, fit, filter, focus, filler, foreign, force)

' "Presolve" and "solve" the problem.

factorizer = IMPLsemisolverless Range("G4").Select solver = Selection.value If Trim(solver) = "SLPQPE_COINMP" Then fork = IMPLslpqpecoinmp ElseIf Trim(solver) = "SLPQPE_GLPK" Then fork = IMPLslpqpeglpk ElseIf Trim(solver) = "SLPQPE_LPSOLVE" Then fork = IMPLslpqpelpsolve ElseIf Trim(solver) = "SLPQPE_CPLEX" Then fork = IMPLslpqpecplex ElseIf Trim(solver) = "IPOPT" Then fork = IMPLipopt Else fork = IMPLslpqpecplex End If fresh = IMPLfirstsession flashback = IMPLbinaryfile feedback = IMPLsummonsless

' Get pointer or address to allow callback, pullback, feedback or summons from IMPL's Presolver.

feedback = GetAddress(AddressOf summons) Worksheets("Log").Select Worksheets("Log").Range("A1").Select

rtn = IMPLpresolver(fact, form, fit, filter, focus, factorizer, fork, fresh, flashback, feedback) ' Display the solver status. Worksheets("Blendshop").Select name = "STATUS" signal = IMPLretrieveSIGNAL(name) Worksheets("Blendshop").Range("G8").Select If signal = IMPLconvergedall Then Selection.value = "CONVERGED" Else Selection.value = "UNCONVERGED" End If ' Display the completed timestamp.

Worksheets("Blendshop").Range("H8").Select Selection.value = TimeValue(Now) ' Display the objective function term values.

Call IMPLretrieveOBJterms2(profit, performance1, performance2, penalty, total) Worksheets("Blendshop").Range("B3").Select Selection.value = profit Worksheets("Blendshop").Range("B4").Select Selection.value = performance1 Worksheets("Blendshop").Range("B5").Select Selection.value = performance2 Worksheets("Blendshop").Range("B6").Select Selection.value = penalty Worksheets("Blendshop").Range("B7").Select Selection.value = total ' Get the number of time-periods in the "past/present" and "future" respectively.

Call IMPLretrieveT(tpn, tfn) ' Retrieve the QLQ phenomena using the UOPSS pointers (position/place/part).

Worksheets("Blendshop").Range("B9").Select uname = "Blender" oname = "Regular" Call IMPLretrieveUOflow2(uname, oname, tpn, tfn, value(1)) Selection.value = value(1 + tpn) Worksheets("Blendshop").Range("D9").Select uname = "Blender" oname = "Premium" Call IMPLretrieveUOflow2(uname, oname, tpn, tfn, value(1)) Selection.value = value(1 + tpn)

Worksheets("Blendshop").Range("B11").Select uname = "Blender" oname = "Regular" sname = "" For i = 1 To 5 pname = "i" + Trim$(Str$(i)) Call IMPLretrieveUOPSyield2(uname, oname, pname, sname, tpn, tfn, value(1)) Selection.value = value(1 + tpn) * 100# ActiveCell.Offset(1, 0).Select Next i Worksheets("Blendshop").Range("D11").Select uname = "Blender" oname = "Premium" sname = "" For i = 1 To 5 pname = "i" + Trim$(Str$(i)) Call IMPLretrieveUOPSyield2(uname, oname, pname, sname, tpn, tfn, value(1)) Selection.value = value(1 + tpn) * 100# ActiveCell.Offset(1, 0).Select Next i Worksheets("Blendshop").Range("B18").Select uname = "Blender" oname = "Regular" pname = "o" sname = "" For i = 1 To nprops bname = propnames(i) Call IMPLretrieveUOPSproperty2(uname, oname, pname, sname, bname, tpn, tfn, value(1)) Selection.value = value(1 + tpn) ActiveCell.Offset(1, 0).Select Next i Worksheets("Blendshop").Range("D18").Select uname = "Blender"

oname = "Premium" pname = "o" sname = "" For i = 1 To nprops bname = propnames(i) Call IMPLretrieveUOPSproperty2(uname, oname, pname, sname, bname, tpn, tfn, value(1)) Selection.value = value(1 + tpn) ActiveCell.Offset(1, 0).Select Next i nrundowns = 6 rundownnames(1) = "Butane" rundownnames(2) = "Pentane" rundownnames(3) = "Naphtha" rundownnames(4) = "Reformate" rundownnames(5) = "MTBE" rundownnames(6) = "XXX" Worksheets("Rundowns").Select Worksheets("Rundowns").Range("A2").Select For i = 1 To nrundowns uname = rundownnames(i) oname = "" pname = "o" sname = "" Selection.value = Trim$(uname) + "," + Trim$(oname) + "," + Trim$(pname) + "," + Trim$(sname) ActiveCell.Offset(0, 1).Select Call IMPLretrieveUOPSflow2(uname, oname, pname, sname, tpn, tfn, value(1)) For t = 1 To tpn + tfn Selection.value = value(t) ActiveCell.Offset(0, 1).Select Next t ActiveCell.Offset(1, -3).Select Next i ntanks = 14 tanknames(1) = "TK1" tanknames(2) = "TK2" tanknames(3) = "TK3" tanknames(4) = "TK4" tanknames(5) = "TK5" tanknames(6) = "TK6" tanknames(7) = "TK7" tanknames(8) = "TK8" tanknames(9) = "TK9" tanknames(10) = "TK10" tanknames(11) = "TK11" tanknames(12) = "TK12" tanknames(13) = "TK13" tanknames(14) = "TK14" matnames(1) = "Butane" matnames(2) = "Butane" matnames(3) = "Pentane" matnames(4) = "Pentane" matnames(5) = "Naphtha" matnames(6) = "Naphtha" matnames(7) = "Reformate" matnames(8) = "Reformate" matnames(9) = "MTBE" matnames(10) = "MTBE" matnames(11) = "Regular" matnames(12) = "Regular" matnames(13) = "Premium" matnames(14) = "Premium" Worksheets("Inventories").Select Worksheets("Inventories").Range("A2").Select For i = 1 To ntanks uname = tanknames(i) oname = matnames(i) Selection.value = Trim$(uname) + "," + Trim$(oname) ActiveCell.Offset(0, 1).Select Call IMPLretrieveUOholdup2(uname, oname, tpn, tfn, value(1)) For t = 1 To tpn + tfn Selection.value = value(t) ActiveCell.Offset(0, 1).Select Next t ActiveCell.Offset(1, -3).Select Next i ' Writeall of the problem data.

rtn = IMPLsummary(fact) rtn = IMPLwriteall(fact, IMPLseriesset, 0, 0) rtn = IMPLwriteall(fact, IMPLsimpleset, 0, 0) rtn = IMPLwriteall(fact, IMPLsymbolset, 0, 0) rtn = IMPLwriteall(fact, IMPLcatalog, 0, 0) rtn = IMPLwriteall(fact, IMPLlist, 0, 0) rtn = IMPLwriteall(fact, IMPLparameter, 0, 0) rtn = IMPLwriteall(fact, IMPLvariable, 0, 0) rtn = IMPLwriteall(fact, IMPLconstraint, 0, 0) rtn = IMPLwriteall(fact, IMPLformula, 0, 0)

rtn = IMPLreport(fact) ' "De-initialize" the problem memory.

rtn = IMPLrelease(IMPLall) ' Write out the mnemonic *.ndt file which contains the symbolic notation of the model.

If form = IMPLsparsic And filter = IMPLquality Then rtn = IMPLroot(fact) rtn = IMPLreserve(fact, IMPLall) face = IMPLimport frames = Chr$(0) rtn = IMPLrestore(fact, IMPLall) form = IMPLsymbolic force = IMPLparameter rtn = IMPLmodelerv(fact, form, fit, filter, focus, filler, foreign, force) force = IMPLvariable rtn = IMPLmodelerv(fact, form, fit, filter, focus, filler, foreign, force) force = IMPLconstraint rtn = IMPLmodelerc(fact, form, fit, filter, focus, filler, foreign, force) fork = IMPLsolverless fresh = IMPLfirstsession rtn = IMPLpresolver(fact, form, fit, filter, focus, factorizer, fork, fresh, flashback, feedback) ptr_dll = LoadLibrary("IMPLmodelerc") ptr_mdl = GetProcAddress(ptr_dll, "IMPLmodelerc") flag = 0 rtn = IMPLwritesymbology(fact, ptr_mdl, flag) rtn = IMPLrelease(IMPLall) End If Worksheets("Blendshop").Select Worksheets("Blendshop").Range("A1").Select End Sub

Appendix D – IMPL-Blendshop-QQ.XLS File (Excel/VBA IMPL Module Code)'' i M P l (c)'' Copyright and Property of i n d u s t r I A L g o r i t h m s LLC.

Option ExplicitOption Compare Text

' IMPL Resource Types. Global Const IMPLconstant = 0Global Const IMPLseriesset = 1Global Const IMPLsimpleset = 2Global Const IMPLsymbolset = 3Global Const IMPLcatalog = 4Global Const IMPLlist = 5Global Const IMPLparameter = 6Global Const IMPLvariable = 7Global Const IMPLconstraint = 8Global Const IMPLderivative = 9Global Const IMPLexpression = 10Global Const IMPLformula = 11Global Const IMPLworki = 12Global Const IMPLworkr = 13Global Const IMPLworkz = 14Global Const IMPLworks = 15Global Const IMPLall = 16 Global Const IMPLnumkeys = 8

' IMPL Resource Items. Global Const IMPLvalue = 0Global Const IMPLlower = 1Global Const IMPLupper = 2Global Const IMPLweight = 3Global Const IMPLtype = 4Global Const IMPLvalidation = 11Global Const IMPLvariance = 12Global Const IMPLvetistic = 13Global Const IMPLvaluation1 = 14Global Const IMPLvaluation2 = 15Global Const IMPLviolation = 16 ' IMPL Reference or Record Statuses. Global Const IMPLkeep = 1Global Const IMPLhide = 2Global Const IMPLerase = -1Global Const IMPLexpel = -2 ' IMPL String Sizes. Global Const IMPLbasestringlen = 64Global Const IMPLnamestringlenmult = 1Global Const IMPLkeystringlenmult = 8

Global Const IMPLlinestringlenmult = 8Global Const IMPLpagestringlenmult = 64 Global Const IMPLnamestringlen = IMPLbasestringlen * IMPLnamestringlenmultGlobal Const IMPLkeystringlen = IMPLbasestringlen * IMPLkeystringlenmultGlobal Const IMPLlinestringlen = IMPLbasestringlen * IMPLlinestringlenmultGlobal Const IMPLpagestringlen = IMPLbasestringlen * IMPLpagestringlenmult ' IMPL Yes/No, On/Off, Open/Close, etc. Signs. Global Const IMPLyes = 1Global Const IMPLno = 0Global Const IMPLon = 1Global Const IMPLoff = 0Global Const IMPLopen = 1Global Const IMPLclose = 0 ' IMPL Settings or Options (IMPL.set) Global Const IMPLuselogfile = -1Global Const IMPLrnnon = -99999#Global Const IMPLepsil = 0.0000000000001Global Const IMPLinfin = 1E+20Global Const IMPLcontol = 0.000001Global Const IMPLcomptol = 0#Global Const IMPLrandseed = 1Global Const IMPLperturbplus = 0.000000000001Global Const IMPLperturbtimes = 0.5Global Const IMPLabslogfuneps = 0.00001Global Const IMPLrellogfuneps = 0.00001Global Const IMPLmaxpasses = 50Global Const IMPLremovefloaters = 0Global Const IMPLpreemptpresolve = 0Global Const IMPLstatusoffset = 1000Global Const IMPLlowerrocl = 0#Global Const IMPLupperrocl = 1#Global Const IMPLlowerstcl = 2#Global Const IMPLupperstcl = 3#Global Const IMPLwritesolvernames = 0Global Const IMPLwritesolverlogfile = 0Global Const IMPLwritesolverlpfile = 0Global Const IMPLsymbology = 0Global Const IMPLsensitivity = 0Global Const IMPLstringnames = 0 ' IMPL Feed and Fact Flags. Global Const IMPLsourceless = ""Global Const IMPLsubjectless = "" ' IMPL Form Flag. Global Const IMPLstructureless = 0Global Const IMPLsparsic = 1Global Const IMPLsymbolic = 2 ' IMPL Fit Flag. Global Const IMPLslotless = 0Global Const IMPLdiscrete = 1Global Const IMPLdistribute = 2Global Const IMPLdifference = 3Global Const IMPLdifferential = 4 ' IMPL Filter Flag. Global Const IMPLselectless = 0Global Const IMPLquantity = 1Global Const IMPLlogistics = 2Global Const IMPLquality = 3Global Const IMPLqualogistics = 4 ' IMPL Focus Flag. Global Const IMPLsyllabusless = 0Global Const IMPLsimulation = 1Global Const IMPLestimation = 2Global Const IMPLoptimization = 3 ' IMPL Face Flag. Global Const IMPLstreamless = 0Global Const IMPLimport = 1Global Const IMPLexport = 2Global Const IMPLoutput = 3Global Const IMPLinput = 4Global Const IMPLinout = 6Global Const IMPLoutin = 5Global Const IMPLinoutdata = 7 ' IMPL Factor Flag. Global Const IMPLscale = 1# ' IMPL Fob Flag.

Global Const IMPLsipherless = 0 ' IMPL Frames Flag.' (Chr$(0):VBA, c_char_p(b'\0'):Python/ctypes, string(char(0)):Julia). 'Global Const IMPLsheetsless = Chr$(0) ' IMPL Filler Flag. Global Const IMPLsupplementalless = 0 ' IMPL Foreign Flag. Global Const IMPLsupplementaryless = "" ' IMPL Force Flag. Global Const IMPLstressless = 0 ' IMPL Factorizer Flag. Global Const IMPLsemisolverless = 0Global Const IMPLy12m = 1Global Const IMPLysmp = 2Global Const IMPLnspiv = 3Global Const IMPLma28 = 4Global Const IMPLpardiso = 5 ' IMPL Fork Flag. Global Const IMPLsolverless = 0Global Const IMPLcoinmp = 1Global Const IMPLglpk = 2Global Const IMPLlpsolve = 3Global Const IMPLscip = 4Global Const IMPLcplex = 5Global Const IMPLgurobi = 6Global Const IMPLlindo = 7Global Const IMPLoptonomy = 8Global Const IMPLxpress = 9Global Const IMPLconopt = 51Global Const IMPLipopt = 52Global Const IMPLknitro = 53Global Const IMPLnova = 54Global Const IMPLworhp = 55 Global Const IMPLslpqpecoinmp = 101Global Const IMPLslpqpeglpk = 102Global Const IMPLslpqpelpsolve = 103Global Const IMPLslpqpescip = 104Global Const IMPLslpqpecplex = 105Global Const IMPLslpqpegurobi = 106Global Const IMPLslpqpelindo = 107Global Const IMPLslpqpeoptonomy = 108Global Const IMPLslpqpexpress = 109Global Const IMPLslpqpeipopt = 152 Global Const IMPLsecqpey12m = 201Global Const IMPLsecqpeymsp = 202Global Const IMPLsecqpenspiv = 203Global Const IMPLsecqpema28 = 204Global Const IMPLsecqpepardiso = 205 Global Const IMPLsecqpesorve = 300Global Const IMPLsecqpey12msorve = 301Global Const IMPLsecqpeysmpsorve = 302Global Const IMPLsecqpenspivsorve = 303Global Const IMPLsecqpema28sorve = 304Global Const IMPLsecqpepardisosorve = 305 Global Const IMPLseosey12mmsorve = 401Global Const IMPLseoseysmpsorve = 402Global Const IMPLseosenspivsorve = 403Global Const IMPLseosema28sorve = 404Global Const IMPLseosepardisosorve = 405 Global Const IMPLspcrey12m = 501Global Const IMPLspcreysmp = 502Global Const IMPLspcrenspiv = 503Global Const IMPLspcrema28 = 504Global Const IMPLspcrepardiso = 505 Global Const IMPLsvve = 601Global Const IMPLssde = 602Global Const IMPLsfcme = 603 Global Const IMPLsbtecoinmp = 701Global Const IMPLsbteglpk = 702Global Const IMPLsbtelpsolve = 703 ' IMPL Fresh Flag. Global Const IMPLfirstsession = 0

' IMPL Flashback Flag. Global Const IMPLbinaryfile = 0Global Const IMPLbinaryram = 1Global Const IMPLflatfile = 2 ' IMPL Feedback Flag. Global Const IMPLsummonsless = 0 ' IMPL Fuse Flag. Global Const IMPLcoldstart = 0Global Const IMPLwarmstart = 1Global Const IMPLhotstart = 2 ' IMPL Fanfare Flag. Global Const IMPLshowseriesset = 0Global Const IMPLshowsimpleset = 1Global Const IMPLsymbolsetset = 2Global Const IMPLshowcatalog = 3Global Const IMPLshowlist = 4Global Const IMPLshowparameter = 5Global Const IMPLshowvariable = 6Global Const IMPLshowconstraint = 7Global Const IMPLshowformula = 8Global Const IMPLshowderivative = 9Global Const IMPLshowexpression = 10Global Const IMPLshowformulary = 11Global Const IMPLshowreport = 12Global Const IMPLshowsummary = 13Global Const IMPLshowstatics = 14Global Const IMPLshowslackness = 15Global Const IMPLshowscalings = 16Global Const IMPLshowall = 1073741823 ' IMPL Server Settings. ' USELOGFILE = If Yes (1) then use a log file else No (0) then no log file.' RNNON = Real Non-Naturally Occurring Number (-99,999).' INFIN = Near infinity (oo) value (1d+20).' EPSIL = Near zero (0) value (1d-13).' CONTOL = Constraint closure tolerance (1d-6).' COMPTOL = Compression tolerance (0d+0).' RANDSEED = Random number seed.' PERTURBPLUS = Plus perturbation size (1d-12).' PERTURBTIMES = Times perturbation size (0.5d+0).' ABSLOGFUNEPS = Absolute tolerance for logical functions such as IF, NOT, etc. (1d-5).' RELLOGFUNEPS = Relative tolerance for logical functions such as IF, NOT, etc. (1d-5).' MAXPASSES = Maximum number of presolver passes (50).' MAXPASSES = Maximum number of presolver passes (50).' REMOVEFLOATERS = If Yes (1) then remove floaters/following variables else No (0).' PREEMPTPRESOLVE = If Yes (1) then preempt, abort or stop presolve if infeasibility detected else No (0)' STATUSOFFSET = Solving - system 's status offset when status can be negative to make it positive (1000).' LOWERROCL = Lower rate-of-change value (0d+0).' UPPERROCL = Upper rate-of-change value (1d+0).' LOWERSTCL = Lower Student-t critical, threshold or control limit values (2d+0).' UPPERSTCL = Upper Student-t critical, threshold or control limit values (3d+0).' WRITESOLVERNAMES = If Yes (1) then write variable and constraint names in solver else No (0).' WRITESOLVERLOGFILE = If Yes (1) then write solver log file else No (0).' WRITESOLVERLPFILE = If Yes (1,2) then write solver lp,mps file else No (0).' WRITESYMBOLOGY = Write flag for symbology routine.' WRITESENSITIVITY = Write flag for sensitivity routine.' WRITESTRINGNAMES = Write number indices (0) versus name indices (1). ' IMPL Server Signals. ' SPRITE' SECURE' STREAM' SCALE' SELECT' SLOT' STRUCTURE' SYLLABUS' SUPPLEMENTAL' SIPHER' STAGE' SCENE' STEP' SUCCESSION' STALE' SESSION' SURPASS' SURPASS2' SEMISOLVER' SOLVER' STATUS' STATUS2' SOLUTION' SAVINGS' SUMMONS' SHOW' START

' STRIDE ' IMPL Server Statistics. ' NVARTOTAL' NVAR' NVARNL' NCONTOTAL' NCON' NCONNL' NCONEQ' NDOF' NDERTOTAL' NDER' NCONEXPTOTAL' NEXPTOTAL' OBJVALUE' ECLOSURE1' ECLOSURE2' ECLOSUREOO' ICLOSURE1' ICLOSURE2' ICLOSUREOO

' IMPL Server Solver Statuses.

Global Const IMPLbadderivatives = 1Global Const IMPLconvergedall = 2Global Const IMPLconvergedmost = 3Global Const IMPLconvergedonobj = 4Global Const IMPLconvergedwitherrors = 5Global Const IMPLdiverged = 6Global Const IMPLdegenerate = 7Global Const IMPLdualcutoff = 8Global Const IMPLfeasibleonly = 9Global Const IMPLincomplete = 10Global Const IMPLinfeasible = 11Global Const IMPLintegerinfeasible = 12Global Const IMPLinterrupted = 13Global Const IMPLlimitedprogress = 14Global Const IMPLmaxiterations = 15Global Const IMPLnodof = 16Global Const IMPLnofeasible = 17Global Const IMPLnumericalfailure = 18Global Const IMPLoptimal = 19Global Const IMPLpresolvedonly = 20Global Const IMPLprimalcutoff = 21Global Const IMPLsearchaborted = 22Global Const IMPLsearchfailed = 23Global Const IMPLsuboptimal = 24Global Const IMPLsystemaborted = 25Global Const IMPLtimedout = 26Global Const IMPLunbounded = 27Global Const IMPLunconverged = 28Global Const IMPLundefined = 29Global Const IMPLunexpectedfailure = 30Global Const IMPLunfinished = 31Global Const IMPLunloaded = 32Global Const IMPLuseraborted = 33 ' IMPL Server Routines. Declare PtrSafe Function IMPLroot Lib "IMPLserver.dll" (ByVal IMLPsprb As String) As LongDeclare PtrSafe Function IMPLreserve Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByVal IMPLtype As Long) As Long

Declare PtrSafe Function IMPLreceiveSETTING Lib "IMPLserver.dll" (ByVal IMPLsetting As String, ByVal IMPLvalue As Double) As LongDeclare PtrSafe Function IMPLretrieveSETTING Lib "IMPLserver.dll" (ByVal IMPLsetting As String) As DoubleDeclare PtrSafe Function IMPLretrieveSIGNAL Lib "IMPLserver.dll" (ByVal IMPLsignal As String) As DoubleDeclare PtrSafe Function IMPLretrieveSTATISTIC Lib "IMPLserver.dll" (ByVal IMPLstatistic As String) As Double

Declare PtrSafe Function IMPLrender Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByVal IMPLtype As Long) As LongDeclare PtrSafe Function IMPLrestore Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByVal IMPLtype As Long) As Long

Declare PtrSafe Function IMPLrefresh Lib "IMPLserver.dll" (ByVal IMPLtype As Long) As LongDeclare PtrSafe Function IMPLresize Lib "IMPLserver.dll" (ByVal IMPLtype As Long, ByVal IMPLnum As Long, ByVal IMPLrank As Long, ByVal IMPLrange As Long, ByVal IMPLlen As Long, ByVal IMPLlenprime As Long, ByVal IMPLlenprime2 As Long, ByVal IMPLlenkey As Long, ByVal IMPLlenval As Long) As LongDeclare PtrSafe Function IMPLrelease Lib "IMPLserver.dll" (ByVal IMPLtype As Long) As Long

Declare PtrSafe Function IMPLwritelog Lib "IMPLserver.dll" (ByVal IMPLmessage As String) As LongDeclare PtrSafe Function IMPLwriteall Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByVal IMPLtype As Long, ByVal IMPLtypebegin As Long, ByVal IMPLtypeend As Long) As LongDeclare PtrSafe Function IMPLreport Lib "IMPLserver.dll" (ByVal IMPLsprb As String) As Long

Declare PtrSafe Function IMPLrow Lib "IMPLserver.dll" (ByVal IMPLname As String, ByRef IMPLkeys As Long) As LongDeclare PtrSafe Function IMPLreview1 Lib "IMPLserver.dll" (ByVal IMPLtype As Long, ByVal IMPLrow As Long, ByVal IMPLitem As Long) As DoubleDeclare PtrSafe Sub IMPLreview2 Lib "IMPLserver.dll" (ByVal IMPLtype As Long, ByVal IMPLnrow As Long, ByVal IMPLrow As Long, ByVal IMPLitem As Long, ByRef IMPLvalue As Double)Declare PtrSafe Function IMPLrevise1 Lib "IMPLserver.dll" (ByVal IMPLtype As Long, ByVal IMPLrow As Long, ByVal IMPLitem As Long) As DoubleDeclare PtrSafe Sub IMPLrevise2 Lib "IMPLserver.dll" (ByVal IMPLtype As Long, ByVal IMPLnrow As Long, ByVal IMPLrow As Long, ByVal IMPLitem As Long, ByRef IMPLvalue As Double)

Declare PtrSafe Function IMPLsummary Lib "IMPLserver.dll" (ByVal IMPLsprb As String) As Long

Public Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtrPublic Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtrDeclare PtrSafe Function IMPLwritesensitivity Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByRef IMPLptrmdl As LongPtr, ByVal IMPLflag As Long) As LongDeclare PtrSafe Function IMPLwritesymbology Lib "IMPLserver.dll" (ByVal IMPLsprb As String, ByRef IMPLptrmdl As LongPtr, ByVal IMPLflag As Long) As Long

' IMPL Interfacer, Modeler and Presolver Routines.

Declare PtrSafe Function IMPLinterfaceri Lib "IMPLinterfaceri.dll" (ByVal IMPLfact As String, ByVal IMPLform As Long, ByVal IMPLfit As Long, ByVal IMPLfilter As Long, ByVal IMPLfocus As Long, ByVal IMPLface As Long, ByVal IMPLfactor As Double, ByVal IMPLfob As Currency, ByVal IMPLframes As String) As LongDeclare PtrSafe Function IMPLinterfacere Lib "IMPLinterfacere.dll" (ByVal IMPLfact As String, ByVal IMPLform As Long, ByVal IMPLfit As Long, ByVal IMPLfilter As Long, ByVal IMPLfocus As Long, ByVal IMPLface As Long, ByVal IMPLfactor As Double, ByVal IMPLfob As Currency, ByVal IMPLframes As String) As LongDeclare PtrSafe Function IMPLmodelerv Lib "IMPLmodelerv.dll" (ByVal IMPLfact As String, ByVal IMPLform As Long, ByVal IMPLfit As Long, ByVal IMPLfilter As Long, ByVal IMPLfocus As Long, ByRef IMPLfiller As LongPtr, ByVal IMPLforeign As String, ByRef IMPLforce As Long) As LongDeclare PtrSafe Function IMPLmodelerc Lib "IMPLmodelerc.dll" (ByVal IMPLfact As String, ByVal IMPLform As Long, ByVal IMPLfit As Long, ByVal IMPLfilter As Long, ByVal IMPLfocus As Long, ByRef IMPLfiller As LongLong, ByVal IMPLforeign As String, ByRef IMPLforce As Long) As LongDeclare PtrSafe Function IMPLpresolver Lib "IMPLpresolver.dll" (ByVal IMPLfact As String, ByVal IMPLform As Long, ByVal IMPLfit As Long, ByVal IMPLfilter As Long, ByVal IMPLfocus As Long, ByVal IMPLfactorizer As Long, ByVal IMPLfork As Long, ByVal IMPLfresh As Long, ByVal IMPLflashback As Long, ByRef IMPLfeedback As LongPtr) As Long

' IMPL Interacter Routines.

Declare PtrSafe Function IMPLreceiveT Lib "IMPLinteracter.dll" (ByVal IMPLdthp As Double, ByVal IMPLdthf As Double, ByVal IMPLdtp As Double) As Long

Declare PtrSafe Function IMPLreceiveUOPSflowweight Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLprowt As Double, ByVal IMPLper1wt As Double, ByVal IMPLperwt2 As Double, ByVal IMPLpenwt As Double, ByVal IMPLstatus As Long) As Long

Declare PtrSafe Function IMPLreceiveUOPSrateorder Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLlower As Double, ByVal IMPLupper As Double, ByVal IMPLtarget As Double, ByVal IMPLbegin As Double, ByVal IMPLend As Double, ByVal IMPLstatus As Long) As LongDeclare PtrSafe Function IMPLreceiveUOPSyieldorder Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLlower As Double, ByVal IMPLupper As Double, ByVal IMPLtarget As Double, ByVal IMPLbegin As Double, ByVal IMPLend As Double, ByVal IMPLstatus As Long) As Long

Declare PtrSafe Function IMPLreceiveProperty Lib "IMPLinteracter.dll" (ByVal IMPLbname As String, ByVal IMPLstatus As Long) As LongDeclare PtrSafe Function IMPLreceiveUOPSproperty Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLbname As String, ByVal IMPLlower As Double, ByVal IMPLupper As Double, ByVal IMPLtarget As Double, ByVal IMPLstatus As Long) As LongDeclare PtrSafe Function IMPLreceiveUpropertyopen Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLbname As String, ByVal IMPLvalue As Double, ByVal IMPLstart As Double, ByVal IMPLstatus As Long) As LongDeclare PtrSafe Function IMPLreceiveUOPSpropertyorder Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLbname As String, ByVal IMPLlower As Double, ByVal IMPLupper As Double, ByVal IMPLtarget As Double, ByVal IMPLbegin As Double, ByVal IMPLend As Double, ByVal IMPLstatus As Long) As Long

Declare PtrSafe Sub IMPLretrieveT Lib "IMPLinteracter.dll" (ByRef IMPLtpn As Long, ByRef IMPLtfn As Long)Declare PtrSafe Sub IMPLretrieveOBJterms2 Lib "IMPLinteracter.dll" (ByRef IMPLprofit As Double, ByRef IMPLperformance1 As Double, ByRef IMPLperformance2 As Double, ByRef IMPLpenalty As Double, ByRef IMPLtotal As Double)

Declare PtrSafe Sub IMPLretrieveUOflow2 Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal tpn As Long, ByVal tfn As Long, ByRef value As Double)Declare PtrSafe Sub IMPLretrieveUOholdup2 Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal tpn As Long, ByVal tfn As Long, ByRef value As Double)Declare PtrSafe Sub IMPLretrieveUOPSflow2 Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal tpn As Long, ByVal tfn As Long, ByRef value As Double)Declare PtrSafe Sub IMPLretrieveUOPSyield2 Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal tpn As Long, ByVal tfn As Long, ByRef value As Double)Declare PtrSafe Sub IMPLretrieveUOPSproperty2 Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String, ByVal IMPLuname As String, ByVal tpn As Long, ByVal tfn As Long, ByRef value As Double)

Declare PtrSafe Function IMPLUOm Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String) As LongDeclare PtrSafe Function IMPLUOPSij Lib "IMPLinteracter.dll" (ByVal IMPLuname As String, ByVal IMPLoname As String, ByVal IMPLpname As String, ByVal IMPLsname As String) As LongDeclare PtrSafe Function IMPLDd Lib "IMPLinteracter.dll" (ByVal IMPLdname As String) As LongDeclare PtrSafe Function IMPLCc Lib "IMPLinteracter.dll" (ByVal IMPLcname As String) As LongDeclare PtrSafe Function IMPLBb Lib "IMPLinteracter.dll" (ByVal IMPLbname As String) As LongDeclare PtrSafe Function IMPLAa Lib "IMPLinteracter.dll" (ByVal IMPLaname As String) As LongDeclare PtrSafe Function IMPLLl Lib "IMPLinteracter.dll" (ByVal IMPLlname As String) As Long

' IMPL Presolver Callback to Excel/VBA routines.

Declare PtrSafe Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As LongPtr) As LongDeclare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal lpvDest As String, ByVal lpvSource As LongPtr, ByVal NumBytes As Long)

Function Ptr2Str(ptr As LongPtr) As String Dim l As Long If ptr = 0 Then Ptr2Str = vbNullString Else l = lstrlen(ptr) Ptr2Str = Space$(l) CopyMemory Ptr2Str, ptr, l End IfEnd Function

Function GetAddress(ByVal ptrAddressOf As LongPtr) As LongPtr GetAddress = ptrAddressOfEnd Function

Function summons(ByRef msglen As Long, ByRef msgptr As LongPtr) As Long Dim msg As String msg = Ptr2Str(msgptr) Worksheets("Log").Select Selection.value = Trim$(msg) ActiveCell.Offset(1, 0).Select ' IMPL User code here ...

End Function