/// <summary>
        /// Initialization: Patient arrival stream for waiting list patients is initialized.
        /// If dispatching is done at discrete events this stream is initialized as well.
        /// </summary>
        /// <param name="startTime">Time the simulation starts</param>
        /// <param name="simEngine">SimEngine that handles the simulation run</param>
        protected override void CustomInitialize(DateTime startTime, ISimulationEngine simEngine)
        {
            WaitingListSchedule.Initialize(startTime);

            AddEntity((EntityWaitingListSchedule)WaitingListSchedule);

            DateTime      nextArrivalTime;
            Admission     admission;
            EntityPatient newPatient = InputData.GetNextWaitingListPatient(out nextArrivalTime, out admission, this, startTime);

            if (newPatient != null)
            {
                EventOutpatientWaitingListPatientArrival nextArrival =
                    new EventOutpatientWaitingListPatientArrival(this,
                                                                 (ControlUnitOutpatient)ParentControlUnit,
                                                                 newPatient,
                                                                 admission,
                                                                 InputData);

                simEngine.AddScheduledEvent(nextArrival, nextArrivalTime);
            } // end if

            WaitingListSchedule.ReadyForDispatch = true;

            if (AssigningSlotsAtEvents)
            {
                EventOutpatientStartDispatching nextDispatch = new EventOutpatientStartDispatching(this, WaitingListSchedule, InputData);

                simEngine.AddScheduledEvent(nextDispatch, InputData.NextDispatching(startTime));

                WaitingListSchedule.ReadyForDispatch = false;
            }
        } // end of Initialize
 protected override void CustomInitialize(DateTime startTime, ISimulationEngine simEngine)
 {
     if (startTime.Date + InputData.InPatientStartTime() >= startTime)
     {
         simEngine.AddScheduledEvent(new EventInpatientDayStart(this), startTime + InputData.InPatientStartTime());
     }
     else
     {
         simEngine.AddScheduledEvent(new EventInpatientDayStart(this), startTime.Date + TimeSpan.FromDays(1) + InputData.InPatientStartTime());
     } // end if
 }     // end of Initialize
示例#3
0
        } // end of AffectedEntities

        #endregion

        //--------------------------------------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------------------------------------

        #region TriggerStartEvent
        /// <summary>
        /// Overrides the state change at start. Server is not idle, and end event is triggered.
        /// </summary>
        override public void StateChangeStartEvent(DateTime time, ISimulationEngine simEngine)
        {
            double serviceTimeMinutes = ((SimulationModelQueuing)ParentControlUnit.ParentSimulationModel).ServiceTime;

            Server.IsIdle = false;
            simEngine.AddScheduledEvent(EndEvent, time + TimeSpan.FromMinutes(Distributions.Instance.Exponential(serviceTimeMinutes)));
        } // end of TriggerStartEvent
        } // end of ControlUnit

        #endregion

        #region Initialize

        /// <summary>
        /// Initializes patient stream
        /// </summary>
        /// <param name="startTime">Start time of the simulation model</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void CustomInitialize(DateTime startTime, ISimulationEngine simEngine)
        {
            EntityPatient patient = InputData.GetNextPatient();

            EventEmergencyPatientArrival firstPatient = new EventEmergencyPatientArrival(this, patient, InputData);

            simEngine.AddScheduledEvent(firstPatient, startTime + InputData.PatientArrivalTime(startTime));
        } // end of Initialize
        } // end of Initialize

        #endregion

        //--------------------------------------------------------------------------------------------------
        // Rule Handling
        //--------------------------------------------------------------------------------------------------

        #region PerformCustomRules

        /// <summary>
        /// Dispatches slot requests by booking in the booking model, further, now show probabilities
        /// and arrival deviations of patients are calculated. Corresponding events for arrival are scheduled.
        /// </summary>
        /// <param name="startTime">Time rules are executed</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        /// <returns>False</returns>
        protected override bool PerformCustomRules(DateTime time, ISimulationEngine simEngine)
        {
            if (RAEL.Count == 0)
            {
                return(false);
            }

            if (!WaitingListSchedule.ReadyForDispatch)
            {
                return(false);
            }

            while (RAEL.Count > 0)
            {
                RequestOutpatientWaitingListPatientToAssignSlot reqToDisptatch = (RequestOutpatientWaitingListPatientToAssignSlot)RAEL.First();

                DateTime earliestTime = time;

                earliestTime = reqToDisptatch.EarliestTime;

                Slot slot = WaitingListSchedule.GetEarliestSlotTime(time,
                                                                    earliestTime,
                                                                    reqToDisptatch.Patient,
                                                                    reqToDisptatch.AdmissionType);

                WaitingListSchedule.BookSlot(slot, reqToDisptatch.AdmissionType);

                reqToDisptatch.Patient.StopCurrentActivities(time, simEngine);
                ParentControlUnit.RemoveRequest(reqToDisptatch);
                RemoveRequest(reqToDisptatch);

                if (InputData.NoShowForAppointment(reqToDisptatch.Patient, reqToDisptatch.AdmissionType, slot, time))
                {
                    continue;
                }

                DateTime arrivalTime = slot.StartTime + InputData.PatientArrivalDeviationFromSlotTime(reqToDisptatch.Patient, reqToDisptatch.AdmissionType);

                arrivalTime = new DateTime(Math.Max(time.Ticks, arrivalTime.Ticks));

                EventOutpatientArrival arrival = new EventOutpatientArrival(ParentControlUnit,
                                                                            reqToDisptatch.Patient,
                                                                            slot.StartTime,
                                                                            InputData,
                                                                            reqToDisptatch.AdmissionType);

                simEngine.AddScheduledEvent(arrival, arrivalTime);

                Event patientWait = reqToDisptatch.Patient.StartWaitingActivity(null);

                patientWait.Trigger(time, simEngine);
            } // end while

            WaitingListSchedule.ReadyForDispatch = false;

            return(false);
        } // end of PerformCustomRules
        } // end of Event

        #endregion

        //--------------------------------------------------------------------------------------------------
        // State Change
        //--------------------------------------------------------------------------------------------------

        #region Trigger

        /// <summary>
        /// State change of event. Sets Dispatching flag to true and schedules next event.
        /// </summary>
        /// <param name="time">Current time</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            WaitingListSchedule.ReadyForDispatch = true;

            EventOutpatientStartDispatching nextDispatch =
                new EventOutpatientStartDispatching(ParentControlUnit, WaitingListSchedule, InputData);

            simEngine.AddScheduledEvent(nextDispatch, InputData.NextDispatching(time));
        } // end of Trigger
        }     // end of

        #endregion

        #region Initialize

        /// <summary>
        /// Arrival stream of clients is initialized
        /// </summary>
        /// <param name="startTime">Start time of simulation</param>
        /// <param name="simEngine">End time of simulation</param>
        protected override void CustomInitialize(DateTime startTime, ISimulationEngine simEngine)
        {
            EntityClient nextClient = new EntityClient();

            EventClientArrival nextClientArrival = new EventClientArrival(this, nextClient);

            double arrivalTimeMinutes = ((SimulationModelQueuing)ParentSimulationModel).ArrivalTime;

            simEngine.AddScheduledEvent(nextClientArrival, startTime
                                        + TimeSpan.FromMinutes(Distributions.Instance.Exponential(arrivalTimeMinutes)));
        } // end of CustomInitialize
        } // end of OutpatientControlUnit

        #endregion

        #region Initialize

        /// <summary>
        /// Initializes walk in patient stream
        /// </summary>
        /// <param name="startTime">Start time of the simulation model</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void CustomInitialize(DateTime startTime, ISimulationEngine simEngine)
        {
            DateTime arrivalWalkIn;

            EntityPatient patient = InputData.GetNextWalkInPatient(out arrivalWalkIn, ParentControlUnit, startTime);

            if (patient != null)
            {
                EventOutpatientWalkInPatientArrival firstPatient = new EventOutpatientWalkInPatientArrival(this, InputData, patient);

                simEngine.AddScheduledEvent(firstPatient, arrivalWalkIn);
            } // end if
        }     // end of Initialize
示例#9
0
        } // end of ControlUnitOutpatient

        #endregion

        #region Initialize

        /// <summary>
        /// Overrides basic initialiing method. Besides standard operations a possible walk in stream of
        /// patients is
        /// </summary>
        /// <param name="startTime">Time the simulation starts</param>
        /// <param name="simEngine">SimEngine that handles the simulation run</param>
        public override void Initialize(DateTime startTime, ISimulationEngine simEngine)
        {
            base.Initialize(startTime, simEngine);

            EntityPatient nextPatient = null;
            DateTime      nextArrivalTime;

            if ((nextPatient = InputData.GetNextWalkInPatient(out nextArrivalTime, this, startTime)) != null)
            {
                EventOutpatientWalkInPatientArrival nextArrival = new EventOutpatientWalkInPatientArrival(this, InputData, nextPatient);

                simEngine.AddScheduledEvent(nextArrival, nextArrivalTime);
            } // end if
        }     // end of CustomInitialize
示例#10
0
        } // end of Event

        #endregion

        //--------------------------------------------------------------------------------------------------
        // State Change
        //--------------------------------------------------------------------------------------------------

        #region StateChange

        /// <summary>
        /// Overriden state change of the event. Request for service is made, next client arrival is scheduled
        /// </summary>
        /// <param name="time">Time the client arrives</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            // next arrival is scheduled

            EntityClient nextClient = new EntityClient();

            EventClientArrival nextClientArrival = new EventClientArrival(ParentControlUnit, nextClient);

            double arrivalTimeMinutes = ((SimulationModelQueuing)ParentControlUnit.ParentSimulationModel).ArrivalTime;

            simEngine.AddScheduledEvent(nextClientArrival, time
                                        + TimeSpan.FromMinutes(Distributions.Instance.Exponential(arrivalTimeMinutes)));

            ParentControlUnit.AddRequest(new RequestQueing("WaitInQueue", Client, time));
        } // end of Trigger
示例#11
0
        } // end of Event

        #endregion

        //--------------------------------------------------------------------------------------------------
        // State Change
        //--------------------------------------------------------------------------------------------------

        #region Trigger

        /// <summary>
        /// State chage of event. Checks if patient comes from outside of the model. In that case
        /// a new event is triggered. Waiting for assign slot is started.
        /// </summary>
        /// <param name="time">Arriving time</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            if (AdmissionType.IsExtern)
            {
                DateTime      nextArrivalTime;
                Admission     admission;
                EntityPatient newPatient = InputData.GetNextWaitingListPatient(out nextArrivalTime,
                                                                               out admission,
                                                                               ParentControlUnit,
                                                                               time);

                if (newPatient != null)
                {
                    EventOutpatientWaitingListPatientArrival nextArrival =
                        new EventOutpatientWaitingListPatientArrival(ParentControlUnit,
                                                                     OutpatientControlUnit,
                                                                     newPatient,
                                                                     admission,
                                                                     InputData);

                    simEngine.AddScheduledEvent(nextArrival, nextArrivalTime);
                } // end if
            }     // end if

            DateTime earliestTime = (time + TimeSpan.FromDays(AdmissionType.MinDaySpan)).Date;
            DateTime latestTime   = DateTime.MaxValue;

            if (AdmissionType.MaxDaySpan < double.MaxValue)
            {
                latestTime = (time + TimeSpan.FromDays(AdmissionType.MaxDaySpan)).Date;
            }

            ActivityOutpatientWaitingListWaitToAssignSlot waitForAssignment
                = new ActivityOutpatientWaitingListWaitToAssignSlot(ParentControlUnit,
                                                                    Patient,
                                                                    AdmissionType,
                                                                    earliestTime,
                                                                    latestTime);

            SequentialEvents.Add(waitForAssignment.StartEvent);
        } // end of Trigger
        } // end of Event

        #endregion

        //--------------------------------------------------------------------------------------------------
        // State Change
        //--------------------------------------------------------------------------------------------------

        #region StateChange

        /// <summary>
        /// Overriden state change of the event. If the patient is arrving externaly then the next arrival is
        /// scheduled. Else the path is updated and the next/first action is taken from the path.
        /// </summary>
        /// <param name="time">Time the patient arrives</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            // if patient has a path it is updated
            if (Patient.EmergencyTreatmentPath != null)
            {
                Patient.EmergencyTreatmentPath.UpdateNextAction();
            }
            else
            {
                // if patient has no path he is arriving externaly

                // path is created
                Patient.EmergencyTreatmentPath = ((ControlUnitEmergency)ParentControlUnit).InputData.CreateEmergencyPath(Patient);

                // patient is added to control unit
                ParentControlUnit.AddEntity(Patient);

                // arrival of next patient is created and scheduled
                EntityPatient nextPatient = ((ControlUnitEmergency)ParentControlUnit).InputData.GetNextPatient();

                EventEmergencyPatientArrival nextPatientArrival = new EventEmergencyPatientArrival(ParentControlUnit, nextPatient, InputData);

                simEngine.AddScheduledEvent(nextPatientArrival, time + ((ControlUnitEmergency)ParentControlUnit).InputData.PatientArrivalTime(time));
            } // end if

            // next action on path is taken
            if (Patient.EmergencyTreatmentPath.TakeNextAction(simEngine, this, time, ParentControlUnit))
            {
                // possible waiting or waiting in facility is triggered
                if (Patient.OccupiedFacility == null || Patient.OccupiedFacility.ParentDepartmentControl != ParentControlUnit)
                {
                    SequentialEvents.Add(Patient.StartWaitingActivity(((ControlUnitEmergency)ParentControlUnit).WaitingAreaPatientForNextActionType(Patient.EmergencyTreatmentPath.GetCurrentActionType())));
                }
                else
                {
                    ActivityWaitInFacility waitInFacility = new ActivityWaitInFacility(ParentControlUnit, Patient, Patient.OccupiedFacility);
                    SequentialEvents.Add(waitInFacility.StartEvent);
                } // end if
            }     // end if
        }         // end of Trigger
示例#13
0
        } // end of InputData

        #endregion

        //--------------------------------------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------------------------------------

        #region StateChange

        /// <summary>
        /// Overriden state change. Initializes a new arrival and patient paths and first action.
        /// </summary>
        /// <param name="time">Time the patient arrives</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            Patient.OutpatientTreatmentPath =
                InputData.CreateOutpatientTreatmentPath(Patient,
                                                        null,
                                                        time,
                                                        true);

            ParentControlUnit.AddEntity(Patient);

            DateTime nextTime;;

            EntityPatient nextPatient = InputData.GetNextWalkInPatient(out nextTime, ParentControlUnit, time);

            EventOutpatientWalkInPatientArrival nextPatientArrival = new EventOutpatientWalkInPatientArrival(ParentControlUnit, InputData, nextPatient);

            simEngine.AddScheduledEvent(nextPatientArrival, nextTime);

            if (Patient.EmergencyTreatmentPath.TakeNextAction(simEngine, this, time, ParentControlUnit))
            {
                SequentialEvents.Add(Patient.StartWaitingActivity());
            } // end if
        }     // end of StateChange
示例#14
0
        } // end of EventStaffChange

        #endregion

        //--------------------------------------------------------------------------------------------------
        // State Change
        //--------------------------------------------------------------------------------------------------

        #region Trigger

        /// <summary>
        /// Overrides the state change method, staffing levels will change, for leaving
        /// staff requests for absence are filed, incoming staff is added to the
        /// parent control unit
        /// </summary>
        /// <param name="time">Time the staffing changes</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        protected override void StateChange(DateTime time, ISimulationEngine simEngine)
        {
            // foreach leaving staff a request to be absent is filed at their control unit
            // arriving staff is automatically added to the control by the triggering
            // of the event
            foreach (ResourceAssignmentStaff staffAssignment in StaffLeaving)
            {
                ParentDepartmentControl.AddRequest(new RequestBeAbsent(staffAssignment.Resource, time));
                staffAssignment.Resource.StaffOutsideShift = true;
            } // end foreach

            foreach (ResourceAssignmentStaff staffAssignment in StaffAriving)
            {
                staffAssignment.Resource.StaffOutsideShift     = false;
                staffAssignment.Resource.BlockedForDispatching = false;
                staffAssignment.Resource.BaseControlUnit       = ParentDepartmentControl;
                staffAssignment.Resource.AssignmentType        = staffAssignment.AssignmentType;

                if (staffAssignment.OrganizationalUnit == "RootDepartment")
                {
                    ParentDepartmentControl.AddEntity(staffAssignment.Resource);
                }
                else
                {
                    ParentDepartmentControl.OrganizationalUnitPerName[staffAssignment.OrganizationalUnit].AddEntity(staffAssignment.Resource);
                }

                SequentialEvents.Add(staffAssignment.Resource.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(staffAssignment.Resource)));
            } // end foreach

            DateTime nextTime;

            // schedule the next staff change
            Event nextChange = StaffHandler.GetNextStaffChangingEvent(ParentDepartmentControl, time, out nextTime);

            simEngine.AddScheduledEvent(nextChange, nextTime);
        } // end of Trigger
示例#15
0
        } // end of ControlUnitHealthCare

        #endregion

        #region Initialize

        /// <summary>
        /// Overrides the base initialize method of control units. All staff members, treatment facilities
        /// and waiting areas are intialized and assigned to sub organizational control units and structural areas
        /// </summary>
        /// <param name="startTime">Time the simulation starts</param>
        /// <param name="simEngine">SimEngine that handles the simulation run</param>
        public override void Initialize(DateTime startTime, ISimulationEngine simEngine)
        {
            #region TreatmentFacilityInitialize

            string[] structuralAreaIdentifier = InputData.GetStructuralAreaIdentifiers();

            Dictionary <string, StructuralArea> strucArePerName = new Dictionary <string, StructuralArea>();

            // create all structural areas that occur in waiting areas and treamtent facilities
            foreach (string identifier in structuralAreaIdentifier)
            {
                strucArePerName.Add(identifier, new StructuralArea(identifier));
            } // end foreach

            _assingedTreatmentFacilities = new List <EntityTreatmentFacility>();

            ResourceAssignmentPhysical <EntityTreatmentFacility>[] treatmentFacilityAssigns = InputData.GetTreatmentFacilities();

            // assign treatment facilities to organizational and structural areas
            foreach (ResourceAssignmentPhysical <EntityTreatmentFacility> assignment in treatmentFacilityAssigns)
            {
                assignment.Resource.SetParentDepartmentControl(this);

                assignment.Resource.AssignmentType = assignment.AssignmentType;

                if (assignment.OrganizationalUnit != "RootDepartment")
                {
                    // the facility is assigned to the specified organizational control
                    OrganizationalUnitPerName[assignment.OrganizationalUnit].AddEntity(assignment.Resource);
                    OrganizationalUnitPerName[assignment.OrganizationalUnit].AddAssignedTreatmentFacility(assignment.Resource);
                }
                else
                {
                    // if no organizational area was specified or the root department was specified
                    // the facility is added in the department control
                    AddEntity(assignment.Resource);
                    AssignedTreatmentFacilities.Add(assignment.Resource);
                } // end if

                // faciltiy is added to the specified structural area
                if (!strucArePerName.ContainsKey(assignment.StructuralArea))
                {
                    throw new InvalidOperationException("Structural area identifier not specified");
                }

                if (assignment.Resource is EntityMultiplePatientTreatmentFacility)
                {
                    strucArePerName[assignment.StructuralArea].MultiplePatientTreatmentFacilities.Add((EntityMultiplePatientTreatmentFacility)assignment.Resource);
                }
                else
                {
                    strucArePerName[assignment.StructuralArea].TreatmentFacilities.Add(assignment.Resource);
                }
            } // end foreach

            #endregion

            #region WaitingAreas

            // same principle as for treatment facility is used for waiting areas

            foreach (ResourceAssignmentPhysical <EntityWaitingArea> waitingRoomAssignment in InputData.GetWaitingRoomPatients())
            {
                if (waitingRoomAssignment.OrganizationalUnit != "RootDepartment")
                {
                    OrganizationalUnitPerName[waitingRoomAssignment.OrganizationalUnit].AddEntity(waitingRoomAssignment.Resource);
                }
                else
                {
                    AddEntity(waitingRoomAssignment.Resource);
                } // end if

                if (!strucArePerName.ContainsKey(waitingRoomAssignment.StructuralArea))
                {
                    throw new InvalidOperationException("Structural area identifier not specified");
                }

                strucArePerName[waitingRoomAssignment.StructuralArea].WaitingAreasPatients.Add(waitingRoomAssignment.Resource);
            } // end foreach

            foreach (ResourceAssignmentPhysical <EntityWaitingArea> waitingRoomAssignment in InputData.GetWaitingRoomsStaff())
            {
                if (waitingRoomAssignment.OrganizationalUnit != "RootDepartment")
                {
                    OrganizationalUnitPerName[waitingRoomAssignment.OrganizationalUnit].AddEntity(waitingRoomAssignment.Resource);
                }
                else
                {
                    AddEntity(waitingRoomAssignment.Resource);
                } // end if

                if (!strucArePerName.ContainsKey(waitingRoomAssignment.StructuralArea))
                {
                    throw new InvalidOperationException("Structural area identifier not specified");
                }

                strucArePerName[waitingRoomAssignment.StructuralArea].StaffWaitingRoom = waitingRoomAssignment.Resource;
            } // end foreach

            #endregion

            _structuralAres = strucArePerName.Values.ToArray();

            #region StaffInitialze

            // the starting staff assignements specified by the input is obtained
            List <ResourceAssignmentStaff> staffAssignments = InputData.StaffHandler.GetStartingStaff(startTime);

            foreach (ResourceAssignmentStaff staffAssignment in staffAssignments)
            {
                staffAssignment.Resource.StaffOutsideShift     = false;
                staffAssignment.Resource.BlockedForDispatching = false;
                staffAssignment.Resource.BaseControlUnit       = this;
                staffAssignment.Resource.AssignmentType        = staffAssignment.AssignmentType;

                // staff is either assigned to a organizational control or the department control
                if (staffAssignment.OrganizationalUnit == "RootDepartment")
                {
                    AddEntity(staffAssignment.Resource);
                }
                else
                {
                    OrganizationalUnitPerName[staffAssignment.OrganizationalUnit].AddEntity(staffAssignment.Resource);
                }
            } // end foreach

            DateTime nextStaffChange;

            // the next time the staffing levels change an event is scheduled with the associated staff changes
            Event staffChangeEvent = InputData.StaffHandler.GetNextStaffChangingEvent(this, startTime, out nextStaffChange);

            simEngine.AddScheduledEvent(staffChangeEvent, nextStaffChange);

            // all hanlded staff members (doctors and nurses) are sent in a waiting activity
            foreach (EntityDoctor doc in HandledDoctors)
            {
                Event docWait = doc.StartWaitingActivity(WaitingRoomForStaff(doc));
                docWait.Trigger(startTime, simEngine);
            } // end foreach

            foreach (EntityNurse nurse in HandledNurses)
            {
                Event nurseWait = nurse.StartWaitingActivity(WaitingRoomForStaff(nurse));
                nurseWait.Trigger(startTime, simEngine);
            } // end foreach

            #endregion

            // base initializ is called to move down the tree
            base.Initialize(startTime, simEngine);
        } // end of Initilaize
示例#16
0
        } // end of ParentDepartmentControl

        #endregion

        //--------------------------------------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------------------------------------

        #region TriggerStartEvent

        /// <summary>
        /// State changes of the activities start event. Most state changes are standardized and configurable via input.
        /// </summary>
        /// <param name="time"> Time of activity start</param>
        /// <param name="simEngine"> SimEngine the handles the activity triggering</param>
        override public void StateChangeStartEvent(DateTime time, ISimulationEngine simEngine)
        {
            //--------------------------------------------------------------------------------------------------
            // Some activities define the start of corresponding doctor, nurses for future reference
            //--------------------------------------------------------------------------------------------------

            #region CorrespondingStaff

            if (ActionType.DefinesCorrespondingDocStart)
            {
                Patient.CorrespondingDoctor = ResourceSet.MainDoctor;
                ResourceSet.MainDoctor.AddPatient(Patient);
            } // end if

            if (ActionType.DefinesCorrespondingNurseStart)
            {
                Patient.CorrespondingNurse = ResourceSet.MainNurse;
                ResourceSet.MainNurse.AddPatient(Patient);
            } // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // If treatment has doctor(s), busyFactors are assigned
            //--------------------------------------------------------------------------------------------------

            #region AssignBusyFactorsDoctors

            if (ResourceSet.MainDoctor != null)
            {
                ResourceSet.MainDoctor.BusyFactor += ActionType.BusyFactorDoctor;
            }

            if (ResourceSet.AssistingDoctors != null)
            {
                if (ResourceSet.AssistingDoctors.Length != ActionType.BusyFactorAssistingDoctors.Length)
                {
                    throw new InvalidOperationException();
                }

                for (int i = 0; i < ResourceSet.AssistingDoctors.Length; i++)
                {
                    ResourceSet.AssistingDoctors[i].BusyFactor += ActionType.BusyFactorAssistingDoctors[i];
                } // end for
            }     // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // If treatment has nurse(s), busyFactors are assigned
            //--------------------------------------------------------------------------------------------------

            #region AssignBusyFactorsNurses

            if (ResourceSet.MainNurse != null)
            {
                ResourceSet.MainNurse.BusyFactor += ActionType.BusyFactorNurse;
            }

            if (ResourceSet.AssistingNurses != null)
            {
                if (ResourceSet.AssistingNurses.Length != ActionType.BusyFactorAssistingNurses.Length)
                {
                    throw new InvalidOperationException();
                }

                for (int i = 0; i < ResourceSet.AssistingNurses.Length; i++)
                {
                    ResourceSet.AssistingNurses[i].BusyFactor += ActionType.BusyFactorAssistingNurses[i];
                } // end for
            }     // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // Preemption
            //--------------------------------------------------------------------------------------------------

            #region Preemption

            // in case the activity was preempted only the remaining duration is considered for scheduling
            // the end event
            if (DegreeOfCompletion > 0)
            {
                DateTime endTime = time + Helpers <double> .MultiplyTimeSpan(Duration, (1 - DegreeOfCompletion));

                simEngine.AddScheduledEvent(this.EndEvent, endTime);
                return;
            } // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // Occupation
            //--------------------------------------------------------------------------------------------------

            #region Occupation

            // in case of a multiple patient treatment facility the patient
            // is added to the holdeld entities
            if (ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility)
            {
                ((EntityMultiplePatientTreatmentFacility)ResourceSet.TreatmentFacility).HoldedEntities.Add(Patient);
            }
            else
            {
                //--------------------------------------------------------------------------------------------------
                // Set treatmentBooth to occupied
                //--------------------------------------------------------------------------------------------------
                ResourceSet.TreatmentFacility.Occupied = true;

                //--------------------------------------------------------------------------------------------------
                // in case patient is blocking the facility required actions are taken
                //--------------------------------------------------------------------------------------------------
                if (ActionType.DefinesFacilitiyOccupationStart)
                {
                    // facility is blocked for patient
                    ResourceSet.TreatmentFacility.PatientBlocking = Patient;

                    // facility is assigned to patient
                    Patient.OccupiedFacility = ResourceSet.TreatmentFacility;
                } // end if
            }     // end if
            #endregion

            //--------------------------------------------------------------------------------------------------
            // Updating of next Acion and possible skipping of latter
            //--------------------------------------------------------------------------------------------------

            #region UpdateNextAction

            PatientPath.UpdateNextAction();

            T nextActionType = PatientPath.GetCurrentActionType();

            #endregion

            #region PossibleSkipOfNextAction

            //--------------------------------------------------------------------------------------------------
            // A treatment may be skipped, e.g. in case that the current doctor is qualified enough
            // This is defined via the input
            //--------------------------------------------------------------------------------------------------
            while (ParentDepartmentControl.SkipNextAction(Patient, ResourceSet.MainDoctor, ActionType, PatientPath.GetCurrentActionType()))
            {
                PatientPath.UpdateNextAction();
                nextActionType = PatientPath.GetCurrentActionType();
            } // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // In case a holding Activity follows no end event is scheduled
            //--------------------------------------------------------------------------------------------------

            #region HoldingOfPatient

            if (ActionType.IsHold)
            {
                // Staff on hold flag is set to true
                foreach (EntityStaff staff in AffectedEntities.Where(p => p is EntityStaff))
                {
                    staff.OnHold = true;
                } // end foreach

                HoldingRequired = true;
                // in case of holding the next action on the path is taken
                if (PatientPath.TakeNextAction(simEngine, StartEvent, time, ParentControlUnit))
                {
                    // either waiting or waiting in the treatment facility is launched
                    if (Patient.OccupiedFacility == null || Patient.OccupiedFacility.ParentDepartmentControl != ParentDepartmentControl)
                    {
                        EndEvent.SequentialEvents.Add(Patient.StartWaitingActivity(ParentDepartmentControl.WaitingAreaPatientForNextActionType(nextActionType)));
                    }
                    else
                    {
                        ActivityWaitInFacility waitInFacility = new ActivityWaitInFacility(ParentControlUnit, Patient, Patient.OccupiedFacility);
                        EndEvent.SequentialEvents.Add(waitInFacility.StartEvent);
                    } // end if
                }     // end if
            }
            else
            {
                // if the activity is not hold the end event is scheduled
                Duration = InputData.PatientActionTime(Patient,
                                                       ResourceSet,
                                                       ActionType);

                DateTime endTime = time + Duration;
                simEngine.AddScheduledEvent(this.EndEvent, endTime);
            } // end if

            #endregion
        } // end of TriggerStartEvent
示例#17
0
        } // end of AffectedEntities

        #endregion

        //--------------------------------------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------------------------------------

        #region TriggerStartEvent

        /// <summary>
        /// Actual state change, calls the leaving method of the origin control unit and scheduled the end event
        /// </summary>
        /// <param name="time"> Time of activity start</param>
        /// <param name="simEngine"> SimEngine the handles the activity triggering</param>
        override public void StateChangeStartEvent(DateTime time, ISimulationEngine simEngine)
        {
            Origin.EntityLeaveControlUnit(time, simEngine, MovingEntity, DelegateOrigin);
            _endTime = time + Duration;
            simEngine.AddScheduledEvent(EndEvent, time + Duration);
        } // end of TriggerStartEvent