This chapter gives the basic information about exploring examples/tutorials, developing models, defining and running a simulation and plotting the simulation results.
DAE Tools (pyDAE module) is installed in daetools
folder within site-packages
(or dist-packages
)
folder of the Python installation. The structure of the folders is given in Fig. 5.1.
Start DAE Tools Tutorials
program to try some examples:
GNU/Linux:
Run Applications/Development/DAE Tools Examples
from the system menu
Windows:
Run i.e. Start/Programs/DAE Tools/daeExamples_1.9.0_py36
from the Start menu
Alternatively, run the following command from the command line (platform independent):
python -m daetools.examples.run_examples
or:
daeexamples
Note
daeexamples
script is located in the Scripts
folder (in Windows) or the bin
folder (GNU/Linux)
of the python installation. Typically, those locations are added to the PATH
by the python installation.
The main window of DAE Tools Examples
application is given in Fig. 5.2 while
the output from the simulation run in Fig. 5.3. There, tutorials can be run, their source code
inspected, and model reports generated.
Model reports open in a new window of the system’s default web browser.
Tutorials can also be started from the shell:
cd .../daetools/examples
python tutorial1.py console
or:
python tutorial1.py gui
The sample output is given in Fig. 5.4:
On GNU/Linux and Windows the DAE Plotter
is started automatically.
It can also be started manually:
GNU/Linux:
Run Applications/Development/DAE Tools Plotter
from the system menu.
Windows:
Run i.e. Start/Programs/DAE Tools/daePlotter_1.9.0_py36
from the Start menu
Alternatively, run the following command from the command line (platform independent):
python -m daetools.dae_plotter.plotter
or:
daeplotter
Note
daeplotter
script is located in the Scripts
folder (in Windows) or the bin
folder (GNU/Linux)
of the python installation. Typically, those locations are added to the PATH
by the python installation.
The DAE Tools Plotter
main window should appear (given in Fig. 5.5)
DAE Tools provide a protocol for reporting the simulation results. It uses a concept of data reporter and data receiver interfaces. Data reporter interface is used by a simulation to send the data, while the data receiver interface is used to receive, store and provide the data to users. There are two types of data reporters: local (store data locally) and remote (send data to a server, i.e. via TCP/IP protocol).
There are three ways to obtain the results from the simulation:
DAE Tools Plotter
GUIdaeDataReporter_t
, daeDataReporterLocal
, daeDataReporterFile
etc.)The simulation/optimisation results can be plotted using the DAE Tools Plotter application.
Several types of plots are supported: Matplotlib-based 2D, animated 2D, auto-update 2D plots, user-defined plot,
plot from the user-specified data, Mayavi 3D plot, and VTK file plot.
After choosing a desired type, a Choose variable (given in Fig. 5.6)
dialog appears where a variable to be plotted can be selected and information about domains
specified - some domains should be fixed while leaving another free by selecting *
from the list
(to create a 2D plot one domain must remain free, while for a 3D plot two domains).
Typical 2D and 3D plots are given in Fig. 5.7 and Fig. 5.8.
{
"curves": [
[
"tutorial4.T",
[
-1
],
[
"*"
],
"tutorial4.T(*)",
{
"color": "black",
"linestyle": "-",
"linewidth": 0.5,
"marker": "o",
"markeredgecolor": "black",
"markerfacecolor": "black",
"markersize": 6
}
]
],
"gridOn": true,
"legendOn": true,
"plotTitle": "",
"updateInterval": 0,
"windowTitle": "tutorial4.T(*)",
"xlabel": "Time (s)",
"xmax": 525.0,
"xmax_policy": 0,
"xmin": -25.0,
"xmin_policy": 0,
"xscale": "linear",
"xtransform": 1.0,
"ylabel": "T (K)",
"ymax": 361.74772465755922,
"ymax_policy": 1,
"ymin": 279.2499308975365,
"ymin_policy": 1,
"yscale": "linear",
"ytransform": 1.0,
}
There is a large number of available data reporters. Some of them are listed below.
daeMatlabMATFileDataReporter
)daeExcelFileDataReporter
)daeJSONFileDataReporter
)daeXMLFileDataReporter
)daeHDF5FileDataReporter
)daeVTKFileDataReporter
)daePandasDataReporter
)daePlotDataReporter
)daeDelegateDataReporter
)daeDataReporterLocal
(stores results internally; can be used for any type of processing)daeNoOpDataReporter
(stores results internally but does nothing with them)daeDataReporterFile
(saves the results into a file in the WriteDataToFile virtual member function)daeBlackHoleDataReporter
(does not store the results and does not process them; useful when the results are not needed)In DAE Tools models are developed by deriving a new class from the base model class (daeModel
).
The process consists of two steps:
__init__()
functionDeclareEquations()
functionAn example model developed in pyDAE (using python programming language):
from daetools.pyDAE import *
class myModel(daeModel):
def __init__(self, name, parent = None, description = ""):
daeModel.__init__(self, name, parent, description)
# Declaration/instantiation of domains, parameters, variables, ports, etc:
self.m = daeParameter("m", kg, self, "Mass of the copper plate")
self.cp = daeParameter("c_p", J/(kg*K), self, "Specific heat capacity of the plate")
self.alpha = daeParameter("α", W/((m**2)*K), self, "Heat transfer coefficient")
self.A = daeParameter("A", m**2, self, "Area of the plate")
self.Tsurr = daeParameter("T_surr", K, self, "Temperature of the surroundings")
self.Qin = daeVariable("Q_in", power_t, self, "Power of the heater")
self.T = daeVariable("T", temperature_t, self, "Temperature of the plate")
def DeclareEquations(self):
# Specification of equations and state transitions:
eq = self.CreateEquation("HeatBalance", "Integral heat balance equation")
eq.Residual = self.m() * self.cp() * self.T.dt() - self.Qin() + self.alpha() * self.A() * (self.T() - self.Tsurr())
The same model developed in cDAE (using c++ programming language):
class myModel : public daeModel
{
public:
// Declarations of domains, parameters, variables, ports, etc:
daeParameter mass;
daeParameter c_p;
daeParameter alpha;
daeParameter A;
daeParameter T_surr;
daeVariable Q_in;
daeVariable T;
public:
myModel(string strName, daeModel* pParent = NULL, string strDescription = "")
: daeModel(strName, pParent, strDescription),
// Instantiation of domains, parameters, variables, ports, etc:
mass ("m", kg, this, "Mass of the copper plate"),
c_p ("c_p", J/(kg*K), this, "Specific heat capacity of the plate"),
alpha ("α", W/((m^2) * K), this, "Heat transfer coefficient"),
A ("A", m ^ 2, this, "Area of the plate"),
T_surr("T_surr", K, this, "Temperature of the surroundings"),
Q_in ("Q_in", power_t, this, "Power of the heater"),
T ("T", temperature_t, this, "Temperature of the plate")
{
}
void DeclareEquations(void)
{
// Specification of equations and state transitions:
daeEquation* eq = CreateEquation("HeatBalance", "Integral heat balance equation");
eq->SetResidual( mass() * c_p() * T.dt() - Q_in() + alpha() * A() * (T() - T_surr()) );
}
};
More information about developing models can be found in User Guide and pyCore.daeModel
.
Also, do not forget to have a look on Tutorials.
Definition of a simulation in DAE Tools requires the following steps:
daeSimulation
)An example simulation developed in pyDAE:
class mySimulation(daeSimulation):
def __init__(self):
daeSimulation.__init__(self)
# Set the model to simulate:
self.m = myModel("myModel")
def SetUpParametersAndDomains(self):
# Set the parameters values:
self.m.cp.SetValue(385 * J/(kg*K))
self.m.m.SetValue(1 * kg)
self.m.alpha.SetValue(200 * W/((m**2)*K))
self.m.A.SetValue(0.1 * m**2)
self.m.Tsurr.SetValue(283 * K)
def SetUpVariables(self):
# Set the degrees of freedom, initial conditions, initial guesses, etc.:
self.m.Qin.AssignValue(1500 * W)
self.m.T.SetInitialCondition(283 * K)
def Run(self):
# A custom operating procedure, if needed.
# Here we use the default one:
daeSimulation.Run(self)
The same simulation in cDAE:
class mySimulation : public daeSimulation
{
public:
myModel m;
public:
mySimulation(void) : m("myModel")
{
// Set the model to simulate:
SetModel(&m);
}
public:
void SetUpParametersAndDomains(void)
{
// Set the parameters values:
model.c_p.SetValue(385 * J/(kg*K));
model.mass.SetValue(1 * kg);
model.alpha.SetValue(200 * W/((m^2)*K));
model.A.SetValue(0.1 * (m^2));
model.T_surr.SetValue(283 * K);
}
void SetUpVariables(void)
{
// Set the degrees of freedom, initial conditions, initial guesses, etc.:
model.Q_in.AssignValue(1500 * W);
model.T.SetInitialCondition(283 * K);
}
void Run(void)
{
// A custom operating procedure, if needed.
// Here we use the default one:
daeSimulation::Run();
}
};
Simulations in pyDAE can be set-up to run in two modes:
From the PyQt4 graphical user interface (pyDAE only):
Here the default log, and data reporter objects will be used, while the user can choose DAE and LA solvers and specify time horizon and reporting interval.
# Import modules
import sys
from time import localtime, strftime
from PyQt4 import QtCore, QtGui
# Create QtApplication object
app = QtGui.QApplication(sys.argv)
# Create simulation object
sim = mySimulation()
# Report ALL variables in the model
sim.m.SetReportingOn(True)
# Show the daeSimulator window to choose the other information needed for simulation
simulator = daeSimulator(app, simulation=sim)
simulator.show()
# Execute applications main loop
app.exec_()
From the shell:
In pyDAE:
# Import modules
import sys
from time import localtime, strftime
# Create Log, Solver, DataReporter and Simulation object
log = daeStdOutLog()
solver = daeIDAS()
datareporter = daeTCPIPDataReporter()
simulation = mySimulation()
# Report ALL variables in the model
simulation.m.SetReportingOn(True)
# Set the time horizon (1000 seconds) and the reporting interval (10 seconds)
simulation.SetReportingInterval(10)
simulation.SetTimeHorizon(1000)
# Connect data reporter
# (use the default TCP/IP connection settings: localhost and 50000 port)
simName = simulation.m.Name + strftime(" [m.%Y %H:%M:%S]", localtime())
if(datareporter.Connect("", simName) == False):
sys.exit()
# Initialize the simulation
simulation.Initialize(solver, datareporter, log)
# Solve at time = 0 (initialization)
simulation.SolveInitial()
# Run
simulation.Run()
# Clean up
simulation.Finalize()
In cDAE:
// Create Log, Solver, DataReporter and Simulation object
boost::scoped_ptr<daeSimulation_t> pSimulation(new mySimulation());
boost::scoped_ptr<daeDataReporter_t> pDataReporter(daeCreateTCPIPDataReporter());
boost::scoped_ptr<daeIDASolver> pDAESolver(daeCreateIDASolver());
boost::scoped_ptr<daeLog_t> pLog(daeCreateStdOutLog());
// Report ALL variables in the model
pSimulation->GetModel()->SetReportingOn(true);
// Set the time horizon (1000 seconds) and the reporting interval (10 seconds)
pSimulation->SetReportingInterval(10);
pSimulation->SetTimeHorizon(1000);
// Connect data reporter
// (use the default TCP/IP connection settings: localhost and 50000 port)
string strName = pSimulation->GetModel()->GetName();
if(!pDataReporter->Connect("", strName))
return;
// Initialize the simulation
pSimulation->Initialize(pDAESolver.get(), pDataReporter.get(), pLog.get());
// Solve at time = 0 (initialization)
pSimulation->SolveInitial();
// Run
pSimulation->Run();
// Clean up
pSimulation->Finalize();
Simulations are started by executing the following shell commands:
cd "directory where simulation file is located"
python mySimulation.py
To define an optimisation problem it is first necessary to develop a model of the process and to define
a simulation (as explained above). Having done these tasks (working model and simulation) the optimisation
in DAE Tools can be defined by specifying the objective function, optimisation variables and optimisation
constraints. It is intentionally chosen to keep simulation and optimisation tightly coupled. The optimisation
problem should be specified in the function SetUpOptimization()
.
Definition of an optimisation in DAE Tools requires the following steps:
continuous
(floating point values in
the given range), integer
(set of integer values in the given range) or binary
(integer value: 0 or 1).equality
and inequality
constraints
To define an equality
constraint its residual and the value has to be specified;
To define an inequality
constraint its residual, the lower and upper bounds have to be specified;
Internally the framework will create a new variable (V_constraint[N]) and a new equation (F_constraint[N])
for each defined constraint, where N is the ordinal number of the constraint.SetUpOptimization()
function should be declared in the simulation class:
In pyDAE:
class mySimulation(daeSimulation):
...
def SetUpOptimization(self):
# Declarations of the obj. function, opt. variables and constraints:
...
In cDAE:
class mySimulation : public daeSimulation
{
...
void SetUpOptimization(void)
{
// Declarations of the obj. function, opt. variables and constraints:
}
};
Optimisations, like simulations can be set-up to run in two modes:
From the PyQt4 graphical user interface (pyDAE only)
Here the default log, and data reporter objects will be used, while the user can choose NLP, DAE and LA solvers and specify time horizon and reporting interval:
# Import modules
import sys
from time import localtime, strftime
from PyQt4 import QtCore, QtGui
# Create QtApplication object
app = QtGui.QApplication(sys.argv)
# Create simulation object
sim = mySimulation()
nlp = daeBONMIN()
# Report ALL variables in the model
sim.m.SetReportingOn(True)
# Show the daeSimulator window to choose the other information needed for optimisation
simulator = daeSimulator(app, simulation=sim, nlpsolver=nlp)
simulator.show()
# Execute applications main loop
app.exec_()
From the shell:
In pyDAE:
# Create Log, NLPSolver, DAESolver, DataReporter, Simulation and Optimization objects
log = daePythonStdOutLog()
daesolver = daeIDAS()
nlpsolver = daeIPOPT()
datareporter = daeTCPIPDataReporter()
simulation = mySimulation()
optimization = daeOptimization()
# Enable reporting of all variables
simulation.m.SetReportingOn(True)
# Set the time horizon and the reporting interval
simulation.ReportingInterval = 10
simulation.TimeHorizon = 100
# Connect data reporter
simName = simulation.m.Name + strftime(" [m.%Y %H:%M:%S]", localtime())
if(datareporter.Connect("", simName) == False):
sys.exit()
# Initialise the optimisation
optimization.Initialize(simulation, nlpsolver, daesolver, datareporter, log)
# Run
optimization.Run()
# Clean up
optimization.Finalize()
In cDAE:
// Create Log, NLPSolver, DAESolver, DataReporter, Simulation and Optimization objects
boost::scoped_ptr<daeSimulation_t> pSimulation(new mySimulation());
boost::scoped_ptr<daeDataReporter_t> pDataReporter(daeCreateTCPIPDataReporter());
boost::scoped_ptr<daeIDASolver> pDAESolver(daeCreateIDASolver());
boost::scoped_ptr<daeLog_t> pLog(daeCreateStdOutLog());
boost::scoped_ptr<daeNLPSolver_t> pNLPSolver(new daeIPOPTSolver());
boost::scoped_ptr<daeOptimization_t> pOptimization(new daeOptimization());
// Report ALL variables in the model
pSimulation->GetModel()->SetReportingOn(true);
// Set the time horizon and the reporting interval
pSimulation->SetReportingInterval(10);
pSimulation->SetTimeHorizon(100);
// Connect data reporter
string strName = pSimulation->GetModel()->GetName();
if(!pDataReporter->Connect("", strName))
return;
// Initialise the optimisation
pOptimization->Initialize(pSimulation.get(),
pNLPSolver.get(),
pDAESolver.get(),
pDataReporter.get(),
pLog.get());
// Run
pOptimization.Run();
// Clean up
pOptimization.Finalize();
More information about simulation can be found in User Guide and daeOptimization
.
Also, do not forget to have a look on Tutorials.
Starting the optimisation problems is analogous to running a simulation.