The SimulationObject Data Structure as Enabler for a Service-Oriented Architecture for Simulation-Based work flows

A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system. – John Gall: Systemantics: How Systems Really Work and How They Fail

All complex systems are modular and hierarchical – by necessity. – Francois Chollet (creator of Keras) on X

The SimulationObject is a simple data model which describes a simulation task. It describes both the (flow sheet) topology and the physical state of a simulation. Mathematically, it is a directed graph, where the

  • edges are connectors (=simulation unit inputs and outputs, e.g. a process stream is a connector)

  • vertices are simulation models (e.g. process units or sub flow sheets)

A SimulationObject describes the flow of mass, energy, information or other quantities between ‘units’ (more generally: mathematical models of technical or physical systems). In our setting SimulationObjects will often resemble flow sheets or simulation units.

The data model is normally serialized as a json string (described by a json schema) - however, high performance implementations relying on gRPC are feasible.

A graphical representation of the contents of a SimulationObject is given below:

Topology: Alt text State: Alt text

SimulationObjects may be used to set up systems hierarchically; a heat exchanger used in a SimulationObject may itself be set up from a SimulationObject which sets up a heat exchanger model as a combination of flow passage models, metal capacitor models, heat transfer models and pressure drop models.

The SimulationObject data model is already supported by a number of ITPP tools (arrows indicate information flow directions):

digraph G{    
    SimulationObject -> OPTISIM;
    OPTISIM -> SimulationObject;
    SimulationObject -> OPTISIM_GUI;
    OPTISIM_GUI -> SimulationObject;
    "UNISIM (USO Writer)" -> SimulationObject;
    "UNISIM SMILE Extension" -> SimulationObject;
    SMILE -> SimulationObject;
    SimulationObject -> SMILE;
    TensorFlow -> SMILE;
    SMILE -> TensorFlow;
    "SCORPION, MB6, GENERIC_HEX" -> SMILE;
    SMILE -> "SCORPION, MB6, GENERIC_HEX";
    "Spyder GUI" -> SimulationObject;
     SimulationObject -> "Spyder GUI";
}

Why should we care?

The SimulationObject data model is intended to allow for

  • a client-server architectures for simulation-based work flows, e.g.

    • OPTISIM \(\leftrightarrow\) OPTISIM GUI, later: OPTISIM GUI \(\leftrightarrow\) SMILE/OPTISIM back end

    • There is a prototype of SimulationObject-based SMILE Simulation Server.

  • aligning software components used at ITPx towards more reusability, e.g (Web) GUI components

    • A PC_VIPS - like generic Process Stream GUI could be implemented as a web GUI, completely independently of the physical property system used

    • A plot tool to visualize data such as column|membrane|HEX profiles could be set up generically and used in the OPTISIM GUI as well as in the UNISIM SMILE Extension as well as in SMILE’s python interface

    • A prototype for a SimObject based GUI tool is the Simulation Object Navigator

  • facilitate outsourcing of components which have only SimulationObject interfaces

  • simplify integration test

  • setting up numerical tasks such as fitting compressor maps or physical properties in a (highly) tool-independent way

Example Simulation Object

A json serialization of a very simple SimulationObject reads as

{
  "Flowsheet": {    
    "ddec7d6c-1ff1-495e-8b7e-7422ebf19a40": {
      "Name": "sqrt",
      "ModelDLL": "Examples/Models[SquareRoot_assign]",
      "Ports": { 
        "V_IN": {
          "UUIDs" : [ 
            "74922c22-7988-4165-8fbd-3db07f673c03"
          ]
        },
        "V_OUT": {
          "UUIDs" : [ 
            "585dd521-f4b7-46a3-9487-4c39b8dcf583"
          ]
        }
      }
    }
  },
  "Connectors": { 
    "74922c22-7988-4165-8fbd-3db07f673c03": {
      "Name": "x",
      "Assigned":  false,
      "Values":  [ 
          2
        ]
    },
    "585dd521-f4b7-46a3-9487-4c39b8dcf583": {
      "Name": "y",
      "Assigned":  true,
      "Values":  [ 
          1.414213562373095          
        ]
    }
  }
}