} // end of Servers #endregion //-------------------------------------------------------------------------------------------------- // Methods //-------------------------------------------------------------------------------------------------- #region PerformCustomRules /// <summary> /// Custom rule set, basically incoming clients are assinged to queues with minimum length /// and clients are selected from front of queues by FIFO (so FIFO within a single queue and FIFO /// of queue fronts) /// </summary> /// <param name="time">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns></returns> protected override bool PerformCustomRules(DateTime time, ISimulationEngine simEngine) { #region PlacedInQueue List <RequestQueing> waitInQueueRequests = RAEL.Where(p => p.Activity == "WaitInQueue").Cast <RequestQueing>().ToList(); foreach (RequestQueing request in waitInQueueRequests) { // determine the smallest QueueLength int minQueueLength = Queues.Select(p => p.HoldedEntities.Count).Aggregate((curmin, x) => ((x) < curmin ? x : curmin)); // select first queue with minimum length EntityQueue queue = Queues.Where(p => p.HoldedEntities.Count == minQueueLength).First(); queue.HoldedEntities.Add(request.Client); RemoveRequest(request); RequestQueing newReq = new RequestQueing("GetServed", request.Client, time); newReq.QueueAssigned = queue; AddRequest(newReq); } // end foreach #endregion #region GetServerd List <RequestQueing> getServedRequests = RAEL.Where(p => p.Activity == "GetServed").Cast <RequestQueing>().ToList(); while (getServedRequests.Count > 0 && Servers.Where(p => p.IsIdle).Count() > 0) { RequestQueing earliestRequest = getServedRequests.Aggregate((curmin, x) => (curmin == null || (x.TimeRequested) < curmin.TimeRequested ? x : curmin)); ActivityGetServed newService = new ActivityGetServed(this, earliestRequest.Client, Servers.Where(p => p.IsIdle).First()); newService.StartEvent.Trigger(time, simEngine); RemoveRequest(earliestRequest); earliestRequest.QueueAssigned.HoldedEntities.Remove(earliestRequest.Client); getServedRequests.Remove(earliestRequest); } // end while #endregion return(false); } // end of PerformCustomRules
} // end of PerformDisptatching #endregion #region PerformControlled /// <summary> /// Sends assisting staff members that are not further required back to their origin /// control unit /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected bool PerformControlled(DateTime time, ISimulationEngine simEngine) { IEnumerable <EntityDoctor> assistingDocs = HandledDoctors.Where(p => p.BaseControlUnit != this); IEnumerable <RequestOutpatientAction> assistedRequests = RAEL.Where(p => p.GetType() == typeof(RequestOutpatientAction) && ((RequestOutpatientAction)p).IsAssistedDoctor).Cast <RequestOutpatientAction>().ToList(); bool moveTriggered = false; foreach (EntityDoctor doc in assistingDocs) { bool skillRequired = false; if (doc.IsWaiting()) { foreach (RequestOutpatientAction req in assistedRequests) { foreach (SkillSet skillSet in req.ActionType.AssistingDoctorRequirements) { if (doc.SatisfiesSkillSet(skillSet)) { skillRequired = true; } } // end foreach } // end foreach if (!skillRequired) { ControlUnitManagement jointControl = (ControlUnitManagement)FindSmallestJointControl(doc.BaseControlUnit); ActivityMove moveBack = new ActivityMove(jointControl, doc, this, doc.BaseControlUnit, null, jointControl.InputData.DurationMove(doc, this, doc.BaseControlUnit)); doc.StopCurrentActivities(time, simEngine); moveBack.StartEvent.Trigger(time, simEngine); moveTriggered = true; } // end if } // end if } // end foreach return(moveTriggered); return(false); } // end of PerformControlled
} // end of PerformCustomRules #endregion #region PerformDisptatching /// <summary> /// Dispatches all requests with respect to FIFO rule, does not distinguish between /// different treatments (XRay, MRI, CT, Lab) /// </summary> /// <param name="startTime">Start time of the simulation model</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> private bool PerformDisptatching(DateTime time, ISimulationEngine simEngine) { List <RequestSpecialFacilityAction> actionRequests = RAEL.Where(p => p.GetType() == typeof(RequestSpecialFacilityAction)).Cast <RequestSpecialFacilityAction>().ToList(); while (actionRequests.Count > 0) { ResourceSet chosenResources; // Get action request Triage-FIFO RequestSpecialFacilityAction requestAction = PatientPriorityPlusFIFO <RequestSpecialFacilityAction, SpecialServiceActionTypeClass>(actionRequests); actionRequests.Remove(requestAction); if (!ChooseResourcesForAction(requestAction, out chosenResources)) { continue; } // enf if // Remove Request from RAEL list RemoveRequest(requestAction); EntityPatient patient = (EntityPatient)requestAction.Origin.First(); ActivityHealthCareAction <SpecialServiceActionTypeClass> action = new ActivityHealthCareAction <SpecialServiceActionTypeClass>( this, InputData, patient, chosenResources, requestAction.ActionType, patient.SpecialFacilityPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); action.StartEvent.Trigger(time, simEngine); } // end while return(false); } // end of PerformDisptatching
} // end of #endregion //-------------------------------------------------------------------------------------------------- // Methods //-------------------------------------------------------------------------------------------------- #region PerformCustomRules /// <summary> /// Custom rules of control, assigns all requests in specified order, patient priority and FIFO principle is /// used for requests of same type /// </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) { #region Consultation List <RequestEmergencyAction> consultationRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Consultation").Cast <RequestEmergencyAction>()); List <RequestEmergencyAction> possibleConsultationRequests = new List <RequestEmergencyAction>(); #region CheckForControllingAllRequiredResources foreach (RequestEmergencyAction request in consultationRequests) { if (request.ReadyForDispatch) { possibleConsultationRequests.Add(request); } else { List <SkillSet> nonAvailableDoctorSkills = ((ControlUnitEmergencyExample)ParentDepartmentControl).CheckAvailabilityOfDoctors(request.ActionType.MainDoctorRequirements, request.ActionType.AssistingDoctorRequirements); if (nonAvailableDoctorSkills.Count() == 0) { possibleConsultationRequests.Add(request); request.ReadyForDispatch = true; } else { if (nonAvailableDoctorSkills.Count > 0 && !request.StaffRequested) { ((ControlUnitEmergencyExample)ParentDepartmentControl).DelegateOutBox.Add(new DelegateRequestDocsForAssisting(this, nonAvailableDoctorSkills)); } request.StaffRequested = true; } // end if } // end if } // end foreach #endregion while (possibleConsultationRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestConsultation = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(possibleConsultationRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestConsultation, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestConsultation); possibleConsultationRequests.Remove(requestConsultation); EntityPatient patient = (EntityPatient)requestConsultation.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> consultation = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestConsultation.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); consultation.StartEvent.Trigger(time, simEngine); } // end while #endregion #region BedPlacement List <RequestEmergencyAction> bedPlacementRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "BedPlacement").Cast <RequestEmergencyAction>()); while (bedPlacementRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction bedPlacementRequest = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(bedPlacementRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, bedPlacementRequest, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(bedPlacementRequest); bedPlacementRequests.Remove(bedPlacementRequest); EntityPatient patient = (EntityPatient)bedPlacementRequest.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> bedPlacement = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, bedPlacementRequest.ActionType, patient.EmergencyTreatmentPath ); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); bedPlacement.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Assessment List <RequestEmergencyAction> assessmentRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Assessment").Cast <RequestEmergencyAction>()); while (assessmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestAssessment = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(assessmentRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestAssessment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestAssessment); assessmentRequests.Remove(requestAssessment); EntityPatient patient = (EntityPatient)requestAssessment.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> assessment = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestAssessment.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Treatment List <RequestEmergencyAction> treatmentRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Treatment").Cast <RequestEmergencyAction>()); while (treatmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestTreatment = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(treatmentRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestTreatment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list and treatmentlist RemoveRequest(requestTreatment); treatmentRequests.Remove(requestTreatment); EntityPatient patient = (EntityPatient)requestTreatment.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> assessment = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestTreatment.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformCustomRules
} // end of #endregion //-------------------------------------------------------------------------------------------------- // Methods //-------------------------------------------------------------------------------------------------- #region PerformCustomRules /// <summary> /// Custom rules of control, assigns all requests in specified order, patient priority and FIFO principle is /// used for requests of same type /// </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) { #region Register List <RequestEmergencyAction> registerRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Register").Cast <RequestEmergencyAction>()); while (registerRequests.Count > 0) { // Get Register request Triage-FIFO RequestEmergencyAction requestRegister = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(registerRequests); ResourceSet chosenResources; if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestRegister, out chosenResources)) { break; } // enf if RemoveRequest(requestRegister); registerRequests.Remove(requestRegister); EntityPatient patient = (EntityPatient)requestRegister.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> register = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestRegister.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); register.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Triage List <RequestEmergencyAction> triageRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Triage").Cast <RequestEmergencyAction>()); while (triageRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestTriage = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(triageRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestTriage, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestTriage); triageRequests.Remove(requestTriage); EntityPatient patient = (EntityPatient)requestTriage.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> triage = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestTriage.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); triage.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformCustomRules
} // end of PerformAssessment #endregion #region PerformDisptatching /// <summary> /// Handles requests of staff members to leave that are out of shift, routes action requests /// to corresponding organizational control units and handles a shared treatment facility by /// assigning it to the busier organizational unit /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected bool PerformDisptatching(DateTime time, ISimulationEngine simEngine) { #region StaffOutsideShift List <RequestBeAbsent> staffEndRequests = RAEL.Where(p => p is RequestBeAbsent).Cast <RequestBeAbsent>().ToList(); foreach (RequestBeAbsent req in staffEndRequests) { if (req.StaffMember.IsWaiting() && req.StaffMember.CurrentPatients.Count == 0) { req.StaffMember.StopCurrentActivities(time, simEngine); EventStaffLeave staffLeave = new EventStaffLeave(req.StaffMember.ParentControlUnit, req.StaffMember); staffLeave.Trigger(time, simEngine); RemoveRequest(req); } // end if } // end foreach #endregion #region RequestRouting List <RequestEmergencyAction> actionRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction").Cast <RequestEmergencyAction>()); foreach (RequestEmergencyAction request in actionRequests) { if (request.ActionType.Type == "Triage" || request.ActionType.Type == "Register") { OrganizationalUnitPerName["OrgUnitTriageRegister"].AssignRequest(request); } else { if (request.Patient.PatientClass.Category == "Surgical") { OrganizationalUnitPerName["OrgUnitSurgical"].AssignRequest(request); } else { OrganizationalUnitPerName["OrgUnitInternal"].AssignRequest(request); } } // end if RemoveRequest(request); } // end foreach #endregion #region ResourceSharing foreach (EntityTreatmentFacility sharedTreatFac in AssignedTreatmentFacilities.Where(p => p.AssignmentType == AssignmentType.Shared)) { if (sharedTreatFac.PatientBlocking != null) { continue; } if (sharedTreatFac.CurrentlyAssignedOrganizationalUnit != null) { sharedTreatFac.CurrentlyAssignedOrganizationalUnit.RemoveAssignedTreatmentFacility(sharedTreatFac); } if (OrganizationalUnitPerName["OrgUnitInternal"].RAEL.Count > OrganizationalUnitPerName["OrgUnitSurgical"].RAEL.Count) { OrganizationalUnitPerName["OrgUnitSurgical"].AddAssignedTreatmentFacility(sharedTreatFac); } else { OrganizationalUnitPerName["OrgUnitInternal"].AddAssignedTreatmentFacility(sharedTreatFac); } // end if } // end foreach #endregion return(false); } // end of PerformDisptatching
} // end of PerformAssessment #endregion #region PerformDisptatching // <summary> /// Handles requests of staff members to leave that are out of shift, register, assessment and treatment /// using patient slot times and priority /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected bool PerformDisptatching(DateTime time, ISimulationEngine simEngine) { #region StaffOutsideShift List <RequestBeAbsent> staffEndRequests = RAEL.Where(p => p is RequestBeAbsent).Cast <RequestBeAbsent>().ToList(); foreach (RequestBeAbsent req in staffEndRequests) { if (req.StaffMember.IsWaiting() && req.StaffMember.CurrentPatients.Count == 0) { req.StaffMember.StopCurrentActivities(time, simEngine); EventStaffLeave staffLeave = new EventStaffLeave(req.StaffMember.ParentControlUnit, req.StaffMember); staffLeave.Trigger(time, simEngine); RemoveRequest(req); } // end if } // end foreach #endregion #region Register List <RequestOutpatientAction> registerRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Register").Cast <RequestOutpatientAction>()); while (registerRequests.Count > 0) { // Get Register request Triage-FIFO RequestOutpatientAction requestRegister = registerRequests.OrderBy(p => p.TimeRequested).First(); ResourceSet chosenResources; if (!ChooseResourcesForAction(requestRegister, out chosenResources)) { break; } // enf if RemoveRequest(requestRegister); registerRequests.Remove(requestRegister); EntityPatient patient = (EntityPatient)requestRegister.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> register = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestRegister.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); register.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Assessment List <RequestOutpatientAction> assessmentRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Assessment").Cast <RequestOutpatientAction>()); while (assessmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Slottime-FIFO RequestOutpatientAction requestAssessment = PatientSlotTimePlusPriority(assessmentRequests); if (!ChooseResourcesForAction(requestAssessment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestAssessment); assessmentRequests.Remove(requestAssessment); EntityPatient patient = (EntityPatient)requestAssessment.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> assessment = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestAssessment.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Treatment List <RequestOutpatientAction> treatmentRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Treatment").Cast <RequestOutpatientAction>()); while (treatmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestOutpatientAction requestTreatment = PatientPriorityPlusFIFO <RequestOutpatientAction, OutpatientActionTypeClass>(treatmentRequests); if (!ChooseResourcesForAction(requestTreatment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list and treatmentlist RemoveRequest(requestTreatment); treatmentRequests.Remove(requestTreatment); EntityPatient patient = (EntityPatient)requestTreatment.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> assessment = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestTreatment.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformDisptatching