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