#
# This code has been auto-generated by the MDE Workbench
# Version: 3.1.24.
#
# File: entities.py
# Date: 2023-03-16 16:04
# Time: 16:04
#


from .enums import *

class EntityBase(object):
    def initialiseFromDictionary(self, data: dict):
        pass

# Class: LocalPosition
# Description: Position with reference to some arbitrary local origin and axes.
class LocalPosition(object):

    # Constructor.
    def __init__(self):

        # X
        self.x = 0.0

        # Y
        self.y = 0.0

        # Z
        self.z = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # X
        self.x = float(data['x'])

        # Y
        self.y = float(data['y'])

        # Z
        self.z = float(data['z'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* LocalPosition')

        # X
        print(f'X:\t{self.x}')

        # Y
        print(f'Y:\t{self.y}')

        # Z
        print(f'Z:\t{self.z}')


# Class: Asset
# Description: Any equipment to be modeled, vessels, pipelines
class Asset(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Location of the asset
        self.location = LocalPosition()


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Location of the asset
        self.location.initialiseFromDictionary(data['location'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Asset')

        # Location of the asset
        self.location.print()



# Class: Transect
# Description: Definition of transect (line segment)
class Transect(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Cartesian coordinates of start point of transect
        self.transectStartPoint = LocalPosition()

        # Cartesian coordinates of end point of transect
        self.transectEndPoint = LocalPosition()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Cartesian coordinates of start point of transect
        self.transectStartPoint.initialiseFromDictionary(data['transectStartPoint'])

        # Cartesian coordinates of end point of transect
        self.transectEndPoint.initialiseFromDictionary(data['transectEndPoint'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Transect')

        # Cartesian coordinates of start point of transect
        self.transectStartPoint.print()

        # Cartesian coordinates of end point of transect
        self.transectEndPoint.print()


# Class: FlammableOutputConfig
# Description: Fire and radiation output configuration
class FlammableOutputConfig(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Position used for radiation calculations (including contours)
        self.position = LocalPosition()

        # Radiation type
        self.radiationType = RadiationType.INTENSITY

        # Plane orientation for contouring
        self.contourType = ContourType.FOOTPRINT

        # Radiation level (could be dose, probit, intensity, etc)
        self.radiationLevel = 0.0

        # Spatial resolution for radiation calculations
        self.radiationResolution = Resolution.MEDIUM

        # Definition of line segment of interest for radiation transects
        self.transect = Transect()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Position used for radiation calculations (including contours)
        self.position.initialiseFromDictionary(data['position'])

        # Radiation type
        self.radiationType = RadiationType(data['radiationType'])

        # Plane orientation for contouring
        self.contourType = ContourType(data['contourType'])

        # Radiation level (could be dose, probit, intensity, etc)
        self.radiationLevel = float(data['radiationLevel'])

        # Spatial resolution for radiation calculations
        self.radiationResolution = Resolution(data['radiationResolution'])

        # Definition of line segment of interest for radiation transects
        self.transect.initialiseFromDictionary(data['transect'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlammableOutputConfig')

        # Position used for radiation calculations (including contours)
        self.position.print()

        # Radiation type
        print('Radiation type\t{0}'.format(self.radiationType))

        # Plane orientation for contouring
        print('Contour type\t{0}'.format(self.contourType))

        # Radiation level (could be dose, probit, intensity, etc)
        print(f'Radiation level:\t{self.radiationLevel}')

        # Spatial resolution for radiation calculations
        print('Radiation resolution\t{0}'.format(self.radiationResolution))

        # Definition of line segment of interest for radiation transects
        self.transect.print()


# Class: MaterialComponent
# Description: Constituent component of a material
class MaterialComponent(object):

    # Constructor.
    def __init__(self):

        # Name of the component.
        self.name = "ComponentName"

        # Mole fraction of the component in the material.
        self.moleFraction = 0.0


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Name of the component.
        self.name = data['name']

        # Mole fraction of the component in the material.
        self.moleFraction = float(data['moleFraction'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* MaterialComponent')

        # Name of the component.
        print(f'Name:\t{self.name}')

        # Mole fraction of the component in the material.
        print(f'Mole fraction:\t{self.moleFraction}')



# Class: Material
class Material(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Material name
        self.name = ""

        # Number of components in the material
        self.componentCount = 1

        # Constituent components
        self.components = list[MaterialComponent]()

        # Property used template for material
        self.propertyTemplate = PropertyTemplate.PHAST_MC


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Material name
        self.name = data['name']

        # Number of components in the material
        self.componentCount = int(data['componentCount'])

        # Constituent components
        for dataItem in data['components']:
            materialComponent = MaterialComponent()
            materialComponent.initialiseFromDictionary(dataItem)
            self.components.append(materialComponent)

        # Property used template for material
        self.propertyTemplate = PropertyTemplate(data['propertyTemplate'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Material')

        # Material name
        print(f'Name:\t{self.name}')

        # Number of components in the material
        print(f'Component count:\t{self.componentCount}')

        # Constituent components
        for item in self.components:
            item.print()

        # Property used template for material
        print('Property template\t{0}'.format(self.propertyTemplate))



# Class: State
# Description: Description of the fluid state.
class State(object):

    # Constructor.
    def __init__(self):

        # Absolute pressure of the fluid
        self.pressure = 0.0

        # Temperature of the fluid
        self.temperature = 0.0

        # Mole fraction of liquid in the fluid
        self.liquidFraction = 0.0

        # How fluid equilibrium is specified
        self.flashFlag = FluidSpec.TP

        # Mixture modelling: Pseudo-component (=0), MC single aerosol (=1), MC multiple aerosol (=3)
        self.mixtureModelling = MixtureModelling.PC

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Absolute pressure of the fluid
        self.pressure = float(data['pressure'])

        # Temperature of the fluid
        self.temperature = float(data['temperature'])

        # Mole fraction of liquid in the fluid
        self.liquidFraction = float(data['liquidFraction'])

        # How fluid equilibrium is specified
        self.flashFlag = FluidSpec(data['flashFlag'])

        # Mixture modelling: Pseudo-component (=0), MC single aerosol (=1), MC multiple aerosol (=3)
        self.mixtureModelling = MixtureModelling(data['mixtureModelling'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* State')

        # Absolute pressure of the fluid
        print(f'Pressure:\t{self.pressure}')

        # Temperature of the fluid
        print(f'Temperature:\t{self.temperature}')

        # Mole fraction of liquid in the fluid
        print(f'Liquid fraction:\t{self.liquidFraction}')

        # How fluid equilibrium is specified
        print('Flash flag\t{0}'.format(self.flashFlag))

        # Mixture modelling: Pseudo-component (=0), MC single aerosol (=1), MC multiple aerosol (=3)
        print('Mixture modelling\t{0}'.format(self.mixtureModelling))


# Class: Vessel
# Description: All vessel types
class Vessel(Asset):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Fluid specification (at liquid surface)
        self.state = State()

        # Internal diameter of the vessel
        self.diameter = 0.0

        # Internal height of the vessel
        self.height = 0.0

        # Internal length of the vessel
        self.length = 0.0

        # Internal width of the vessel
        self.width = 0.0

        # Shape
        self.shape = VesselShape.VESSEL_SPHERE

        # Material
        self.material = Material()

        # Vessel conditions
        self.vesselConditions = VesselConditions.PURE_GAS

        # The liquid fill fraction in the vessel by volume
        self.liquidFillFractionByVolume = 0.0


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        Asset.initialiseFromDictionary(self, data)

        # Fluid specification (at liquid surface)
        self.state.initialiseFromDictionary(data['state'])

        # Internal diameter of the vessel
        self.diameter = float(data['diameter'])

        # Internal height of the vessel
        self.height = float(data['height'])

        # Internal length of the vessel
        self.length = float(data['length'])

        # Internal width of the vessel
        self.width = float(data['width'])

        # Shape
        self.shape = VesselShape(data['shape'])

        # Material
        self.material.initialiseFromDictionary(data['material'])

        # Vessel conditions
        self.vesselConditions = VesselConditions(data['vesselConditions'])

        # The liquid fill fraction in the vessel by volume
        self.liquidFillFractionByVolume = float(data['liquidFillFractionByVolume'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Vessel')

        # Fluid specification (at liquid surface)
        self.state.print()

        # Internal diameter of the vessel
        print(f'Diameter:\t{self.diameter}')

        # Internal height of the vessel
        print(f'Height:\t{self.height}')

        # Internal length of the vessel
        print(f'Length:\t{self.length}')

        # Internal width of the vessel
        print(f'Width:\t{self.width}')

        # Shape
        print('Shape\t{0}'.format(self.shape))

        # Material
        self.material.print()

        # Vessel conditions
        print('Vessel conditions\t{0}'.format(self.vesselConditions))

        # The liquid fill fraction in the vessel by volume
        print(f'Liquid fill fraction by volume:\t{self.liquidFillFractionByVolume}')



# Class: PropertiesDipprPT3
class PropertiesDipprPT3(object):

    # Constructor.
    def __init__(self):

        # Saturated vapour entropy
        self.sVapSat = []

        # Saturated liquid entropy
        self.sLiqSat = []

        # Saturated vapour density
        self.rhoVapSat = []

        # Saturated vapour enthalpy
        self.hVapSat = []

        # Vapour density at 1 atm
        self.rhoVapAtm = []

        # Saturated vapour temperature
        self.tVapSat = []

        # Surface tension
        self.surfaceTension = []

        # Liquid density
        self.rhoLiq = []

        # Liquid enthalpy
        self.hLiq = []

        # Liquid entropy
        self.sLiq = []

        # Vapour density
        self.rhoVap = []

        # Vapour enthalpy
        self.hVap = []

        # Vapour entropy
        self.sVap = []

        # Vapour compressibility
        self.zVap = []

        # Vapour sonic velocity
        self.sonicVelVap = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Saturated vapour entropy
        for dataItem in data['sVapSat']:
            self.sVapSat.append(float(dataItem))

        # Saturated liquid entropy
        for dataItem in data['sLiqSat']:
            self.sLiqSat.append(float(dataItem))

        # Saturated vapour density
        for dataItem in data['rhoVapSat']:
            self.rhoVapSat.append(float(dataItem))

        # Saturated vapour enthalpy
        for dataItem in data['hVapSat']:
            self.hVapSat.append(float(dataItem))

        # Vapour density at 1 atm
        for dataItem in data['rhoVapAtm']:
            self.rhoVapAtm.append(float(dataItem))

        # Saturated vapour temperature
        for dataItem in data['tVapSat']:
            self.tVapSat.append(float(dataItem))

        # Surface tension
        for dataItem in data['surfaceTension']:
            self.surfaceTension.append(float(dataItem))

        # Liquid density
        for dataItem in data['rhoLiq']:
            self.rhoLiq.append(float(dataItem))

        # Liquid enthalpy
        for dataItem in data['hLiq']:
            self.hLiq.append(float(dataItem))

        # Liquid entropy
        for dataItem in data['sLiq']:
            self.sLiq.append(float(dataItem))

        # Vapour density
        for dataItem in data['rhoVap']:
            self.rhoVap.append(float(dataItem))

        # Vapour enthalpy
        for dataItem in data['hVap']:
            self.hVap.append(float(dataItem))

        # Vapour entropy
        for dataItem in data['sVap']:
            self.sVap.append(float(dataItem))

        # Vapour compressibility
        for dataItem in data['zVap']:
            self.zVap.append(float(dataItem))

        # Vapour sonic velocity
        for dataItem in data['sonicVelVap']:
            self.sonicVelVap.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDipprPT3')

        # Saturated vapour entropy
        for item in self.sVapSat:
            print(f'{item}')

        # Saturated liquid entropy
        for item in self.sLiqSat:
            print(f'{item}')

        # Saturated vapour density
        for item in self.rhoVapSat:
            print(f'{item}')

        # Saturated vapour enthalpy
        for item in self.hVapSat:
            print(f'{item}')

        # Vapour density at 1 atm
        for item in self.rhoVapAtm:
            print(f'{item}')

        # Saturated vapour temperature
        for item in self.tVapSat:
            print(f'{item}')

        # Surface tension
        for item in self.surfaceTension:
            print(f'{item}')

        # Liquid density
        for item in self.rhoLiq:
            print(f'{item}')

        # Liquid enthalpy
        for item in self.hLiq:
            print(f'{item}')

        # Liquid entropy
        for item in self.sLiq:
            print(f'{item}')

        # Vapour density
        for item in self.rhoVap:
            print(f'{item}')

        # Vapour enthalpy
        for item in self.hVap:
            print(f'{item}')

        # Vapour entropy
        for item in self.sVap:
            print(f'{item}')

        # Vapour compressibility
        for item in self.zVap:
            print(f'{item}')

        # Vapour sonic velocity
        for item in self.sonicVelVap:
            print(f'{item}')


# Class: RadiationRecord
# Description: Radiation type and level at specific point (x,y,z)
class RadiationRecord(object):

    # Constructor.
    def __init__(self):

        # Cartesian coordinates of a specific point
        self.position = LocalPosition()

        # Type of radiation result
        self.radiationType = RadiationType.UNSET

        # Radiation level
        self.radiationResult = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Cartesian coordinates of a specific point
        self.position.initialiseFromDictionary(data['position'])

        # Type of radiation result
        self.radiationType = RadiationType(data['radiationType'])

        # Radiation level
        self.radiationResult = float(data['radiationResult'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* RadiationRecord')

        # Cartesian coordinates of a specific point
        self.position.print()

        # Type of radiation result
        print('Radiation type\t{0}'.format(self.radiationType))

        # Radiation level
        print(f'Radiation result:\t{self.radiationResult}')


# Class: Scenario
# Description: Base struct/class for all scenario types.
class Scenario(EntityBase):

        # Constructor.
        def __init__(self):
            super().__init__()

        # Initialise entity with data from a dictionary.
        def initialiseFromDictionary(self, data: dict):
            super(Scenario, self).initialiseFromDictionary(data)


            # Utility method to get the Scenario entity to print itself.
            def print(self):
                pass

# Class: ReleaseOverTime
# Description: Scenario representing a release over time.
class ReleaseOverTime(Scenario):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Angle above horizontal of release
        self.releaseAngle = 0.0

        # Time-varying or steady-state modelling
        self.timeVaryingOption = TimeVaryingOption.INITIAL_RATE


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        Scenario.initialiseFromDictionary(self, data)

        # Angle above horizontal of release
        self.releaseAngle = float(data['releaseAngle'])

        # Time-varying or steady-state modelling
        self.timeVaryingOption = TimeVaryingOption(data['timeVaryingOption'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ReleaseOverTime')

        # Angle above horizontal of release
        print(f'Release angle:\t{self.releaseAngle}')

        # Time-varying or steady-state modelling
        print('Time varying option\t{0}'.format(self.timeVaryingOption))



# Class: Leak
# Description: Leak scenario.
class Leak(ReleaseOverTime):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Diameter of the hole
        self.holeDiameter = 0.0

        # Location of the hole above the base of the vessel as a fraction of vessel height
        self.holeHeightFraction = 0.0


    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        ReleaseOverTime.initialiseFromDictionary(self, data)

        # Diameter of the hole
        self.holeDiameter = float(data['holeDiameter'])

        # Location of the hole above the base of the vessel as a fraction of vessel height
        self.holeHeightFraction = float(data['holeHeightFraction'])


    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Leak')

        # Diameter of the hole
        print(f'Hole diameter:\t{self.holeDiameter}')

        # Location of the hole above the base of the vessel as a fraction of vessel height
        print(f'Hole height fraction:\t{self.holeHeightFraction}')



# Class: Bund
class Bund(object):

    # Constructor.
    def __init__(self):

        # Bund height
        self.bundHeight = 0.0

        # Bund diameter
        self.bundDiameter = 0.0

        # Specify a bund
        self.specifyBund = False

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Bund height
        self.bundHeight = float(data['bundHeight'])

        # Bund diameter
        self.bundDiameter = float(data['bundDiameter'])

        # Specify a bund
        self.specifyBund = bool(data['specifyBund'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Bund')

        # Bund height
        print(f'Bund height:\t{self.bundHeight}')

        # Bund diameter
        print(f'Bund diameter:\t{self.bundDiameter}')

        # Specify a bund
        print(f'Specify bund:\t{self.specifyBund}')


# Class: Substrate
# Description: The ground over which a release is taking place.
class Substrate(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Surface roughness length
        self.surfaceRoughness = 0.183

        # Dispersing surface type
        self.surfaceType = SurfaceType.LAND

        # Pool or bund surface type
        self.poolSurfaceType = PoolSurfaceType.CONCRETE

        # Bund data
        self.bund = Bund()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Surface roughness length
        self.surfaceRoughness = float(data['surfaceRoughness'])

        # Dispersing surface type
        self.surfaceType = SurfaceType(data['surfaceType'])

        # Pool or bund surface type
        self.poolSurfaceType = PoolSurfaceType(data['poolSurfaceType'])

        # Bund data
        self.bund.initialiseFromDictionary(data['bund'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Substrate')

        # Surface roughness length
        print(f'Surface roughness:\t{self.surfaceRoughness}')

        # Dispersing surface type
        print('Surface type\t{0}'.format(self.surfaceType))

        # Pool or bund surface type
        print('Pool surface type\t{0}'.format(self.poolSurfaceType))

        # Bund data
        self.bund.print()


# Class: ToxicRecord
# Description: Toxic result: dose, probit or lethality
class ToxicRecord(object):

    # Constructor.
    def __init__(self):

        # Cartesian coordinates of a specific point
        self.position = LocalPosition()

        # Type of toxic result
        self.toxicResultType = ToxicResultType.UNSET

        # Dose, probit or lethality level
        self.toxicResult = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Cartesian coordinates of a specific point
        self.position.initialiseFromDictionary(data['position'])

        # Type of toxic result
        self.toxicResultType = ToxicResultType(data['toxicResultType'])

        # Dose, probit or lethality level
        self.toxicResult = float(data['toxicResult'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ToxicRecord')

        # Cartesian coordinates of a specific point
        self.position.print()

        # Type of toxic result
        print('Toxic result type\t{0}'.format(self.toxicResultType))

        # Dose, probit or lethality level
        print(f'Toxic result:\t{self.toxicResult}')


# Class: Instantaneous
# Description: Base struct/class for instantaneous release scenarios.
class Instantaneous(Scenario):

        # Constructor.
        def __init__(self):
            super().__init__()

        # Initialise entity with data from a dictionary.
        def initialiseFromDictionary(self, data: dict):
            super(Instantaneous, self).initialiseFromDictionary(data)


            # Utility method to get the Instantaneous entity to print itself.
            def print(self):
                pass

# Class: CatastrophicRupture
# Description: Catastrophic rupture of a vessel scenario.
class CatastrophicRupture(Instantaneous):

        # Constructor.
        def __init__(self):
            super().__init__()

        # Initialise entity with data from a dictionary.
        def initialiseFromDictionary(self, data: dict):
            super(CatastrophicRupture, self).initialiseFromDictionary(data)


            # Utility method to get the CatastrophicRupture entity to print itself.
            def print(self):
                pass

# Class: DischargeResult
# Description: Scalar discharge results.
class DischargeResult(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Specific expansion energy (instantaneous releases only)
        self.expansionEnergy = 0.0

        # Released mass
        self.releaseMass = 0.0

        # Release height above ground
        self.height = 0.0

        # Release angle (non-instantaneous releases only)
        self.angle = 0.0

        # Instantaneous, continuous or time-varying
        self.releaseType = DynamicType.UNSET

        # Diameter of the hole
        self.holeDiameter = 0.0

        # Pre-dilution air rate
        self.preDilutionAirRate = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Specific expansion energy (instantaneous releases only)
        self.expansionEnergy = float(data['expansionEnergy'])

        # Released mass
        self.releaseMass = float(data['releaseMass'])

        # Release height above ground
        self.height = float(data['height'])

        # Release angle (non-instantaneous releases only)
        self.angle = float(data['angle'])

        # Instantaneous, continuous or time-varying
        self.releaseType = DynamicType(data['releaseType'])

        # Diameter of the hole
        self.holeDiameter = float(data['holeDiameter'])

        # Pre-dilution air rate
        self.preDilutionAirRate = float(data['preDilutionAirRate'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DischargeResult')

        # Specific expansion energy (instantaneous releases only)
        print(f'Expansion energy:\t{self.expansionEnergy}')

        # Released mass
        print(f'Release mass:\t{self.releaseMass}')

        # Release height above ground
        print(f'Height:\t{self.height}')

        # Release angle (non-instantaneous releases only)
        print(f'Angle:\t{self.angle}')

        # Instantaneous, continuous or time-varying
        print('Release type\t{0}'.format(self.releaseType))

        # Diameter of the hole
        print(f'Hole diameter:\t{self.holeDiameter}')

        # Pre-dilution air rate
        print(f'Pre dilution air rate:\t{self.preDilutionAirRate}')


# Class: PropertiesDnvPT2
class PropertiesDnvPT2(object):

    # Constructor.
    def __init__(self):

        # Toxic property N
        self.toxicN = []

        # Toxic property A
        self.toxicA = []

        # Toxic property B
        self.toxicB = []

        # Enthalpy interpolation range
        self.hIntRange = []

        # Liquid water surface tension
        self.liqWaterSurfTen = []

        # Solubility in water
        self.solubilityWater = []

        # Heat of solution
        self.heatSolution = []

        # Reaction with water flag
        self.waterReactionFlag = []

        # Water heat transfer coefficient
        self.alphaWater = []

        # Probability of delayed explosion (continuous)
        self.probDelayedExpCont = []

        # Probability of delayed explosion (instantaneous & QI)
        self.probDelayedExpInst = []

        # Probability of delayed flash fire (continuous)
        self.probDelayedFlashFireCont = []

        # Probability of delayed flash fire (instantaneous & QI)
        self.probDelayedFlashFireInst = []

        # Probability of delayed ignition (cont., inst. & QI)
        self.probDelayedIgnition = []

        # Probability of early ignition (continuous)
        self.probEarlyIgnitionCont = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Toxic property N
        for dataItem in data['toxicN']:
            self.toxicN.append(float(dataItem))

        # Toxic property A
        for dataItem in data['toxicA']:
            self.toxicA.append(float(dataItem))

        # Toxic property B
        for dataItem in data['toxicB']:
            self.toxicB.append(float(dataItem))

        # Enthalpy interpolation range
        for dataItem in data['hIntRange']:
            self.hIntRange.append(float(dataItem))

        # Liquid water surface tension
        for dataItem in data['liqWaterSurfTen']:
            self.liqWaterSurfTen.append(float(dataItem))

        # Solubility in water
        for dataItem in data['solubilityWater']:
            self.solubilityWater.append(float(dataItem))

        # Heat of solution
        for dataItem in data['heatSolution']:
            self.heatSolution.append(float(dataItem))

        # Reaction with water flag
        for dataItem in data['waterReactionFlag']:
            self.waterReactionFlag.append(float(dataItem))

        # Water heat transfer coefficient
        for dataItem in data['alphaWater']:
            self.alphaWater.append(float(dataItem))

        # Probability of delayed explosion (continuous)
        for dataItem in data['probDelayedExpCont']:
            self.probDelayedExpCont.append(float(dataItem))

        # Probability of delayed explosion (instantaneous & QI)
        for dataItem in data['probDelayedExpInst']:
            self.probDelayedExpInst.append(float(dataItem))

        # Probability of delayed flash fire (continuous)
        for dataItem in data['probDelayedFlashFireCont']:
            self.probDelayedFlashFireCont.append(float(dataItem))

        # Probability of delayed flash fire (instantaneous & QI)
        for dataItem in data['probDelayedFlashFireInst']:
            self.probDelayedFlashFireInst.append(float(dataItem))

        # Probability of delayed ignition (cont., inst. & QI)
        for dataItem in data['probDelayedIgnition']:
            self.probDelayedIgnition.append(float(dataItem))

        # Probability of early ignition (continuous)
        for dataItem in data['probEarlyIgnitionCont']:
            self.probEarlyIgnitionCont.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDnvPT2')

        # Toxic property N
        for item in self.toxicN:
            print(f'{item}')

        # Toxic property A
        for item in self.toxicA:
            print(f'{item}')

        # Toxic property B
        for item in self.toxicB:
            print(f'{item}')

        # Enthalpy interpolation range
        for item in self.hIntRange:
            print(f'{item}')

        # Liquid water surface tension
        for item in self.liqWaterSurfTen:
            print(f'{item}')

        # Solubility in water
        for item in self.solubilityWater:
            print(f'{item}')

        # Heat of solution
        for item in self.heatSolution:
            print(f'{item}')

        # Reaction with water flag
        for item in self.waterReactionFlag:
            print(f'{item}')

        # Water heat transfer coefficient
        for item in self.alphaWater:
            print(f'{item}')

        # Probability of delayed explosion (continuous)
        for item in self.probDelayedExpCont:
            print(f'{item}')

        # Probability of delayed explosion (instantaneous & QI)
        for item in self.probDelayedExpInst:
            print(f'{item}')

        # Probability of delayed flash fire (continuous)
        for item in self.probDelayedFlashFireCont:
            print(f'{item}')

        # Probability of delayed flash fire (instantaneous & QI)
        for item in self.probDelayedFlashFireInst:
            print(f'{item}')

        # Probability of delayed ignition (cont., inst. & QI)
        for item in self.probDelayedIgnition:
            print(f'{item}')

        # Probability of early ignition (continuous)
        for item in self.probEarlyIgnitionCont:
            print(f'{item}')


# Class: MaterialComponentDataItem
# Description: Material component data item.
class MaterialComponentDataItem(object):

    # Constructor.
    def __init__(self):

        # Material component data item description.
        self.description = ""

        # Equation number.
        self.equationNumber = 0

        # Equation string.
        self.equationString = ""

        # Equation coefficients
        self.equationCoefficients = []

        # Calculation limits
        self.calculationLimits = []

        # Super critical extrapolation flag.
        self.supercriticalExtrapolation = 0.0

        # Fraction of critical temperature.
        self.fractionTc = 1.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Material component data item description.
        self.description = data['description']

        # Equation number.
        self.equationNumber = int(data['equationNumber'])

        # Equation string.
        self.equationString = data['equationString']

        # Equation coefficients
        for dataItem in data['equationCoefficients']:
            self.equationCoefficients.append(float(dataItem))

        # Calculation limits
        for dataItem in data['calculationLimits']:
            self.calculationLimits.append(float(dataItem))

        # Super critical extrapolation flag.
        self.supercriticalExtrapolation = float(data['supercriticalExtrapolation'])

        # Fraction of critical temperature.
        self.fractionTc = float(data['fractionTc'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* MaterialComponentDataItem')

        # Material component data item description.
        print(f'Description:\t{self.description}')

        # Equation number.
        print(f'Equation number:\t{self.equationNumber}')

        # Equation string.
        print(f'Equation string:\t{self.equationString}')

        # Equation coefficients
        for item in self.equationCoefficients:
            print(f'{item}')

        # Calculation limits
        for item in self.calculationLimits:
            print(f'{item}')

        # Super critical extrapolation flag.
        print(f'Supercritical extrapolation:\t{self.supercriticalExtrapolation}')

        # Fraction of critical temperature.
        print(f'Fraction tc:\t{self.fractionTc}')


# Class: MaterialComponentData
# Description: Material component data
class MaterialComponentData(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Name of the material component data.
        self.name = ""

        # DIPPR version number.
        self.dipprVersion = 0

        # CAS id
        self.casId = 0

        # List of data items defining the material component data.
        self.dataItem = list[MaterialComponentDataItem]()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Name of the material component data.
        self.name = data['name']

        # DIPPR version number.
        self.dipprVersion = int(data['dipprVersion'])

        # CAS id
        self.casId = int(data['casId'])

        # List of data items defining the material component data.
        for dataItem in data['dataItem']:
            materialComponentDataItem = MaterialComponentDataItem()
            materialComponentDataItem.initialiseFromDictionary(dataItem)
            self.dataItem.append(materialComponentDataItem)

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* MaterialComponentData')

        # Name of the material component data.
        print(f'Name:\t{self.name}')

        # DIPPR version number.
        print(f'Dippr version:\t{self.dipprVersion}')

        # CAS id
        print(f'Cas id:\t{self.casId}')

        # List of data items defining the material component data.
        for item in self.dataItem:
            item.print()


# Class: FlammableParameters
# Description: Fire and radiation parameters
class FlammableParameters(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Maximum exposure duration to radiation effects
        self.maxExposureDuration = 20.0

        # Relative tolerance for radiation calculations
        self.radiationRelativeTolerance = 0.01

        # Type of pool fire modelling
        self.poolFireType = PoolFireType.LATE

        # Option to automatically select jet fire modelling
        self.jetFireAutoSelect = 0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Maximum exposure duration to radiation effects
        self.maxExposureDuration = float(data['maxExposureDuration'])

        # Relative tolerance for radiation calculations
        self.radiationRelativeTolerance = float(data['radiationRelativeTolerance'])

        # Type of pool fire modelling
        self.poolFireType = PoolFireType(data['poolFireType'])

        # Option to automatically select jet fire modelling
        self.jetFireAutoSelect = bool(data['jetFireAutoSelect'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlammableParameters')

        # Maximum exposure duration to radiation effects
        print(f'Max exposure duration:\t{self.maxExposureDuration}')

        # Relative tolerance for radiation calculations
        print(f'Radiation relative tolerance:\t{self.radiationRelativeTolerance}')

        # Type of pool fire modelling
        print('Pool fire type\t{0}'.format(self.poolFireType))

        # Option to automatically select jet fire modelling
        print(f'Jet fire auto select:\t{self.jetFireAutoSelect}')


# Class: FlameResult
# Description: Fire results
class FlameResult(object):

    # Constructor.
    def __init__(self):

        # Time of fire, or duration if initial rate
        self.time = 0.0

        # Surface emissive power of flame
        self.surfaceEmissivePower = 0.0

        # Fire type  (Fireball, pool, cone jet, API jet, Multi point source jet)
        self.fireType = FireType.NO_FIRE

        # Length of the flame
        self.flameLength = 0.0

        # Diameter of the flame
        self.flameDiameter = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Time of fire, or duration if initial rate
        self.time = float(data['time'])

        # Surface emissive power of flame
        self.surfaceEmissivePower = float(data['surfaceEmissivePower'])

        # Fire type  (Fireball, pool, cone jet, API jet, Multi point source jet)
        self.fireType = FireType(data['fireType'])

        # Length of the flame
        self.flameLength = float(data['flameLength'])

        # Diameter of the flame
        self.flameDiameter = float(data['flameDiameter'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlameResult')

        # Time of fire, or duration if initial rate
        print(f'Time:\t{self.time}')

        # Surface emissive power of flame
        print(f'Surface emissive power:\t{self.surfaceEmissivePower}')

        # Fire type  (Fireball, pool, cone jet, API jet, Multi point source jet)
        print('Fire type\t{0}'.format(self.fireType))

        # Length of the flame
        print(f'Flame length:\t{self.flameLength}')

        # Diameter of the flame
        print(f'Flame diameter:\t{self.flameDiameter}')


# Class: PoolFireFlameResult
class PoolFireFlameResult(FlameResult):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Surface emissive power from each of the two pool fire zones
        self.poolZoneSEP = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        FlameResult.initialiseFromDictionary(self, data)

        # Surface emissive power from each of the two pool fire zones
        for dataItem in data['poolZoneSEP']:
            self.poolZoneSEP.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PoolFireFlameResult')

        # Surface emissive power from each of the two pool fire zones
        for item in self.poolZoneSEP:
            print(f'{item}')


# Class: PropertiesDipprPT1
class PropertiesDipprPT1(object):

    # Constructor.
    def __init__(self):

        # Description of new property.
        self.totalStepsUsed = 0

        # Array of pressure values
        self.pressure = []

        # Array of temperatures
        self.temperature = []

        # Mass of the composition
        self.massComp = []

        # Description of new property.
        self.mwComp = []

        # Dangerous Toxic Load
        self.dangerousToxicLoad = []

        # Critical pressure 
        self.pCrit = []

        # Description of new property.
        self.tCrit = []

        # Melting point
        self.tMelt = []

        # Boiling point
        self.tBoil = []

        # Flash point
        self.tFlash = []

        # Heat of combustion
        self.hComb = []

        # Lower flammability limit - vol%
        self.lfl = []

        # upper flammability limit
        self.ufl = []

        # Combustion coefficient At
        self.combAt = []

        # Combustion coefficient Ct
        self.combCt = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Description of new property.
        self.totalStepsUsed = int(data['totalStepsUsed'])

        # Array of pressure values
        for dataItem in data['pressure']:
            self.pressure.append(float(dataItem))

        # Array of temperatures
        for dataItem in data['temperature']:
            self.temperature.append(float(dataItem))

        # Mass of the composition
        for dataItem in data['massComp']:
            self.massComp.append(float(dataItem))

        # Description of new property.
        for dataItem in data['mwComp']:
            self.mwComp.append(float(dataItem))

        # Dangerous Toxic Load
        for dataItem in data['dangerousToxicLoad']:
            self.dangerousToxicLoad.append(float(dataItem))

        # Critical pressure 
        for dataItem in data['pCrit']:
            self.pCrit.append(float(dataItem))

        # Description of new property.
        for dataItem in data['tCrit']:
            self.tCrit.append(float(dataItem))

        # Melting point
        for dataItem in data['tMelt']:
            self.tMelt.append(float(dataItem))

        # Boiling point
        for dataItem in data['tBoil']:
            self.tBoil.append(float(dataItem))

        # Flash point
        for dataItem in data['tFlash']:
            self.tFlash.append(float(dataItem))

        # Heat of combustion
        for dataItem in data['hComb']:
            self.hComb.append(float(dataItem))

        # Lower flammability limit - vol%
        for dataItem in data['lfl']:
            self.lfl.append(float(dataItem))

        # upper flammability limit
        for dataItem in data['ufl']:
            self.ufl.append(float(dataItem))

        # Combustion coefficient At
        for dataItem in data['combAt']:
            self.combAt.append(float(dataItem))

        # Combustion coefficient Ct
        for dataItem in data['combCt']:
            self.combCt.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDipprPT1')

        # Description of new property.
        print(f'Total steps used:\t{self.totalStepsUsed}')

        # Array of pressure values
        for item in self.pressure:
            print(f'{item}')

        # Array of temperatures
        for item in self.temperature:
            print(f'{item}')

        # Mass of the composition
        for item in self.massComp:
            print(f'{item}')

        # Description of new property.
        for item in self.mwComp:
            print(f'{item}')

        # Dangerous Toxic Load
        for item in self.dangerousToxicLoad:
            print(f'{item}')

        # Critical pressure 
        for item in self.pCrit:
            print(f'{item}')

        # Description of new property.
        for item in self.tCrit:
            print(f'{item}')

        # Melting point
        for item in self.tMelt:
            print(f'{item}')

        # Boiling point
        for item in self.tBoil:
            print(f'{item}')

        # Flash point
        for item in self.tFlash:
            print(f'{item}')

        # Heat of combustion
        for item in self.hComb:
            print(f'{item}')

        # Lower flammability limit - vol%
        for item in self.lfl:
            print(f'{item}')

        # upper flammability limit
        for item in self.ufl:
            print(f'{item}')

        # Combustion coefficient At
        for item in self.combAt:
            print(f'{item}')

        # Combustion coefficient Ct
        for item in self.combCt:
            print(f'{item}')


# Class: ConcentrationRecord
class ConcentrationRecord(object):

    # Constructor.
    def __init__(self):

        # Cloud concentration at an x, y, z position
        self.concentration = 0.0

        # x, y, z position
        self.position = LocalPosition()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Cloud concentration at an x, y, z position
        self.concentration = float(data['concentration'])

        # x, y, z position
        self.position.initialiseFromDictionary(data['position'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ConcentrationRecord')

        # Cloud concentration at an x, y, z position
        print(f'Concentration:\t{self.concentration}')

        # x, y, z position
        self.position.print()


# Class: Pipe
# Description: All pipe types
class Pipe(Asset):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Pipeline nodes
        self.nodes = list[LocalPosition]()

        # Pipe diameter
        self.diameter = 0.0

        # Pipe roughness
        self.roughness = 4.5e-5

        # Material
        self.material = Material()

        # Fluid state
        self.state = State()

        # Upstream pumped inflow
        self.pumpedInflow = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        Asset.initialiseFromDictionary(self, data)

        # Pipeline nodes
        for dataItem in data['nodes']:
            localPosition = LocalPosition()
            localPosition.initialiseFromDictionary(dataItem)
            self.nodes.append(localPosition)

        # Pipe diameter
        self.diameter = float(data['diameter'])

        # Pipe roughness
        self.roughness = float(data['roughness'])

        # Material
        self.material.initialiseFromDictionary(data['material'])

        # Fluid state
        self.state.initialiseFromDictionary(data['state'])

        # Upstream pumped inflow
        self.pumpedInflow = float(data['pumpedInflow'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Pipe')

        # Pipeline nodes
        for item in self.nodes:
            item.print()

        # Pipe diameter
        print(f'Diameter:\t{self.diameter}')

        # Pipe roughness
        print(f'Roughness:\t{self.roughness}')

        # Material
        self.material.print()

        # Fluid state
        self.state.print()

        # Upstream pumped inflow
        print(f'Pumped inflow:\t{self.pumpedInflow}')


# Class: Interval
# Description: A range of permitted values for the design variable when carrying out a design optimization workflow
class Interval(object):

    # Constructor.
    def __init__(self):

        # The lower boundary of the interval
        self.lowerBoundary = 0.0

        # The upper boundary of the interval
        self.upperBoundary = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # The lower boundary of the interval
        self.lowerBoundary = float(data['lowerBoundary'])

        # The upper boundary of the interval
        self.upperBoundary = float(data['upperBoundary'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Interval')

        # The lower boundary of the interval
        print(f'Lower boundary:\t{self.lowerBoundary}')

        # The upper boundary of the interval
        print(f'Upper boundary:\t{self.upperBoundary}')


# Class: Constraint
# Description: A set of data describing a design constraint. This includes the result target of interest  (e.g. mass flow) and the design variable (e.g. stack diameter).
class Constraint(object):

    # Constructor.
    def __init__(self):

        # The result type to be prescribed as a design target
        self.targetVariable = TargetVariable.MASS_FLOW_RATE

        # User-defined target value for the chosen result type
        self.targetVariableValue = 0.0

        # The input type to vary to achieve the design target
        self.designVariable = DesignVariable.PIPE_DIAMETER

        # An interval of permitted values for the design variable
        self.permittedDesignVariableInterval = Interval()

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # The result type to be prescribed as a design target
        self.targetVariable = TargetVariable(data['targetVariable'])

        # User-defined target value for the chosen result type
        self.targetVariableValue = float(data['targetVariableValue'])

        # The input type to vary to achieve the design target
        self.designVariable = DesignVariable(data['designVariable'])

        # An interval of permitted values for the design variable
        self.permittedDesignVariableInterval.initialiseFromDictionary(data['permittedDesignVariableInterval'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Constraint')

        # The result type to be prescribed as a design target
        print('Target variable\t{0}'.format(self.targetVariable))

        # User-defined target value for the chosen result type
        print(f'Target variable value:\t{self.targetVariableValue}')

        # The input type to vary to achieve the design target
        print('Design variable\t{0}'.format(self.designVariable))

        # An interval of permitted values for the design variable
        self.permittedDesignVariableInterval.print()


# Class: VesselRuleSet
# Description: Rule set for generating scenarios from a vessel
class VesselRuleSet(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Use time-varying leaks
        self.useTimeVarying = False

        # Include catastrophic rupture scenarios
        self.includeCatastrophicRupture = False

        # Hole diameters for leaks
        self.holeDiameters = []

        # Number of hole diameters (<= 5)
        self.numberOfDiameters = 3

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Use time-varying leaks
        self.useTimeVarying = bool(data['useTimeVarying'])

        # Include catastrophic rupture scenarios
        self.includeCatastrophicRupture = bool(data['includeCatastrophicRupture'])

        # Hole diameters for leaks
        for dataItem in data['holeDiameters']:
            self.holeDiameters.append(float(dataItem))

        # Number of hole diameters (<= 5)
        self.numberOfDiameters = int(data['numberOfDiameters'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* VesselRuleSet')

        # Use time-varying leaks
        print(f'Use time varying:\t{self.useTimeVarying}')

        # Include catastrophic rupture scenarios
        print(f'Include catastrophic rupture:\t{self.includeCatastrophicRupture}')

        # Hole diameters for leaks
        for item in self.holeDiameters:
            print(f'{item}')

        # Number of hole diameters (<= 5)
        print(f'Number of diameters:\t{self.numberOfDiameters}')


# Class: PropertiesDnvPT3
class PropertiesDnvPT3(object):

    # Constructor.
    def __init__(self):

        # Probability of early ignition (instantaneous & QI)
        self.probEarlyIgnitionInst = []

        # Probability of early pool fire
        self.probEarlyPoolFire = []

        # Probability of fireball
        self.probFireball = []

        # Probability of free jet explosion
        self.probFreeJetExp = []

        # Probability of free jet fire
        self.probFreeJetFire = []

        # Probability of late pool fire
        self.probLatePoolFire = []

        # Dimer coefficient
        self.dimerCoeff = []

        # Trimer coefficient
        self.trimerCoeff = []

        # Hexamer coefficient
        self.hexamerCoeff = []

        # Octamer coefficient
        self.octamerCoeff = []

        # Liquid water enthalpy 
        self.hLiqWater = []

        # Natural log of the saturated vap. pressure
        self.pVapSatLn = []

        # First derivative of the natural log of sat.vap.pres. w.r.t. temp.
        self.dpVapSatLnDT = []

        # Second der. of the natural log. of sat.vap.pres. w.r.t. temp.
        self.d2pVapSatLnDT2 = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Probability of early ignition (instantaneous & QI)
        for dataItem in data['probEarlyIgnitionInst']:
            self.probEarlyIgnitionInst.append(float(dataItem))

        # Probability of early pool fire
        for dataItem in data['probEarlyPoolFire']:
            self.probEarlyPoolFire.append(float(dataItem))

        # Probability of fireball
        for dataItem in data['probFireball']:
            self.probFireball.append(float(dataItem))

        # Probability of free jet explosion
        for dataItem in data['probFreeJetExp']:
            self.probFreeJetExp.append(float(dataItem))

        # Probability of free jet fire
        for dataItem in data['probFreeJetFire']:
            self.probFreeJetFire.append(float(dataItem))

        # Probability of late pool fire
        for dataItem in data['probLatePoolFire']:
            self.probLatePoolFire.append(float(dataItem))

        # Dimer coefficient
        for dataItem in data['dimerCoeff']:
            self.dimerCoeff.append(float(dataItem))

        # Trimer coefficient
        for dataItem in data['trimerCoeff']:
            self.trimerCoeff.append(float(dataItem))

        # Hexamer coefficient
        for dataItem in data['hexamerCoeff']:
            self.hexamerCoeff.append(float(dataItem))

        # Octamer coefficient
        for dataItem in data['octamerCoeff']:
            self.octamerCoeff.append(float(dataItem))

        # Liquid water enthalpy 
        for dataItem in data['hLiqWater']:
            self.hLiqWater.append(float(dataItem))

        # Natural log of the saturated vap. pressure
        for dataItem in data['pVapSatLn']:
            self.pVapSatLn.append(float(dataItem))

        # First derivative of the natural log of sat.vap.pres. w.r.t. temp.
        for dataItem in data['dpVapSatLnDT']:
            self.dpVapSatLnDT.append(float(dataItem))

        # Second der. of the natural log. of sat.vap.pres. w.r.t. temp.
        for dataItem in data['d2pVapSatLnDT2']:
            self.d2pVapSatLnDT2.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDnvPT3')

        # Probability of early ignition (instantaneous & QI)
        for item in self.probEarlyIgnitionInst:
            print(f'{item}')

        # Probability of early pool fire
        for item in self.probEarlyPoolFire:
            print(f'{item}')

        # Probability of fireball
        for item in self.probFireball:
            print(f'{item}')

        # Probability of free jet explosion
        for item in self.probFreeJetExp:
            print(f'{item}')

        # Probability of free jet fire
        for item in self.probFreeJetFire:
            print(f'{item}')

        # Probability of late pool fire
        for item in self.probLatePoolFire:
            print(f'{item}')

        # Dimer coefficient
        for item in self.dimerCoeff:
            print(f'{item}')

        # Trimer coefficient
        for item in self.trimerCoeff:
            print(f'{item}')

        # Hexamer coefficient
        for item in self.hexamerCoeff:
            print(f'{item}')

        # Octamer coefficient
        for item in self.octamerCoeff:
            print(f'{item}')

        # Liquid water enthalpy 
        for item in self.hLiqWater:
            print(f'{item}')

        # Natural log of the saturated vap. pressure
        for item in self.pVapSatLn:
            print(f'{item}')

        # First derivative of the natural log of sat.vap.pres. w.r.t. temp.
        for item in self.dpVapSatLnDT:
            print(f'{item}')

        # Second der. of the natural log. of sat.vap.pres. w.r.t. temp.
        for item in self.d2pVapSatLnDT2:
            print(f'{item}')


# Class: Weather
# Description: A sum of the meteorological conditions at the time
class Weather(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Wind speed at reference height
        self.windSpeed = 0.0

        # Stability class
        self.stabilityClass = AtmosphericStabilityClass.STABILITY_D

        # Ambient temperature
        self.temperature = 283.0

        # Relative humidity
        self.relativeHumidity = 0.7

        # Mixing layer height
        self.mixingLayerHeight = 800.0

        # Solar radiation flux
        self.solarRadiation = 500.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Wind speed at reference height
        self.windSpeed = float(data['windSpeed'])

        # Stability class
        self.stabilityClass = AtmosphericStabilityClass(data['stabilityClass'])

        # Ambient temperature
        self.temperature = float(data['temperature'])

        # Relative humidity
        self.relativeHumidity = float(data['relativeHumidity'])

        # Mixing layer height
        self.mixingLayerHeight = float(data['mixingLayerHeight'])

        # Solar radiation flux
        self.solarRadiation = float(data['solarRadiation'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* Weather')

        # Wind speed at reference height
        print(f'Wind speed:\t{self.windSpeed}')

        # Stability class
        print('Stability class\t{0}'.format(self.stabilityClass))

        # Ambient temperature
        print(f'Temperature:\t{self.temperature}')

        # Relative humidity
        print(f'Relative humidity:\t{self.relativeHumidity}')

        # Mixing layer height
        print(f'Mixing layer height:\t{self.mixingLayerHeight}')

        # Solar radiation flux
        print(f'Solar radiation:\t{self.solarRadiation}')


# Class: ExplosionOutputConfig
# Description: Explosion output configuration
class ExplosionOutputConfig(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Overpressure of interest for explosions
        self.overpressureLevel = 2068.0

        # Explosion ME confined method where Uniform Confined = 3, User Defined = 1
        self.meConfinedMethod = MEConfinedMethod.UNIFORM_CONFINED

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Overpressure of interest for explosions
        self.overpressureLevel = float(data['overpressureLevel'])

        # Explosion ME confined method where Uniform Confined = 3, User Defined = 1
        self.meConfinedMethod = MEConfinedMethod(data['meConfinedMethod'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ExplosionOutputConfig')

        # Overpressure of interest for explosions
        print(f'Overpressure level:\t{self.overpressureLevel}')

        # Explosion ME confined method where Uniform Confined = 3, User Defined = 1
        print('M e confined method\t{0}'.format(self.meConfinedMethod))


# Class: FlashResult
# Description: Physical properties for a material generated at a particular pressure and temperature
class FlashResult(object):

    # Constructor.
    def __init__(self):

        # Pressure
        self.pressure = 0.0

        # Temperature
        self.temperature = 0.0

        # Liquid fraction (mole)
        self.liquidMoleFraction = 0.0

        # Density of liquid phase
        self.liquidDensity = 0.0

        # Density of vapour phase
        self.vapourDensity = 0.0

        # Entropy of liquid phase
        self.liquidEntropy = 0.0

        # Entropy of vapour phase
        self.vapourEntropy = 0.0

        # Enthalpy of liquid phase
        self.liquidEnthalpy = 0.0

        # Enthalpy of vapour phase
        self.vapourEnthalpy = 0.0

        # Vapour, liquid or two-phase
        self.fluidPhase = Phase.UNSET

        # Mixture bubble point pressure at given temperature
        self.bubblePointPressure = 0.0

        # Mixture bubble point temperature at given pressure
        self.bubblePointTemperature = 0.0

        # Mixture dew point pressure at given temperature
        self.dewPointPressure = 0.0

        # Mixture dew point temperature at given pressure
        self.dewPointTemperature = 0.0

        # Total fluid density (mass-based)
        self.totalFluidDensity = 0.0

        # Liquid mass fraction
        self.liquidMassFraction = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Pressure
        self.pressure = float(data['pressure'])

        # Temperature
        self.temperature = float(data['temperature'])

        # Liquid fraction (mole)
        self.liquidMoleFraction = float(data['liquidMoleFraction'])

        # Density of liquid phase
        self.liquidDensity = float(data['liquidDensity'])

        # Density of vapour phase
        self.vapourDensity = float(data['vapourDensity'])

        # Entropy of liquid phase
        self.liquidEntropy = float(data['liquidEntropy'])

        # Entropy of vapour phase
        self.vapourEntropy = float(data['vapourEntropy'])

        # Enthalpy of liquid phase
        self.liquidEnthalpy = float(data['liquidEnthalpy'])

        # Enthalpy of vapour phase
        self.vapourEnthalpy = float(data['vapourEnthalpy'])

        # Vapour, liquid or two-phase
        self.fluidPhase = Phase(data['fluidPhase'])

        # Mixture bubble point pressure at given temperature
        self.bubblePointPressure = float(data['bubblePointPressure'])

        # Mixture bubble point temperature at given pressure
        self.bubblePointTemperature = float(data['bubblePointTemperature'])

        # Mixture dew point pressure at given temperature
        self.dewPointPressure = float(data['dewPointPressure'])

        # Mixture dew point temperature at given pressure
        self.dewPointTemperature = float(data['dewPointTemperature'])

        # Total fluid density (mass-based)
        self.totalFluidDensity = float(data['totalFluidDensity'])

        # Liquid mass fraction
        self.liquidMassFraction = float(data['liquidMassFraction'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlashResult')

        # Pressure
        print(f'Pressure:\t{self.pressure}')

        # Temperature
        print(f'Temperature:\t{self.temperature}')

        # Liquid fraction (mole)
        print(f'Liquid mole fraction:\t{self.liquidMoleFraction}')

        # Density of liquid phase
        print(f'Liquid density:\t{self.liquidDensity}')

        # Density of vapour phase
        print(f'Vapour density:\t{self.vapourDensity}')

        # Entropy of liquid phase
        print(f'Liquid entropy:\t{self.liquidEntropy}')

        # Entropy of vapour phase
        print(f'Vapour entropy:\t{self.vapourEntropy}')

        # Enthalpy of liquid phase
        print(f'Liquid enthalpy:\t{self.liquidEnthalpy}')

        # Enthalpy of vapour phase
        print(f'Vapour enthalpy:\t{self.vapourEnthalpy}')

        # Vapour, liquid or two-phase
        print('Fluid phase\t{0}'.format(self.fluidPhase))

        # Mixture bubble point pressure at given temperature
        print(f'Bubble point pressure:\t{self.bubblePointPressure}')

        # Mixture bubble point temperature at given pressure
        print(f'Bubble point temperature:\t{self.bubblePointTemperature}')

        # Mixture dew point pressure at given temperature
        print(f'Dew point pressure:\t{self.dewPointPressure}')

        # Mixture dew point temperature at given pressure
        print(f'Dew point temperature:\t{self.dewPointTemperature}')

        # Total fluid density (mass-based)
        print(f'Total fluid density:\t{self.totalFluidDensity}')

        # Liquid mass fraction
        print(f'Liquid mass fraction:\t{self.liquidMassFraction}')


# Class: ScalarUdmOutputs
# Description: Scalar UDM output values required for post processing dispersion results.
class ScalarUdmOutputs(object):

    # Constructor.
    def __init__(self):

        # Number of observers
        self.observerCount = 0

        # Number of records
        self.recordCount = 0

        # Cloud type
        self.cloudType = DynamicType.UNSET

        # Minimum concentration
        self.minimumConcentration = 0.0

        # Wind power
        self.windPower = 0.0

        # Friction velocity
        self.frictionVelocity = 0.0

        # When is the last release observer released?
        self.dispersionReleaseDuration = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Number of observers
        self.observerCount = int(data['observerCount'])

        # Number of records
        self.recordCount = int(data['recordCount'])

        # Cloud type
        self.cloudType = DynamicType(data['cloudType'])

        # Minimum concentration
        self.minimumConcentration = float(data['minimumConcentration'])

        # Wind power
        self.windPower = float(data['windPower'])

        # Friction velocity
        self.frictionVelocity = float(data['frictionVelocity'])

        # When is the last release observer released?
        self.dispersionReleaseDuration = float(data['dispersionReleaseDuration'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ScalarUdmOutputs')

        # Number of observers
        print(f'Observer count:\t{self.observerCount}')

        # Number of records
        print(f'Record count:\t{self.recordCount}')

        # Cloud type
        print('Cloud type\t{0}'.format(self.cloudType))

        # Minimum concentration
        print(f'Minimum concentration:\t{self.minimumConcentration}')

        # Wind power
        print(f'Wind power:\t{self.windPower}')

        # Friction velocity
        print(f'Friction velocity:\t{self.frictionVelocity}')

        # When is the last release observer released?
        print(f'Dispersion release duration:\t{self.dispersionReleaseDuration}')


# Class: PTRange
class PTRange(object):

    # Constructor.
    def __init__(self):

        # Start value of pressure range
        self.pressureLow = 0.0

        # End value of pressure range
        self.pressureHigh = 0.0

        # Start value of temperature range
        self.tempLow = 0.0

        # End value of temperature range
        self.tempHigh = 0.0

        # Description of new property.
        self.stepsPerVariable = 20

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Start value of pressure range
        self.pressureLow = float(data['pressureLow'])

        # End value of pressure range
        self.pressureHigh = float(data['pressureHigh'])

        # Start value of temperature range
        self.tempLow = float(data['tempLow'])

        # End value of temperature range
        self.tempHigh = float(data['tempHigh'])

        # Description of new property.
        self.stepsPerVariable = int(data['stepsPerVariable'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PTRange')

        # Start value of pressure range
        print(f'Pressure low:\t{self.pressureLow}')

        # End value of pressure range
        print(f'Pressure high:\t{self.pressureHigh}')

        # Start value of temperature range
        print(f'Temp low:\t{self.tempLow}')

        # End value of temperature range
        print(f'Temp high:\t{self.tempHigh}')

        # Description of new property.
        print(f'Steps per variable:\t{self.stepsPerVariable}')


# Class: PipeBreach
# Description: Breach in a long pipe (runs GSPP / PBRK).
class PipeBreach(ReleaseOverTime):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Distance downstream
        self.distanceDownstream = 0.0

        # Breach relative aperture
        self.relativeAperture = 1.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        ReleaseOverTime.initialiseFromDictionary(self, data)

        # Distance downstream
        self.distanceDownstream = float(data['distanceDownstream'])

        # Breach relative aperture
        self.relativeAperture = float(data['relativeAperture'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PipeBreach')

        # Distance downstream
        print(f'Distance downstream:\t{self.distanceDownstream}')

        # Breach relative aperture
        print(f'Relative aperture:\t{self.relativeAperture}')


# Class: MixtureConstantPropertiesResult
class MixtureConstantPropertiesResult(object):

    # Constructor.
    def __init__(self):

        # Description of new property.
        self.lowerFlammabilityLimit = 0.0

        # Description of new property.
        self.upperFlammabilityLimit = 0.0

        # Critical pressure
        self.criticalPressure = 0.0

        # Critical temperature
        self.criticalTemperature = 0.0

        # Flammable or toxic flag
        self.flammableToxicFlag = FlammableToxic.INERT

        # Flash point
        self.flashPoint = 0.0

        # Heat of combustion
        self.heatCombustion = 0.0

        # Maximum burn rate
        self.maximumBurnRate = 0.0

        # Maximum surface emissive power
        self.maximumSEP = 0.0

        # Molecular weight
        self.molecularWeight = 0.0

        # Bubble point at atmospheric pressure
        self.bubblePoint = 0.0

        # Pool fire burn rate length
        self.poolFireBurnRateLength = 0.0

        # Luminous or smoky flame
        self.luminousSmokyFlame = LuminousSmokyFlame.GENERAL

        # Dew point at atmospheric pressure
        self.dewPoint = 0.0

        # Emissive power length scale
        self.emissivePowerLengthScale = 0.0

        # Laminar burning velocity of mixture
        self.laminarBurningVelocity = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Description of new property.
        self.lowerFlammabilityLimit = float(data['lowerFlammabilityLimit'])

        # Description of new property.
        self.upperFlammabilityLimit = float(data['upperFlammabilityLimit'])

        # Critical pressure
        self.criticalPressure = float(data['criticalPressure'])

        # Critical temperature
        self.criticalTemperature = float(data['criticalTemperature'])

        # Flammable or toxic flag
        self.flammableToxicFlag = FlammableToxic(data['flammableToxicFlag'])

        # Flash point
        self.flashPoint = float(data['flashPoint'])

        # Heat of combustion
        self.heatCombustion = float(data['heatCombustion'])

        # Maximum burn rate
        self.maximumBurnRate = float(data['maximumBurnRate'])

        # Maximum surface emissive power
        self.maximumSEP = float(data['maximumSEP'])

        # Molecular weight
        self.molecularWeight = float(data['molecularWeight'])

        # Bubble point at atmospheric pressure
        self.bubblePoint = float(data['bubblePoint'])

        # Pool fire burn rate length
        self.poolFireBurnRateLength = float(data['poolFireBurnRateLength'])

        # Luminous or smoky flame
        self.luminousSmokyFlame = LuminousSmokyFlame(data['luminousSmokyFlame'])

        # Dew point at atmospheric pressure
        self.dewPoint = float(data['dewPoint'])

        # Emissive power length scale
        self.emissivePowerLengthScale = float(data['emissivePowerLengthScale'])

        # Laminar burning velocity of mixture
        self.laminarBurningVelocity = float(data['laminarBurningVelocity'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* MixtureConstantPropertiesResult')

        # Description of new property.
        print(f'Lower flammability limit:\t{self.lowerFlammabilityLimit}')

        # Description of new property.
        print(f'Upper flammability limit:\t{self.upperFlammabilityLimit}')

        # Critical pressure
        print(f'Critical pressure:\t{self.criticalPressure}')

        # Critical temperature
        print(f'Critical temperature:\t{self.criticalTemperature}')

        # Flammable or toxic flag
        print('Flammable toxic flag\t{0}'.format(self.flammableToxicFlag))

        # Flash point
        print(f'Flash point:\t{self.flashPoint}')

        # Heat of combustion
        print(f'Heat combustion:\t{self.heatCombustion}')

        # Maximum burn rate
        print(f'Maximum burn rate:\t{self.maximumBurnRate}')

        # Maximum surface emissive power
        print(f'Maximum s e p:\t{self.maximumSEP}')

        # Molecular weight
        print(f'Molecular weight:\t{self.molecularWeight}')

        # Bubble point at atmospheric pressure
        print(f'Bubble point:\t{self.bubblePoint}')

        # Pool fire burn rate length
        print(f'Pool fire burn rate length:\t{self.poolFireBurnRateLength}')

        # Luminous or smoky flame
        print('Luminous smoky flame\t{0}'.format(self.luminousSmokyFlame))

        # Dew point at atmospheric pressure
        print(f'Dew point:\t{self.dewPoint}')

        # Emissive power length scale
        print(f'Emissive power length scale:\t{self.emissivePowerLengthScale}')

        # Laminar burning velocity of mixture
        print(f'Laminar burning velocity:\t{self.laminarBurningVelocity}')


# Class: FlareStack
# Description: Contains inputs required for running a flare stack calculation.
class FlareStack(Asset):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Material being flared
        self.flareStackMaterial = Material()

        # Fluid state in flare stack (driving the outflow)
        self.flareStackFluidState = State()

        # Flare stack tip height above ground level
        self.flareStackHeight = 0.0

        # Diameter of flare stack tip
        self.flareStackTipDiameter = 0.0

        # Phase of the stored material
        self.flareStackConditions = VesselConditions.PURE_GAS

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        Asset.initialiseFromDictionary(self, data)

        # Material being flared
        self.flareStackMaterial.initialiseFromDictionary(data['flareStackMaterial'])

        # Fluid state in flare stack (driving the outflow)
        self.flareStackFluidState.initialiseFromDictionary(data['flareStackFluidState'])

        # Flare stack tip height above ground level
        self.flareStackHeight = float(data['flareStackHeight'])

        # Diameter of flare stack tip
        self.flareStackTipDiameter = float(data['flareStackTipDiameter'])

        # Phase of the stored material
        self.flareStackConditions = VesselConditions(data['flareStackConditions'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlareStack')

        # Material being flared
        self.flareStackMaterial.print()

        # Fluid state in flare stack (driving the outflow)
        self.flareStackFluidState.print()

        # Flare stack tip height above ground level
        print(f'Flare stack height:\t{self.flareStackHeight}')

        # Diameter of flare stack tip
        print(f'Flare stack tip diameter:\t{self.flareStackTipDiameter}')

        # Phase of the stored material
        print('Flare stack conditions\t{0}'.format(self.flareStackConditions))


# Class: DispersionRecord
# Description: Observer dispersion record at a given time.
class DispersionRecord(object):

    # Constructor.
    def __init__(self):

        # Id of the observer associated with this record
        self.observerIndex = 0

        # Centreline concentraton (molar)
        self.centrelineConcentration = 0.0

        # Distance downwind
        self.downwindDistance = 0.0

        # Time after the start of the release
        self.time = 0.0

        # Uncorrected centreline concentraton (molar)
        self.centrelineConcentrationUncorrected = 0.0

        # Crosswind radius
        self.crosswindRadius = 0.0

        # Vertical radius
        self.verticalRadius = 0.0

        # Crosswind exponent
        self.crosswindExponent = 0.0

        # Vertical exponent
        self.verticalExponent = 0.0

        # Centreline angle from horizontal
        self.theta = 0.0

        # Centreline height
        self.centrelineHeight = 0.0

        # Liquid mass fraction
        self.liquidFraction = 0.0

        # Vapour temperature
        self.vapourTemperature = 0.0

        # Mass concentration
        self.massConc = 0.0

        # Velocity
        self.velocity = 0.0

        # Mass flow rate (non-instantaneous)
        self.massFlow = 0.0

        # Instantanous or continuous (time-varying not permitted)
        self.instCon = DynamicType.UNSET

        # Profile flag
        self.profileFlag = 0

        # Elevation flag
        self.elevFlag = 0

        # Cloud density
        self.rhoCloud = 0.0

        # Liquid temperature
        self.liqTemp = 0.0

        # Effective width
        self.effectiveWidth = 0.0

        # Effective height
        self.effectiveHeight = 0.0

        # Passive transition distance
        self.passTranDist = 0.0

        # Downwind radius
        self.downwindRadius = 0.0

        # Droplet diameter
        self.dropletDiameter = 0.0

        # Droplet height
        self.dropletHeight = 0.0

        # Droplet downwind distance
        self.dropletDistance = 0.0

        # Mass (instantaneous)
        self.mass = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Id of the observer associated with this record
        self.observerIndex = int(data['observerIndex'])

        # Centreline concentraton (molar)
        self.centrelineConcentration = float(data['centrelineConcentration'])

        # Distance downwind
        self.downwindDistance = float(data['downwindDistance'])

        # Time after the start of the release
        self.time = float(data['time'])

        # Uncorrected centreline concentraton (molar)
        self.centrelineConcentrationUncorrected = float(data['centrelineConcentrationUncorrected'])

        # Crosswind radius
        self.crosswindRadius = float(data['crosswindRadius'])

        # Vertical radius
        self.verticalRadius = float(data['verticalRadius'])

        # Crosswind exponent
        self.crosswindExponent = float(data['crosswindExponent'])

        # Vertical exponent
        self.verticalExponent = float(data['verticalExponent'])

        # Centreline angle from horizontal
        self.theta = float(data['theta'])

        # Centreline height
        self.centrelineHeight = float(data['centrelineHeight'])

        # Liquid mass fraction
        self.liquidFraction = float(data['liquidFraction'])

        # Vapour temperature
        self.vapourTemperature = float(data['vapourTemperature'])

        # Mass concentration
        self.massConc = float(data['massConc'])

        # Velocity
        self.velocity = float(data['velocity'])

        # Mass flow rate (non-instantaneous)
        self.massFlow = float(data['massFlow'])

        # Instantanous or continuous (time-varying not permitted)
        self.instCon = DynamicType(data['instCon'])

        # Profile flag
        self.profileFlag = int(data['profileFlag'])

        # Elevation flag
        self.elevFlag = int(data['elevFlag'])

        # Cloud density
        self.rhoCloud = float(data['rhoCloud'])

        # Liquid temperature
        self.liqTemp = float(data['liqTemp'])

        # Effective width
        self.effectiveWidth = float(data['effectiveWidth'])

        # Effective height
        self.effectiveHeight = float(data['effectiveHeight'])

        # Passive transition distance
        self.passTranDist = float(data['passTranDist'])

        # Downwind radius
        self.downwindRadius = float(data['downwindRadius'])

        # Droplet diameter
        self.dropletDiameter = float(data['dropletDiameter'])

        # Droplet height
        self.dropletHeight = float(data['dropletHeight'])

        # Droplet downwind distance
        self.dropletDistance = float(data['dropletDistance'])

        # Mass (instantaneous)
        self.mass = float(data['mass'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DispersionRecord')

        # Id of the observer associated with this record
        print(f'Observer index:\t{self.observerIndex}')

        # Centreline concentraton (molar)
        print(f'Centreline concentration:\t{self.centrelineConcentration}')

        # Distance downwind
        print(f'Downwind distance:\t{self.downwindDistance}')

        # Time after the start of the release
        print(f'Time:\t{self.time}')

        # Uncorrected centreline concentraton (molar)
        print(f'Centreline concentration uncorrected:\t{self.centrelineConcentrationUncorrected}')

        # Crosswind radius
        print(f'Crosswind radius:\t{self.crosswindRadius}')

        # Vertical radius
        print(f'Vertical radius:\t{self.verticalRadius}')

        # Crosswind exponent
        print(f'Crosswind exponent:\t{self.crosswindExponent}')

        # Vertical exponent
        print(f'Vertical exponent:\t{self.verticalExponent}')

        # Centreline angle from horizontal
        print(f'Theta:\t{self.theta}')

        # Centreline height
        print(f'Centreline height:\t{self.centrelineHeight}')

        # Liquid mass fraction
        print(f'Liquid fraction:\t{self.liquidFraction}')

        # Vapour temperature
        print(f'Vapour temperature:\t{self.vapourTemperature}')

        # Mass concentration
        print(f'Mass conc:\t{self.massConc}')

        # Velocity
        print(f'Velocity:\t{self.velocity}')

        # Mass flow rate (non-instantaneous)
        print(f'Mass flow:\t{self.massFlow}')

        # Instantanous or continuous (time-varying not permitted)
        print('Inst con\t{0}'.format(self.instCon))

        # Profile flag
        print(f'Profile flag:\t{self.profileFlag}')

        # Elevation flag
        print(f'Elev flag:\t{self.elevFlag}')

        # Cloud density
        print(f'Rho cloud:\t{self.rhoCloud}')

        # Liquid temperature
        print(f'Liq temp:\t{self.liqTemp}')

        # Effective width
        print(f'Effective width:\t{self.effectiveWidth}')

        # Effective height
        print(f'Effective height:\t{self.effectiveHeight}')

        # Passive transition distance
        print(f'Pass tran dist:\t{self.passTranDist}')

        # Downwind radius
        print(f'Downwind radius:\t{self.downwindRadius}')

        # Droplet diameter
        print(f'Droplet diameter:\t{self.dropletDiameter}')

        # Droplet height
        print(f'Droplet height:\t{self.dropletHeight}')

        # Droplet downwind distance
        print(f'Droplet distance:\t{self.dropletDistance}')

        # Mass (instantaneous)
        print(f'Mass:\t{self.mass}')


# Class: ThermoPathRecord
# Description: Contains a point on the thermodynamic depressurization trajectory for each of isothermal, isentropic and isenthalpic assumptions.
class ThermoPathRecord(object):

    # Constructor.
    def __init__(self):

        # Absolute pressure value at specific point on the thermodynamic path
        self.pressure = 0.0

        # Bubble point temperature at given pressure
        self.bubbleTemperature = 0.0

        # Dew point temperature at given pressure
        self.dewTemperature = 0.0

        # Temperature at given pressure following isentropic depressurization
        self.isentropicTemperature = 0.0

        # Temperature at given pressure following isenthalpic depressurization
        self.isenthalpicTemperature = 0.0

        # Temperature at given pressure following isothermal depressurization
        self.isothermalTemperature = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Absolute pressure value at specific point on the thermodynamic path
        self.pressure = float(data['pressure'])

        # Bubble point temperature at given pressure
        self.bubbleTemperature = float(data['bubbleTemperature'])

        # Dew point temperature at given pressure
        self.dewTemperature = float(data['dewTemperature'])

        # Temperature at given pressure following isentropic depressurization
        self.isentropicTemperature = float(data['isentropicTemperature'])

        # Temperature at given pressure following isenthalpic depressurization
        self.isenthalpicTemperature = float(data['isenthalpicTemperature'])

        # Temperature at given pressure following isothermal depressurization
        self.isothermalTemperature = float(data['isothermalTemperature'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ThermoPathRecord')

        # Absolute pressure value at specific point on the thermodynamic path
        print(f'Pressure:\t{self.pressure}')

        # Bubble point temperature at given pressure
        print(f'Bubble temperature:\t{self.bubbleTemperature}')

        # Dew point temperature at given pressure
        print(f'Dew temperature:\t{self.dewTemperature}')

        # Temperature at given pressure following isentropic depressurization
        print(f'Isentropic temperature:\t{self.isentropicTemperature}')

        # Temperature at given pressure following isenthalpic depressurization
        print(f'Isenthalpic temperature:\t{self.isenthalpicTemperature}')

        # Temperature at given pressure following isothermal depressurization
        print(f'Isothermal temperature:\t{self.isothermalTemperature}')


# Class: DispersionParameters
# Description: Dispersion Parameters.
class DispersionParameters(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Relative tolerance
        self.relativeTolerance = 0.001

        # Rainout and equilibrium method
        self.rainoutThermoFlag = RainoutThermoFlag.RAINOUT_NON_EQUILIBRIUM

        # Fixed step size
        self.fixedStepSize = 0.01

        # Ratio to increase step size
        self.outputStepMultiplier = 1.2

        # Absolute maximum distance for dispersion calculations
        self.maxDispersionDistance = 50000.0

        # Absolute maximum height for dispersion calculations
        self.maxDispersionHeight = 1000.0

        # Number of release observers for time-varying releases
        self.numberOfReleaseObservers = 5

        # Number of pool observers for rainout cases
        self.numberOfPoolObservers = 10

        # Core averaging time
        self.averagingTime = 18.75

        # The lowest LFL fraction of interest
        self.lflFractionToStop = 0.5

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Relative tolerance
        self.relativeTolerance = float(data['relativeTolerance'])

        # Rainout and equilibrium method
        self.rainoutThermoFlag = RainoutThermoFlag(data['rainoutThermoFlag'])

        # Fixed step size
        self.fixedStepSize = float(data['fixedStepSize'])

        # Ratio to increase step size
        self.outputStepMultiplier = float(data['outputStepMultiplier'])

        # Absolute maximum distance for dispersion calculations
        self.maxDispersionDistance = float(data['maxDispersionDistance'])

        # Absolute maximum height for dispersion calculations
        self.maxDispersionHeight = float(data['maxDispersionHeight'])

        # Number of release observers for time-varying releases
        self.numberOfReleaseObservers = int(data['numberOfReleaseObservers'])

        # Number of pool observers for rainout cases
        self.numberOfPoolObservers = int(data['numberOfPoolObservers'])

        # Core averaging time
        self.averagingTime = float(data['averagingTime'])

        # The lowest LFL fraction of interest
        self.lflFractionToStop = float(data['lflFractionToStop'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DispersionParameters')

        # Relative tolerance
        print(f'Relative tolerance:\t{self.relativeTolerance}')

        # Rainout and equilibrium method
        print('Rainout thermo flag\t{0}'.format(self.rainoutThermoFlag))

        # Fixed step size
        print(f'Fixed step size:\t{self.fixedStepSize}')

        # Ratio to increase step size
        print(f'Output step multiplier:\t{self.outputStepMultiplier}')

        # Absolute maximum distance for dispersion calculations
        print(f'Max dispersion distance:\t{self.maxDispersionDistance}')

        # Absolute maximum height for dispersion calculations
        print(f'Max dispersion height:\t{self.maxDispersionHeight}')

        # Number of release observers for time-varying releases
        print(f'Number of release observers:\t{self.numberOfReleaseObservers}')

        # Number of pool observers for rainout cases
        print(f'Number of pool observers:\t{self.numberOfPoolObservers}')

        # Core averaging time
        print(f'Averaging time:\t{self.averagingTime}')

        # The lowest LFL fraction of interest
        print(f'LFL fraction to stop:\t{self.lflFractionToStop}')


# Class: ExplosionConfinedVolume
# Description: Confined explosion volume data
class ExplosionConfinedVolume(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Explosion strength of confined volume
        self.confinedStrength = 0.0

        # Explosion volume of confined source
        self.confinedVolume = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Explosion strength of confined volume
        self.confinedStrength = float(data['confinedStrength'])

        # Explosion volume of confined source
        self.confinedVolume = float(data['confinedVolume'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ExplosionConfinedVolume')

        # Explosion strength of confined volume
        print(f'Confined strength:\t{self.confinedStrength}')

        # Explosion volume of confined source
        print(f'Confined volume:\t{self.confinedVolume}')


# Class: ConstantMaterialResult
# Description: Constant material properties, i.e. critical pressure, temperature, mole weight
class ConstantMaterialResult(object):

    # Constructor.
    def __init__(self):

        # The critical pressure of the material
        self.criticalPressure = 0.0

        # The critical temperature of the material
        self.criticalTemperature = 0.0

        # The total molecular weight of the material
        self.totalMolecularWeight = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # The critical pressure of the material
        self.criticalPressure = float(data['criticalPressure'])

        # The critical temperature of the material
        self.criticalTemperature = float(data['criticalTemperature'])

        # The total molecular weight of the material
        self.totalMolecularWeight = float(data['totalMolecularWeight'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ConstantMaterialResult')

        # The critical pressure of the material
        print(f'Critical pressure:\t{self.criticalPressure}')

        # The critical temperature of the material
        print(f'Critical temperature:\t{self.criticalTemperature}')

        # The total molecular weight of the material
        print(f'Total molecular weight:\t{self.totalMolecularWeight}')


# Class: FlameRecord
# Description: Flame geometry description
class FlameRecord(object):

    # Constructor.
    def __init__(self):

        # Distance downwind
        self.xCoordinate = 0.0

        # Height above ground
        self.zCoordinate = 0.0

        # Flame radius
        self.rCoordinate = 0.0

        # Inclination from vertical
        self.phiCoordinate = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Distance downwind
        self.xCoordinate = float(data['xCoordinate'])

        # Height above ground
        self.zCoordinate = float(data['zCoordinate'])

        # Flame radius
        self.rCoordinate = float(data['rCoordinate'])

        # Inclination from vertical
        self.phiCoordinate = float(data['phiCoordinate'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* FlameRecord')

        # Distance downwind
        print(f'X coordinate:\t{self.xCoordinate}')

        # Height above ground
        print(f'Z coordinate:\t{self.zCoordinate}')

        # Flame radius
        print(f'R coordinate:\t{self.rCoordinate}')

        # Inclination from vertical
        print(f'Phi coordinate:\t{self.phiCoordinate}')


# Class: DispersionOutputConfig
# Description: Dispersion plotting and reporting control parameters.
class DispersionOutputConfig(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Downwind distance
        self.downwindDistance = 100.0

        # Time since start of the release
        self.time = 60.0

        # Output resolution of results and gird
        self.resolution = Resolution.HIGH

        # Height of interest above ground level
        self.elevation = 1.0

        # Pre-defined concentration
        self.specialConcentration = SpecialConcentration.MIN

        # Concentration (vol fraction). Not used unless SpecialConcentration is undefined
        self.concentration = 0.0

        # Crosswind distance
        self.crosswindDistance = 0.0

        # List of view types
        self.contourType = ContourType.FOOTPRINT

        # Value of the lower flammable limit fraction
        self.lflFractionValue = 0.5

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Downwind distance
        self.downwindDistance = float(data['downwindDistance'])

        # Time since start of the release
        self.time = float(data['time'])

        # Output resolution of results and gird
        self.resolution = Resolution(data['resolution'])

        # Height of interest above ground level
        self.elevation = float(data['elevation'])

        # Pre-defined concentration
        self.specialConcentration = SpecialConcentration(data['specialConcentration'])

        # Concentration (vol fraction). Not used unless SpecialConcentration is undefined
        self.concentration = float(data['concentration'])

        # Crosswind distance
        self.crosswindDistance = float(data['crosswindDistance'])

        # List of view types
        self.contourType = ContourType(data['contourType'])

        # Value of the lower flammable limit fraction
        self.lflFractionValue = float(data['lflFractionValue'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DispersionOutputConfig')

        # Downwind distance
        print(f'Downwind distance:\t{self.downwindDistance}')

        # Time since start of the release
        print(f'Time:\t{self.time}')

        # Output resolution of results and gird
        print('Resolution\t{0}'.format(self.resolution))

        # Height of interest above ground level
        print(f'Elevation:\t{self.elevation}')

        # Pre-defined concentration
        print('Special concentration\t{0}'.format(self.specialConcentration))

        # Concentration (vol fraction). Not used unless SpecialConcentration is undefined
        print(f'Concentration:\t{self.concentration}')

        # Crosswind distance
        print(f'Crosswind distance:\t{self.crosswindDistance}')

        # List of view types
        print('Contour type\t{0}'.format(self.contourType))

        # Value of the lower flammable limit fraction
        print(f'LFL fraction value:\t{self.lflFractionValue}')


# Class: PropertiesDipprPT2
class PropertiesDipprPT2(object):

    # Constructor.
    def __init__(self):

        # Ignotion category
        self.ignitionCategory = []

        # Laminar burn velocity
        self.lamBurnVelocity = []

        # Saturated liquid density
        self.rhoLiqSat = []

        # Vapour pressure
        self.pVap = []

        # Ideal gas heat capacity
        self.cpIdeal = []

        # Liquid heat capacity
        self.cpLiq = []

        # Ratio of specific heat capacities
        self.cpRatio = []

        # Second virial coefficient
        self.virial2 = []

        # Vapour viscosity
        self.muVap = []

        # Liquid viscosity
        self.muLiq = []

        # Vapour thermal conductivity
        self.kVap = []

        # Liquid thermal conductivity
        self.kLiq = []

        # Heat of vaporisation
        self.heatVap = []

        # Ideal gas enthalpy
        self.hVapIdeal = []

        # Saturated liquid enthalpy
        self.hLiqSat = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Ignotion category
        for dataItem in data['ignitionCategory']:
            self.ignitionCategory.append(float(dataItem))

        # Laminar burn velocity
        for dataItem in data['lamBurnVelocity']:
            self.lamBurnVelocity.append(float(dataItem))

        # Saturated liquid density
        for dataItem in data['rhoLiqSat']:
            self.rhoLiqSat.append(float(dataItem))

        # Vapour pressure
        for dataItem in data['pVap']:
            self.pVap.append(float(dataItem))

        # Ideal gas heat capacity
        for dataItem in data['cpIdeal']:
            self.cpIdeal.append(float(dataItem))

        # Liquid heat capacity
        for dataItem in data['cpLiq']:
            self.cpLiq.append(float(dataItem))

        # Ratio of specific heat capacities
        for dataItem in data['cpRatio']:
            self.cpRatio.append(float(dataItem))

        # Second virial coefficient
        for dataItem in data['virial2']:
            self.virial2.append(float(dataItem))

        # Vapour viscosity
        for dataItem in data['muVap']:
            self.muVap.append(float(dataItem))

        # Liquid viscosity
        for dataItem in data['muLiq']:
            self.muLiq.append(float(dataItem))

        # Vapour thermal conductivity
        for dataItem in data['kVap']:
            self.kVap.append(float(dataItem))

        # Liquid thermal conductivity
        for dataItem in data['kLiq']:
            self.kLiq.append(float(dataItem))

        # Heat of vaporisation
        for dataItem in data['heatVap']:
            self.heatVap.append(float(dataItem))

        # Ideal gas enthalpy
        for dataItem in data['hVapIdeal']:
            self.hVapIdeal.append(float(dataItem))

        # Saturated liquid enthalpy
        for dataItem in data['hLiqSat']:
            self.hLiqSat.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDipprPT2')

        # Ignotion category
        for item in self.ignitionCategory:
            print(f'{item}')

        # Laminar burn velocity
        for item in self.lamBurnVelocity:
            print(f'{item}')

        # Saturated liquid density
        for item in self.rhoLiqSat:
            print(f'{item}')

        # Vapour pressure
        for item in self.pVap:
            print(f'{item}')

        # Ideal gas heat capacity
        for item in self.cpIdeal:
            print(f'{item}')

        # Liquid heat capacity
        for item in self.cpLiq:
            print(f'{item}')

        # Ratio of specific heat capacities
        for item in self.cpRatio:
            print(f'{item}')

        # Second virial coefficient
        for item in self.virial2:
            print(f'{item}')

        # Vapour viscosity
        for item in self.muVap:
            print(f'{item}')

        # Liquid viscosity
        for item in self.muLiq:
            print(f'{item}')

        # Vapour thermal conductivity
        for item in self.kVap:
            print(f'{item}')

        # Liquid thermal conductivity
        for item in self.kLiq:
            print(f'{item}')

        # Heat of vaporisation
        for item in self.heatVap:
            print(f'{item}')

        # Ideal gas enthalpy
        for item in self.hVapIdeal:
            print(f'{item}')

        # Saturated liquid enthalpy
        for item in self.hLiqSat:
            print(f'{item}')


# Class: PoolVapourisationParameters
# Description: Pool vapourisation parameters
class PoolVapourisationParameters(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Cutoff rate for toxic materials
        self.toxicsCutoffRate = 0.001

        # Cutoff rate for flammable materials
        self.flammableCutoffRate = 0.1

        # Relative tolerance
        self.relativeTolerance = 0.001

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Cutoff rate for toxic materials
        self.toxicsCutoffRate = float(data['toxicsCutoffRate'])

        # Cutoff rate for flammable materials
        self.flammableCutoffRate = float(data['flammableCutoffRate'])

        # Relative tolerance
        self.relativeTolerance = float(data['relativeTolerance'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PoolVapourisationParameters')

        # Cutoff rate for toxic materials
        print(f'Toxics cutoff rate:\t{self.toxicsCutoffRate}')

        # Cutoff rate for flammable materials
        print(f'Flammable cutoff rate:\t{self.flammableCutoffRate}')

        # Relative tolerance
        print(f'Relative tolerance:\t{self.relativeTolerance}')


# Class: PoolRecord
# Description: Pool results at a given time
class PoolRecord(object):

    # Constructor.
    def __init__(self):

        # Time since rainout
        self.time = 0.0

        # Mass spilled
        self.massSpilt = 0.0

        # Mass vaporised
        self.massVaporised = 0.0

        # Mass dissolved
        self.massDissolved = 0.0

        # Mass remaining
        self.massRemaining = 0.0

        # Vapourisation rate
        self.vapourisationRate = 0.0

        # Solution rate
        self.solutionRate = 0.0

        # Effective radius
        self.effectiveRadius = 0.0

        # Pool depth
        self.depth = 0.0

        # Pool temperature
        self.temperature = 0.0

        # Spill rate
        self.spillRate = 0.0

        # Actual pool radius
        self.actualRadius = 0.0

        # Pool centre
        self.poolCentre = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Time since rainout
        self.time = float(data['time'])

        # Mass spilled
        self.massSpilt = float(data['massSpilt'])

        # Mass vaporised
        self.massVaporised = float(data['massVaporised'])

        # Mass dissolved
        self.massDissolved = float(data['massDissolved'])

        # Mass remaining
        self.massRemaining = float(data['massRemaining'])

        # Vapourisation rate
        self.vapourisationRate = float(data['vapourisationRate'])

        # Solution rate
        self.solutionRate = float(data['solutionRate'])

        # Effective radius
        self.effectiveRadius = float(data['effectiveRadius'])

        # Pool depth
        self.depth = float(data['depth'])

        # Pool temperature
        self.temperature = float(data['temperature'])

        # Spill rate
        self.spillRate = float(data['spillRate'])

        # Actual pool radius
        self.actualRadius = float(data['actualRadius'])

        # Pool centre
        self.poolCentre = float(data['poolCentre'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PoolRecord')

        # Time since rainout
        print(f'Time:\t{self.time}')

        # Mass spilled
        print(f'Mass spilt:\t{self.massSpilt}')

        # Mass vaporised
        print(f'Mass vaporised:\t{self.massVaporised}')

        # Mass dissolved
        print(f'Mass dissolved:\t{self.massDissolved}')

        # Mass remaining
        print(f'Mass remaining:\t{self.massRemaining}')

        # Vapourisation rate
        print(f'Vapourisation rate:\t{self.vapourisationRate}')

        # Solution rate
        print(f'Solution rate:\t{self.solutionRate}')

        # Effective radius
        print(f'Effective radius:\t{self.effectiveRadius}')

        # Pool depth
        print(f'Depth:\t{self.depth}')

        # Pool temperature
        print(f'Temperature:\t{self.temperature}')

        # Spill rate
        print(f'Spill rate:\t{self.spillRate}')

        # Actual pool radius
        print(f'Actual radius:\t{self.actualRadius}')

        # Pool centre
        print(f'Pool centre:\t{self.poolCentre}')


# Class: ExplosionOverpressureResult
# Description: Worst case explosion summary results for a given overpressure.
class ExplosionOverpressureResult(object):

    # Constructor.
    def __init__(self):

        # Overpressure for this result
        self.overpressure = 0.0

        # Centre of the explosion (distance downwind)
        self.explosionCentre = 0.0

        # Maximum distance to overpressure (downwind edge)
        self.maximumDistance = 0.0

        # Flammable mass used in the explosion
        self.explodedMass = 0.0

        # Time of ignition
        self.ignitionTime = 0.0

        # Radius of the explosion at the explosion centre
        self.radius = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Overpressure for this result
        self.overpressure = float(data['overpressure'])

        # Centre of the explosion (distance downwind)
        self.explosionCentre = float(data['explosionCentre'])

        # Maximum distance to overpressure (downwind edge)
        self.maximumDistance = float(data['maximumDistance'])

        # Flammable mass used in the explosion
        self.explodedMass = float(data['explodedMass'])

        # Time of ignition
        self.ignitionTime = float(data['ignitionTime'])

        # Radius of the explosion at the explosion centre
        self.radius = float(data['radius'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ExplosionOverpressureResult')

        # Overpressure for this result
        print(f'Overpressure:\t{self.overpressure}')

        # Centre of the explosion (distance downwind)
        print(f'Explosion centre:\t{self.explosionCentre}')

        # Maximum distance to overpressure (downwind edge)
        print(f'Maximum distance:\t{self.maximumDistance}')

        # Flammable mass used in the explosion
        print(f'Exploded mass:\t{self.explodedMass}')

        # Time of ignition
        print(f'Ignition time:\t{self.ignitionTime}')

        # Radius of the explosion at the explosion centre
        print(f'Radius:\t{self.radius}')


# Class: VesselLeakMaxFlammableCloudResults
# Description: Results for a linked run of vessel leak followed by dispersion and views from the cloud
class VesselLeakMaxFlammableCloudResults(object):

    # Constructor.
    def __init__(self):

        # Leak discharge mass rate
        self.dischargeRate = 0.0

        # Post atmospheric expansion temperature
        self.expandedTemperature = 0.0

        # Post atmospheric expansion fluid phase
        self.phase = Phase.UNSET

        # Maximum downwind distance to LFL
        self.lflExtent = 0.0

        # Horizontal area within LFL envelope
        self.lflArea = 0.0

        # Height of maximum LFL extent
        self.lflHeight = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Leak discharge mass rate
        self.dischargeRate = float(data['dischargeRate'])

        # Post atmospheric expansion temperature
        self.expandedTemperature = float(data['expandedTemperature'])

        # Post atmospheric expansion fluid phase
        self.phase = Phase(data['phase'])

        # Maximum downwind distance to LFL
        self.lflExtent = float(data['lflExtent'])

        # Horizontal area within LFL envelope
        self.lflArea = float(data['lflArea'])

        # Height of maximum LFL extent
        self.lflHeight = float(data['lflHeight'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* VesselLeakMaxFlammableCloudResults')

        # Leak discharge mass rate
        print(f'Discharge rate:\t{self.dischargeRate}')

        # Post atmospheric expansion temperature
        print(f'Expanded temperature:\t{self.expandedTemperature}')

        # Post atmospheric expansion fluid phase
        print('Phase\t{0}'.format(self.phase))

        # Maximum downwind distance to LFL
        print(f'LFL extent:\t{self.lflExtent}')

        # Horizontal area within LFL envelope
        print(f'LFL area:\t{self.lflArea}')

        # Height of maximum LFL extent
        print(f'LFL height:\t{self.lflHeight}')


# Class: DischargeRecord
# Description: Discharge results at a given time.
class DischargeRecord(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Time
        self.time = 0.0

        # Mass flow rate (continuous and time-varying)
        self.massFlow = 0.0

        # Final fluid state
        self.finalState = State()

        # Final velocity
        self.finalVelocity = 0.0

        # Orifice fluid state
        self.orificeState = State()

        # Orifice velocity
        self.orificeVelocity = 0.0

        # Storage fluid state
        self.storageState = State()

        # Representative droplet size
        self.dropletDiameter = 0.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Time
        self.time = float(data['time'])

        # Mass flow rate (continuous and time-varying)
        self.massFlow = float(data['massFlow'])

        # Final fluid state
        self.finalState.initialiseFromDictionary(data['finalState'])

        # Final velocity
        self.finalVelocity = float(data['finalVelocity'])

        # Orifice fluid state
        self.orificeState.initialiseFromDictionary(data['orificeState'])

        # Orifice velocity
        self.orificeVelocity = float(data['orificeVelocity'])

        # Storage fluid state
        self.storageState.initialiseFromDictionary(data['storageState'])

        # Representative droplet size
        self.dropletDiameter = float(data['dropletDiameter'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DischargeRecord')

        # Time
        print(f'Time:\t{self.time}')

        # Mass flow rate (continuous and time-varying)
        print(f'Mass flow:\t{self.massFlow}')

        # Final fluid state
        self.finalState.print()

        # Final velocity
        print(f'Final velocity:\t{self.finalVelocity}')

        # Orifice fluid state
        self.orificeState.print()

        # Orifice velocity
        print(f'Orifice velocity:\t{self.orificeVelocity}')

        # Storage fluid state
        self.storageState.print()

        # Representative droplet size
        print(f'Droplet diameter:\t{self.dropletDiameter}')


# Class: ExplosionParameters
# Description: Explosion parameters
class ExplosionParameters(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Explosion strength for uniform unconfined (Multi-energy method)
        self.explosionUniformStrength = 10.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Explosion strength for uniform unconfined (Multi-energy method)
        self.explosionUniformStrength = float(data['explosionUniformStrength'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* ExplosionParameters')

        # Explosion strength for uniform unconfined (Multi-energy method)
        print(f'Explosion uniform strength:\t{self.explosionUniformStrength}')


# Class: PropertiesDnvPT1
class PropertiesDnvPT1(object):

    # Constructor.
    def __init__(self):

        # Total PT steps
        self.totalStepsUsed = 0

        # Pressure
        self.pressure = []

        # Temperature
        self.temperature = []

        # Composition
        self.massComp = []

        #  Flammable/toxic flag
        self.flamTox = []

        # Luminous smoky flame flag
        self.lumSmoky = []

        # Maximum surface emissive power
        self.sepMax = []

        # Emissive power length scale
        self.sepLength = []

        # Pool fire burn rate length
        self.poolFireBurnRate = []

        # Maximum burn rate
        self.burnRateMax = []

        # TNT explosion efficiency
        self.tntEfficiency = []

        # ERPG1 concentration
        self.eRPG1 = []

        # ERPG2 concentration
        self.eRPG2 = []

        # ERPG3 concentration
        self.eRPG3 = []

        # IDLH concentration
        self.iDLH = []

        # STEL concentration
        self.sTEL = []

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Total PT steps
        self.totalStepsUsed = int(data['totalStepsUsed'])

        # Pressure
        for dataItem in data['pressure']:
            self.pressure.append(float(dataItem))

        # Temperature
        for dataItem in data['temperature']:
            self.temperature.append(float(dataItem))

        # Composition
        for dataItem in data['massComp']:
            self.massComp.append(float(dataItem))

        #  Flammable/toxic flag
        for dataItem in data['flamTox']:
            self.flamTox.append(float(dataItem))

        # Luminous smoky flame flag
        for dataItem in data['lumSmoky']:
            self.lumSmoky.append(float(dataItem))

        # Maximum surface emissive power
        for dataItem in data['sepMax']:
            self.sepMax.append(float(dataItem))

        # Emissive power length scale
        for dataItem in data['sepLength']:
            self.sepLength.append(float(dataItem))

        # Pool fire burn rate length
        for dataItem in data['poolFireBurnRate']:
            self.poolFireBurnRate.append(float(dataItem))

        # Maximum burn rate
        for dataItem in data['burnRateMax']:
            self.burnRateMax.append(float(dataItem))

        # TNT explosion efficiency
        for dataItem in data['tntEfficiency']:
            self.tntEfficiency.append(float(dataItem))

        # ERPG1 concentration
        for dataItem in data['eRPG1']:
            self.eRPG1.append(float(dataItem))

        # ERPG2 concentration
        for dataItem in data['eRPG2']:
            self.eRPG2.append(float(dataItem))

        # ERPG3 concentration
        for dataItem in data['eRPG3']:
            self.eRPG3.append(float(dataItem))

        # IDLH concentration
        for dataItem in data['iDLH']:
            self.iDLH.append(float(dataItem))

        # STEL concentration
        for dataItem in data['sTEL']:
            self.sTEL.append(float(dataItem))

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* PropertiesDnvPT1')

        # Total PT steps
        print(f'Total steps used:\t{self.totalStepsUsed}')

        # Pressure
        for item in self.pressure:
            print(f'{item}')

        # Temperature
        for item in self.temperature:
            print(f'{item}')

        # Composition
        for item in self.massComp:
            print(f'{item}')

        #  Flammable/toxic flag
        for item in self.flamTox:
            print(f'{item}')

        # Luminous smoky flame flag
        for item in self.lumSmoky:
            print(f'{item}')

        # Maximum surface emissive power
        for item in self.sepMax:
            print(f'{item}')

        # Emissive power length scale
        for item in self.sepLength:
            print(f'{item}')

        # Pool fire burn rate length
        for item in self.poolFireBurnRate:
            print(f'{item}')

        # Maximum burn rate
        for item in self.burnRateMax:
            print(f'{item}')

        # TNT explosion efficiency
        for item in self.tntEfficiency:
            print(f'{item}')

        # ERPG1 concentration
        for item in self.eRPG1:
            print(f'{item}')

        # ERPG2 concentration
        for item in self.eRPG2:
            print(f'{item}')

        # ERPG3 concentration
        for item in self.eRPG3:
            print(f'{item}')

        # IDLH concentration
        for item in self.iDLH:
            print(f'{item}')

        # STEL concentration
        for item in self.sTEL:
            print(f'{item}')


# Class: WeatherStationData
# Description: Compiled data from weather live service
class WeatherStationData(object):

    # Constructor.
    def __init__(self):

        # Latitude measured in degrees
        self.latitude = 0.0

        # Longitude coordinate in degrees
        self.longitude = 0.0

        # Indicates if it is day or night
        self.dayNightOption = DayNight.UNSET

        # Cloud coverage in percentage
        self.cloudiness = 0.0

        # Wind speed at reference height
        self.windSpeed = 0.0

        # Ambient temperature
        self.temperature = 0.0

        # Relative humidity
        self.relativeHumidity = 0.0

        # Solar radiation flux
        self.solarRadiation = 500.0

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Latitude measured in degrees
        self.latitude = float(data['latitude'])

        # Longitude coordinate in degrees
        self.longitude = float(data['longitude'])

        # Indicates if it is day or night
        self.dayNightOption = DayNight(data['dayNightOption'])

        # Cloud coverage in percentage
        self.cloudiness = float(data['cloudiness'])

        # Wind speed at reference height
        self.windSpeed = float(data['windSpeed'])

        # Ambient temperature
        self.temperature = float(data['temperature'])

        # Relative humidity
        self.relativeHumidity = float(data['relativeHumidity'])

        # Solar radiation flux
        self.solarRadiation = float(data['solarRadiation'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* WeatherStationData')

        # Latitude measured in degrees
        print(f'Latitude:\t{self.latitude}')

        # Longitude coordinate in degrees
        print(f'Longitude:\t{self.longitude}')

        # Indicates if it is day or night
        print('Day night option\t{0}'.format(self.dayNightOption))

        # Cloud coverage in percentage
        print(f'Cloudiness:\t{self.cloudiness}')

        # Wind speed at reference height
        print(f'Wind speed:\t{self.windSpeed}')

        # Ambient temperature
        print(f'Temperature:\t{self.temperature}')

        # Relative humidity
        print(f'Relative humidity:\t{self.relativeHumidity}')

        # Solar radiation flux
        print(f'Solar radiation:\t{self.solarRadiation}')


# Class: DischargeParameters
# Description: Discharge parameters.
class DischargeParameters(EntityBase):

    # Constructor.
    def __init__(self):
        super().__init__()

        # Flashing at orifice
        self.flashAtOrifice = FlashAtOrifice.DISALLOW_LIQUID_FLASH

    # Initialise entity with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Call the base class initialiseFromDictionary method
        EntityBase.initialiseFromDictionary(self, data)

        # Flashing at orifice
        self.flashAtOrifice = FlashAtOrifice(data['flashAtOrifice'])

    # Print out the entity's properties.
    def print(self):

        # Print out the entity name.
        print('* DischargeParameters')

        # Flashing at orifice
        print('Flash at orifice\t{0}'.format(self.flashAtOrifice))


