Process Flow uses FlexSim's powerful lists feature. Using lists, you can:
- Simplify connections in your model
- Sync tokens or objects
- Organize groups of objects
- Track custom statistics
- Use search concepts like filtering and prioritization for making choices in the model
This tutorial will teach you how to use lists in a process flow. It will also teach how to use Resources, which are another type of shared asset in the Process Flow module. You will build a model where items in a queue are transported downstream by operators, and those operators occasionally require water breaks.
Tasks Covered
This tutorial will cover the following tasks:
- Using lists to sort and select different objects
- Using Resources to handle Task Executers
- Advanced properties of lists and Resources
How It Will Work
The model you will build is shown in the following image.
In this model, two operators will be used to move items from the queue to the two processors. Moving items will be their primary responsibility. However, each time an operator travels a total of 100 meters, he or she will become thirsty and need to take a water break. The cylinder shape at the bottom of the model will represent the water cooler location where the operators will go for a water break.
The process flow that will drive the transport of items is shown in the following image.
Standard Functionality Can Do This
FlexSim's standard functionality can actually do much of this logic automatically. All you'd need to do is check the Use Transport box on the Queue and connect it to a Dispatcher. So why use Process Flow? Using Process Flow has several advantages, including:
- The logic for doing water breaks (based on distance traveled), would require custom code on an operator's On Resource Available trigger, which might be difficult for some users.
- Using Process Flow gives you better visibility into the state of the model at any given time, and it gives you more detailed control in directing the operators without having to write custom task sequence code (in this model the operator will travel back to the queue after unloading, rather than staying at the processor).
- Using Process Flow can give you much deeper statistical insight. For example, let's say you want to know how long it takes on average to acquire an operator. This would be difficult to do using the standard mechanism, but it is relatively simple in Process Flow.
That said, if the standard, non-Process-Flow mechanism works for you, by all means use that method. Or you may choose to mix and match between the two methods as needed. Process Flow was designed to allow you the flexibility to choose the method that best meets your needs and capabilities.
Key Concepts
This model will several of the list's features. In order to understand what's going on in the model, you'll need to know a few basic list concepts. See the main list topic for more detailed information on how lists work.
lists
At the most basic level, a list is just that: a list of values. In this model you will use two lists:
- A list of items that need to be transported.
- A list of operators that are available to do work.
lists are dynamic. Their content changes during the simulation run. For example, the list of items to be transported will contain only those items that are in the Queue awaiting transport. Items are added to the list when they become ready to be transported from Queue to Processor. They are removed from the list by the process flow, which then creates the logic that will control the transportation.
Pushing/Pulling and Back Orders
The Process Flow module uses the terms push and pull to represent logic that adds and removes values from a list. Why, you might ask, is it not simply called adding or removing? The answer is that the pull operation represents much more than just the removal of a value:
- A pull may include a search of the list based on a filtering criteria and/or a prioritization rule.
- Also, a pull operation, if it does not immediately find a value to remove, will create a back order on the list. Once a matching value is then pushed onto the list, the back order will be fulfilled and the value will be immediately removed.
- Additionally, the pull operation includes a return value, namely the value that was pulled from the list.
So a pull operation involves much more than just the removal of a value from the list. For that reason, the specialized terms of push and pull are more accurate.
list Fields
lists can also include fields. A field is a defined value associated with the entry on the list. Fields can be used in pull operations to filter and prioritize what should be pulled. In this model you will use list fields to only get "thirsty" operators to take a water break.
Resources and lists
Resources represents a limited supply of some resource that can be acquired and released. It can be used to simulate a supply of goods, services, time, materials, employees, etc. In this model you will use a Resource to manage the availability of the operators. When an item needs an operator, a token will acquire the Resource (one of the operators), and then the operator will be released when those tokens are finished with the operator. When the resource operates in object mode, it can internally use a list to manage which operators are available. It will push each of the operators onto this list when the simulation starts. Then, each acquire will pull an operator from the list, and each release will push the operator back onto the list. This means that you can use the same filtering and prioritization features of a list when acquiring a resource.
Process Flow Logic Areas
The Process Flow will be separated into three main logical sections: Work Generation, Work Execution, and Water Breaks.
Work Generation
The work generation section is what is generating the transport work that needs to be done. Here you will add a Global list called Itemlist1. When an item is ready to be transported from the queue to a processor, logic on the queue will push the item onto Itemlist1. Then within the Process Flow, you will pull from the list. Once pulled, you will create a separate token to perform the transport (Work Execution), and then loop back around and pull the next item from the list.
Work Execution
The work execution section is spawned by Work Generation, and defines the control logic for the operator to transport the item. It primarily acquires an operator, tells the operator to load the item from the queue, then unload it to the processor, then travel back to the queue. Finally, it releases the operator.
Water Breaks
The water breaks section manages when and how to perform water breaks. It acquires a "thirsty" operator. This is where you will use the resource's list features to only acquire an operator who is "thirsty", i.e. an operator who has traveled at least 100 meters since his last water break. Once acquired, you will tell the operator to travel to the water cooler and "drink", i.e. delay for 30 seconds. Then you will save off his travel distance (for use in figuring out when he will become thirsty again), and release the operator. Finally you will loop back and do the whole thing over again.
PerspectivesProcess Flow logic is often implemented from "perspectives". This model, for example, is implemented from the perspective of the work that needs to be done. When items need to be moved, they acquire operators and tell the operators to move them. Even water breaks are implemented from this perspective. The "water breaker" acquires a thirsty operator and tells him to go get water. While you will use this method for this model, that doesn't mean it cannot be implemented from a different perspective. You may, for example, think of the operation through the eyes of the operator. He may look for items and transport them, and then, every time he finishes a transport operation, he checks if he's thirsty and branches to a separate "water break" logic. Each of these perspectives is perfectly valid. While you will use this tutorial model's "work perspective" because it lends itself well to demonstrating list and Resource features, the perspective you use will depend on what seems most intuitive and easy to implement. As you become more acquainted with Process Flow's features, you will become more confident in making this judgment call.
Build the Model Objects
First, you'll create the model's 3D objects.
- From the Library, drag out a source, a queue, an operator, two processors, a shape object, and a sink. Connect them as shown in the following image.
- Open the queue's properties. In the Flow tab, check Use Transport, then click on its button and select Use list > Push to Item list (No Task Sequence).
- In the settings pop-up, under list, press the button and select Add New list.... This will add a new global list named Itemlist1 and open its properties. You can close the properties. The Use Transport settings should be as follows.
The Push to Item list (No Task Sequence) option will push the item onto an item list. It will not create a transport task sequence (you want to create the task sequence ourselves in the Process Flow). Instead, it stores required data on the item's labels (the Store Data on Item code snippet), and pushes the item onto the list. Note that the destination (the processor that the item should to be sent to) is stored on the destination label of the item:
setlabel(item, "destination", destination)
. This will be used in our Process Flow to figure out where to send the item.
Build the Process Flow
Next, you'll define the Process Flow. Create a new General Process Flow from the Toolbox. It will open up in a separate pane to the right. Recreate the layout shown in the following image.
Shared Assets
The Process Flow requires the following shared assets:
- A list
Add the list, name it Itemlist1, and in its properties, under list, press the button. Then move the cursor over Itemlist1 in the Toolbox and click on it (you can move the cursor over the Toolbox tab to select the tab). Choose Tools/Globallists/Itemlist1.
This makes the list block into a "surrogate" for the global list Itemlist1. Any push or pull operations on the list in the Process Flow will operate on the global list.
- A Resource
This resource will manage the operators. Add the resource, name it Operators, and in its properties, under Reference, press the button. Then click on the operator in the 3D model. This associates the resource with that operator.
Next, under Count, enter 2. This will make 2 operators available (an additional operator will be created the next time you reset the model).
Work Generation
The image shows the activities surrounded by a square Flow Chart display object. This does not affect simulation execution, but visually organizes activities. Add this object if desired and place subsequent activities inside it.
The work generation section requires the following activities.
- A Schedule Source activity
Add the activity and name it. Its default settings will create a single token at simulation start. This is exactly what you want, so you can leave its properties as their defaults.
- A Pull From list activity
Add the activity and name it. Then click on its icon and then click on Itemlist1 to connect it to the list. You can leave all other properties as their default, but note that the result of the pull will be assigned to the token's pulled label (its Assign To field). You will use this in the next activity.
The Pull From list activity will pull an item from the list and assign it to the token's pulled label. If an item is not on the list, a back order will be created and the activity will hold the token until the back order is fulfilled.
- A Create Tokens activity
Add the activity and name it. In this case you'll need to look ahead and create the first activity in the Work Execution section, because this activity will create a new token and send it to that activity. So, add an Assign Labels activity, to be defined later in Work Execution, then click on the Create Tokens activity's icon and then click on the activity you created.
In the activity's properties, you won't need a reference back to the parent token, so for Create As select Independent Tokens.
Next, you want to copy the reference to the item from the parent token to the new token. Under Assign Labels to Created Tokens, remove any default label assignments, and then add one. Define it's Name as item, and for its Value enter Label: pulled. This will assign a label named item on the new token to the parent token's pulled label value, which is the reference to the item that was pulled from the list in the previous activity.
Once you've created the activities in the Work Generation section, connect them with connectors as shown in the following image.
Work Execution
The image shows the activities surrounded by a square Flow Chart display object. Add this object if desired and place subsequent activities inside it.
The work execution section requires the following activities.
- An Assign Labels activity
You should have already created this activity when building the work generation section. Name it. In its properties, add a single label assignment, and give it the Name of destination, and for its Value, enter
getlabel(getlabel(token, "item"), "destination")
.This assignment first gets access to the item in the queue (remember you assigned the item label on the newly created token to reference the item in the queue). Then it gets that item's destination label. Remember when you defined the queue properties you noted that the destination was assigned on the item's destination label. Finally, it assigns that destination value to the token's destination label.
To put it more simply, this label assignment is just pulling the destination label from the item to a label on the token. Having labels stored directly on the token can make later operations simpler to define.
- An Acquire Resource activity
Add the activity and name it. Click on the activity's icon and then click on the Operators resource to connect it to the resource.
All other properties can be left as their defaults. Note that the acquired resource will be assigned to the token's resource label. You will use this label to reference the acquired operator.
- A Load activity
Add the activity and name it. In its properties, under Executer / Task Sequence, enter Label: resource.
For Station, click the button, and then click on the queue in the model. Choose Queue3 from the menu.
Make sure the Item value is Label: item
This load activity will tell the operator (the allocated object you assigned to the resource label) to load the item (the object assigned to the token's item label) from Queue3.
- An Unload activity
Add the activity and name it. In its properties, under Executer / Task Sequence, enter Label: resource.
For Station, enter Label: destination.
Make sure the Item value is Label: item
This unload activity will tell the operator (the allocated object you assigned to the resource label) to unload the item (the object assigned to the token's item label) to a destination processor (the object that was assigned originally to the item, and then pulled onto the token's destination label).
- A Travel activity
Add the activity and name it. In its properties, under Executer / Task Sequence, enter Label: resource.
For Destination, click the button, and then click on the queue in the model. Choose Queue3 from the menu.
This travel activity will tell the operator (the allocated object you assigned to the resource label) to travel back to the queue.
- A Release Resource activity
Add the activity and name it. In its properties, make sure that the value for Resource(s) Assigned To is Label: resource.
This activity will release the operator (the allocated object you assigned to the token's resource label).
- A Sink activity
Add the activity and name it.
This activity will finish and destroy the token.
Test the Model
Before moving on to the final section, you should be able to test this model now. Reset and run. Items should enter the queue, and then be transported by the two operators to one of the destinations. You should also see tokens moving through the Process Flow corresponding to events in the 3D model.
Operators Resource Configuration
Before you implement the water breaks section, you need to do some configuration on the Operators resource. Remember that the rule for water breaks was that only "thirsty" operators will take water breaks, i.e. operators who have traveled at least 100 meters since their last water break. You need to add fields to the Operators resource's internal list, to allow us to filter for "thirsty" operators.
- Click on the Operators resource in the Process Flow view. In its properties, press the Advanced button. This will open the properties window for the resource's internal list.
- In the Fields tab, press the button and select TaskExecuter > totalTravel.
This will add a field call totalTravel to the list. This represents the total travel distance of the operator on the list. Once the field is added, you can query its value when you are acquiring the operator.
Notice that the expression for the field's value is
getvarnum(value, "totaltraveldist")
. This gets the variable named totaltraveldist on value (the operator on the list). You will use this same expression later when you want to store off the total travel distance after the operator is finished taking a water break. - In the Fields tab, press the button again, and select Label. In the added Label Field, enter lastDrinkTotalTravel. This adds a field to the list corresponding to a label on the operator named lastDrinkTotalTravel. You will assign this label to the operator's total travel each time the operator finishes a water break.
- Press OK to close the list properties.
Water Breaks
Now you'll build the final section, the logic for performing water breaks.
Like in the other sections, the activities are surrounded by a square Flow Chart display object. Add this object if desired and place subsequent activities inside it.
The water breaks section requires the following activities.
- A Schedule Source activity
Add the activity and name it. You can leave its properties as their defaults. This will create a single token when the simulation starts.
- An Acquire Resource activity
Add the activity and name it. Click on the activity's icon and then click on the Operators resource to connect it to the resource.
Under Query, enter
WHERE totalTravel - lastDrinkTotalTravel > 100
.This where clause tells the activity to only acquire an operator whose total travel since his last water break (
totalTravel - lastDrinkTotalTravel
) is greater than 100. - A Travel activity
Add the activity and name it.
Under Executer / Task Sequence enter Label: resource.
For Destination press the button, and then click on the cylinder object in the model.
This travel activity will tell the operator (the allocated object you assigned to the resource label) to travel to the water cooler shape.
- A Task Sequence Delay activity
Add the activity and name it.
Under Executer / Task Sequence enter Label: resource.
For Delay Time enter 30.
This activity will tell the operator to wait for 30 seconds while "drinking".
- An Assign Labels activity
This is where you will save off the operator's total travel distance to his lastDrinkTotalTravel label. Add the activity and name it.
Under Assign To enter Label: resource.
Add a label assignment, and under Name, enter lastDrinkTotalTravel. For its Value enter
getvarnum(getlabel(token, "resource"), "totaltraveldist")
.This activity will assign a label named lastDrinkTotalTravel to the operator (the allocated object assigned to the token's resource label). The assigned value is the value of the variable named totaltraveldist on the operator (
getlabel(token, "resource")
). Note that this expression is the same as the expression of the list's totalTravel field, expcept that in place of value (the value on a list), you reference an operator reference through the resource label on the token.When the operator is released and consequently pushed back on to the Operators resource's internal list, the lastDrinkTotalTravel field will be updated to the operator's new value.
- A Release Resource activity
Add the activity and name it.
In its properties, make sure that Resource(s) Assigned To is Label: resource.
This activity will release the operator (the allocated object assigned to the token's resource label).
Once you've added these activities, make sure they are connected as shown in the following image.
Run the Simulation
Your model should now be ready. Reset and run the simulation. Now when the operators travel 100 meters, they will travel to the water cooler and "drink" for thirty seconds.
If you want to see the list in more detail, you can view the Operators resource's live entries. While the model is running, click on the Operators resource, and in its properties, press View Entries. This will show a view of the operators that are currently on the list, and their respective totalTravel and lastDrinkTotalTravel values. You can also view back orders (outstanding acquire requests for the resource), by pressing View Back Orders in its properties.