Nodes of different colours represent the following:
Solid arrows point from a parent (sub)module to the submodule which is descended from it. Dashed arrows point from a module being used to the module or program unit using it. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | LoopNum | |||
| integer, | intent(in) | :: | LoopSideNum | 
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
TYPE(m_FlowControlValidator) FUNCTION ValidateFlowControlPaths(LoopNum, LoopSideNum) RESULT(ValidLoopSide)
          ! FUNCTION INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   July 2010
          !       MODIFIED       na
          !       RE-ENGINEERED  na
          ! PURPOSE OF THIS FUNCTION:
          ! This routine will scan all the loop side paths and validate the component topology according
          !  to current topology rules and regulations.
          ! METHODOLOGY EMPLOYED:
          ! Scan this loop side and begin by scanning the first branch, then follow with the remainder of the flow paths
          !  - this would be from splitter outlet nodes all the way to the loop side outlet node.
          ! The current rules are that "other types" of components (as defined below in the references) can be placed along each
          !  flow path as needed.  At this point, any number of "load-range based" components can be placed along the flow
          !  path.  After this, the user is allowed to place another set of any number of "other types" of components.
          ! The key restriction is that an "other type" of component may not be sandwiched by "load-range based" components.
          ! This is due to the load range based needing to be simulated all at once along each flow path.
          ! REFERENCES:
          ! "other types" of components: basically not load-range based heat transfer components.  This would include:
          !    - demand based components such as coils
          !    - component setpoint based operating components
          !    - heat exchanger components including waterside economizers
          ! "load-range based" components are heat transfer components which are controlled based on a single load range.
          !    - currently only one load range based scheme is available at a given time, although other control types
          !      may be enabled, such as component setpoint.
          ! Pumps are separate components since the pump heat is not accounted for in the flow path order.
          !  Improvements during the demand side rewrite has allowed pumps to be placed as -not- the first component on a branch
          !  Pumps can be placed anywhere, even between load-range based components, since they will not affect loop load
          ! RETURN VALUE:
          ! Returns a control validator flow structure, including a flag for successful or not, then if not successful
          !  the other values are filled in such as location on the loop where the error occurred and a message error description
          ! USE STATEMENTS:
  USE DataPlant,    ONLY: PlantLoop, LoadRangeBasedMin, LoadRangeBasedMax, PumpOpSchemeType, NoControlOpSchemeType, &
                          UnknownStatusOpSchemeType
  USE DataLoopNode, ONLY: Node
  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN)  :: LoopNum
  INTEGER, INTENT(IN)  :: LoopSideNum
          ! FUNCTION PARAMETER DEFINITIONS:
  INTEGER, PARAMETER   :: Parallel = 1
  INTEGER, PARAMETER   :: Outlet   = 2
          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  !~ Indexing variables
  INTEGER  :: BranchIndex
  INTEGER  :: CompIndex
  INTEGER  :: NumParallelPaths
  INTEGER  :: PathCounter
  INTEGER  :: ParallelOrOutletIndex
  !~ General variables
  LOGICAL  :: EncounteredLRB
  LOGICAL  :: EncounteredNonLRBAfterLRB
  !~ Initialze
  ValidLoopSide%Valid         = .TRUE.
  EncounteredLRB              = .FALSE.
  EncounteredNonLRBAfterLRB   = .FALSE.
  NumParallelPaths            =  PlantLoop(LoopNum)%LoopSide(LoopSideNum)%TotalBranches - 2
  ! We'll start by stepping through the first branch, which may be the only branch
  ! If we find a load range based, then trip the flag and just keep moving
  ! If we only have one branch and all is good, then RETURN early
  ! If we have parallel branches, then start looping through each flow path to
  !  decide if it is a valid path.
  ! If any one path is invalid then all is wrong
  BranchIndex = 1
  DO CompIndex = 1,  PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%TotalComponents
    SELECT CASE (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%CurOpSchemeType)
      CASE (LoadRangeBasedMin:LoadRangeBasedMax) !~ load range based
        IF (EncounteredNonLRBAfterLRB) THEN
          ! We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad
          ValidLoopSide%Valid = .FALSE.
          ValidLoopSide%ErrorPoint%LoopNum     = LoopNum
          ValidLoopSide%ErrorPoint%LoopSideNum = LoopSideNum
          ValidLoopSide%ErrorPoint%BranchNum   = BranchIndex
          ValidLoopSide%ErrorPoint%CompNum     = CompIndex
          ValidLoopSide%Reason  = 'Invalid: Load range based components are separated by other control type components. '//&
                                  'Load Range Based should be grouped together on each flow path.'
          RETURN
        ELSE
          EncounteredLRB = .TRUE.
        END IF
      CASE (PumpOpSchemeType)       !~ pump
        ! For now this is just a placeholder, because I think pumps will be available anywhere,
        !  and they won't affect the load distribution
      CASE (NoControlOpSchemeType)   !~ Such as pipes
        ! For now this is just a placeholder, because these components shouldn't cause a problem anywhere...
      CASE (UnknownStatusOpSchemeType)  !~ Uninitialized, this should be a sufficient place to catch for this on branch 1
        !throw fatal
        CALL ShowSevereError('ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: ' &
                    //TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%Name))
        CALL ShowFatalError('ValidateFlowControlPaths: developer notice, Inlet path validation loop')
!        WRITE(*,*) 'Uninitialized operation scheme type for the following component: '
!        WRITE(*,*) 'Name: '//TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%Name)
!        WRITE(*,*) 'TYPE: '//TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%TypeOf)
!        WRITE(*,*) 'Location: Loop/LoopSide/Branch/Comp'
!        100 FORMAT (3(I2,'//'), I2)
!        WRITE(*,100) LoopNum, LoopSideNum, BranchIndex, CompIndex
!        WRITE(*,*) 'Occurs in ValidateFlowControlPaths::Inlet path validation loop'
!        WRITE(*,*) 'Immediate program closure, press ENTER to end.'
!        READ(*,*)
!        STOP 45
      CASE DEFAULT !~ Other control type
        IF (EncounteredLRB) THEN
          EncounteredNonLRBAfterLRB = .TRUE.
        ELSE
          ! For now don't do anything, but we'll see...
        END IF
    END SELECT
  END DO
  ! Return early if we only needed to do the one branch
  IF (NumParallelPaths .LE. 0) RETURN
  ! Now, if we have multiple parallel branches, I think the easiest way is to go all the way from the inlet node
  !  of each parallel branch to the loop outlet node and check the flow path
  ! This way we don't have to remember the conditions on each of the parallel branches when we would finally move
  !  to analyzing the outlet node when all done
  ! This will reduce allocation on the heap because we will keep from storing that array
  ! For each parallel path, we will need to check two branches: the parallel branch and the loopside outlet branch
  DO PathCounter = 1, NumParallelPaths
    DO ParallelOrOutletIndex = Parallel, Outlet
      IF (ParallelOrOutletIndex == Parallel) THEN
        ! The branch index will be the current pathtype + 1 to add the inlet branch
        BranchIndex = PathCounter + 1
      ELSEIF (ParallelOrOutletIndex == Outlet) THEN
        ! The branch index will be the loopside outlet node
        BranchIndex =  PlantLoop(LoopNum)%LoopSide(LoopSideNum)%TotalBranches
      END IF
      !Now that we have the branch index, let's do the control type check over all the components
      DO CompIndex = 1,  PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%TotalComponents
        SELECT CASE (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%CurOpSchemeType)
          CASE (LoadRangeBasedMin:LoadRangeBasedMax) !~ load range based
            IF (EncounteredNonLRBAfterLRB) THEN
              ! We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad
              ValidLoopSide%Valid = .FALSE.
              ValidLoopSide%ErrorPoint%LoopNum     = LoopNum
              ValidLoopSide%ErrorPoint%LoopSideNum = LoopSideNum
              ValidLoopSide%ErrorPoint%BranchNum   = BranchIndex
              ValidLoopSide%ErrorPoint%CompNum     = CompIndex
              ValidLoopSide%Reason='Invalid: Load range based components are separated by other control type components. '//&
                                          'Load Range Based should be grouped together on each flow path.'
              RETURN
            ELSE
              EncounteredLRB = .TRUE.
            END IF
          CASE (NoControlOpSchemeType)   !~ Such as pipes
            ! For now this is just a placeholder, because these components shouldn't cause a problem anywhere...
          CASE (PumpOpSchemeType)       !~ pump
            ! For now this is just a placeholder, because I think pumps will be available anywhere,
            !  and they won't affect the load distribution
          CASE (UnknownStatusOpSchemeType)  !~ Uninitialized, this should be sufficient place to catch for this on other branches
            !throw fatal error
            Call ShowSevereError('ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: ' &
                    //TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%Name))
            CALL ShowFatalError('ValidateFlowControlPaths: developer notice, problem in Parallel path validation loop')
!            WRITE(*,*) 'Uninitialized operation scheme type for the following component: '
!            WRITE(*,*) 'Name: '//TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%Name)
!            WRITE(*,*) 'TYPE: '//TRIM(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchIndex)%Comp(CompIndex)%TypeOf)
!            WRITE(*,*) 'Location: Loop/LoopSide/Branch/Comp'
!            WRITE(*,100) LoopNum, LoopSideNum, BranchIndex, CompIndex
!            WRITE(*,*) 'Occurs in ValidateFlowControlPaths::Parallel path validation loop'
!            WRITE(*,*) 'Immediate program closure, press ENTER to end.'
!            READ(*,*)
!            STOP 45
          CASE DEFAULT !~ Other control type
            IF (EncounteredLRB) THEN
              EncounteredNonLRBAfterLRB = .TRUE.
            ELSE
              ! For now don't do anything, but we'll see...
            END IF
        END SELECT
      END DO !~ CompIndex
    END DO !~ Parallel and Outlet Branches
  END DO !~ Parallel Paths
 RETURN
END FUNCTION ValidateFlowControlPaths