Difference between revisions of "Dynamic Simulation Tutorial with DWSIM and Python, Part 1: Concepts and Steady-State Model"

From DWSIM - Chemical Process Simulator
Jump to navigation Jump to search
(Created page with " <div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><table style="color: white; background-color: steelblue;" cellpadding="10" width="100%"> <tbody><tr> <...")
 
m
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
<div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><table style="color: white; background-color: steelblue;" cellpadding="10" width="100%">
+
<div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr">
<tbody><tr>
+
<table style="color: white; background-color: darkred;" cellpadding="10" width="100%">
<td colspan="1"> <a href="http://dwsim.inforside.com.br/wiki/index.php?title=File:Dialog-warning.png" class="image"><img alt="Dialog-warning.png" src="./dyn1_files/Dialog-warning.png" width="32" height="32"></a> This tutorial requires advanced or above average Python programming skills.
+
<tr>
 +
<td colspan="1"> [[File:Dialog-warning.png]] As of DWSIM v6.0, which include native Dynamic Simulation capabilities, this tutorial is obsolete.
 
</td></tr>
 
</td></tr>
</tbody></table>
+
</table>
 
<table style="color: white; background-color: steelblue; margin-top: 5px" cellpadding="10" width="100%">
 
<table style="color: white; background-color: steelblue; margin-top: 5px" cellpadding="10" width="100%">
<tbody><tr>
+
<tr>
<td colspan="1"> <a href="http://dwsim.inforside.com.br/wiki/index.php?title=File:Dialog-information.png" class="image"><img alt="Dialog-information.png" src="./dyn1_files/Dialog-information.png" width="32" height="32"></a> You'll need at least <b>DWSIM v5.1</b> on Windows, Linux or macOS to follow/reproduce the tasks within this tutorial.
+
<td colspan="1"> [[File:Dialog-warning.png]] This tutorial requires advanced or above average Python programming skills.
 
</td></tr>
 
</td></tr>
</tbody></table>
+
</table>
 +
<table style="color: white; background-color: steelblue; margin-top: 5px" cellpadding="10" width="100%">
 +
<tr>
 +
<td colspan="1"> [[File:Dialog-information.png]] You'll need at least <b>DWSIM v5.7 (Cross-Platform UI)</b> on Windows, Linux or macOS to follow/reproduce the tasks within this tutorial.
 +
</td></tr>
 +
</table>
 +
<br/>
 
<h1><span class="mw-headline" id="Introduction">Introduction</span></h1>
 
<h1><span class="mw-headline" id="Introduction">Introduction</span></h1>
 
<p>On this tutorial, you'll learn how to use advanced DWSIM features to build a dynamic process model, adding and tuning a PID Controller with existing tools.
 
<p>On this tutorial, you'll learn how to use advanced DWSIM features to build a dynamic process model, adding and tuning a PID Controller with existing tools.
Line 30: Line 37:
 
<p>The scripting capability in DWSIM allows the user to execute additional tasks in the simulation through the use of Python scripts, which have access to all objects in the flowsheet, the solver and the simulation itself. You can play with the objects in the flowsheet, do calculations using property packages, get data from external sources, run multiple cases while changing properties between runs and much more.
 
<p>The scripting capability in DWSIM allows the user to execute additional tasks in the simulation through the use of Python scripts, which have access to all objects in the flowsheet, the solver and the simulation itself. You can play with the objects in the flowsheet, do calculations using property packages, get data from external sources, run multiple cases while changing properties between runs and much more.
 
The script blocks can be associated with events in the flowsheet, i.e. they can run when a specific object is calculated or when an error occurs in the calculation. A script can also run when the simulation is opened, closed and saved.
 
The script blocks can be associated with events in the flowsheet, i.e. they can run when a specific object is calculated or when an error occurs in the calculation. A script can also run when the simulation is opened, closed and saved.
</p><p>More information: <a href="http://dwsim.inforside.com.br/wiki/index.php?title=Using_the_IronPython_Script_Manager" title="Using the IronPython Script Manager"> Script Manager Tutorial</a>
 
 
</p>
 
</p>
 
<h1><span class="mw-headline" id="Concepts">Concepts</span></h1>
 
<h1><span class="mw-headline" id="Concepts">Concepts</span></h1>
Line 37: Line 43:
 
</p><p>For instance, you can add a new property to a valve object on the flowsheet called "Cv", setting a value for it for later use on an additional calculation step:
 
</p><p>For instance, you can add a new property to a valve object on the flowsheet called "Cv", setting a value for it for later use on an additional calculation step:
 
</p>
 
</p>
<div><div id="highlighter_534577" class="syntaxhighlighter  python"><div class="toolbar"><span><a href="http://dwsim.inforside.com.br/wiki/index.php?title=Dynamic_Simulation_Tutorial_with_DWSIM_and_Python,_Part_1:_Concepts_and_Steady-State_Model#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">valve </code><code class="python keyword">=</code> <code class="python plain">Flowsheet.GetFlowsheetSimulationObject(</code><code class="python string">"FV-01"</code><code class="python plain">)</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python plain">valve.ExtraProperties.Cv </code><code class="python keyword">=</code> <code class="python value">3102.78</code></div></div></td></tr></tbody></table></div></div>
+
 
<div><div id="highlighter_942938" class="syntaxhighlighter  python"><div class="toolbar"><span><a href="http://dwsim.inforside.com.br/wiki/index.php?title=Dynamic_Simulation_Tutorial_with_DWSIM_and_Python,_Part_1:_Concepts_and_Steady-State_Model#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">valve </code><code class="python keyword">=</code> <code class="python plain">Flowsheet.GetFlowsheetSimulationObject(</code><code class="python string">"FV-01"</code><code class="python plain">)</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python plain">props </code><code class="python keyword">=</code> <code class="python plain">valve.ExtraProperties</code></div><div class="line number4 index3 alt1">&nbsp;</div><div class="line number5 index4 alt2"><code class="python comments"># Cv = 11.6 Q (SG / dp)^0.5</code></div><div class="line number6 index5 alt1"><code class="python comments"># dp = SG/(Cv/11.6Q)^2</code></div><div class="line number7 index6 alt2"><code class="python comments"># where</code></div><div class="line number8 index7 alt1"><code class="python comments"># q = water flow (m3/hr)</code></div><div class="line number9 index8 alt2"><code class="python comments"># SG = specific gravity (1 for water)</code></div><div class="line number10 index9 alt1"><code class="python comments"># dp = pressure drop (kPa)</code></div><div class="line number11 index10 alt2">&nbsp;</div><div class="line number12 index11 alt1"><code class="python plain">DP </code><code class="python keyword">=</code> <code class="python plain">valve.DeltaP </code><code class="python keyword">/</code> <code class="python value">1000</code></div><div class="line number13 index12 alt2">&nbsp;</div><div class="line number14 index13 alt1"><code class="python plain">SG </code><code class="python keyword">=</code> <code class="python plain">inlet.Phases[</code><code class="python value">0</code><code class="python plain">].Properties.density </code><code class="python keyword">/</code> <code class="python value">1000</code></div><div class="line number15 index14 alt2">&nbsp;</div><div class="line number16 index15 alt1"><code class="python plain">Q </code><code class="python keyword">=</code> <code class="python plain">props.Cv </code><code class="python keyword">/</code> <code class="python value">11.6</code> <code class="python keyword">/</code> <code class="python plain">(SG</code><code class="python keyword">/</code><code class="python plain">DP) </code><code class="python keyword">*</code><code class="python keyword">*</code> <code class="python value">0.5</code> <code class="python keyword">/</code> <code class="python value">60</code> <code class="python keyword">/</code> <code class="python value">60</code> <code class="python comments"># m3/s</code></div></div></td></tr></tbody></table></div></div>
+
<source lang="python">
<p>The Dynamic Properties feature in DWSIM makes use of the <a rel="nofollow" class="external text" href="https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/">System.Dynamic.ExpandoObject</a> class present in the Dynamic Language Runtime (DLR) on .NET. Each flowsheet object, including the flowsheet itself, contains a variable named "ExtraProperties", which is actually an instance of the ExpandoObject class. <a rel="nofollow" class="external autonumber" href="http://dwsim.inforside.com.br/api_help5/html/P_DWSIM_SharedClasses_UnitOperations_BaseClass_ExtraProperties.htm">[1]</a>
+
valve = Flowsheet.GetFlowsheetSimulationObject("FV-01")
 +
 +
valve.ExtraProperties.Cv = 3102.78
 +
</source>
 +
 
 +
<source lang="python">
 +
valve = Flowsheet.GetFlowsheetSimulationObject("FV-01")
 +
 +
props = valve.ExtraProperties
 +
 +
# Cv = 11.6 Q (SG / dp)^0.5
 +
# dp = SG/(Cv/11.6Q)^2
 +
# where
 +
# q = water flow (m3/hr)
 +
# SG = specific gravity (1 for water)
 +
# dp = pressure drop (kPa)
 +
 +
DP = valve.DeltaP / 1000
 +
 +
SG = inlet.Phases[0].Properties.density / 1000
 +
 +
Q = props.Cv / 11.6 / (SG/DP) ** 0.5 / 60 / 60 # m3/s
 +
</source>
 +
 
 +
<p>The Dynamic Properties feature in DWSIM makes use of the [https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/ System.Dynamic.ExpandoObject] class present in the Dynamic Language Runtime (DLR) on .NET. Each flowsheet object, including the flowsheet itself, contains a variable named "ExtraProperties", which is actually an instance of the ExpandoObject class. http://dwsim.inforside.com.br/api_help60/html/P_DWSIM_SharedClasses_UnitOperations_BaseClass_ExtraProperties.htm
 
</p>
 
</p>
 
<h2><span class="mw-headline" id="Linked_Scripts">Linked Scripts</span></h2>
 
<h2><span class="mw-headline" id="Linked_Scripts">Linked Scripts</span></h2>
Line 59: Line 89:
 
<p>You can load external libraries into scripts to perform additional tasks. You can, for instance, load the Excel Library and export the results from a calculation to a new spreadsheet:
 
<p>You can load external libraries into scripts to perform additional tasks. You can, for instance, load the Excel Library and export the results from a calculation to a new spreadsheet:
 
</p>
 
</p>
<div><div id="highlighter_854886" class="syntaxhighlighter  python"><div class="toolbar"><span><a href="http://dwsim.inforside.com.br/wiki/index.php?title=Dynamic_Simulation_Tutorial_with_DWSIM_and_Python,_Part_1:_Concepts_and_Steady-State_Model#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">clr</code></div><div class="line number2 index1 alt1"><code class="python keyword">import</code> <code class="python plain">sys</code></div><div class="line number3 index2 alt2">&nbsp;</div><div class="line number4 index3 alt1"><code class="python plain">clr.AddReferenceByName(</code><code class="python string">'Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'</code><code class="python plain">)</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="python keyword">from</code> <code class="python plain">Microsoft.Office.Interop </code><code class="python keyword">import</code> <code class="python plain">Excel</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="python plain">ex </code><code class="python keyword">=</code> <code class="python plain">Excel.ApplicationClass()&nbsp;&nbsp; </code></div><div class="line number9 index8 alt2">&nbsp;</div><div class="line number10 index9 alt1"><code class="python plain">ex.Visible </code><code class="python keyword">=</code> <code class="python color1">False</code></div><div class="line number11 index10 alt2"><code class="python plain">ex.DisplayAlerts </code><code class="python keyword">=</code> <code class="python color1">True</code>&nbsp;&nbsp;</div><div class="line number12 index11 alt1">&nbsp;</div><div class="line number13 index12 alt2"><code class="python plain">workbook </code><code class="python keyword">=</code> <code class="python plain">ex.Workbooks.Add()</code></div><div class="line number14 index13 alt1"><code class="python plain">workbook.Worksheets.Add()</code></div><div class="line number15 index14 alt2"><code class="python plain">ws1 </code><code class="python keyword">=</code> <code class="python plain">workbook.Worksheets[</code><code class="python value">1</code><code class="python plain">]</code></div><div class="line number16 index15 alt1">&nbsp;</div><div class="line number17 index16 alt2"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">1</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"time"</code></div><div class="line number18 index17 alt1"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">2</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"source_level"</code></div><div class="line number19 index18 alt2"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">3</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"sink_level"</code></div><div class="line number20 index19 alt1"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">4</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"hot_water_flow"</code></div><div class="line number21 index20 alt2"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">5</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"hot_water_temp"</code></div><div class="line number22 index21 alt1"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">6</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"cooling_water_flow"</code></div><div class="line number23 index22 alt2"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">7</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"cooling_water_temp"</code></div><div class="line number24 index23 alt1"><code class="python plain">ws1.UsedRange.Cells[</code><code class="python value">1</code><code class="python plain">, </code><code class="python value">8</code><code class="python plain">].Value2 </code><code class="python keyword">=</code> <code class="python string">"valve_opening"</code></div><div class="line number25 index24 alt2">&nbsp;</div><div class="line number26 index25 alt1"><code class="python plain">ex.Visible </code><code class="python keyword">=</code> <code class="python color1">True</code></div></div></td></tr></tbody></table></div></div>
+
 
 +
<source lang="python">
 +
 
 +
import clr
 +
import sys
 +
 +
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
 +
 +
from Microsoft.Office.Interop import Excel
 +
 +
ex = Excel.ApplicationClass()  
 +
 +
ex.Visible = False
 +
ex.DisplayAlerts = True
 +
 +
workbook = ex.Workbooks.Add()
 +
workbook.Worksheets.Add()
 +
ws1 = workbook.Worksheets[1]
 +
 +
ws1.UsedRange.Cells[1, 1].Value2 = "time"
 +
ws1.UsedRange.Cells[1, 2].Value2 = "source_level"
 +
ws1.UsedRange.Cells[1, 3].Value2 = "sink_level"
 +
ws1.UsedRange.Cells[1, 4].Value2 = "hot_water_flow"
 +
ws1.UsedRange.Cells[1, 5].Value2 = "hot_water_temp"
 +
ws1.UsedRange.Cells[1, 6].Value2 = "cooling_water_flow"
 +
ws1.UsedRange.Cells[1, 7].Value2 = "cooling_water_temp"
 +
ws1.UsedRange.Cells[1, 8].Value2 = "valve_opening"
 +
 +
ex.Visible = True
 +
 
 +
</source>  
 +
 
 
<h1><span class="mw-headline" id="Building_the_Steady-State_Process_Model">Building the Steady-State Process Model</span></h1>
 
<h1><span class="mw-headline" id="Building_the_Steady-State_Process_Model">Building the Steady-State Process Model</span></h1>
 
<h2><span class="mw-headline" id="Process_Description">Process Description</span></h2>
 
<h2><span class="mw-headline" id="Process_Description">Process Description</span></h2>
 
<p>Our process consists of a heat exchanger which cools a hot water stream using cold water, stored in a tank. A valve controls the cold water flow from the source to the sink tank.
 
<p>Our process consists of a heat exchanger which cools a hot water stream using cold water, stored in a tank. A valve controls the cold water flow from the source to the sink tank.
 
</p>
 
</p>
<div class="fullwidth"><a href="http://dwsim.inforside.com.br/wiki/index.php?title=File:Dynamic_model.jpg" class="image"><img alt="Dynamic model.jpg" src="./dyn1_files/Dynamic_model.jpg" width="1240" height="640"></a></div>
+
<div class="fullwidth">[[File:Dynamic_model.jpg]]</div>
 
<h2><span class="mw-headline" id="Setup">Setup</span></h2>
 
<h2><span class="mw-headline" id="Setup">Setup</span></h2>
 
<ol><li>Create a new simulation.</li>
 
<ol><li>Create a new simulation.</li>
Line 76: Line 137:
 
<li>Set the hot_water pressure to 1000000 Pa.</li>
 
<li>Set the hot_water pressure to 1000000 Pa.</li>
 
<li>Set the heat exchanger (HX-01) calculation mode to "Shell and Tube (Rating)", with the following geometry:</li></ol>
 
<li>Set the heat exchanger (HX-01) calculation mode to "Shell and Tube (Rating)", with the following geometry:</li></ol>
<p><a href="http://dwsim.inforside.com.br/wiki/index.php?title=File:Dynamic_hx.jpg" class="image"><img alt="Dynamic hx.jpg" src="./dyn1_files/Dynamic_hx.jpg" width="517" height="785"></a>
+
<p>[[File:Dynamic_hx.jpg]]
 
</p>
 
</p>
 
<h2><span class="mw-headline" id="Run">Run</span></h2>
 
<h2><span class="mw-headline" id="Run">Run</span></h2>
Line 84: Line 145:
 
</p>
 
</p>
 
<h2><span class="mw-headline" id="Download_File">Download File</span></h2>
 
<h2><span class="mw-headline" id="Download_File">Download File</span></h2>
<p>Download the simulation file with what has been done so far: <a rel="nofollow" class="external text" href="http://dwsim.inforside.com.br/files/dynamic_part1.dwxmz">dynamic_part1.dwxmz</a>
+
<p>Download the simulation file with what has been done so far: [http://dwsim.inforside.com.br/files/dynamic_part1.dwxmz dynamic_part1.dwxmz]
</p><p>Proceed to <a href="http://dwsim.inforside.com.br/wiki/index.php?title=Dynamic_Simulation_Tutorial_with_DWSIM_and_Python,_Part_2:_Building_the_Dynamic_Model" title="Dynamic Simulation Tutorial with DWSIM and Python, Part 2: Building the Dynamic Model"> Part 2: Building the Dynamic Model</a>
+
</p><p>Proceed to [[Dynamic Simulation Tutorial with DWSIM and Python, Part 2: Building the Dynamic Model]]
 
</p>
 
</p>

Latest revision as of 16:44, 10 August 2020

Dialog-warning.png As of DWSIM v6.0, which include native Dynamic Simulation capabilities, this tutorial is obsolete.
Dialog-warning.png This tutorial requires advanced or above average Python programming skills.
Dialog-information.png You'll need at least DWSIM v5.7 (Cross-Platform UI) on Windows, Linux or macOS to follow/reproduce the tasks within this tutorial.


Introduction

On this tutorial, you'll learn how to use advanced DWSIM features to build a dynamic process model, adding and tuning a PID Controller with existing tools.

Dynamic Process Model

The key difference between the steady-state models and dynamic process models is the ability to take into account variation over time. However, as can be seen below the difference is not simply the addition of a time dimension; dynamic modeling often brings a whole different approach that results in dynamic models being a much truer-to-life representation of the process in many other respects.

While steady-state analysis is mainly used for process flowsheet design, usually to determine mass and energy balances and approximate equipment sizes, or perhaps stream properties, the ability of dynamic models to model transient behavior opens up a whole new world of application. Typical applications of dynamic models are as follows:

  • analysis of transient behavior, including performance during start-up, shutdown, and load change;
  • regulatory (i.e., PID) control scheme analysis and design;
  • design of optimal operating procedures – for example, to optimize transition between product grades;
  • design of batch processes;
  • design of inherently dynamic continuous processes – for example, pressure swing adsorption;
  • fitting data from nonsteady-state operations – for example, dynamic experiments, which contain much more information than steady-state experiments, or estimation of process parameters from transient plant data;
  • safety analysis – for example, the determination of peak pressures on compressor trip;
  • inventory accounting and reconciliation of plant data;
  • online or offline parameter re-estimation to determine key operating parameters such as fouling or deactivation constants;
  • online soft-sensing;
  • operator training.

Python Scripting in DWSIM

The scripting capability in DWSIM allows the user to execute additional tasks in the simulation through the use of Python scripts, which have access to all objects in the flowsheet, the solver and the simulation itself. You can play with the objects in the flowsheet, do calculations using property packages, get data from external sources, run multiple cases while changing properties between runs and much more. The script blocks can be associated with events in the flowsheet, i.e. they can run when a specific object is calculated or when an error occurs in the calculation. A script can also run when the simulation is opened, closed and saved.

Concepts

Dynamic Properties

The Dynamic Properties feature in DWSIM allows you to add new properties to flowsheet objects, which will persist between simulation file saving/opening cycles. These properties can be used by scripts to perform additional calculations, or even override the actual models.

For instance, you can add a new property to a valve object on the flowsheet called "Cv", setting a value for it for later use on an additional calculation step:

valve = Flowsheet.GetFlowsheetSimulationObject("FV-01")
 
valve.ExtraProperties.Cv = 3102.78
valve = Flowsheet.GetFlowsheetSimulationObject("FV-01")
 
props = valve.ExtraProperties
 
# Cv = 11.6 Q (SG / dp)^0.5
# dp = SG/(Cv/11.6Q)^2
# where
# q = water flow (m3/hr)
# SG = specific gravity (1 for water)
# dp = pressure drop (kPa)
 
DP = valve.DeltaP / 1000
 
SG = inlet.Phases[0].Properties.density / 1000
 
Q = props.Cv / 11.6 / (SG/DP) ** 0.5 / 60 / 60 # m3/s

The Dynamic Properties feature in DWSIM makes use of the System.Dynamic.ExpandoObject class present in the Dynamic Language Runtime (DLR) on .NET. Each flowsheet object, including the flowsheet itself, contains a variable named "ExtraProperties", which is actually an instance of the ExpandoObject class. http://dwsim.inforside.com.br/api_help60/html/P_DWSIM_SharedClasses_UnitOperations_BaseClass_ExtraProperties.htm

Linked Scripts

Scripts can be associated with events in the Flowsheet. You can tell DWSIM to run a script only after an object was calculated successfully, for instance. This is the basis for our dynamic modeling scheme, where the dynamic models will be executed after the steady-state models run.

To link a script to an event in the flowsheet, click on the Link checkbox in the Script Editor window. The following events are available for linking:

  • Simulation: Opened, Closed and Saved.
  • Solver: Calculation Started, Finished and Recycle Loop (raised when there are recycles in the flowsheet and the solver iterates through them to achieve convergence).
  • Remaining Objects in the flowsheet: Object Calculation Started, Finished and Error.

The scripts don't necessarily need to be associated with events. You can keep a collection of non-associated scripts and run them at your will using the Script Manager.

LINQ

Language Integrated Query (LINQ, pronounced "link") is a Microsoft .NET Framework component that adds native data querying capabilities to .NET languages.

LINQ extends the language by the addition of query expressions, which are akin to SQL statements, and can be used to conveniently extract and process data from arrays, enumerable classes, XML documents, relational databases, and third-party data sources. Other uses, which utilize query expressions as a general framework for readably composing arbitrary computations, include the construction of event handlers[1] or monadic parsers.

LINQ also defines a set of method names (called standard query operators, or standard sequence operators), along with translation rules used by the compiler to translate fluent-style query expressions into expressions using these method names, lambda expressions and anonymous types.

LINQ statements can be used in scripts to get specific flowsheet objects from the container collections, or even other script blocks form the flowsheet.

External Libraries

You can load external libraries into scripts to perform additional tasks. You can, for instance, load the Excel Library and export the results from a calculation to a new spreadsheet:


import clr
import sys
 
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
 
from Microsoft.Office.Interop import Excel
 
ex = Excel.ApplicationClass()   
 
ex.Visible = False
ex.DisplayAlerts = True  
 
workbook = ex.Workbooks.Add()
workbook.Worksheets.Add()
ws1 = workbook.Worksheets[1]
 
ws1.UsedRange.Cells[1, 1].Value2 = "time"
ws1.UsedRange.Cells[1, 2].Value2 = "source_level"
ws1.UsedRange.Cells[1, 3].Value2 = "sink_level"
ws1.UsedRange.Cells[1, 4].Value2 = "hot_water_flow"
ws1.UsedRange.Cells[1, 5].Value2 = "hot_water_temp"
ws1.UsedRange.Cells[1, 6].Value2 = "cooling_water_flow"
ws1.UsedRange.Cells[1, 7].Value2 = "cooling_water_temp"
ws1.UsedRange.Cells[1, 8].Value2 = "valve_opening"
 
ex.Visible = True

Building the Steady-State Process Model

Process Description

Our process consists of a heat exchanger which cools a hot water stream using cold water, stored in a tank. A valve controls the cold water flow from the source to the sink tank.

Dynamic model.jpg

Setup

  1. Create a new simulation.
  2. Add Water as the single compound.
  3. Add an instance of the IAPWS-IF97 Property Package.

Build

  1. Add, name and connect the flowsheet objects as per the above screenshot.
  2. Set the dummy_in mass flow to 23.6155 kg/s.
  3. Set the hot_water mass flow to 7.46 kg/s.
  4. Set the hot_water temperature to 397 K.
  5. Set the hot_water pressure to 1000000 Pa.
  6. Set the heat exchanger (HX-01) calculation mode to "Shell and Tube (Rating)", with the following geometry:

Dynamic hx.jpg

Run

Press F5 to run the model. After running the model, the hot water outlet temperature should be about 323.15 K (50 C), which is our primary objective - to control the outlet temperature of the hot water stream always near 50 C.

What happens if the hot water flow rate changes? If the flow increases, the valve should allow more cold water pass through it to compensate the increase of the hot water flow rate and keep its outlet temperature at 50 C, the opposite also being true. This would decrease the water level in the source tank and increase the level in the sink tank.

None of what was described in the above sentence is possible to simulate in a Steady-State model. In the next part of this tutorial, we will add new properties to objects and create scripts to enhance our model, making it dynamic and able to predict the overall system response when the hot water flow rate changes.

Download File

Download the simulation file with what has been done so far: dynamic_part1.dwxmz

Proceed to Dynamic Simulation Tutorial with DWSIM and Python, Part 2: Building the Dynamic Model