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