22. Februar 2022

Modellierung von veränderlichen Ressourcenbedarfen

In der Prozessindustrie ist es nicht ungewöhnlich, dass sich der Bedarf an Ressourcen über eine Prozessoperation ändert. Typische Beispiele hierfür sind Kühlmäntel von Reaktoren, in denen sich der Kühlmittelbedarf über die Reaktionsdauer ändert. Da es sich bei INOSIM um eine ereignis-diskrete Simulationssoftware handelt, kann der Ressourcenbedarf nur zu bestimmten Ereignissen geändert werden. Zeitlich veränderliche Ressourcenbedarfe können über zusätzliche Ereignisse modelliert werden. Im Folgenden werden zwei Methoden vorgestellt, um veränderliche Ressourcenmengen zu modellieren:

Erste Option: Operation teilen

Um zusätzliche Ereignisse zu schaffen, wird bei dieser Methode eine Operation in mehrere Operationen aufgeteilt. Mit jeder zusätzlichen Operation wird ein neues Parametrisierungsereignis erschaffen, an denen der Ressourcenbedarf geändert werden kann. In einem Beispiel fällt der Bedarf an Kühlmittel über die Reaktionszeit. Dazu wird die Reaktion in vier Schritte aufgeteilt:

In der ersten Reaktionsoperation wird eine Parametersteuerung verwendet, um die Dauer der einzelnen Reaktionsoperationen und die benötigte Menge der Ressource zu setzen. Dabei kann dann zum Beispiel eine Funktion genutzt werden, die den Ressourcenbedarf in jedem Schritt bestimmt. In diesem Beispiel wird eine Exponentialfunktion verwendet, um den Kühlmittelstrom im Kühlmantel über die Zeit zu beschreiben. Damit die Ressource nicht nach jeder Reaktionsoperation wieder freigegeben wird, wird die Ressource dauerhaft belegt. Am Anfang der ersten Reaktionsoperation wird der benötigte Startwert des benötigten Kühlmittels als Ressource dauerhaft zugeordnet. Am Ende jeder Reaktionsoperation wird die Differenz zwischen dem Funktionswert und dem Ressourcenbedarf aus dem vorherigen Schritt wieder freigegeben. Die Parametersteuerung zu dem beschriebenen Vorgehen sieht so aus (bitte beachten Sie: in allen Codebeispielen dieses Artikels wird WWB.NET verwendet):

Sub Cooling_exponential_SplitOperations(cop As OrderOperation, mop As RecipeOperation)
    
    'f(x)=0.9^(x-25), with x in [h]

    Dim n_op As Integer
    Dim res As New OrderResource
    Dim res_start As New OrderResource
    Dim start As Double
    Dim i As Integer
    Dim op As OrderOperation

    n_op=4 'number of operations

    For i=1 To n_op
        op=cop.OrderProcedure.OrderOperations("Reaction" & i)
        op.Duration=t_reac(cop.Order.Material.Name, "ReactionDuration")*3600/n_op   
            'set the duration for every single operation
            'durations are saved in parameter sheet
        res=New OrderResource

        If i=1 Then
            start=0.9^(0-25) 
                'at the beginning of the first operation, the start value 
                'has to be assigned in this case it is for x=0
            res_start.Amount=start
            res_start.Allocation=0 
                'the resource should be allocated over the whole
                'duration of the Reaction (amount>0 and allocation=0)
            res_start.Resources=Resources("Cooling agent")
            op.OrderResources.Add res_start
    
            res.Amount=-(start-0.9^((i)*op.Duration/3600-25)) 
                'at the end of the operation the difference between 
                'the start value and the first value of the function 
                'should be deallocated (allocation=0 and amount<0)
    
        ElseIf i=n_op Then 
            'the last operation
      
            res.Amount=-(0.9^((i-1)*op.Duration/3600-25)) 
                'at the end of the last operation the rest of 
                'the resource should be deallocated
        Else
            res.Amount=-(start-0.9^((i)*op.Duration/3600-25)) 
                'in every other call: difference between value 
                'of function for last batch(saved in CustomAttribute) 
                'and value for current batch is deallocated (amount<0)
        End If


        start=(0.9^((i)*op.Duration/3600-25)) 
            'saving the current value of function for next loop
        res.Allocation=0
        res.Resources=Resources("Cooling agent")
        op.OrderResources.Add res
    Next

End Sub

Die Ergebnisse der Simulation zeigen dann einen abnehmenden Bedarf an Kühlmittel über die gesamte Reaktionszeit:

Diese Lösung ist der einfachste Weg, neue Events für einen zeitlich veränderlichen Ressourcenbedarf zu erschaffen. Der Nachteil ist allerdings, dass der Ansatz sehr unflexibel ist und Rezepte sehr groß werden können, falls eine genauere Auflösung des Ressourcenbedarfs nötig ist. Um eine größere Anzahl an Events zu erzeugen, kann ein zweiter Ansatz genutzt werden.

Zweite Option: Verwendung einer zusätzlichen Teilanlage

Die zweite Möglichkeit, zeitlich veränderliche Ressourcenbedarfe darzustellen, ist eine zusätzliche Teilanlage einzuführen, auf der mehrere Events erzeugt werden. An dem Kühlmantel-Beispiel wird gezeigt, wie diese Methode umgesetzt wird.

Der Kühlmantel des Reaktors wird hier als extra Teilanlage modelliert. Um nun zusätzliche Events zu erschaffen, wird der Kühlmantel in einer zweiten UnitProcedure modelliert und durch den Start der Reaktion synchronisiert. So wird die Kühlmantel-Teilanlage erst belegt, wenn die Reaktion startet.

Mit der UnitProcedure auf dem Kühlmantel werden nun neue künstliche Events erzeugt, indem die Anzahl der Instanzen der UnitProcedure pro Batch gesetzt wird. Durch die zusätzlichen Instanzen wird die UnitProcedure mehr als einmal pro Batch ausgeführt. Diese Einstellung ist in den Eigenschaften der UnitProcedure zu finden:

Die Dauer der Operation Cool muss dementsprechend an die Anzahl der Instanzen angepasst werden. In diesem Beispiel ist die Dauer der Einzeloperationen somit die gesamte Reaktionszeit geteilt durch 50.

Im letzten Schritt muss in einer Parametersteuerung für die Operation Cool erstellt werden, welche der Operation den Ressourcenbedarf, hier bestimmt durch eine Funktion, zuordnet. Wie auch zuvor wird hier zunächst der Startwert als permanente Ressource zugeordnet. Am Ende der Operation wird die Differenz zwischen der Funktion und dem vorherigen Ressourcenbedarf freigegeben.

Sub Cooling_exponential(cop As OrderOperation, mop As RecipeOperation)
    
    'f(x)=0.9^(x-25), with x in [h]

    Dim batch As Integer
    Dim duration As Double
    Dim res As New OrderResource
    Dim res_start As New OrderResource
    Dim start As Double

    batch=cop.OrderProcedure.Batch 
    'Currently executed instance of the batch
    duration=cop.Duration

    If batch=1 Then
        start=0.9^(0-25) 
            'at the beginning of the first batch, the start 
            'value has to be assigned in this case it is at x=0
        res_start.Amount=start
        res_start.Allocation=0 
            'the resource should be allocated over the whole 
            'duration of the Reaction (amount>0 and allocation=0)
        res_start.Resources=Resources("Cooling agent")
        cop.OrderResources.Add res_start

        res.Amount=-(start-0.9^((batch)*duration/3600-25)) 
            'at the end of the operation the difference between 
            'the start value and the first value of the function 
            'should be deallocated (allocation=0 and amount<0)

    ElseIf batch=cop.ProcedureInstance.Batches Then 
            'the last operation
        start=cop.Order.CustomAttributes("start")
        res.Amount=-(0.9^((batch-1)*duration/3600-25)) 
            'at the end of the last operation the rest 
            'of the resource should be deallocated

    Else
        
        start=cop.Order.CustomAttributes("start")
        res.Amount=-(start-0.9^((batch)*duration/3600-25)) 
            'in every other call: difference between value of 
            'function for last batch(saved in CustomAttribute) 
            'and value for current batch is deallocated (amount<0)

    End If

    cop.Order.CustomAttributes("start")=(0.9^((batch)*duration/3600-25)) 
        'saving the current value of function for next instance
    res.Allocation=0
    res.Resources=Resources("Cooling agent")
    cop.OrderResources.Add res
End Sub

Als Ergebnis ist eine exponentiell fallende Ressourcenmenge über die Reaktionszeit zu sehen:

Um die Flexibilität des Modells noch weiter zu erhöhen, ist es auch möglich, die Anzahl an Instanzen pro Batch in VBA zu ändern. In der ersten Instanz der UnitProcedure kann die Anzahl der Batches so auf 50 gesetzt werden:

If cop.OrderProcedure.Batch=1 Then
    cop.ProcedureInstance.Batches=50
End If

In diesem Fall kann es dann auch von Vorteil sein, die Dauer der Operation entsprechend per VBA anzupassen.

Mit diesem Vorgehen kann man zum Beispiel Peaks in Ressourcenverbräuchen identifizieren. Um einen limitierenden Einfluss der Ressource auf das Modell zu ermitteln, ist diese Methode so noch nicht ausreichend, da die Ressource nicht direkt mit dem Reaktor, sondern mit dem Kühlmantel verbunden ist. Falls es also zu einem Mangel an einer Ressource kommt, kommt es nur zu einer Wartezeit auf dem Kühlmantel, aber nicht auf dem Reaktor. Damit der Reaktor auch wartet, muss das Rezept erweitert werden.

Nach der Cool-Operation wurden eine Alternativverzweigung und eine Verknüpfungsbedingung eingeführt. In der Bedingung wird überprüft, ob es sich um die letzte Instanz der UnitProcedure handelt. Falls es sich um die letzte Instanz handelt, wird der Alternativzweig mit der NoOperation ausgeführt. Diese NoOperation synchronisiert wiederum die Operation nach der Reaktion. Dadurch wird die Ausführung des Rezeptes nach der Reaktion verzögert, falls nicht genug Kühlmittel zur Verfügung steht.

Die Steuerung für die Alternativbedingung:

Sub Condition_LastBatch(cond As OrderLinkCondition)
    If cond.OrderOperationFrom.OrderProcedure.Batch=cond.OrderOperationFrom.ProcedureInstance.Batches Then
        'if it is the last batch
        cond.Value=False
    Else
        cond.Value=True
    End If
End Sub

In diesem Simulationslauf ist die verfügbare Kühlmittelmenge auf 35 kg/h beschränkt. Die Simulation zeigt dann Wartezeiten im Gantt-Diagramm. Die Wartezeiten auf dem Kühlmantel sieht man am Anfang der Reaktionszeit, während die Wartezeiten auf den Reaktoren am Ende der Reaktion zu sehen sind. Es kommt also zu einer Unschärfe in der Darstellung im Gantt-Diagramm. Der Ressourcenbedarf wird jedoch korrekt abgebildet, da die Ressource nur genutzt wird, wenn auch genug davon vorhanden ist. Falls nicht genug Ressource zur Verfügung steht, kommt es ebenfalls zu einer Verzögerung in der Reaktion.

Spezialfall: abnehmender Ressourcenbedarf

In dem gezeigten Beispiel wird ein über die Reaktionsdauer abfallenden Ressourcenbedarf betrachtet. Um so einen Bedarf abzubilden, gibt es eine weitere Möglichkeit. Dazu müssen keine neuen Events in INOSIM genutzt werden, sondern es wird die Möglichkeit ausgenutzt Ressourcen nur für einen bestimmten Anteil am Anfang der Reaktionszeit zu belegen (Ressource Allocation <1). In diesem Beispiel wir der Ressourcenbedarf in 50 Schritten entsprechend einer Exponentialfunktion über die Reaktionszeit geändert. Dazu wird der kleinste Wert der Funktion, die den Kühlmitelbedarf beschreibt, über die ganze Reaktionszeit benötigt. Die Differenz zwischen dem kleinsten Funktionswert und dem nächstgrößeren wird dann für die gesamte Reaktionszeit minus der Schrittweite benötigt. In diesem Beispiel würde sich so die Differenz für 49/50 der Reaktionszeit zu dem kleinsten Funktionswert addieren. So geht man bis zum höchsten Funktionswert vor, dessen Differenz zum vorherigen Wert dann nur in den ersten 1/50 der Reaktionszeit benötigt wird. In VBA lässt sich dieses Verhalten mit einer Schleife in einer Parametersteuerung lösen:

Sub Cooling_exponential_ressourcesplit(cop As OrderOperation, mop As RecipeOperation)
    
    'f(x)=0.9^(x-25) x in h


    Dim duration As Double
    Dim res As New OrderResource
    Dim start As Double
    Dim number As Integer
    Dim i As Integer

    number=50 'number of increments

    cop.Duration=t_reac(cop.Order.Material.Name, "ReactionDuration")*3600'Duration of Reaction is saved in parameter sheet

    For i=1 To number
        duration=cop.Duration/number 'Duration of increment
        res=New OrderResource
        res.Resources=Resources("Cooling agent")

        If i=1Then
            res.Amount=(0.9^((number-i)*duration/3600-25)) 'first loop:smallest value that is need over the whole reaction duration (allocation:50/50=1)
        Else
            res.Amount=(0.9^((number-i)*duration/3600-25))-start 'difference between current function and value before, adding up to the function (allocation: 49/50; 48/50; ...)
        End If

        res.Allocation=1-(i-1)/number 'allocation of increment: 50/50; 49/50; 48/50; ...
        cop.OrderResources.Add res
        start=0.9^((number-i)*duration/3600-25) 'saving value for next loop
    Next

End Sub

In einer Simulation, bei der ebenfalls die Ressourcenverfügbarkeit limitiert ist, erhält man folgendes Gantt Chart:

Dieses Vorgehen kann jedoch nur bei abnehmenden Ressourcenverbräuchen genutzt werden. Bei einem Ressourcenbedarf, der nur für einen Teil der Operation benötigt wird (Allocation<1), wird dieser in INOSIM für den entsprechenden ersten Anteil der Operationsdauer genutzt. Das bedeutet bei dieser Methode kann der Ressourcenbedarf nur am Anfang der Prozesszeit höher dargestellt werden.

Diese Methoden von zeitlich veränderlichen Ressourcenverbräuchen sind sehr sinnvoll, wenn ein detailliertes Ressourcenmodell nötig ist, um zum Beispiel Peaks oder Limitierungen zu bestimmen. Die zusätzlichen Events können jedoch dafür sorgen, dass die Simulation langsamer wird, wenn es sehr viele sind. Falls ein detailliertes Bild nötig ist, bildet diese Vorgehensweise jedoch einen guten Workaround.

Das vollständige Modell ist in den Downloads zu finden.

Downloads

(nur für registrierte INOSIM Kunden)

  • INOSIM-Projekt
  • PDF-Ausdruck zu diesem Tipp & Trick

Fragen?

Möchten Sie mehr über dieses Thema erfahren oder haben weitere Fragen? Bitte kontaktieren Sie uns.

Array ( [posts_per_page] => 3 [post_type] => [category__in] => Array ( [0] => 171 ) [orderby] => rand [order] => ASC )

Mehr Tipps & Tricks

Arbeiten mit externen Excel-Arbeitsmappen Neben dem Zugriff auf die in INOSIM eingebaute Excel-Arbeitsmappe (siehe Tipp Nutzen Sie Ihr Excel-VBA-Wissen bei der Arbeit mit INOSIM), können mit Hilfe…

Dieser Tipp & Trick beschreibt eine Vielzahl von Methoden zur Vermeidung und Behandlung von Laufzeitfehlern in Ihrem VBA-Code. Sie werden mit den FindColumn– und FindRow-Methoden…

Mit der neuen INOSIM 13 Version wurde der Basic-Editor umgestellt. So unterstützt dieser nun zusätzlich zu der WWB-COM auch die WWB.NET Sprachvariante, welche mit Visual…

mehr

INOSIM Kontakt

Zu den lokalen Geschäftszeiten

Deutschland +49 231 97 00 250