xref: /phasta/phSolver/compressible/MachControl.f90 (revision 3e4d567892ef7e8d6a7306f3925c3cf144cef766)
110167291SKenneth E. Jansen      module MachControl
210167291SKenneth E. Jansen        logical exMC            !Mach Control enable / Does the MC file
310167291SKenneth E. Jansen                                !exist
410167291SKenneth E. Jansen
510167291SKenneth E. Jansen        integer :: MC_iPP       !Probe Point index
610167291SKenneth E. Jansen        integer :: MC_surfID    !Surface ID to identify where to apply
710167291SKenneth E. Jansen                                ! the boundary condition
810167291SKenneth E. Jansen
910167291SKenneth E. Jansen        real*8 :: MC_dt         !simulaiton time step
1010167291SKenneth E. Jansen        real*8 :: MC_MtTarget   !Target throat Mach number
1110167291SKenneth E. Jansen        real*8 :: MC_dMtCO      !M_throat Cut Off (frequency) (for
1210167291SKenneth E. Jansen                                ! filtering the state)
1310167291SKenneth E. Jansen        real*8 :: MC_ulim(2)    !u_inlet velocity limit
1410167291SKenneth E. Jansen                                !u_inlet(1)     lower limit
1510167291SKenneth E. Jansen                                !u_inlet(2)     upper limit
1610167291SKenneth E. Jansen        !States
1710167291SKenneth E. Jansen        real*8 :: MC_Mt         !actual Mach number
1810167291SKenneth E. Jansen        real*8 :: MC_dMtdt      !time derivative of MC_dMt
1910167291SKenneth E. Jansen        real*8 :: MC_dMt        !filtered state deviation from target
2010167291SKenneth E. Jansen        real*8 :: MC_IdMt       !integreal of MC_dMt
2110167291SKenneth E. Jansen
2210167291SKenneth E. Jansen        !Gains
2310167291SKenneth E. Jansen        real*8 :: MC_Kd         !derivative gain
2410167291SKenneth E. Jansen        real*8 :: MC_Kp         !proportional gain
2510167291SKenneth E. Jansen        real*8 :: MC_KI         !integral gain
2610167291SKenneth E. Jansen
2710167291SKenneth E. Jansen        !Variables to apply the boundary condition
2810167291SKenneth E. Jansen        integer, allocatable, dimension(:) :: MC_imapInlet(:)
2910167291SKenneth E. Jansen        integer :: MC_icountInlet   !number of inlet boundary points
3010167291SKenneth E. Jansen        real*8, allocatable, dimension(:) :: MC_vscale(:)   !scaling factor for BL
3110167291SKenneth E. Jansen        real*8 :: MC_BLdelta        !boundary layer thickness
3210167291SKenneth E. Jansen        real*8 :: MC_uInlet     !x-velocity at the inlet
3310167291SKenneth E. Jansen
3410167291SKenneth E. Jansen      end module
3510167291SKenneth E. Jansen
3610167291SKenneth E. Jansen      subroutine MC_init(dt, tstep, BC)
3710167291SKenneth E. Jansen        use MachControl
3810167291SKenneth E. Jansen        use turbSA
39*3e4d5678SCameron Smith        use mkdir_mod
4010167291SKenneth E. Jansen        include "common.h"
4110167291SKenneth E. Jansen        include "mpif.h"
4210167291SKenneth E. Jansen
4310167291SKenneth E. Jansen        dimension :: BC(nshg, ndofBC)
4410167291SKenneth E. Jansen        logical :: MC_existDir
4510167291SKenneth E. Jansen        real*8 :: dt
4610167291SKenneth E. Jansen        real*8 :: vBC, vBCg
4710167291SKenneth E. Jansen        integer :: tstep
4810167291SKenneth E. Jansen        vBCg = 0
4910167291SKenneth E. Jansen
5010167291SKenneth E. Jansen        if(myrank == master) then
5110167291SKenneth E. Jansen          inquire(file="./MachControl/.", exist=MC_existDir)
5210167291SKenneth E. Jansen          if(.not. MC_existDir) then
53*3e4d5678SCameron Smith            call mkdir("./MachControl")
5410167291SKenneth E. Jansen          endif
5510167291SKenneth E. Jansen        endif
5610167291SKenneth E. Jansen
5710167291SKenneth E. Jansen        call MC_readState(tstep)
5810167291SKenneth E. Jansen
5910167291SKenneth E. Jansen        if(exMC) then
6010167291SKenneth E. Jansen          !find the node associated with isetBlowerID_Duct and write the
6110167291SKenneth E. Jansen          !scale vector to linear ramp velocity near the walls.
6210167291SKenneth E. Jansen          allocate(MC_imapInlet(nshg))
6310167291SKenneth E. Jansen          allocate(MC_vscale(nshg))
6410167291SKenneth E. Jansen          call sfID2np(MC_surfID, MC_icountInlet, MC_imapInlet)
6510167291SKenneth E. Jansen
6610167291SKenneth E. Jansen          if(MC_BLdelta > 0) then
6710167291SKenneth E. Jansen            do i = 1, MC_icountInlet
6810167291SKenneth E. Jansen              imapped = MC_imapInlet(i)
6910167291SKenneth E. Jansen
7010167291SKenneth E. Jansen              MC_vscale(i) = min(one, d2wall(imapped)/MC_BLdelta)
7110167291SKenneth E. Jansen              !MC_vscale(i) = d2wall(imapped)/MC_BLdelta
7210167291SKenneth E. Jansen              !if(MC_vscale(i) > 1) MC_vscale(i) = 1
7310167291SKenneth E. Jansen
7410167291SKenneth E. Jansen              !Also look for the inlet velocity. This will get
7510167291SKenneth E. Jansen              !overwritten in the next time step, but it's nice to know
7610167291SKenneth E. Jansen              !what it started with.
7710167291SKenneth E. Jansen              vBCg = max(vBCg, BC(imapped, 3))
7810167291SKenneth E. Jansen            enddo
7910167291SKenneth E. Jansen          endif
8010167291SKenneth E. Jansen
8110167291SKenneth E. Jansen          !Look for the maximum global inlet velocity among all parts.
8210167291SKenneth E. Jansen          if(numpe > 1) then
8310167291SKenneth E. Jansen            call MPI_ALLREDUCE(vBCg, MC_uInlet, 1,
8410167291SKenneth E. Jansen     &           MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_WORLD, ierr)
8510167291SKenneth E. Jansen          endif
8610167291SKenneth E. Jansen
8710167291SKenneth E. Jansen          MC_dt = dt
8810167291SKenneth E. Jansen        endif
8910167291SKenneth E. Jansen      end subroutine
9010167291SKenneth E. Jansen
9110167291SKenneth E. Jansen
9210167291SKenneth E. Jansen      subroutine MC_updateState()
9310167291SKenneth E. Jansen        !Updates the derivative, proportional and integral values used
9410167291SKenneth E. Jansen        !when calculating MC_uInlet.
9510167291SKenneth E. Jansen        !Note: This function uses the most recent values in the TimeData
9610167291SKenneth E. Jansen        !buffer vartsbuff. TD_bufferData should be called prior to this
9710167291SKenneth E. Jansen        !subroutine.
9810167291SKenneth E. Jansen
9910167291SKenneth E. Jansen        use MachControl
1000d32f9a8SKenneth E. Jansen        use timedataC
10110167291SKenneth E. Jansen        include "common.h"
10210167291SKenneth E. Jansen        include "mpif.h"
10310167291SKenneth E. Jansen
10410167291SKenneth E. Jansen        real*8 :: u2, T
10510167291SKenneth E. Jansen        real*8 :: Mt, dMt, MC_alpha
10610167291SKenneth E. Jansen        logical :: bangbang
10710167291SKenneth E. Jansen
10810167291SKenneth E. Jansen        if(myrank == master) then !MC_* are not set on other processors
10910167291SKenneth E. Jansen          T  = vartsbuff(MC_iPP, 5, ivartsBuff)
11010167291SKenneth E. Jansen          u2 = vartsbuff(MC_iPP, 2, ivartsBuff)**2 +
11110167291SKenneth E. Jansen     &         vartsbuff(MC_iPP, 3, ivartsBuff)**2 +
11210167291SKenneth E. Jansen     &         vartsbuff(MC_iPP, 4, ivartsBuff)**2
11310167291SKenneth E. Jansen
11410167291SKenneth E. Jansen          MC_Mt = sqrt(u2/(1.4*Rgas*T))
11510167291SKenneth E. Jansen          dMt = MC_Mt - MC_MtTarget
11610167291SKenneth E. Jansen
11710167291SKenneth E. Jansen          !Note: MC_uInlet should always equal the previous time step;
11810167291SKenneth E. Jansen          !on the first time step of a run, MC_uInlet is computed based
11910167291SKenneth E. Jansen          !off of the maximum inlet velocity in the solution.
12010167291SKenneth E. Jansen          bangbang = MC_uInlet <= MC_uLim(1) .or.
12110167291SKenneth E. Jansen     &               MC_uInlet >= MC_uLim(2)
12210167291SKenneth E. Jansen
12310167291SKenneth E. Jansen          !Low pass filter dMt
12410167291SKenneth E. Jansen          MC_alpha = MC_dt/(MC_dMtCO + MC_dt)
12510167291SKenneth E. Jansen          dMt = MC_alpha*dMt + (1 - MC_alpha)*MC_dMt
12610167291SKenneth E. Jansen
12710167291SKenneth E. Jansen          !Calculate derivatives and integrals
12810167291SKenneth E. Jansen          if(.not. bangbang) then
12910167291SKenneth E. Jansen            !Only integrate when not hitting the limits. This introduces
13010167291SKenneth E. Jansen            !a nonlinearity in the control scheme which minimizes the
13110167291SKenneth E. Jansen            !overshoot when starting from zero initial conditions
13210167291SKenneth E. Jansen            MC_IdMt  = (dMt + MC_dMt)*MC_dt/2 + MC_IdMt !trapezoidal rule
13310167291SKenneth E. Jansen          endif
13410167291SKenneth E. Jansen          MC_dMtdt = (dMt - MC_dMt)/MC_dt !first order BE FD derivative
13510167291SKenneth E. Jansen          MC_dMt = dMt !update the actual state
13610167291SKenneth E. Jansen        endif
13710167291SKenneth E. Jansen      end subroutine
13810167291SKenneth E. Jansen
13910167291SKenneth E. Jansen
14010167291SKenneth E. Jansen      subroutine MC_applyBC(BC)
14110167291SKenneth E. Jansen        use MachControl
14210167291SKenneth E. Jansen        include "common.h"
14310167291SKenneth E. Jansen        include "mpif.h"
14410167291SKenneth E. Jansen
14510167291SKenneth E. Jansen        dimension :: BC(nshg, ndofBC)
14610167291SKenneth E. Jansen        real*8 :: vInlet
14710167291SKenneth E. Jansen        integer :: imapped
14810167291SKenneth E. Jansen        real*8 :: tmp
14910167291SKenneth E. Jansen
15010167291SKenneth E. Jansen        if(myrank .eq. master) then
15110167291SKenneth E. Jansen          MC_uInlet = MC_Kd*MC_dMtdt +
15210167291SKenneth E. Jansen     &                MC_Kp*MC_dMt +
15310167291SKenneth E. Jansen     &                MC_KI*MC_IdMt
15410167291SKenneth E. Jansen
15510167291SKenneth E. Jansen          !clip to [MC_uLim(1),MC_uLim(2)]
15610167291SKenneth E. Jansen          if(MC_uLim(1) < MC_ulim(2)) then
15710167291SKenneth E. Jansen            MC_uInlet = min(max(MC_uInlet, MC_uLim(1)), MC_uLim(2))
15810167291SKenneth E. Jansen          endif
15910167291SKenneth E. Jansen        endif
16010167291SKenneth E. Jansen        if(numpe .gt. 1)
16110167291SKenneth E. Jansen     &    call MPI_Bcast(MC_uInlet, 1, MPI_DOUBLE_PRECISION,
16210167291SKenneth E. Jansen     &                         master, MPI_COMM_WORLD, ierr)
16310167291SKenneth E. Jansen
16410167291SKenneth E. Jansen        if(MC_BLdelta .gt. 0) then !Apply a velocity profile with a BL
16510167291SKenneth E. Jansen          do i = 1, MC_icountInlet
16610167291SKenneth E. Jansen            imapped = MC_imapInlet(i)
16710167291SKenneth E. Jansen            BC(imapped,3) = MC_uInlet*MC_vscale(i)
16810167291SKenneth E. Jansen          enddo
16910167291SKenneth E. Jansen        else   !Apply a uniform inlet velocity.
17010167291SKenneth E. Jansen          do i = 1, MC_icountInlet
17110167291SKenneth E. Jansen            BC(MC_imapInlet(i), 3) = MC_uInlet
17210167291SKenneth E. Jansen          enddo
17310167291SKenneth E. Jansen        endif
17410167291SKenneth E. Jansen
17510167291SKenneth E. Jansen      end subroutine
17610167291SKenneth E. Jansen
17710167291SKenneth E. Jansen
17810167291SKenneth E. Jansen      subroutine MC_printState()
17910167291SKenneth E. Jansen      !Prints the Mach Control states into the output
18010167291SKenneth E. Jansen
18110167291SKenneth E. Jansen        use MachControl
18210167291SKenneth E. Jansen        include "common.h"
18310167291SKenneth E. Jansen
18410167291SKenneth E. Jansen        if(myrank == master) then
18510167291SKenneth E. Jansen          write(*, "('M_throat: ',F8.6,'  dM_throat: ',F8.6)")
18610167291SKenneth E. Jansen     &             MC_Mt, MC_Mt - MC_MtTarget
18710167291SKenneth E. Jansen          write(*,"('dM/dt = ',E14.6,'  M  = ',E14.6,'  I(M) =',E14.6)")
18810167291SKenneth E. Jansen     &             MC_dMtdt, MC_dMt, MC_IdMt
18910167291SKenneth E. Jansen          write(*,"('Kd    = ',E14.6,'  Kp = ',E14.6,'  KI   =',E14.6)")
19010167291SKenneth E. Jansen     &            MC_Kd, MC_Kp, MC_KI
19110167291SKenneth E. Jansen          write(*, "('u_inlet: ',F9.6)") MC_uInlet
19210167291SKenneth E. Jansen        endif
19310167291SKenneth E. Jansen      end subroutine
19410167291SKenneth E. Jansen
19510167291SKenneth E. Jansen      subroutine MC_readState(tstep)
19610167291SKenneth E. Jansen        !Reads the intput / state file for MachControl.
19710167291SKenneth E. Jansen        !Written by: Nicholas Mati      2014-04-19
19810167291SKenneth E. Jansen        !Revision History:
19910167291SKenneth E. Jansen        ! - 2014-04-19: created
20010167291SKenneth E. Jansen        !
20110167291SKenneth E. Jansen        !The file is expected to be of the form:
20210167291SKenneth E. Jansen        ! MC_iPP   MC_surfID  MC_MtTarget
20310167291SKenneth E. Jansen        ! MC_dMtdt MC_dMt MC_IdMt
20410167291SKenneth E. Jansen        ! MC_Kd    MC_Kp  MC_KI
20510167291SKenneth E. Jansen        ! MC_dMtCO MC_BLdelta
20610167291SKenneth E. Jansen
20710167291SKenneth E. Jansen        use MachControl
20810167291SKenneth E. Jansen        include "common.h"
20910167291SKenneth E. Jansen        include "mpif.h"
21010167291SKenneth E. Jansen
21110167291SKenneth E. Jansen        integer :: tstep
21210167291SKenneth E. Jansen        character(len=60) :: fname
21310167291SKenneth E. Jansen
21410167291SKenneth E. Jansen        if(myrank == master) then
21510167291SKenneth E. Jansen          write(fname, "('./MachControl/MachControl.',I0,'.dat')") tstep
21610167291SKenneth E. Jansen          inquire(file=fname, exist=exMC)
21710167291SKenneth E. Jansen
21810167291SKenneth E. Jansen          if(exMC) then
21910167291SKenneth E. Jansen            open(unit=1002, file=fname, status='old')
22010167291SKenneth E. Jansen
22110167291SKenneth E. Jansen            read(1002, *)  MC_iPP,   MC_surfID
22210167291SKenneth E. Jansen            read(1002, *)  MC_Mt,    MC_MtTarget
22310167291SKenneth E. Jansen            read(1002, *)  MC_dMtdt, MC_dMt,    MC_IdMt
22410167291SKenneth E. Jansen            read(1002, *)  MC_Kd,    MC_Kp,     MC_KI
22510167291SKenneth E. Jansen            read(1002, *)  MC_dMtCO, MC_BLdelta
22610167291SKenneth E. Jansen            read(1002, *)  MC_uLim(1), MC_uLim(2)
22710167291SKenneth E. Jansen            close(1002)
22810167291SKenneth E. Jansen
22910167291SKenneth E. Jansen            !If d2wall is not available, then set the inlet BL thickness
23010167291SKenneth E. Jansen            !to zero to disable wall scalling.
23110167291SKenneth E. Jansen            if(iRANS >= 0) MC_BLdelta = 0
23210167291SKenneth E. Jansen          endif
23310167291SKenneth E. Jansen        endif
23410167291SKenneth E. Jansen
23510167291SKenneth E. Jansen        !Only a few values are needed across other processors.
23610167291SKenneth E. Jansen         if(numpe > 1) then
23710167291SKenneth E. Jansen          call MPI_BCAST(MC_BLdelta, 1, MPI_DOUBLE_PRECISION,
23810167291SKenneth E. Jansen     &                          master, MPI_COMM_WORLD, ierr)
23910167291SKenneth E. Jansen          call MPI_BCAST(MC_surfID,  1, MPI_INTEGER,
24010167291SKenneth E. Jansen     &                          master, MPI_COMM_WORLD, ierr)
24110167291SKenneth E. Jansen          call MPI_BCAST(exMC,       1, MPI_INTEGER,
24210167291SKenneth E. Jansen     &                          master, MPI_COMM_WORLD, ierr)
24310167291SKenneth E. Jansen        endif
24410167291SKenneth E. Jansen
24510167291SKenneth E. Jansen      end subroutine
24610167291SKenneth E. Jansen
24710167291SKenneth E. Jansen      subroutine MC_writeState(tstep)
24810167291SKenneth E. Jansen        !Writes a file with the name MachControl.[ts].dat that can later
24910167291SKenneth E. Jansen        !be read in and restarted from.
25010167291SKenneth E. Jansen
25110167291SKenneth E. Jansen        use MachControl
25210167291SKenneth E. Jansen        include "common.h"
25310167291SKenneth E. Jansen
25410167291SKenneth E. Jansen        integer tstep
25510167291SKenneth E. Jansen        character(len=60) :: fname
25610167291SKenneth E. Jansen
25710167291SKenneth E. Jansen        if(myrank == master) then
25810167291SKenneth E. Jansen          write(fname, "('./MachControl/MachControl.',I0,'.dat')") tstep
25910167291SKenneth E. Jansen          open(unit=1002, file=fname, status='unknown')
26010167291SKenneth E. Jansen
26110167291SKenneth E. Jansen          write(1002, "(2(i9))")         MC_iPP,   MC_surfID
26210167291SKenneth E. Jansen          write(1002, "(2(F18.14))")     MC_Mt,    MC_MtTarget
26310167291SKenneth E. Jansen          write(1002, "(3(F18.14))")     MC_dMtdt, MC_dMt,    MC_IdMt
26410167291SKenneth E. Jansen          write(1002, "(3(F18.10))")     MC_Kd,    MC_Kp,     MC_KI
26510167291SKenneth E. Jansen          write(1002, "(2(F18.14))")     MC_dMtCO, MC_BLdelta
26610167291SKenneth E. Jansen          write(1002, "(2(F18.14))")     MC_uLim(1), MC_uLim(2)
26710167291SKenneth E. Jansen          close(1002)
26810167291SKenneth E. Jansen        endif
26910167291SKenneth E. Jansen      end subroutine
27010167291SKenneth E. Jansen
27110167291SKenneth E. Jansen      subroutine MC_finalize()
27210167291SKenneth E. Jansen
27310167291SKenneth E. Jansen        use MachControl
27410167291SKenneth E. Jansen
27510167291SKenneth E. Jansen        deallocate(MC_imapInlet)
27610167291SKenneth E. Jansen        deallocate(MC_vscale)
27710167291SKenneth E. Jansen      end subroutine
27810167291SKenneth E. Jansen
27910167291SKenneth E. Jansen
280