c----------------------------------------------------------------------- c c This module conveys temporal BC data. Below functions read in the data c and interpolate it to the current time level. c c----------------------------------------------------------------------- module specialBC use pointer_data real*8, allocatable :: BCt(:,:), acs(:,:), spamp(:) real*8, allocatable :: ytarget(:,:) real*8, allocatable :: BCperiod(:) integer, allocatable :: nBCt(:), numBCt(:) type(r2d),dimension(:),allocatable :: BCtptr ! BCtptr%p(:,:) is to replace BCt(ic,:,:), in which ! the second index is dynamically decided in ! the setup stage. integer ntv,nptsmax c$$$ integer itvn end module c----------------------------------------------------------------------- c c This module conveys flow rate history for the different impedance outlets c over one period. Below functions read in the data and store it for the c current time level. c c----------------------------------------------------------------------- module convolImpFlow real*8, allocatable :: QHistImp(:,:), ValueImpt(:,:,:) real*8, allocatable :: ValueListImp(:,:), ConvCoef(:,:) real*8, allocatable :: ImpConvCoef(:,:), poldImp(:) integer ntimeptpT,numDataImp integer, allocatable :: nImpt(:), numImpt(:) integer nptsImpmax real*8, allocatable :: QHistTry(:,:), QHistTryF(:,:) !filter integer cutfreq !filter end module c----------------------------------------------------------------------- c c This module conveys the parameters for the different RCR outlets. c Below functions read in the inputs (proximal resistance, capacitance, c distal resistance and distal pressure) and store it for the c current time level. c c----------------------------------------------------------------------- module convolRCRFlow real*8, allocatable :: ValueListRCR(:,:), ValuePdist(:,:,:) !inputs real*8, allocatable :: QHistRCR(:,:), HopRCR(:) !calc real*8, allocatable :: RCRConvCoef(:,:), poldRCR(:) !calc real*8, allocatable :: dtRCR(:) !scaled timestep: deltat/RdC real*8, allocatable :: RCRic(:) !(P(0)-RQ(0)-Pd(0)) integer nptsRCRmax,numDataRCR !to read inputs integer, allocatable :: numRCRt(:) !to read inputs end module c----------------------------------------------------------------------- c c Initialize: c c----------------------------------------------------------------------- subroutine initSponge( y,x) use specialBC include "common.h" real*8 y(nshg,nflow), x(numnp,3) allocate (ytarget(nshg,nflow)) if(matflg(5,1).eq.5) then write(*,*) 'calculating IC sponge' ytarget = y else write(*,*) 'calculating Analytic sponge' c c OLD style sponge pushed onto target. You need to be sure that your c solver.inp entries for start and stop of sponge match as well as the c growth rates c vcl=datmat(1,5,1) ! velocity on centerline rslc=datmat(2,5,1) ! shear layer center radius bfz=datmat(3,5,1) we=3.0*29./682. rsteep=3.0 zstart=30.0 radst=10.0 radsts=radst*radst do id=1,numnp radsqr=x(id,2)**2+x(id,1)**2 c if((x(id,3).gt. zstart) .or. (radsqr.gt.radsts)) then rad=sqrt(radsqr) radc=max(rad,radst) zval=max(x(id,3),zstart) utarget=(tanh(rsteep*(rslc-rad))+one)/two* & (vcl-we) + we Ttarget = press/(ro*Rgas) ptarget= press ytarget(id,1) = zero ytarget(id,2) = zero ytarget(id,3) = utarget ytarget(id,4) = ptarget ytarget(id,5) = Ttarget c endif enddo endif return end c----------------------------------------------------------------------- c c Initialize:time varying boundary condition c c----------------------------------------------------------------------- subroutine initBCt( x, iBC, BC ) use specialBC include "common.h" real*8 x(numnp,nsd), BC(nshg,ndofBC), rj1,rj2,rj3,rj4,distd,epsd integer iBC(nshg) character*80 card real*8 distds real*8 dd integer irstart real(kind=8),allocatable,dimension(:) :: bcttest real*8 t0,tlen,t1,tstart,tend integer i0,ilen,i1,nper,istart,iend c c This one should be used for boundary layer meshes where bct.dat must c be given to greater precision than is currently being generated. c c epsd=1.0d-12 ! this is distance SQUARED to save square root epsd=1.0d-8 ! this is distance SQUARED to save square root ic=0 !count the number on this processor ! ************ Chun Sun: limit the memory use if required time steps ! ************ is smaller than total bct.dat length. ! readin the start timestep open(unit=72,file='numstart.dat',status='old') read(72,*) irstart close(72) ! use irstart-1 and nstep+1 to avoid machine tolerance issues t0 = max(zero,(irstart-1)*Delt(1)) tlen = (nstep(1)+1)*Delt(1) ! Assumption: constant time step in one run. If you use variable ! time step in one run, this should be modified. t1 = t0 + tlen if(myrank.eq.master) & write(*,*) 'necessary bct timing: from ',t0,' to ',t1 ! ************************************************************** if(any(ibits(iBC,3,3).eq.7)) then if(myrank.eq.master) write(*,*) 'opening bct.dat' c open(unit=567, file='bct.dat',status='old') open(unit=567, file='bct.dat',ACTION='READ',STATUS='old') read (567,'(a80)') card read (card,*) ntv, nptsmax c read(567,*) ntv,nptsmax allocate (nBCt(numnp)) allocate (numBCt(ntv)) allocate (BCt(nptsmax,4)) allocate (BCperiod(ntv)) allocate (BCtptr(ntv)) ! dynamic bct allocation do k=1,ntv read(567,*) x1,x2,x3,ntpts c c Find the point on the boundary (if it is on this processor) c that matches this point c do i=1,numnp if(ibits(ibc(i),3,3) .eq.7) then dd= distds(x1,x2,x3,x(i,1),x(i,2),x(i,3)) if(dd.lt.epsd) then ic=ic+1 nBCt(ic)=i ! the pointer to this point ! numBCt(ic)=ntpts ! the number of time series do j=1,ntpts c read(567,*) BCt(ic,j,4),(BCt(ic,j,n),n=1,3) read(567,*) (BCt(j,n),n=1,4) enddo ! at this point we have all bc data of spacial point ! ic/i in all time domain. now we figure out which subset ! is necessary. if (tlen.ge.BCt(ntpts,4)) then ! whole run is larger than whole period ! should take all data ilen = ntpts allocate(BCtptr(ic)%p(ilen,4)) BCtptr(ic)%p = BCt(1:ilen,:) else nper = t0/BCt(ntpts,4) tstart = t0-nper*BCt(ntpts,4) nper = t1/BCt(ntpts,4) tend = t1-nper*BCt(ntpts,4) istart = iBfind(BCt(:,4),ntpts,tstart) iend = iBfind(BCt(:,4),ntpts,tend) if (istart>1) istart=istart-1 if (iend