19.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