The FixedResource is a superclass of the Source, Queue, Processor, Sink, Combiner, Separator, Rack, and MultiProcessor objects. It defines logic for pulling flowitems into the station, as well as sending the object on. You will not drag this object explicitly into your model, but will instead edit FixedResource logic using the Flow tab of sub-class objects.
Details
The term FixedResource describes a class of objects that handles flowitems in a certain way. They receive flowitems through their input ports, do something to those flowitems, then release the flowitems to be sent on through their output ports. While different types of FixedResources receive and release flowitems at different times, the processes of receiving and releasing a flowitem are the same for all FixedResources. For example, the Queue can receive several flowitems at the same time. The Queue also releases each flowitem as soon as it enters the Queue. The Processor on the other hand receives exactly one flowitem, processes that flowitem, then releases it and waits until the flowitem has left before receiving the next flowitem. Although the Queue and Processor receive and release flowitems at different times, the processes of receiving and releasing the flowitem are the same for both. Each goes through a certain set of steps for each flowitem that it receives and releases. Some of these steps are automatically handled by the FixedResource, and some allow you as a modeler to define the way flowitems are received and released. All of these modeler-defined inputs can be edited in the Flow tab of an object's Properties window. The following diagram shows the steps that a FixedResource object goes through for each flowitem that it receives and subsequently releases.
1. Open input ports and find a flowitem to receive
When the FixedResource becomes ready to receive a flowitem, it checks first to see if it is in Pull mode. If it is in Pull mode, then it calls the Pull Strategy function. This function returns a value of the input port number to open. If 0 is returned, then it will open all input ports. When an upstream item is released, it calls the Pull Requirement field for that item. This field should return a true (1) or false (0). If true, then it receives the flowitem. If false, then it tries calling the Pull Requirement function again for the next flowitem that has been released, or waits until another flowitem is released by an upstream FixedResource. It continues this loop until the Pull Requirement returns a yes (1) for a particular item, upon which it receives that item. If the object is not in Pull mode, however, then the FixedResource skips all of the pulling logic, and simply waits for the first flowitem that becomes available.
Pull Logic Example
The above diagram shows two FixedResources. The Pulling FixedResource is set to pull from the Upstream Fixed Resource. The Upstream FixedResource has released 3 of its flowitems (green), while 2 flowitems are still being processed (red). When the Pulling FixedResource is ready to receive one of the Upstream FixedResource's flowitems, it calls its Pull Requirement function for each of the 3 released flowitems, until the Pull Requirement function returns a yes (1). As soon as a yes is returned, the Pulling FixedResource will receive that item and finish its pulling logic, until it is ready to receive the next flowitem. If all of the 3 calls to Pull Requirement return a no (0), then the Pulling FixedResource will wait. When flowitem 4 is released later in the simulation, the Pulling FixedResource will then call Pull Requirement for item 4, and if it returns yes, item 4 will be received. If it returns no, this process will repeat until a flowitem is found that meets the Pull Requirement.
Note for a FixedResource waiting for an upstream flowitem to be released: When an upstream flowitem is released, the Pulling FixedResource will only call the Pull Requirement on that specific flowitem. It will not call the Pull Requirement on previously released flowitems for which the Pull Requirement has already returned a no (0).
Note on the Send To Port of upstream objects that an object is pulling from: In FlexSim versions before 6: if an object was configured to pull from upstream objects, the Send To Port of those objects was nullified. In version 6, the Send To Port of upstream objects is evaluated in conjunction with the pull strategy. Both the send-to-port and the pull strategy must be true for the item to be pulled.
2. Process the flowitem
Once the flowitem has entered the FixedResource, the item is "processed" according to the type of FixedResource, and then released. For example, if it is a Processor object, then the flowitem will be processed for a certain amount of time. If it is a Queue object, then the product is released immediately.
3. Release the flowitem and determine which output ports to open
When the flowitem is released, the FixedResource calls the Send To Port function. Like the Pull from Port function, this function returns a port number. The FixedResource then opens that port. If the port number is 0, then it will open all of its output ports. Once the ports are opened, the FixedResource waits until a downstream object becomes ready to receive the flowitem. If the FixedResource is configured to reevaluate its Send To Port, then each time a downstream FixedResource becomes available to receive a new flowitem, the upstream FixedResource will reevaluate the Send To Port for that flowitem. It's important to note here that this is only executed when the downstream object becomes available. It does not continuously evaluate just because a downstream object is already available. If you want to manually force a re-evaluation at some other time than when a downstream object becomes available, then you can do so by calling the openoutput() command on the upstream object.
Note on the returned Send To Port value: If the returned port is greater than 0, then that port will be opened. If the returned port is 0, then all ports will be opened. If the returned port is -1, the flowitem will not be released, and should be released explicitly later on using the releaseitem() command, or should be moved out using the moveobject command. When it is released again, the Send To Port function will be called again. A -1 return value is more for advanced users.
4. Transfer the flowitem to the next station
Once the flowitem is released, and a downstream object is ready to receive it, if the "Use Transport" checkbox is not checked, then the item will be passed immediately in to the downstream object. If the "Use Transport" checkbox is checked, then the FixedResource will call the Request Transport from function. This function should return a reference to a TaskExecuter or Dispatcher. If a valid reference is returned, then a default task sequence will automatically be created, and a TaskExecuter will eventually pick the flowitem up and take it to its destination. You can also return a 0 value in the Request Transport From field. If a 0 value is returned, then the FixedResource will assume that a task sequence has been created explicitly by the user, and will not create the default task sequence himself. If you return a zero, then you will need to create the task sequence yourself. You can easily get started at doing this by selecting the "Create task sequence manually" pick option in the Request Transport Field picklist, then manually editing the code from there.
Using a Transport
If an object is configured to use a transport to transport flowitems to downstream objects, then when the downstream object pulls the flowitem or becomes ready to receive the flowitem, instead of immediately moving the flowitem into the next station, the object creates a task sequence for a TaskExecuter to travel to the object, pick up the flowitem, travel to the downstream object, and drop it off there. This operation involves several important steps. First, when this happens, the object calls its Request Transport From function, and gets a reference of the object to give the task sequence to. Then the flowitem goes into a "Waiting For Transport" state. This means that the destination for that flowitem has been set in stone, and cannot be changed. Send To Port and pull screening has already finished and decided on sending the flowitem out that port, and this decision will not change. Also, each FixedResource object keeps track of two numbers: the number of flowitems that are in transit to the object, and the number of flowitems that will be transported out of the object, but have not been picked up yet. These two variables are respectively called nroftransportsin and nroftransportsout. Once the object has called the Request Transport From field, it increments its own nroftransportsout variable, and notifies the downstream object, which subsequently increments its own nroftransportsin variable. The object then creates a task sequence of:
- Travel to the upstream object: Travel task.
- Load the item: FRLoad task.
- Break to other task sequences if appropriate: Break task.
- Travel to the downstream object: Travel task.
- Unload the item into the downstream object: FRUnload task.
Note that the FixedResource uses frload/frunload tasks instead of regular load/unload tasks. These tasks are just like regular load and unload tasks except that right before the TaskExecuter moves the flowitem, it notifies the FixedResource of the operation being done, so that the FixedResource can appropriately decrement its nroftransportsin/nroftransportsout variable. In summary, the nroftransportsout of the upstream object and the nroftransportsin variable of the downstream object are both incremented at the same time that the Request Transport From function is called and the task sequence is created. The nroftransportsout variable is then decremented just before the TaskExecuter finishes the frload tasks and moves the flowitem out of the upstream object. The nroftransportsin variable is decremented just before the TaskExecuter finishes an frunload task and moves the flowitem into the downstream object.
The integrity of the nroftransportsin and nroftransportsout variables is essential to the correct operation of the objects involved because each object may screen further input/output based on these variables. For example, consider a queue with capacity of 10. If the queue's current content is 5 and it also has 5 products that have not arrived yet, but are in transit to the queue, then the queue must close its input ports because it may possibly become full, even though at this point it only has 5 products. An incorrect nroftransportsin variable could cause serious problems for the queue's content. What does this mean for you? Two things. First, if an object has chosen to transport a flowitem to a given downstream object, there is no turning back or redirecting the flowitem to a different destination, because this would mess up the proper decrementing of nroftransportsin/out variables. Secondly, be very aware of when you use frload/frunload versus regular load/unload, because this can affect the input/output functionality of the objects. Simply put, each execution of a Request Transport From function should eventually (if not immediately) result in the creation of exactly one frload task to load the item from the upstream object and exactly one frunload task to unload the item to the downstream object. In all other cases, regular load and unload tasks should be used.
Alternatives to Using Port Connections
You can control the flow of items between fixed resources using a few different methods:
- Use standard port connections and standard send-to/pull logic as explained in the previous sections.
- Push and pull from a list, instead of connecting output/input ports.
- Initiate transport manually, bypassing port hand-shaking logic.
The following sections describe these scenarios.
Using Standard Port Connections
It's important to first explain what the standard port connection mechanism is doing.
- Ports define the objects a FixedResource can send to and pull from
When you connect FixedResource input and output ports together, you are defining the search patterns by which upstream FixedResources can find downstream FixedResources to send their items to, and/or the search patterns by which downstream FixedResources can find items to pull from upstream FixedResources. For example, when a downstream FixedResource is ready to receive its next item, it is limited in its search for receivable items to the objects that are connected to its input ports. Also it will search them in the order that the ports are connected (input port 1 first, then port 2, and so forth).
- Ports contain open/closed state to determine availability
Input and output ports can be open or closed. FixedResources use this open/closed state in deciding where items can go. When an item is released to port 1, for example, the object's output port 1 is made open (green). If the corresponding input port of the downstream object is also open (green), then that is a signal that the downstream object is ready to receive an item, so the item will be sent to that downstream object.
- Port rankings can be important
If you are use routing rules based on defined values, i.e. itemtype or labels, port rankings can be important. For example, if you're sending by itemtype directly, then items with itemtype 1 will be sent to port 1. This means you must make sure your port rankings are ordered correctly.
Situations That Work Well Using Port Connections
- One-to-One Routing - Port connections work well when you're just sending an item from one station to a single next station. Just connect the the upstream station to the downstream station with an 'A' connection.
- One-to-Many Routing - Using port connections works well if you're sending an item from one station to one of many stations using a basic routing rule like round-robin, first available, random, or by some defined value like itemtype. Just connect the station to the set of downstream stations, then define the routing rule through the Send To Port field in the object's Flow tab.
- Many-to-One Routing - Using port connections can work well if you're send an item from one of many stations to a single downstream station using a basic pulling rule like round-robin, first available, longest waiting, random, or by some defined value like item type. Just connect each upstream station to the downstream station, then define the pulling rule through the Pull Strategy field in the object's Flow tab.
Pushing and Pulling from a List
Some scenarios can make the management of port connections difficult, such as many-to-many routing, or when prioritization is complex. In these cases, using Lists to define the search pattern for sending and receiving items can be easier than using ports. The connectionless routing example shows how to do this.
In this example you use pick list options that push and pull from an item list. These pick list options override the default port connection mechanism. Here the upstream objects' Send To Port logic pushes items onto the list, while downstream objects' Pull Strategy pulls items from the list. The search pattern is thus defined by the items that are on the list at any given time, i.e. the items that have been released by upstream objects. Since the searching relies solely on the list, connecting ports is no longer necessary, so you can leave objects that use this mechanism unconnected.
Initiating Transport Manually
In some cases, you may want to initiate transport of items before the downstream object(s) are ready to receive them. As explained above, when using standard send-to/pull logic, transport defined by the Use Transport checkbox will only be initiated when the downstream object is ready to receive the item. To override this functionality you would need to bypass the send-to/pull mechanism altogether. To do this, leave the upstream and downstream object input and output ports unconnected. Then use triggers on the upstream object(s), such as OnEntry or OnProcessFinish, to manually create a task sequence to transport the items to their destinations. If you are using the Process Flow module, you could use an Event-Triggered Source to start a custom process when the desired event happens. You can use center ports for referencing between objects.