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