Categories
Dynamic Modeling iOS MacOS Windows

Swift vs Python for Dynamic Simulation

Swift and Python are two programming languages I’ve recently used to write process models for interactive, dynamic simulations. They are both modern and powerful with Swift being the youngest; still evolving and improving. Python is very popular overall and has found use in a number of areas, more recently Machine Learning.

Both Python and Swift support Object-Oriented programming, which is essential for building modular dynamic simulation models. While the syntax for the two languages is different, it is still relatively straightforward to construct a function or a class in one language given the design in the other. But I must say that working from models implemented in Swift towards designs in Python seems easier than the other way around. This could have to do with the fact that Swift is strongly typed and Python is not.

The dynamic nature of Python makes it ideal for rapid construction and experimentation. You can create a class in Python, add some attributes and member functions (also called methods) and test it right away. This is because Python is an interpreted language. What that means is that the keywords and instructions you enter as your program are interpreted by the Python executable and then sent to various pre-compiled functions within the application for execution. The big advantage of this approach is that you don’t have to specify variable types (e.g. int, double, etc) you use; the interpreter figures that out for you from the context of how they are used. However, this flexibility comes at a cost. First, since variables are not explicitly typed there is little to no help or warnings given to you before you run the program. Although debugging is relatively easy, I often find that many errors made by me could readily have been caught by a compiler before I even attempted to hit the “run” button.

The second, and possibly most serious drawback of an interpreted language is execution speed. This is particularly true for simulations of complex models with plenty of math. While there are some areas of computation where execution speed is of secondary importance compared to flexibility, the area of dynamic simulations is not one of them.

At this point you might wonder why I even considered Python for dynamic simulations instead of using fast languages like C++, C#, and Java. And certainly, 20-30 years ago those were my work horses. But back then computers were a lot slower than they are today and every bit of help from a compiled language was needed in order to make an interactive simulation fast enough to be useful. Today the situation is different. Most laptops or even tablets are fast enough to run an interactive, dynamic simulation written in Swift or Python at an acceptable speed. Notice the emphasis on interactive. It means that a process simulation runs much faster than real time but not so fast that you the “operator” don’t have time to interact to make changes. Here is an example of what I’m talking about.

Example of an interactive, dynamic simulation running on an iPad and written in Swift.

So with today’s computers Python cannot be dismissed solely on the basis of execution speed. And once we decide to keep it in the running we can focus on the many advantages offered by the language itself and its rich set of libraries. One of those is the plotting library Matplotlib (https://matplotlib.org). The library is described on its website in one sentence: “Matplotlib is a comprehensive library for creating static, animated, and interactive visualizations in Python”. I would add that it is powerful and easy to use. And very importantly, like Python itself, it’s open source and freely available. You will find many examples in my blogs of how I use Matplotlib in my own research.

In addition to Matplotlib the other library that is practically mandatory for dynamic simulations is NumPy (https://numpy.org). The single sentence characterization of this library is: “The fundamental package for scientific computing with Python”. NumPy is a set of routines written in C that significantly boosts the speed of mathematical expressions used to write dynamic simulation models. In my code examples you will see how I practically always use NumPy.

Another area of great importance for interactive, dynamic simulations is graphical user interfaces (GUI). If you are writing code in Swift for iOS devices you get help in creating slick interfaces from the tools in Apple’s development environment, Xcode. Personally I have never found it particularly easy to get it exactly right but it’s probably my old desktop/laptop background getting in the way of modern iOS thinking. Presumably for the same reasons I have found it easier to work with some of the external libraries that integrate with Python, for example PyQt5 (https://pypi.org/project/PyQt5/ ). This library contains a set of graphical interface routines written in C++ with a Python API. I will show in a separate blog how I have used PyQt5 to build a flexible and reusable interface for dynamic simulations.

It may feel that I’m writing mostly about Python, almost to justify its use. This is partly true because Swift does not need much in terms of justification, Apple got it right from the beginning. Swift not only supports Object-oriented programming but also advocates what they call protocol oriented designs. A Swift protocol is like a C++ or Java interface (if that helps anybody?) and does not have a direct counterpart in Python. Python’s abstract base class has some features along the lines of an interface, but not really. And Swift’s protocols are quite powerful, even more so than a classic Java interface. In fact, you can create a whole design based just on protocols that can later be implemented in various ways.

Swift is a strongly typed and compiled language. What that means is that all class variables you introduce must be of some type (e.g. Int, Double, some class or even a protocol) and be initialized before they are cleared for compilation. This is a huge advantage since you are guaranteed not to send messages to objects that can’t receive them. Of course you can still make logical mistakes just like you can in all programming languages. But that’s up to you and a good debugger to figure out. The compilation into machine code, and linking with runtime libraries, is not overly fast but once your program is compiled it is really fast! We are talking about orders of magnitude faster than Python especially for simulation tasks. And that is with use of NumPy. Surely you can take steps to speed up your Python code but now you have lost some time in development, made the code a little more fragile and perhaps lost some generality. Swift is consistently fast right from the get go.

Now you might think that Swift is the clear winner? Well, if runtime speed were everything it would be. But there are other considerations. While Swift has been made open source (https://www.swift.org) it is still very young and does not yet have nearly the same eco system of support that Python has. What I’m especially missing today is a good plotting package, like Matplotlib, that is freely available and integrates readily with Swift on all platforms. It will come, I’m sure.

Swift was designed by Apple to replace Obj-C, their other language for which many excellent libraries were written. When you run Swift on iOS and OS X devices you take advantage of all that code and enjoy great performance. The open source team is porting Swift (both development and runtime) to other platforms like Windows. I have not tried Swift on Windows yet but I know that Python runs equally well on both platforms.

Conclusions

Swift and Python are both excellent programming languages for writing dynamic simulation models. Both being modern emphasize “people time” over run time. Python is senior to Swift and enjoys a rich set of high quality, open source libraries. Swift is strongly typed, logical and fast. I use both in my work and research. For production and customer requested models I prefer Swift. For my own research and experimentation I prefer Python. Most of my process models are implemented in both languages, developed and tested in one language first and then ported to the other.

Categories
iOS Process Control

Controller Tuning Techniques

Why do I think anybody would be interested in controller tuning? Well, perhaps nobody is, but I can think of a few situations where it is useful to know how to do it or at least be able to tell whether it has been done correctly or not. Here are some scenarios.

  1. You work as a process engineer in a large processing plant. Most likely you are not responsible for the DCS system or loop tuning. However, if a unit is acting up (oscillatory, not staying on spec., etc.) it could be due to one or more poorly tuned controllers. I say could because many times it is a process problem and they are usually harder to fix. That’s why it is good to be able to eliminate controller tuning issues first.
  2. You are in charge of a pilot plant or an elaborate laboratory setup with instruments and controllers. Now you might be responsible checking the instruments and tuning controllers.
  3. You work with data analysis from either of the first two process scenarios. Analyzing dynamic process data can be challenging in its own right but poorly tuned controllers in the mix don’t make it any easier. More than once have I found strange oscillations in process data I’ve analyzed remotely. In those cases I ask the local process engineer or instrument technician for the controller tuning constants to see if they make sense.
  4. You might be a student or a process engineer setting up a dynamic process simulation in some commercial software. Or perhaps you have written your own simulation like I do. In either case you will most likely have some feedback controllers that need to be tuned for the simulation to be stable and give good results.
  5. You might be fortunate, like I was for many years, to be part of design teams for new plants or pilot plants. In those projects you might be responsible for suggesting new control strategies and test them in dynamic simulators. Knowing how to tune the controllers is of course a must in order to gauge whether the system is adequate and to be able to suggest tuning constants for those who ultimately configure the DCS system.

I’m only looking at tuning PID controllers since they are by far the most common controllers in use. If you feel unsure of what a PID controller is, or how it works, I recommend watching one of my YouTube videos, for example https://www.youtube.com/watch?v=sITzOS9sFAg.

Finding the best tuning constants for a PID controller depends to a large extent on what process is being controlled. In the processing industries we can classify a controller as either a flow-, level-, temperature-, pressure-, or composition controller. Once we have made this classification there are some rather simple tuning rules that can be applied to some of the classes. Before I share these simple rules let us take a look at a P&ID for a complete processing plant.

P&ID for a Vinyl acetate process. (adapted from Luyben, M. and Tyreus, B. , Computers Chem. Engng, Vol. 22, No. 7-8, pp. 867-877, 1998.)

I have redrawn this diagram from a paper I published in 1998 with Dr. Michael Luyben. It is useful to name controllers with a suffix to identify their class. So most controllers are either FC, LC, TC, PC, or XC corresponding to flow-, level-, temperature-, pressure-, or composition controllers. Of the 24 controllers in the process, half are either flow, level or pressure. So let me give you some simple tuning rules for these.

  1. Flow controllers: Kc = 0.2 – 0.5, Ti = 0.002 h (=0.12 minutes or 7 seconds). No derivative action allowed in flow loops.
  2. Level controllers: Kc = 2, Ti = 0. If Kc <= 1 is desired then set Ti so the following equality is satisfied Kc * Ti = T_HU where T_HU is the holdup time of the tank in the same units as Ti.
  3. Pressure controllers: Kc = 2 – 10, Ti = 0 for tight pressure control. If for some reason a lower gain is desired, the integral time cannot be too small. A similar rule as with level controllers apply.

Those simple rules took care of 50% of the controllers in our process without having to do plant testing or other process identification.

It is much harder to come up with general guidelines for temperature and composition loops. For these we have to look at the process gain in conjunction with the dead time to time constant ratio (D/tau). Or we can simply perform an ATV test on the process or the simulator and apply the Tyreus-Luyben (Professor William Luyben of Lehigh U. in this case).

Kc = Ku / 3.22, Ti = 2.2 * Pu

The following video demonstrates both the ATV test and the application of the T-L tuning rule to four different cases of a temperature control loop.

Conclusions

In this blog post I hope to have shown that knowing a bit about controller tuning can be useful and does not need to be rocket science. I have presented some general tuning rules for a few classes of controllers and shown how other loops can be identified and tuned. Most modern DCS systems and commercial simulators have provisions to make ATV tests.