### 18.9.4. Junction Box Example 4: Solver Control

This example stops the Solver when the max, min, or mean value of a variable falls in a specified range. The user specifies the variable, its range and whether to use max, min, or mean in the `USER` section of their CCL. This method can be useful for ventilation cases, where a transient simulation must be performed to determine when a flammable gas or contaminant falls below a certain limit. The routine should be called at the end of each timestep. It is a specialist routine, as it requires knowledge of solver data structures in order to issue the `STOP` instruction. This may require different operation depending on whether the simulation is transient or steady-state.

The following routine solver_control.F is supplied in the `CFXROOT`/examples/UserFortran/ directory of your CFX installation. Some comment lines may be omitted below.

    #include "cfx5ext.h"
    dllexport(stopinteg)
          SUBROUTINE STOPINTEG (CZ,DZ,IZ,LZ,RZ)
    C
    C Stops solver when a variable integrated quantity falls in a range
    C Junction box routine, to be called at the end of each timestep
    C
    C Include directives
    #include "cfd_constants.h"
    #include "MMS.h"
    #include "stack_point.h"
    C
    C Arguments
          INTEGER IZ(*)
          CHARACTER CZ(*)*(1)
          DOUBLE PRECISION DZ(*)
          LOGICAL LZ(*)
          REAL RZ(*)
    C External functions
          INTEGER LENACT
          EXTERNAL  LENACT
    C
          CHARACTER*15 CFROMR
          EXTERNAL CFROMR
    C
    C Local parameters
          CHARACTER*(*) ROUTIN
          PARAMETER (ROUTIN = 'STOPINTEG')
    C
    C Local Variables
          CHARACTER*4 CRESLT
          CHARACTER*(MXDNAM) CDIR_GLOB, CDIR_TEST, CZONE
          CHARACTER*80 USER_DOMAIN, USER_VAR, USER_OPER
    C
          REAL USER_MIN, USER_MAX, VAR
    C
    C ======================================================================
    C Executable Statements
    C ======================================================================
    C
    C ----------------------------------------------------------------------
    C Obtain user domain name, assuming one domain only.
    C ----------------------------------------------------------------------
    C
    C---- Obtain global meshdata
    C
          CDIR_GLOB = ' '
          CALL USER_GET_MESH_INFO (ROUTIN,'GET','STOP','LATEST',
         &              ' ',' ',CDIR_GLOB,CRESLT, CZ,DZ,IZ,LZ,RZ)
    C
    C---- CZONE = first solver domain name
    C
          CALL PEEKCA ('/USER/'//CDIR_GLOB//'/CZONE',IONE,CZONE,
         &             'STOP',CRESLT, CZ)
    C
    C---- Convert to user domain name
    C
          CALL CONVERT_NAME_S2U ('Domain',CZONE,' ',USER_DOMAIN,
         &                       CRESLT, CZ,DZ,IZ,LZ,RZ)
    C
    C ----------------------------------------------------------------------
    C Get names and values from /USER
    C ----------------------------------------------------------------------
    C
    C Get names and values from /USER
    C
          CALL USER_PEEKCS ('UserVarName', USER_VAR, 'STOP', CRESLT, CZ)
          CALL USER_PEEKCS ('UserVarOper', USER_OPER, 'STOP', CRESLT, CZ)
          CALL USER_PEEKR ('UserVarMin',IONE, USER_MIN, 'STOP', CRESLT, CZ)
          CALL USER_PEEKR ('UserVarMax',IONE, USER_MAX, 'STOP', CRESLT, CZ)
    C
    C ----------------------------------------------------------------------
    C Obtain the integrated quantity required
    C ----------------------------------------------------------------------
    C
          CALL USER_GET_GVAR (USER_VAR, USER_DOMAIN, USER_OPER,
         &                    CRESLT, VAR, CZ,DZ,IZ,LZ,RZ)
    C
          CALL MESAGE( 'WRITE', ' ')
          CALL MESAGE( 'WRITE', '--------------------------------')
          CALL MESAGE( 'WRITE', 'Entered subroutine '//ROUTIN)
          CALL MESAGE( 'WRITE', '----------------------0---------')
          CALL MESAGE( 'WRITE', ' ')
          CALL MESAGE( 'WRITE', 'Domain Name  = '//USER_DOMAIN)
          CALL MESAGE( 'WRITE', 'User Variable  = '//USER_VAR)
          CALL MESAGE( 'WRITE', 'User Operation = '//USER_OPER)
          CALL MESAGE( 'WRITE', 'Minimum Value  = '//CFROMR(USER_MIN))
          CALL MESAGE( 'WRITE', 'Maximum Value  = '//CFROMR(USER_MAX))
          CALL MESAGE( 'WRITE', 'Integrated Value = '//CFROMR(VAR))
    C
    C ----------------------------------------------------------------------
    C If conditions are met, print a banner and stop after this timestep
    C ----------------------------------------------------------------------
    C
    C Stop achieved by setting /FLOW/ALGORITHM/CONTROL/NEXT_TSTEP to FALSE
          IF (VAR.GE.USER_MIN .AND. VAR.LE.USER_MAX) THEN
    C
            CALL MESAGE( 'WRITE', ' ')
            CALL MESAGE( 'WRITE', '-------------------------------------')
            CALL MESAGE( 'WRITE', 'Stopping the solver in SOLVER_CONTROL ')
            CALL MESAGE( 'WRITE', '-------------------------------------')
            CALL MESAGE( 'WRITE', ' ')
    C
    C Stop flag in case of transient simulation
    C
          CALL POKEL ('/FLOW/ALGORITHM/CONTROL/NEXT_TSTEP',IONE,.FALSE.,
         &              'STOP', CRESLT, LZ)
    C
    C Stop flag in case of steady-state simulation
    C
    C        CALL POKEL ('/FLOW/ALGORITHM/CONTROL/STOP_TSL',IONE,.TRUE.,
    C     &              'STOP', CRESLT, LZ)
    CC
          END IF
    C
          END

Release 18.2 - © ANSYS, Inc. All rights reserved.