This article explores creating Fluid Tanks from a Basic FR and Process Flow. This turned out to be a lot more complicated than I thought. If you need fluid objects in FlexSim, use the standard fluid objects in the library or buy FloWorks. The approach in this article requires a lot of up-front work just to get started, and you probably want to spend that time configuring well-tested objects instead of cutting your own path.
This article is directed at two audiences:
- Those who don't want to use the fluid library or FloWorks (they have elected the way of pain)
- Those who like learning from example models
If you are still interested, read on!
Kinetic Tracked Variables
Tracked Variables hold a number. As you change the value, the Tracked Variable tracks the min, max, average, etc. You can optionally track the history of the value over time (this history) or the amount of time spent at specific values (the profile). You can also listen to when a Tracked Variable changes.
A special kind of Tracked Variable is a Kinetic Tracked Variable (KTV). A KTV lets you set a rate. The rate is the ratio of the change in value divided by the change in model time units. If you set a rate, the KTV records when you set the rate and the initial value. In this way, you can as a KTV for its value at any point and get the exact continuous value.
KTVs are the heart of this model. You can use a KTV as a label value. Each tank has a label called "Level" that is a KTV that holds the level of the tank. They are also used to represent the progress of a transfer of fluid between tanks.
Custom Draw
The fluid tanks you see in the model are BasicFR objects. The shape of the object is set to a cylinder. The color of the object determines the color of the fluid.
To draw the changing fluid level, the OnDraw trigger of the tanks use the Level label to determine the height of the fluid. Then the OnDraw trigger draws a cylinder covering the remainder of the tank. Because the draw code accesses the Level label's value, the cylinder will change as the value of the Level label changes.
Tank: An Object Process Flow
Most of the logic in this model is defined in an Object Process Flow called Tank. I used an Object Process Flow so that it would be easy to attach other objects to the flow to imbue them with fluid tank logic. In a way, it's like defining a programming class. When you attach an object, you create an instance of that class.
The Tank flow defines behavior for a general fluid tank:
- A Tank can have fluid transferred in, out, or both
- A transfer indicates a source tank and a destination tank, and amount, and a rate. If the source tank is null, then the fluid is generated in the tank. If the destination tank is null, fluid is consumed in the tank.
- A tank can have as many active transfers as the user adds to it. There's not an accompanying concept of "pipes" in this setup.
- Each transfer changes the rate of the Level KTV for each tank.
- If the tank gets full, input transfers are paused until the the tank empties below a threshold (95% of its capacity).
- If the tank gets empty, output transfers are paused until the tank fills above a threshold (5% of its capacity).
- If the tank is stopped, both input and output transfers are paused until the tank is resumed.
The Model Logic
The model logic is contained in the process flow called Process Flow. It picks a random recipe from the Recipes table and uses that to create transfers into the Mixer tank. Once those transfers are complete, the Mixer tank empties itself. When it's completely empty, the tank produces an item. Then that process repeats.
By using an Object Process Flow, the logic for "how to tanks work in general" is separated from "what are the tanks doing."
Pros and Cons
The main con is that you would need to implement this logic yourself rather than starting with an object. This includes finding and fixing bugs. I have found and fixed many bugs in this demo model, but I'm fairly confident there are more. It turns out creating an object is tricky.
However, there are a few pros:
- Compared to the fluid library, there is no ticker. The fluid library relies on a ticker to handle changes in level. This approach uses KTVs instead. KTVs are newer than the fluid library. A ticker adds a frequent event to the model and loops through fluid objects checking for changes. It is possible that the approach in this article is more accurate and faster to run. It's also possible that it's slower, due to the number of process flow activities.
- Compared to FloWorks, there is no monetary cost. This may actually be a con as time spent developing logic is an expense. This approach will take 10x longer or worse to get right. Your future self will thank you for just buying it.
- You have full control over the behavior. If you don't like how something works, or you want to add additional logic, the logic is all available for you to edit. Again, this might be a con, because you have to fix bugs as you make them.
Conclusion
Overall, this demo model shows lots of FlexSim features working together. That is valuable in itself. As a replacement for fluid objects, this demo model isn't a great route, unless you have very specific needs. As I built this model, I realized that I was probably solving the same set of issues that the developers of the fluid library were solving. What I thought was going to be somewhat simple turned out more complicated. I still think this is doable, but I'd look at other options very carefully first.