1 subroutine itrdrv (y, ac, 2 & uold, x, 3 & iBC, BC, 4 & iper, ilwork, shp, 5 & shgl, shpb, shglb, 6 & ifath, velbar, nsons ) 7c 8c---------------------------------------------------------------------- 9c 10c This iterative driver is the semi-discrete, predictor multi-corrector 11c algorithm. It contains the Hulbert Generalized Alpha method which 12c is 2nd order accurate for Rho_inf from 0 to 1. The method can be 13c made first-order accurate by setting Rho_inf=-1. It uses CGP and 14c GMRES iterative solvers. 15c 16c working arrays: 17c y (nshg,ndof) : Y variables 18c x (nshg,nsd) : node coordinates 19c iBC (nshg) : BC codes 20c BC (nshg,ndofBC) : BC constraint parameters 21c iper (nshg) : periodicity table 22c 23c 24c Zdenek Johan, Winter 1991. (Fortran 90) 25c Alberto Figueroa, Winter 2004. CMM-FSI 26c Irene Vignon, Fall 2004. Impedance BC 27c---------------------------------------------------------------------- 28c 29 use pvsQbi !gives us splag (the spmass at the end of this run 30 use specialBC !gives us itvn 31 use timedata !allows collection of time series 32 use convolImpFlow !for Imp bc 33 use convolRCRFlow !for RCR bc 34!MR CHANGE 35 use turbsa ! used to access d2wall 36!MR CHANGE END 37 use iso_c_binding 38 39c use readarrays !reads in uold and acold 40 41 include "common.h" 42 include "mpif.h" 43 include "auxmpi.h" 44c 45 46 47 real*8 y(nshg,ndof), ac(nshg,ndof), 48 & yold(nshg,ndof), acold(nshg,ndof), 49 & u(nshg,nsd), uold(nshg,nsd), 50 & x(numnp,nsd), solinc(nshg,ndof), 51 & BC(nshg,ndofBC), tf(nshg,ndof), 52 & GradV(nshg,nsdsq) 53 54c 55 real*8 res(nshg,ndof) 56c 57 real*8 shp(MAXTOP,maxsh,MAXQPT), 58 & shgl(MAXTOP,nsd,maxsh,MAXQPT), 59 & shpb(MAXTOP,maxsh,MAXQPT), 60 & shglb(MAXTOP,nsd,maxsh,MAXQPT) 61c 62 integer rowp(nshg,nnz), colm(nshg+1), 63 & iBC(nshg), 64 & ilwork(nlwork), 65 & iper(nshg), ifuncs(6) 66 67 real*8 vbc_prof(nshg,3) 68 69 integer stopjob 70 character*10 cname2 71 character*5 cname 72c 73c stuff for dynamic model s.w.avg and wall model 74c 75 dimension ifath(numnp), velbar(nfath,ndof), nsons(nfath) 76 77 dimension wallubar(2),walltot(2) 78c 79c.... For Farzin's Library 80c 81 integer eqnType, prjFlag, presPrjFlag, verbose 82c 83 real*8, allocatable, dimension(:,:) :: aperm, atemp, atempS 84 real*8, allocatable, dimension(:,:,:) :: apermS 85 86 real*8, allocatable, dimension(:,:) :: lhsP, lhsK, lhsS 87 real*8 almit, alfit, gamit 88c 89 character*1024 servername 90 character*20 fname1,fmt1 91 character*20 fname2,fmt2 92 character*60 fnamepold, fvarts 93 character*4 fname4c ! 4 characters 94 integer iarray(50) ! integers for headers 95 integer isgn(ndof), isgng(ndof) 96 97!MR CHANGE 98! real*8 rerr(nshg,10), ybar(nshg,13) ! including 7 sq. terms with 3 cross terms of uv, uw and vw 99! real*8 rerr(nshg,10), ybar(nshg,12) ! including 7 sq. terms with 3 cross terms of uv, uw and vw 100 real*8 rerr(nshg,10) 101 real*8, allocatable, dimension(:,:) :: ybar, strain, vorticity 102 real*8, allocatable, dimension(:,:) :: wallssVec, wallssVecbar 103!MR CHANGE 104 105 real*8 tcorecp(2), tcorecpscal(2) 106 107 integer, allocatable, dimension(:) :: ivarts 108 integer, allocatable, dimension(:) :: ivartsg 109 integer, allocatable, dimension(:) :: iv_rank 110 real*8, allocatable, dimension(:) :: vartssoln 111 real*8, allocatable, dimension(:) :: vartssolng 112 real*8, allocatable, dimension(:,:,:) :: yphbar 113 real*8 CFLworst(numel) 114 115!MR CHANGE 116 integer :: iv_rankpernode, iv_totnodes, iv_totcores 117 integer :: iv_node, iv_core, iv_thread 118!MR CHANGE 119 120 impistat = 0 121 impistat2 = 0 122 iISend = 0 123 iISendScal = 0 124 iIRecv = 0 125 iIRecvScal = 0 126 iWaitAll = 0 127 iWaitAllScal = 0 128 iAllR = 0 129 iAllRScal = 0 130 rISend = zero 131 rISendScal = zero 132 rIRecv = zero 133 rIRecvScal = zero 134 rWaitAll = zero 135 rWaitAllScal = zero 136 rAllR = zero 137 rAllRScal = zero 138 rCommu = zero 139 rCommuScal = zero 140 141 call initmemstat() 142 143c 144c hack SA variable 145c 146cHack BC(:,7)=BC(:,7)*0.001 147cHack if(lstep.eq.0) y(:,6)=y(:,6)*0.001 148 call SolverLicenseServer(servername) 149c 150c only master should be verbose 151c 152 153 if(numpe.gt.0 .and. myrank.ne.master)iverbose=0 154c 155 156 lskeep=lstep 157 158 inquire(file='xyzts.dat',exist=exts) 159 if(exts) then 160 161 open(unit=626,file='xyzts.dat',status='old') 162 read(626,*) ntspts, freq, tolpt, iterat, varcod 163 call sTD ! sets data structures 164 165 do jj=1,ntspts ! read coordinate data where solution desired 166 read(626,*) ptts(jj,1),ptts(jj,2),ptts(jj,3) 167 enddo 168 close(626) 169 170 statptts(:,:) = 0 171 parptts(:,:) = zero 172 varts(:,:) = zero 173 174 allocate (ivarts(ntspts*ndof)) 175 allocate (ivartsg(ntspts*ndof)) 176 allocate (iv_rank(ntspts)) 177 allocate (vartssoln(ntspts*ndof)) 178 allocate (vartssolng(ntspts*ndof)) 179 180 iv_rankpernode = iv_rankpercore*iv_corepernode 181 iv_totnodes = numpe/iv_rankpernode 182 iv_totcores = iv_corepernode*iv_totnodes 183 if (myrank .eq. 0) then 184 write(*,*) 'Info for probes:' 185 write(*,*) ' Ranks per core:',iv_rankpercore 186 write(*,*) ' Cores per node:',iv_corepernode 187 write(*,*) ' Ranks per node:',iv_rankpernode 188 write(*,*) ' Total number of nodes:',iv_totnodes 189 write(*,*) ' Total number of cores',iv_totcores 190 endif 191 192! if (myrank .eq. numpe-1) then 193 do jj=1,ntspts 194 195 ! Compute the adequate rank which will take care of probe jj 196 jjm1 = jj-1 197 iv_node = (iv_totnodes-1)-mod(jjm1,iv_totnodes) 198 iv_core = (iv_corepernode-1) - mod((jjm1 - 199 & mod(jjm1,iv_totnodes))/iv_totnodes,iv_corepernode) 200 iv_thread = (iv_rankpercore-1) - mod((jjm1- 201 & (mod(jjm1,iv_totcores)))/iv_totcores,iv_rankpercore) 202 iv_rank(jj) = iv_node*iv_rankpernode 203 & + iv_core*iv_rankpercore 204 & + iv_thread 205 206 if(myrank == 0) then 207 write(*,*) ' Probe', jj, 'handled by rank', 208 & iv_rank(jj), ' on node', iv_node 209 endif 210 211 ! Verification just in case 212 if(iv_rank(jj) .lt.0 .or. iv_rank(jj) .ge. numpe) then 213 write(*,*) 'WARNING: iv_rank(',jj,') is ', iv_rank(jj), 214 & ' and reset to numpe-1' 215 iv_rank(jj) = numpe-1 216 endif 217 218 ! Open the varts files 219 if(myrank == iv_rank(jj)) then 220 fvarts='varts/varts' 221 fvarts=trim(fvarts)//trim(cname2(jj)) 222 fvarts=trim(fvarts)//trim(cname2(lstep)) 223 fvarts=trim(fvarts)//'.dat' 224 fvarts=trim(fvarts) 225 open(unit=1000+jj, file=fvarts, status='unknown') 226 endif 227 enddo 228! endif 229 230 endif 231c 232c.... open history and aerodynamic forces files 233c 234 if (myrank .eq. master) then 235! open (unit=ihist, file=fhist, status='unknown') 236 open (unit=iforce, file=fforce, status='unknown') 237 open (unit=76, file="fort.76", status='unknown') 238 if(numImpSrfs.gt.0 .or. numRCRSrfs.gt.0) then 239 fnamepold = 'pold' 240 fnamepold = trim(fnamepold)//trim(cname2(lstep)) 241 fnamepold = trim(fnamepold)//'.dat' 242 fnamepold = trim(fnamepold) 243 open (unit=8177, file=fnamepold, status='unknown') 244 endif 245 endif 246c 247c.... initialize 248c 249 ifuncs(:) = 0 ! func. evaluation counter 250 istep = 0 251 yold = y 252 acold = ac 253 254 rerr = zero 255 256 if(ierrcalc.eq.1 .or. ioybar.eq.1) then ! we need ybar for error too 257 if (ivort == 1) then 258 allocate(ybar(nshg,17)) ! more space for vorticity if requested 259 else 260 allocate(ybar(nshg,13)) 261 endif 262 ybar = zero ! Initialize ybar to zero, which is essential 263 endif 264 265 if(ivort == 1) then 266 allocate(strain(nshg,6)) 267 allocate(vorticity(nshg,5)) 268 endif 269 270 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 271 allocate(wallssVec(nshg,3)) 272 if (ioybar .eq. 1) then 273 allocate(wallssVecbar(nshg,3)) 274 wallssVecbar = zero ! Initialization important if mean wss computed 275 endif 276 endif 277 278! both nstepsincycle and nphasesincycle needs to be set 279 if(nstepsincycle.eq.0) nphasesincycle = 0 280 if(nphasesincycle.ne.0) then 281! & allocate(yphbar(nshg,5,nphasesincycle)) 282 if (ivort == 1) then 283 allocate(yphbar(nshg,15,nphasesincycle)) ! more space for vorticity 284 else 285 allocate(yphbar(nshg,11,nphasesincycle)) 286 endif 287 yphbar = zero 288 endif 289 290!MR CHANGE END 291 292 vbc_prof(:,1:3) = BC(:,3:5) 293 if(iramp.eq.1) then 294 call BCprofileInit(vbc_prof,x) 295 endif 296 297c 298c.... ---------------> initialize Farzin's Library <--------------- 299c 300c.... assign parameter values 301c 302 do i = 1, 100 303 numeqns(i) = i 304 enddo 305 nKvecs = Kspace 306 prjFlag = iprjFlag 307 presPrjFlag = ipresPrjFlag 308 verbose = iverbose 309c 310c.... determine how many scalar equations we are going to need to solve 311c 312 nsolt=mod(impl(1),2) ! 1 if solving temperature 313 nsclrsol=nsolt+nsclr ! total number of scalars solved At 314 ! some point we probably want to create 315 ! a map, considering stepseq(), to find 316 ! what is actually solved and only 317 ! dimension lhs to the appropriate 318 ! size. (see 1.6.1 and earlier for a 319 ! "failed" attempt at this). 320 321 322 nsolflow=mod(impl(1),100)/10 ! 1 if solving flow 323 324c 325c.... Now, call Farzin's lesNew routine to initialize 326c memory space 327c 328 call genadj(colm, rowp, icnt ) ! preprocess the adjacency list 329 330 nnz_tot=icnt ! this is exactly the number of non-zero blocks on 331 ! this proc 332 333 if (nsolflow.eq.1) then 334 lesId = numeqns(1) 335 eqnType = 1 336 nDofs = 4 337 call myfLesNew( lesId, 41994, 338 & eqnType, 339 & nDofs, minIters, maxIters, 340 & nKvecs, prjFlag, nPrjs, 341 & presPrjFlag, nPresPrjs, epstol(1), 342 & prestol, verbose, statsflow, 343 & nPermDims, nTmpDims, servername ) 344 345 allocate (aperm(nshg,nPermDims)) 346 allocate (atemp(nshg,nTmpDims)) 347 allocate (lhsP(4,nnz_tot)) 348 allocate (lhsK(9,nnz_tot)) 349 350 call readLesRestart( lesId, aperm, nshg, myrank, lstep, 351 & nPermDims ) 352 353 else 354 nPermDims = 0 355 nTempDims = 0 356 endif 357 358 359 if(nsclrsol.gt.0) then 360 do isolsc=1,nsclrsol 361 lesId = numeqns(isolsc+1) 362 eqnType = 2 363 nDofs = 1 364 presPrjflag = 0 365 nPresPrjs = 0 366 prjFlag = 1 367 indx=isolsc+2-nsolt ! complicated to keep epstol(2) for 368 ! temperature followed by scalars 369 call myfLesNew( lesId, 41994, 370 & eqnType, 371 & nDofs, minIters, maxIters, 372 & nKvecs, prjFlag, nPrjs, 373 & presPrjFlag, nPresPrjs, epstol(indx), 374 & prestol, verbose, statssclr, 375 & nPermDimsS, nTmpDimsS, servername ) 376 enddo 377c 378c Assume all scalars have the same size needs 379c 380 allocate (apermS(nshg,nPermDimsS,nsclrsol)) 381 allocate (atempS(nshg,nTmpDimsS)) !they can all share this 382 allocate (lhsS(nnz_tot,nsclrsol)) 383c 384c actually they could even share with atemp but leave that for later 385c 386 else 387 nPermDimsS = 0 388 nTmpDimsS = 0 389 endif 390c 391c... prepare lumped mass if needed 392c 393 if((flmpr.ne.0).or.(flmpl.ne.0)) call genlmass(x, shp,shgl) 394c 395c.... -----------------> End of initialization <----------------- 396c 397c.....open the necessary files to gather time series 398c 399 lstep0 = lstep+1 400 nsteprcr = nstep(1)+lstep 401c 402c.... loop through the time sequences 403c 404 405 406 do 3000 itsq = 1, ntseq 407 itseq = itsq 408 409CAD tcorecp1 = second(0) 410CAD tcorewc1 = second(-1) 411c 412c.... set up the time integration parameters 413c 414 nstp = nstep(itseq) 415 nitr = niter(itseq) 416 LCtime = loctim(itseq) 417 dtol(:)= deltol(itseq,:) 418 419 call itrSetup ( y, acold ) 420c 421c...initialize the coefficients for the impedance convolution, 422c which are functions of alphaf so need to do it after itrSetup 423 if(numImpSrfs.gt.zero) then 424 call calcImpConvCoef (numImpSrfs, ntimeptpT) 425 endif 426c 427c...initialize the initial condition P(0)-RQ(0)-Pd(0) for RCR BC 428c need ndsurf so should be after initNABI 429 if(numRCRSrfs.gt.zero) then 430 call calcRCRic(y,nsrflistRCR,numRCRSrfs) 431 endif 432c 433c find the last solve of the flow in the step sequence so that we will 434c know when we are at/near end of step 435c 436c ilast=0 437 nitr=0 ! count number of flow solves in a step (# of iterations) 438 do i=1,seqsize 439 if(stepseq(i).eq.0) nitr=nitr+1 440 enddo 441 442 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 443 tcorecp(:) = zero ! used in solfar.f (solflow) 444 tcorecpscal(:) = zero ! used in solfar.f (solflow) 445 if(myrank.eq.0) then 446 tcorecp1 = TMRC() 447 endif 448 449c 450c.... loop through the time steps 451c 452 istop=0 453 rmub=datmat(1,2,1) 454 if(rmutarget.gt.0) then 455 rmue=rmutarget 456 else 457 rmue=datmat(1,2,1) ! keep constant 458 endif 459 460 if(iramp.eq.1) then 461 call BCprofileScale(vbc_prof,BC,yold) ! fix the yold values to the reset BC 462 isclr=1 ! fix scalar 463 do isclr=1,nsclr 464 call itrBCSclr(yold,ac,iBC,BC,iper,ilwork) 465 enddo 466 endif 467 468 do 2000 istp = 1, nstp 469 if(iramp.eq.1) 470 & call BCprofileScale(vbc_prof,BC,yold) 471 472 call rerun_check(stopjob) 473 if(myrank.eq.master) write(*,*) 474 & 'stopjob,lstep,istep', stopjob,lstep,istep 475 if(stopjob.eq.lstep) then 476 stopjob=-2 ! this is the code to finish 477 if ((irs .ge. 1) .and. (mod(lstep, ntout) .eq. 0)) then 478 if(myrank.eq.master) write(*,*) 479 & 'line 473 says last step written so exit' 480 goto 2002 ! the step was written last step so just exit 481 else 482 if(myrank.eq.master) 483 & write(*,*) 'line 473 says last step not written' 484 istep=nstp ! have to do this so that solution will be written 485 goto 2001 486 endif 487 endif 488 489 xi=istp*1.0/nstp 490 datmat(1,2,1)=rmub*(1.0-xi)+xi*rmue 491c write(*,*) "current mol. visc = ", datmat(1,2,1) 492c.... if we have time varying boundary conditions update the values of BC. 493c these will be for time step n+1 so use lstep+1 494c 495 if(itvn.gt.0) call BCint((lstep+1)*Delt(1), shp, shgl, 496 & shpb, shglb, x, BC, iBC) 497 498c 499c ... calculate the pressure contribution that depends on the history for the Imp. BC 500c 501 if(numImpSrfs.gt.0) then 502 call pHist(poldImp,QHistImp,ImpConvCoef, 503 & ntimeptpT,numImpSrfs) 504 if (myrank.eq.master) 505 & write(8177,*) (poldImp(n), n=1,numImpSrfs) 506 endif 507c 508c ... calc the pressure contribution that depends on the history for the RCR BC 509c 510 if(numRCRSrfs.gt.0) then 511 call CalcHopRCR (Delt(itseq), lstep, numRCRSrfs) 512 call CalcRCRConvCoef(lstep,numRCRSrfs) 513 call pHist(poldRCR,QHistRCR,RCRConvCoef,nsteprcr, 514 & numRCRSrfs) 515 if (myrank.eq.master) 516 & write(8177,*) (poldRCR(n), n=1,numRCRSrfs) 517 endif 518c 519c Decay of scalars 520c 521 if(nsclr.gt.0 .and. tdecay.ne.1) then 522 yold(:,6:ndof)=y(:,6:ndof)*tdecay 523 BC(:,7:6+nsclr)= BC(:,7:6+nsclr)*tdecay 524 endif 525 526 if(nosource.eq.1) BC(:,7:6+nsclr)= BC(:,7:6+nsclr)*0.8 527 528 529 if(iLES.gt.0) then !complicated stuff has moved to 530 !routine below 531 call lesmodels(yold, acold, shgl, shp, 532 & iper, ilwork, rowp, colm, 533 & nsons, ifath, x, 534 & iBC, BC) 535 536 537 endif 538 539c.... set traction BCs for modeled walls 540c 541 if (itwmod.ne.0) then 542 call asbwmod(yold, acold, x, BC, iBC, 543 & iper, ilwork, ifath, velbar) 544 endif 545 546!MR CHANGE 547c 548c.... Determine whether the vorticity field needs to be computed for this time step or not 549c 550 icomputevort = 0 551 if (ivort == 1) then ! Print vorticity = True in solver.inp 552 ! We then compute the vorticity only if we 553 ! 1) we write an intermediate checkpoint 554 ! 2) we reach the last time step and write the last checkpoint 555 ! 3) we accumulate statistics in ybar for every time step 556 ! BEWARE: we need here lstep+1 and istep+1 because the lstep and 557 ! istep gets incremened after the flowsolve, further below 558 if (((irs .ge. 1) .and. (mod(lstep+1, ntout) .eq. 0)) .or. 559 & istep+1.eq.nstep(itseq) .or. ioybar == 1) then 560 icomputevort = 1 561 endif 562 endif 563 564! write(*,*) 'icomputevort: ',icomputevort, ' - istep: ', 565! & istep,' - nstep(itseq):',nstep(itseq),'- lstep:', 566! & lstep, '- ntout:', ntout 567!MR CHANGE 568 569c 570c.... -----------------------> predictor phase <----------------------- 571c 572 call itrPredict(yold, y, acold, ac , uold, u, iBC) 573 call itrBC (y, ac, iBC, BC, iper,ilwork) 574 575 if(nsolt.eq.1) then 576 isclr=0 577 call itrBCSclr (y, ac, iBC, BC, iper, ilwork) 578 endif 579 do isclr=1,nsclr 580 call itrBCSclr (y, ac, iBC, BC, iper, ilwork) 581 enddo 582 iter=0 583 ilss=0 ! this is a switch thrown on first solve of LS redistance 584 do istepc=1,seqsize 585 icode=stepseq(istepc) 586 if(mod(icode,5).eq.0) then ! this is a solve 587 isolve=icode/10 588 if(icode.eq.0) then ! flow solve (encoded as 0) 589c 590 iter = iter+1 591 ifuncs(1) = ifuncs(1) + 1 592c 593 Force(1) = zero 594 Force(2) = zero 595 Force(3) = zero 596 HFlux = zero 597 lhs = 1 - min(1,mod(ifuncs(1)-1,LHSupd(1))) 598 599 call SolFlow(y, ac, u, 600 & yold, acold, uold, 601 & x, iBC, 602 & BC, res, 603 & nPermDims, nTmpDims, aperm, 604 & atemp, iper, 605 & ilwork, shp, shgl, 606 & shpb, shglb, rowp, 607 & colm, lhsK, lhsP, 608 & solinc, rerr, tcorecp, 609 & GradV) 610 611 else ! scalar type solve 612 if (icode.eq.5) then ! Solve for Temperature 613 ! (encoded as (nsclr+1)*10) 614 isclr=0 615 ifuncs(2) = ifuncs(2) + 1 616 j=1 617 else ! solve a scalar (encoded at isclr*10) 618 isclr=isolve 619 ifuncs(isclr+2) = ifuncs(isclr+2) + 1 620 j=isclr+nsolt 621 if((iLSet.eq.2).and.(ilss.eq.0) 622 & .and.(isclr.eq.2)) then 623 ilss=1 ! throw switch (once per step) 624 y(:,7)=y(:,6) ! redistance field initialized 625 ac(:,7) = zero 626 call itrBCSclr ( y, ac, iBC, BC, iper, 627 & ilwork) 628c 629c....store the flow alpha, gamma parameter values and assigm them the 630c....Backward Euler parameters to solve the second levelset scalar 631c 632 alfit=alfi 633 gamit=gami 634 almit=almi 635 Deltt=Delt(1) 636 Dtglt=Dtgl 637 alfi = 1 638 gami = 1 639 almi = 1 640c Delt(1)= Deltt ! Give a pseudo time step 641 Dtgl = one / Delt(1) 642 endif ! level set eq. 2 643 endif ! deciding between temperature and scalar 644 645 lhs = 1 - min(1,mod(ifuncs(isclr+2)-1, 646 & LHSupd(isclr+2))) 647 648 call SolSclr(y, ac, u, 649 & yold, acold, uold, 650 & x, iBC, 651 & BC, nPermDimsS,nTmpDimsS, 652 & apermS(1,1,j), atempS, iper, 653 & ilwork, shp, shgl, 654 & shpb, shglb, rowp, 655 & colm, lhsS(1,j), 656 & solinc(1,isclr+5), tcorecpscal) 657 658 659 endif ! end of scalar type solve 660 661 else ! this is an update (mod did not equal zero) 662 iupdate=icode/10 ! what to update 663 if(icode.eq.1) then !update flow 664 call itrCorrect ( y, ac, u, solinc, iBC) 665 call itrBC (y, ac, iBC, BC, iper, ilwork) 666 else ! update scalar 667 isclr=iupdate !unless 668 if(icode.eq.6) isclr=0 669 if(iRANS.lt.-100)then ! RANS 670 call itrCorrectSclrPos(y,ac,solinc(1,isclr+5)) 671 else 672 call itrCorrectSclr (y, ac, solinc(1,isclr+5)) 673 endif 674 if (ilset.eq.2 .and. isclr.eq.2) then 675 if (ivconstraint .eq. 1) then 676 call itrBCSclr ( y, ac, iBC, BC, iper, 677 & ilwork) 678c 679c ... applying the volume constraint on second level set scalar 680c 681 call solvecon (y, x, iBC, BC, 682 & iper, ilwork, shp, shgl) 683c 684 endif ! end of volume constraint calculations 685 endif ! end of redistance calculations 686c 687 call itrBCSclr ( y, ac, iBC, BC, iper, 688 & ilwork) 689 endif ! end of flow or scalar update 690 endif ! end of switch between solve or update 691 enddo ! loop over sequence in step 692c 693c 694c.... obtain the time average statistics 695c 696 if (ioform .eq. 2) then 697 698 call stsGetStats( y, yold, ac, acold, 699 & u, uold, x, 700 & shp, shgl, shpb, shglb, 701 & iBC, BC, iper, ilwork, 702 & rowp, colm, lhsK, lhsP ) 703 endif 704 705c 706c Find the solution at the end of the timestep and move it to old 707c 708c 709c ...First to reassign the parameters for the original time integrator scheme 710c 711 if((iLSet.eq.2).and.(ilss.eq.1)) then 712 alfi =alfit 713 gami =gamit 714 almi =almit 715 Delt(1)=Deltt 716 Dtgl =Dtglt 717 endif 718 call itrUpdate( yold, acold, uold, y, ac, u) 719 call itrBC (yold, acold, iBC, BC, iper,ilwork) 720 721 istep = istep + 1 722 lstep = lstep + 1 723c 724c .. Print memory consumption on BGQ 725c 726 call printmeminfo("itrdrv"//char(0)) 727 728c 729c .. Compute vorticity 730c 731 if ( icomputevort == 1) then 732 733 ! vorticity components and magnitude 734 vorticity(:,1) = GradV(:,8)-GradV(:,6) !omega_x 735 vorticity(:,2) = GradV(:,3)-GradV(:,7) !omega_y 736 vorticity(:,3) = GradV(:,4)-GradV(:,2) !omega_z 737 vorticity(:,4) = sqrt( vorticity(:,1)*vorticity(:,1) 738 & + vorticity(:,2)*vorticity(:,2) 739 & + vorticity(:,3)*vorticity(:,3) ) 740 ! Q 741 strain(:,1) = GradV(:,1) !S11 742 strain(:,2) = 0.5*(GradV(:,2)+GradV(:,4)) !S12 743 strain(:,3) = 0.5*(GradV(:,3)+GradV(:,7)) !S13 744 strain(:,4) = GradV(:,5) !S22 745 strain(:,5) = 0.5*(GradV(:,6)+GradV(:,8)) !S23 746 strain(:,6) = GradV(:,9) !S33 747 748 vorticity(:,5) = 0.25*( vorticity(:,4)*vorticity(:,4) !Q 749 & - 2.0*( strain(:,1)*strain(:,1) 750 & + 2* strain(:,2)*strain(:,2) 751 & + 2* strain(:,3)*strain(:,3) 752 & + strain(:,4)*strain(:,4) 753 & + 2* strain(:,5)*strain(:,5) 754 & + strain(:,6)*strain(:,6))) 755 756 endif 757c 758c .. write out the instantaneous solution 759c 7602001 continue ! we could get here by 2001 label if user requested stop 761 if (((irs .ge. 1) .and. (mod(lstep, ntout) .eq. 0)) .or. 762 & istep.eq.nstep(itseq)) then 763 764!so that we can see progress in force file close it so that it flushes 765!and then reopen in append mode 766 767 close(iforce) 768 open (unit=iforce, file=fforce, position='append') 769 770! Call to restar() will open restart file in write mode (and not append mode) 771! that is needed as other fields are written in append mode 772 773 call restar ('out ', yold ,ac) 774 if(ideformwall == 1) then 775 call write_displ(myrank, lstep, nshg, 3, uold ) 776 endif 777 778 if(ivort == 1) then 779 call write_field(myrank,'a','vorticity',9,vorticity, 780 & 'd',nshg,5,lstep) 781 endif 782 783 call printmeminfo("itrdrv after checkpoint"//char(0)) 784 else if(stopjob.eq.-2) then 785 if(myrank.eq.master) then 786 write(*,*) 'line 755 says no write before stopping' 787 write(*,*) 'istep,nstep,irs',istep,nstep(itseq),irs 788 endif 789 endif !just the instantaneous stuff for videos 790c 791c.... compute the consistent boundary flux 792c 793 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 794 call Bflux ( yold, acold, uold, x, 795 & shp, shgl, shpb, 796 & shglb, ilwork, iBC, 797 & BC, iper, wallssVec) 798 endif 799 800 if(stopjob.eq.-2) goto 2003 801 802 803c 804c ... update the flow history for the impedance convolution, filter it and write it out 805c 806 if(numImpSrfs.gt.zero) then 807 call UpdHistConv(y,nsrflistImp,numImpSrfs) !uses Delt(1) 808 endif 809 810c 811c ... update the flow history for the RCR convolution 812c 813 if(numRCRSrfs.gt.zero) then 814 call UpdHistConv(y,nsrflistRCR,numRCRSrfs) !uses lstep 815 endif 816 817 818c... dump TIME SERIES 819 820 if (exts) then 821 if (mod(lstep-1,freq).eq.0) then 822 823 if (numpe > 1) then 824 do jj = 1, ntspts 825 vartssoln((jj-1)*ndof+1:jj*ndof)=varts(jj,:) 826 ivarts=zero 827 enddo 828 do k=1,ndof*ntspts 829 if(vartssoln(k).ne.zero) ivarts(k)=1 830 enddo 831 832! call MPI_REDUCE(vartssoln, vartssolng, ndof*ntspts, 833! & MPI_DOUBLE_PRECISION, MPI_SUM, master, 834! & MPI_COMM_WORLD, ierr) 835 836 call MPI_BARRIER(MPI_COMM_WORLD, ierr) 837 call MPI_ALLREDUCE(vartssoln, vartssolng, 838 & ndof*ntspts, 839 & MPI_DOUBLE_PRECISION, MPI_SUM, 840 & MPI_COMM_WORLD, ierr) 841 842! call MPI_REDUCE(ivarts, ivartsg, ndof*ntspts, 843! & MPI_INTEGER, MPI_SUM, master, 844! & MPI_COMM_WORLD, ierr) 845 846 call MPI_BARRIER(MPI_COMM_WORLD, ierr) 847 call MPI_ALLREDUCE(ivarts, ivartsg, ndof*ntspts, 848 & MPI_INTEGER, MPI_SUM, 849 & MPI_COMM_WORLD, ierr) 850 851! if (myrank.eq.zero) then 852 do jj = 1, ntspts 853 854 if(myrank .eq. iv_rank(jj)) then 855 ! No need to update all varts components, only the one treated by the expected rank 856 ! Note: keep varts as a vector, as multiple probes could be treated by one rank 857 indxvarts = (jj-1)*ndof 858 do k=1,ndof 859 if(ivartsg(indxvarts+k).ne.0) then ! none of the vartssoln(parts) were non zero 860 varts(jj,k)=vartssolng(indxvarts+k)/ 861 & ivartsg(indxvarts+k) 862 endif 863 enddo 864 endif !only if myrank eq iv_rank(jj) 865 enddo 866! endif !only on master 867 endif !only if numpe > 1 868 869! if (myrank.eq.zero) then 870 do jj = 1, ntspts 871 if(myrank .eq. iv_rank(jj)) then 872 ifile = 1000+jj 873 write(ifile,555) lstep, (varts(jj,k),k=1,ndof) !Beware of format 555 - check ndof 874c call flush(ifile) 875 if (((irs .ge. 1) .and. 876 & (mod(lstep, ntout) .eq. 0))) then 877 close(ifile) 878 fvarts='varts/varts' 879 fvarts=trim(fvarts)//trim(cname2(jj)) 880 fvarts=trim(fvarts)//trim(cname2(lskeep)) 881 fvarts=trim(fvarts)//'.dat' 882 fvarts=trim(fvarts) 883 open(unit=ifile, file=fvarts, 884 & position='append') 885 endif !only when dumping restart 886 endif 887 enddo 888! endif !only on master 889 890 varts(:,:) = zero ! reset the array for next step 891 892 893!555 format(i6,5(2x,E12.5e2)) 894555 format(i6,6(2x,E20.12e2)) !assuming ndof = 6 here 895 896 endif 897 endif 898 899c 900c.... update and the aerodynamic forces 901c 902 call forces ( yold, ilwork ) 903 904 if((irscale.ge.0).or.(itwmod.gt.0)) 905 & call getvel (yold, ilwork, iBC, 906 & nsons, ifath, velbar) 907 908 if((irscale.ge.0).and.(myrank.eq.master)) then 909 call genscale(yold, x, iper, 910 & iBC, ifath, velbar, 911 & nsons) 912 endif 913c 914c.... print out results. 915c 916 ntoutv=max(ntout,100) ! velb is not needed so often 917 if ((irs .ge. 1) .and. (mod(lstep, ntout) .eq. 0)) then 918 if( (mod(lstep, ntoutv) .eq. 0) .and. 919 & ((irscale.ge.0).or.(itwmod.gt.0) .or. 920 & ((nsonmax.eq.1).and.(iLES.gt.0)))) 921 & call rwvelb ('out ', velbar ,ifail) 922 endif 923c 924c.... end of the NSTEP and NTSEQ loops 925c 926 927 928c 929c.... -------------------> error calculation <----------------- 930c 931 if(ierrcalc.eq.1 .or. ioybar.eq.1) then 932c$$$c 933c$$$c compute average 934c$$$c 935c$$$ tfact=one/istep 936c$$$ ybar =tfact*yold + (one-tfact)*ybar 937 938c compute average 939c ybar(:,1:3) are average velocity components 940c ybar(:,4) is average pressure 941c ybar(:,5) is average speed 942c ybar(:,6:8) is average of sq. of each vel. component 943c ybar(:,9) is average of sq. of pressure 944c ybar(:,10:12) is average of cross vel. components : uv, uw and vw 945c averaging procedure justified only for identical time step sizes 946c ybar(:,13) is average of eddy viscosity 947c ybar(:,14:16) is average vorticity components 948c ybar(:,17) is average vorticity magnitude 949c istep is number of time step 950c 951 icollectybar = 0 952 if(nphasesincycle.eq.0 .or. 953 & istep.gt.ncycles_startphaseavg*nstepsincycle) then 954 icollectybar = 1 955 if((istep-1).eq.ncycles_startphaseavg*nstepsincycle) 956 & istepsinybar = 0 ! init. to zero in first cycle in avg. 957 endif 958 959 if(icollectybar.eq.1) then 960 istepsinybar = istepsinybar+1 961 tfact=one/istepsinybar 962 963 if(myrank.eq.master .and. nphasesincycle.ne.0 .and. 964 & mod((istep-1),nstepsincycle).eq.0) 965 & write(*,*)'nsamples in phase average:',istepsinybar 966 967c ybar to contain the averaged ((u,v,w),p)-fields 968c and speed average, i.e., sqrt(u^2+v^2+w^2) 969c and avg. of sq. terms including 970c u^2, v^2, w^2, p^2 and cross terms of uv, uw and vw 971 972 ybar(:,1) = tfact*yold(:,1) + (one-tfact)*ybar(:,1) 973 ybar(:,2) = tfact*yold(:,2) + (one-tfact)*ybar(:,2) 974 ybar(:,3) = tfact*yold(:,3) + (one-tfact)*ybar(:,3) 975 ybar(:,4) = tfact*yold(:,4) + (one-tfact)*ybar(:,4) 976 ybar(:,5) = tfact*sqrt(yold(:,1)**2+yold(:,2)**2+ 977 & yold(:,3)**2) + (one-tfact)*ybar(:,5) 978 ybar(:,6) = tfact*yold(:,1)**2 + 979 & (one-tfact)*ybar(:,6) 980 ybar(:,7) = tfact*yold(:,2)**2 + 981 & (one-tfact)*ybar(:,7) 982 ybar(:,8) = tfact*yold(:,3)**2 + 983 & (one-tfact)*ybar(:,8) 984 ybar(:,9) = tfact*yold(:,4)**2 + 985 & (one-tfact)*ybar(:,9) 986 ybar(:,10) = tfact*yold(:,1)*yold(:,2) + !uv 987 & (one-tfact)*ybar(:,10) 988 ybar(:,11) = tfact*yold(:,1)*yold(:,3) + !uw 989 & (one-tfact)*ybar(:,11) 990 ybar(:,12) = tfact*yold(:,2)*yold(:,3) + !vw 991 & (one-tfact)*ybar(:,12) 992!MR CHANGE 993 if(nsclr.gt.0) !nut 994 & ybar(:,13) = tfact*yold(:,6) + (one-tfact)*ybar(:,13) 995 996 if(ivort == 1) then !vorticity 997 ybar(:,14) = tfact*vorticity(:,1) + 998 & (one-tfact)*ybar(:,14) 999 ybar(:,15) = tfact*vorticity(:,2) + 1000 & (one-tfact)*ybar(:,15) 1001 ybar(:,16) = tfact*vorticity(:,3) + 1002 & (one-tfact)*ybar(:,16) 1003 ybar(:,17) = tfact*vorticity(:,4) + 1004 & (one-tfact)*ybar(:,17) 1005 endif 1006 1007 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 1008 wallssVecBar(:,1) = tfact*wallssVec(:,1) 1009 & +(one-tfact)*wallssVecBar(:,1) 1010 wallssVecBar(:,2) = tfact*wallssVec(:,2) 1011 & +(one-tfact)*wallssVecBar(:,2) 1012 wallssVecBar(:,3) = tfact*wallssVec(:,3) 1013 & +(one-tfact)*wallssVecBar(:,3) 1014 endif 1015!MR CHANGE END 1016 endif 1017c 1018c compute phase average 1019c 1020 if(nphasesincycle.ne.0 .and. 1021 & istep.gt.ncycles_startphaseavg*nstepsincycle) then 1022 1023c beginning of cycle is considered as ncycles_startphaseavg*nstepsincycle+1 1024 if((istep-1).eq.ncycles_startphaseavg*nstepsincycle) 1025 & icyclesinavg = 0 ! init. to zero in first cycle in avg. 1026 1027 ! find number of steps between phases 1028 nstepsbtwphase = nstepsincycle/nphasesincycle ! integer value 1029 if(mod(istep-1,nstepsincycle).eq.0) then 1030 iphase = 1 ! init. to one in beginning of every cycle 1031 icyclesinavg = icyclesinavg + 1 1032 endif 1033 1034 icollectphase = 0 1035 istepincycle = mod(istep,nstepsincycle) 1036 if(istepincycle.eq.0) istepincycle=nstepsincycle 1037 if(istepincycle.eq.iphase*nstepsbtwphase) then 1038 icollectphase = 1 1039 iphase = iphase+1 ! use 'iphase-1' below 1040 endif 1041 1042 if(icollectphase.eq.1) then 1043 tfactphase = one/icyclesinavg 1044 1045 if(myrank.eq.master) then 1046 write(*,*) 'nsamples in phase ',iphase-1,': ', 1047 & icyclesinavg 1048 endif 1049 1050 yphbar(:,1,iphase-1) = tfactphase*yold(:,1) + 1051 & (one-tfactphase)*yphbar(:,1,iphase-1) 1052 yphbar(:,2,iphase-1) = tfactphase*yold(:,2) + 1053 & (one-tfactphase)*yphbar(:,2,iphase-1) 1054 yphbar(:,3,iphase-1) = tfactphase*yold(:,3) + 1055 & (one-tfactphase)*yphbar(:,3,iphase-1) 1056 yphbar(:,4,iphase-1) = tfactphase*yold(:,4) + 1057 & (one-tfactphase)*yphbar(:,4,iphase-1) 1058 yphbar(:,5,iphase-1) = tfactphase*sqrt(yold(:,1)**2 1059 & +yold(:,2)**2+yold(:,3)**2) + 1060 & (one-tfactphase)*yphbar(:,5,iphase-1) 1061!MR CHANGE 1062 yphbar(:,6,iphase-1) = 1063 & tfactphase*yold(:,1)*yold(:,1) 1064 & +(one-tfactphase)*yphbar(:,6,iphase-1) 1065 1066 yphbar(:,7,iphase-1) = 1067 & tfactphase*yold(:,1)*yold(:,2) 1068 & +(one-tfactphase)*yphbar(:,7,iphase-1) 1069 1070 yphbar(:,8,iphase-1) = 1071 & tfactphase*yold(:,1)*yold(:,3) 1072 & +(one-tfactphase)*yphbar(:,8,iphase-1) 1073 1074 yphbar(:,9,iphase-1) = 1075 & tfactphase*yold(:,2)*yold(:,2) 1076 & +(one-tfactphase)*yphbar(:,9,iphase-1) 1077 1078 yphbar(:,10,iphase-1) = 1079 & tfactphase*yold(:,2)*yold(:,3) 1080 & +(one-tfactphase)*yphbar(:,10,iphase-1) 1081 1082 yphbar(:,11,iphase-1) = 1083 & tfactphase*yold(:,3)*yold(:,3) 1084 & +(one-tfactphase)*yphbar(:,11,iphase-1) 1085 1086 if(ivort == 1) then 1087 yphbar(:,12,iphase-1) = 1088 & tfactphase*vorticity(:,1) 1089 & +(one-tfactphase)*yphbar(:,12,iphase-1) 1090 yphbar(:,13,iphase-1) = 1091 & tfactphase*vorticity(:,2) 1092 & +(one-tfactphase)*yphbar(:,13,iphase-1) 1093 yphbar(:,14,iphase-1) = 1094 & tfactphase*vorticity(:,3) 1095 & +(one-tfactphase)*yphbar(:,14,iphase-1) 1096 yphbar(:,15,iphase-1) = 1097 & tfactphase*vorticity(:,4) 1098 & +(one-tfactphase)*yphbar(:,15,iphase-1) 1099 endif 1100!MR CHANGE END 1101 endif 1102 endif 1103c 1104c compute rms 1105c 1106 if(icollectybar.eq.1) then 1107 rerr(:, 7)=rerr(:, 7)+(yold(:,1)-ybar(:,1))**2 1108 rerr(:, 8)=rerr(:, 8)+(yold(:,2)-ybar(:,2))**2 1109 rerr(:, 9)=rerr(:, 9)+(yold(:,3)-ybar(:,3))**2 1110 rerr(:,10)=rerr(:,10)+(yold(:,4)-ybar(:,4))**2 1111 endif 1112 endif 1113 2003 continue ! we get here if stopjob equals lstep and this jumped over 1114! the statistics computation because we have no new data to average in 1115! rather we are just trying to output the last state that was not already 1116! written 1117c 1118c.... ----------------------> Complete Restart Processing <---------------------- 1119c 1120! for now it is the same frequency but need to change this 1121! soon.... but don't forget to change the field counter in 1122! new_interface.cc 1123! 1124 if (((irs .ge. 1) .and. (mod(lstep, ntout) .eq. 0)) .or. 1125 & istep.eq.nstep(itseq)) then 1126 if ((irs .ge. 1) .and. ((mod(lstep, ntout) .ne. 0) .or. 1127 & (nstp .eq. 0))) then 1128 if( 1129 & ((irscale.ge.0).or.(itwmod.gt.0) .or. 1130 & ((nsonmax.eq.1).and.iLES.gt.0))) 1131 & call rwvelb ('out ', velbar ,ifail) 1132 endif 1133 1134 lesId = numeqns(1) 1135 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1136 if(myrank.eq.0) then 1137 tcormr1 = TMRC() 1138 endif 1139 call saveLesRestart( lesId, aperm , nshg, myrank, lstep, 1140 & nPermDims ) 1141 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1142 if(myrank.eq.0) then 1143 tcormr2 = TMRC() 1144 write(6,*) 'call saveLesRestart for projection and'// 1145 & 'pressure projection vectors', tcormr2-tcormr1 1146 endif 1147 1148 if(ierrcalc.eq.1) then 1149c 1150c.....smooth the error indicators 1151c 1152 do i=1,ierrsmooth 1153 call errsmooth( rerr, x, iper, ilwork, shp, shgl, iBC ) 1154 end do 1155 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1156 if(myrank.eq.0) then 1157 tcormr1 = TMRC() 1158 endif 1159 call write_error(myrank, lstep, nshg, 10, rerr ) 1160 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1161 if(myrank.eq.0) then 1162 tcormr2 = TMRC() 1163 write(6,*) 'Time to write the error fields to the disks', 1164 & tcormr2-tcormr1 1165 endif 1166 endif ! ierrcalc 1167 1168 if(ioybar.eq.1) then 1169 if(ivort == 1) then 1170 call write_field(myrank,'a','ybar',4, 1171 & ybar,'d',nshg,17,lstep) 1172 else 1173 call write_field(myrank,'a','ybar',4, 1174 & ybar,'d',nshg,13,lstep) 1175 endif 1176 1177 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 1178 call write_field(myrank,'a','wssbar',6, 1179 & wallssVecBar,'d',nshg,3,lstep) 1180 endif 1181 1182 if(nphasesincycle .gt. 0) then 1183 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1184 if(myrank.eq.0) then 1185 tcormr1 = TMRC() 1186 endif 1187 do iphase=1,nphasesincycle 1188 if(ivort == 1) then 1189 call write_phavg2(myrank,'a','phase_average',13,iphase, 1190 & nphasesincycle,yphbar(:,:,iphase),'d',nshg,15,lstep) 1191 else 1192 call write_phavg2(myrank,'a','phase_average',13,iphase, 1193 & nphasesincycle,yphbar(:,:,iphase),'d',nshg,11,lstep) 1194 endif 1195 end do 1196 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1197 if(myrank.eq.0) then 1198 tcormr2 = TMRC() 1199 write(6,*) 'write all phase avg to the disks = ', 1200 & tcormr2-tcormr1 1201 endif 1202 endif !nphasesincyle 1203 endif !ioybar 1204 1205 if ( ( ihessian .eq. 1 ) .and. ( numpe < 2 ) )then 1206 uhess = zero 1207 gradu = zero 1208 tf = zero 1209 1210 do ku=1,nshg 1211 tf(ku,1) = x(ku,1)**3 1212 end do 1213 call hessian( yold, x, shp, shgl, iBC, 1214 & shpb, shglb, iper, ilwork, uhess, gradu ) 1215 1216 call write_hessian( uhess, gradu, nshg ) 1217 endif 1218 1219 if(iRANS.lt.0) then 1220 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1221 if(myrank.eq.0) then 1222 tcormr1 = TMRC() 1223 endif 1224 call write_field(myrank,'a','dwal',4,d2wall,'d', 1225 & nshg,1,lstep) 1226 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1227 if(myrank.eq.0) then 1228 tcormr2 = TMRC() 1229 write(6,*) 'Time to write dwal to the disks = ', 1230 & tcormr2-tcormr1 1231 endif 1232 endif !iRANS 1233 1234 endif ! write out complete restart state 1235 !next 2 lines are two ways to end early 1236 if(stopjob.eq.-2) goto 2002 1237 if(istop.eq.1000) goto 2002 ! stop when delta small (see rstatic) 1238 2000 continue 1239 2002 continue 1240 1241! done with time stepping so deallocate fields already written 1242! 1243 if(ioybar.eq.1) then 1244 deallocate(ybar) 1245 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 1246 deallocate(wallssVecbar) 1247 endif 1248 if(nphasesincycle .gt. 0) then 1249 deallocate(yphbar) 1250 endif !nphasesincyle 1251 endif !ioybar 1252 if(ivort == 1) then 1253 deallocate(strain,vorticity) 1254 endif 1255 if(abs(itwmod).ne.1 .and. iowflux.eq.1) then 1256 deallocate(wallssVec) 1257 endif 1258 if(iRANS.lt.0) then 1259 deallocate(d2wall) 1260 endif 1261 1262 1263CAD tcorecp2 = second(0) 1264CAD tcorewc2 = second(-1) 1265 1266CAD write(6,*) 'T(core) cpu-wallclock = ',tcorecp2-tcorecp1, 1267CAD & tcorewc2-tcorewc1 1268 1269 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1270 if(myrank.eq.0) then 1271 tcorecp2 = TMRC() 1272 write(6,*) 'T(core) cpu = ',tcorecp2-tcorecp1 1273 write(6,*) '(Elm. form.',tcorecp(1), 1274 & ',Lin. alg. sol.',tcorecp(2),')' 1275 write(6,*) '(Elm. form. Scal.',tcorecpscal(1), 1276 & ',Lin. alg. sol. Scal.',tcorecpscal(2),')' 1277 write(6,*) '' 1278 1279 endif 1280 1281 call print_system_stats(tcorecp, tcorecpscal) 1282 call print_mesh_stats() 1283 call print_mpi_stats() 1284 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1285! return 1286c call MPI_Finalize() 1287c call MPI_ABORT(MPI_COMM_WORLD, ierr) 1288 1289 3000 continue 1290 1291 1292c 1293c.... close history and aerodynamic forces files 1294c 1295 if (myrank .eq. master) then 1296! close (ihist) 1297 close (iforce) 1298 close(76) 1299 if(numImpSrfs.gt.0 .or. numRCRSrfs.gt.0) then 1300 close (8177) 1301 endif 1302 endif 1303c 1304c.... close varts file for probes 1305c 1306 if(exts) then 1307 do jj=1,ntspts 1308 if (myrank == iv_rank(jj)) then 1309 close(1000+jj) 1310 endif 1311 enddo 1312 deallocate (ivarts) 1313 deallocate (ivartsg) 1314 deallocate (iv_rank) 1315 deallocate (vartssoln) 1316 deallocate (vartssolng) 1317 endif 1318 1319!MR CHANGE 1320 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1321 if(myrank.eq.0) then 1322 write(*,*) 'itrdrv - done with aerodynamic forces' 1323 endif 1324!MR CHANGE 1325 1326 do isrf = 0,MAXSURF 1327! if ( nsrflist(isrf).ne.0 ) then 1328 if ( nsrflist(isrf).ne.0 .and. 1329 & myrank.eq.irankfilesforce(isrf)) then 1330 iunit=60+isrf 1331 close(iunit) 1332 endif 1333 enddo 1334 1335!MR CHANGE 1336 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1337 if(myrank.eq.0) then 1338 write(*,*) 'itrdrv - done with MAXSURF' 1339 endif 1340!MR CHANGE 1341 1342 1343 5 format(1X,F15.10,3X,F15.10,3X,F15.10,3X,F15.10) 1344 444 format(6(2x,e14.7)) 1345c 1346c.... end 1347c 1348 if(nsolflow.eq.1) then 1349 deallocate (lhsK) 1350 deallocate (lhsP) 1351 deallocate (aperm) 1352 deallocate (atemp) 1353 endif 1354 if(nsclrsol.gt.0) then 1355 deallocate (lhsS) 1356 deallocate (apermS) 1357 deallocate (atempS) 1358 endif 1359 1360 if(iabc==1) deallocate(acs) 1361 1362!MR CHANGE 1363 if (numpe > 1) call MPI_BARRIER(MPI_COMM_WORLD, ierr) 1364 if(myrank.eq.0) then 1365 write(*,*) 'itrdrv - done - BACK TO process.f' 1366 endif 1367!MR CHANGE 1368 1369 1370 1371 return 1372 end 1373 1374 subroutine lesmodels(y, ac, shgl, shp, 1375 & iper, ilwork, rowp, colm, 1376 & nsons, ifath, x, 1377 & iBC, BC) 1378 1379 include "common.h" 1380 1381 real*8 y(nshg,ndof), ac(nshg,ndof), 1382 & x(numnp,nsd), 1383 & BC(nshg,ndofBC) 1384 real*8 shp(MAXTOP,maxsh,MAXQPT), 1385 & shgl(MAXTOP,nsd,maxsh,MAXQPT) 1386 1387c 1388 integer rowp(nshg,nnz), colm(nshg+1), 1389 & iBC(nshg), 1390 & ilwork(nlwork), 1391 & iper(nshg) 1392 dimension ifath(numnp), nsons(nfath) 1393 1394 real*8, allocatable, dimension(:) :: fwr2,fwr3,fwr4 1395 real*8, allocatable, dimension(:) :: stabdis,cdelsq1 1396 real*8, allocatable, dimension(:,:) :: xavegt, xavegt2,xavegt3 1397 1398 if( (iLES.gt.1) ) then ! Allocate Stuff for advanced LES models 1399 allocate (fwr2(nshg)) 1400 allocate (fwr3(nshg)) 1401 allocate (fwr4(nshg)) 1402 allocate (xavegt(nfath,12)) 1403 allocate (xavegt2(nfath,12)) 1404 allocate (xavegt3(nfath,12)) 1405 allocate (stabdis(nfath)) 1406 endif 1407 1408c.... get dynamic model coefficient 1409c 1410 ilesmod=iLES/10 1411c 1412c digit bit set filter rule, 10 bit set model 1413c 1414 if (ilesmod.eq.0) then ! 0 < iLES< 10 => dyn. model calculated 1415 ! at nodes based on discrete filtering 1416 1417 1418 if(isubmod.eq.2) then 1419 call SUPGdis(y, ac, shgl, shp, 1420 & iper, ilwork, 1421 & nsons, ifath, x, 1422 & iBC, BC, stabdis, xavegt3) 1423 endif 1424 1425 if( ((isubmod.eq.0).or.(isubmod.eq.2)))then ! If no 1426 ! sub-model 1427 ! or SUPG 1428 ! model wanted 1429 1430 if(i2filt.eq.0)then ! If simple filter 1431 1432 if(modlstats .eq. 0) then ! If no model stats wanted 1433 call getdmc (y, shgl, shp, 1434 & iper, ilwork, nsons, 1435 & ifath, x) 1436 else ! else get model stats 1437 call stdfdmc (y, shgl, shp, 1438 & iper, ilwork, nsons, 1439 & ifath, x) 1440 endif ! end of stats if statement 1441 1442 else ! else if twice filtering 1443 1444 call widefdmc(y, shgl, shp, 1445 & iper, ilwork, nsons, 1446 & ifath, x) 1447 1448 1449 endif ! end of simple filter if statement 1450 1451 endif ! end of SUPG or no sub-model if statement 1452 1453 1454 if( (isubmod.eq.1) ) then ! If DFWR sub-model wanted 1455 call cdelBHsq (y, shgl, shp, 1456 & iper, ilwork, nsons, 1457 & ifath, x, cdelsq1) 1458 call FiltRat (y, shgl, shp, 1459 & iper, ilwork, nsons, 1460 & ifath, x, cdelsq1, 1461 & fwr4, fwr3) 1462 1463 1464 if (i2filt.eq.0) then ! If simple filter wanted 1465 call DFWRsfdmc(y, shgl, shp, 1466 & iper, ilwork, nsons, 1467 & ifath, x, fwr2, fwr3) 1468 else ! else if twice filtering wanted 1469 call DFWRwfdmc(y, shgl, shp, 1470 & iper, ilwork, nsons, 1471 & ifath, x, fwr4, fwr4) 1472 endif ! end of simple filter if statement 1473 1474 endif ! end of DFWR sub-model if statement 1475 1476 if( (isubmod.eq.2) )then ! If SUPG sub-model wanted 1477 call dmcSUPG (y, ac, shgl, 1478 & shp, iper, ilwork, 1479 & nsons, ifath, x, 1480 & iBC, BC, rowp, colm, 1481 & xavegt2, stabdis) 1482 endif 1483 1484 if(idis.eq.1)then ! If SUPG/Model dissipation wanted 1485 call ediss (y, ac, shgl, 1486 & shp, iper, ilwork, 1487 & nsons, ifath, x, 1488 & iBC, BC, xavegt) 1489 endif 1490 1491 endif ! end of ilesmod 1492 1493 if (ilesmod .eq. 1) then ! 10 < iLES < 20 => dynamic-mixed 1494 ! at nodes based on discrete filtering 1495 call bardmc (y, shgl, shp, 1496 & iper, ilwork, 1497 & nsons, ifath, x) 1498 endif 1499 1500 if (ilesmod .eq. 2) then ! 20 < iLES < 30 => dynamic at quad 1501 ! pts based on lumped projection filt. 1502 1503 if(isubmod.eq.0)then 1504 call projdmc (y, shgl, shp, 1505 & iper, ilwork, x) 1506 else 1507 call cpjdmcnoi (y, shgl, shp, 1508 & iper, ilwork, x, 1509 & rowp, colm, 1510 & iBC, BC) 1511 endif 1512 1513 endif 1514 1515 if( (iLES.gt.1) ) then ! Deallocate Stuff for advanced LES models 1516 deallocate (fwr2) 1517 deallocate (fwr3) 1518 deallocate (fwr4) 1519 deallocate (xavegt) 1520 deallocate (xavegt2) 1521 deallocate (xavegt3) 1522 deallocate (stabdis) 1523 endif 1524 return 1525 end 1526 1527c 1528c...initialize the coefficients for the impedance convolution 1529c 1530 subroutine CalcImpConvCoef (numISrfs, numTpoints) 1531 1532 use convolImpFlow !uses flow history and impedance for convolution 1533 1534 include "common.h" !for alfi 1535 1536 integer numISrfs, numTpoints 1537 1538 allocate (ConvCoef(numTpoints+2,3)) !same time discret. for all imp. BC 1539 do j=1,numTpoints+2 1540 ConvCoef(j,:)=0.5/numTpoints !dt/2 divided by period T=N*dt 1541 ConvCoef(j,1)=ConvCoef(j,1)*(1.0-alfi)*(1.0-alfi) 1542 ConvCoef(j,2)=ConvCoef(j,2)*(1.0+2*alfi*(1.0-alfi)) 1543 ConvCoef(j,3)=ConvCoef(j,3)*alfi*alfi 1544 enddo 1545 ConvCoef(1,2)=zero 1546 ConvCoef(1,3)=zero 1547 ConvCoef(2,3)=zero 1548 ConvCoef(numTpoints+1,1)=zero 1549 ConvCoef(numTpoints+2,2)=zero 1550 ConvCoef(numTpoints+2,1)=zero 1551c 1552c...calculate the coefficients for the impedance convolution 1553c 1554 allocate (ImpConvCoef(numTpoints+2,numISrfs)) 1555 1556c..coefficients below assume Q linear in time step, Z constant 1557c do j=3,numTpoints 1558c ImpConvCoef(j,:) = ValueListImp(j-1,:)*ConvCoef(j,3) 1559c & + ValueListImp(j,:)*ConvCoef(j,2) 1560c & + ValueListImp(j+1,:)*ConvCoef(j,1) 1561c enddo 1562c ImpConvCoef(1,:) = ValueListImp(2,:)*ConvCoef(1,1) 1563c ImpConvCoef(2,:) = ValueListImp(2,:)*ConvCoef(2,2) 1564c & + ValueListImp(3,:)*ConvCoef(2,1) 1565c ImpConvCoef(numTpoints+1,:) = 1566c & ValueListImp(numTpoints,:)*ConvCoef(numTpoints+1,3) 1567c & + ValueListImp(numTpoints+1,:)*ConvCoef(numTpoints+1,2) 1568c ImpConvCoef(numTpoints+2,:) = 1569c & ValueListImp(numTpoints+1,:)*ConvCoef(numTpoints+2,3) 1570 1571c..try easiest convolution Q and Z constant per time step 1572 do j=3,numTpoints+1 1573 ImpConvCoef(j,:) = ValueListImp(j-1,:)/numTpoints 1574 enddo 1575 ImpConvCoef(1,:) =zero 1576 ImpConvCoef(2,:) =zero 1577 ImpConvCoef(numTpoints+2,:) = 1578 & ValueListImp(numTpoints+1,:)/numTpoints 1579c compensate for yalpha passed not y in Elmgmr() 1580 ImpConvCoef(numTpoints+1,:)= ImpConvCoef(numTpoints+1,:) 1581 & - ImpConvCoef(numTpoints+2,:)*(1.0-alfi)/alfi 1582 ImpConvCoef(numTpoints+2,:)= ImpConvCoef(numTpoints+2,:)/alfi 1583 return 1584 end 1585 1586c 1587c ... update the flow rate history for the impedance convolution, filter it and write it out 1588c 1589 subroutine UpdHistConv(y,nsrfIdList,numSrfs) 1590 1591 use convolImpFlow !brings ntimeptpT, QHistImp, QHistTry, QHistTryF, numImpSrfs 1592 use convolRCRFlow !brings QHistRCR, numRCRSrfs 1593 1594 include "common.h" 1595 1596 integer nsrfIdList(0:MAXSURF), numSrfs 1597 character*20 fname1 1598 character*10 cname2 1599 character*5 cname 1600 real*8 y(nshg,3) !velocity at time n+1 1601 real*8 NewQ(0:MAXSURF) !temporary unknown for the flow rate 1602 !that needs to be added to the flow history 1603 1604 call GetFlowQ(NewQ,y,nsrfIdList,numSrfs) !new flow at time n+1 1605c 1606c... for imp BC: shift QHist, add new constribution, filter and write out 1607c 1608 if(numImpSrfs.gt.zero) then 1609 do j=1, ntimeptpT 1610 QHistImp(j,1:numSrfs)=QHistImp(j+1,1:numSrfs) 1611 enddo 1612 QHistImp(ntimeptpT+1,1:numSrfs) = NewQ(1:numSrfs) 1613 1614c 1615c....filter the flow rate history 1616c 1617 cutfreq = 10 !hardcoded cutting frequency of the filter 1618 do j=1, ntimeptpT 1619 QHistTry(j,:)=QHistImp(j+1,:) 1620 enddo 1621 call Filter(QHistTryF,QHistTry,ntimeptpT,Delt(1),cutfreq) 1622c.... if no filter applied then uncomment next three lines 1623c do j=1, ntimeptpT 1624c QHistTryF(j,:)=QHistTry(j,:) 1625c enddo 1626 1627c QHistImp(1,:)=zero ! why do we do this? for beta(1,:) = zero it does not really matters 1628 do j=1, ntimeptpT 1629 QHistImp(j+1,:)=QHistTryF(j,:) 1630 enddo 1631c 1632c.... write out the new history of flow rates to Qhistor.dat 1633c 1634 if (((irs .ge. 1) .and. ((mod(lstep, ntout) .eq. 0) .or. 1635 & (istep .eq. nstep(1)))) .and. 1636 & (myrank .eq. master)) then 1637 open(unit=816, file='Qhistor.dat',status='replace') 1638 write(816,*) ntimeptpT 1639 do j=1,ntimeptpT+1 1640 write(816,*) (QHistImp(j,n),n=1, numSrfs) 1641 enddo 1642 close(816) 1643c... write out a copy with step number to be able to restart 1644 fname1 = 'Qhistor' 1645 fname1 = trim(fname1)//trim(cname2(lstep))//'.dat' 1646 open(unit=8166,file=trim(fname1),status='unknown') 1647 write(8166,*) ntimeptpT 1648 do j=1,ntimeptpT+1 1649 write(8166,*) (QHistImp(j,n),n=1, numSrfs) 1650 enddo 1651 close(8166) 1652 endif 1653 endif 1654 1655c 1656c... for RCR bc just add the new contribution 1657c 1658 if(numRCRSrfs.gt.zero) then 1659 QHistRCR(lstep+1,1:numSrfs) = NewQ(1:numSrfs) 1660c 1661c.... write out the new history of flow rates to Qhistor.dat 1662c 1663 if ((irs .ge. 1) .and. (myrank .eq. master)) then 1664 if(istep.eq.1) then 1665 open(unit=816,file='Qhistor.dat',status='unknown') 1666 else 1667 open(unit=816,file='Qhistor.dat',position='append') 1668 endif 1669 if(istep.eq.1) then 1670 do j=1,lstep 1671 write(816,*) j, (QHistRCR(j,n),n=1,numSrfs) ! read from file of previous run 1672 enddo 1673 endif 1674 write(816,*) lstep+1, (QHistRCR(lstep+1,n),n=1, numSrfs) 1675 close(816) 1676c... write out a copy with step number to be able to restart 1677 if (((irs .ge. 1) .and. ((mod(lstep, ntout) .eq. 0) .or. 1678 & (istep .eq. nstep(1)))) .and. 1679 & (myrank .eq. master)) then 1680 fname1 = 'Qhistor' 1681 fname1 = trim(fname1)//trim(cname2(lstep))//'.dat' 1682 open(unit=8166,file=trim(fname1),status='unknown') 1683 write(8166,*) lstep+1 1684 do j=1,lstep+1 1685 write(8166,*) (QHistRCR(j,n),n=1, numSrfs) 1686 enddo 1687 close(8166) 1688 endif 1689 endif 1690 endif 1691 1692 return 1693 end 1694 1695c 1696c...calculate the time varying coefficients for the RCR convolution 1697c 1698 subroutine CalcRCRConvCoef (stepn, numSrfs) 1699 1700 use convolRCRFlow !brings in ValueListRCR, dtRCR 1701 1702 include "common.h" !brings alfi 1703 1704 integer numSrfs, stepn 1705 1706 RCRConvCoef = zero 1707 if (stepn .eq. 0) then 1708 RCRConvCoef(1,:) = ValueListRCR(1,:)*(1.0-alfi) + 1709 & ValueListRCR(3,:)*(-alfi + 1.0 + 1/dtRCR(:) 1710 & - exp(-alfi*dtRCR(:))*(1 + 1/dtRCR(:))) 1711 RCRConvCoef(2,:) = ValueListRCR(1,:)*alfi 1712 & + ValueListRCR(3,:) 1713 & *(alfi - 1/dtRCR(:) + exp(-alfi*dtRCR(:))/dtRCR(:)) 1714 endif 1715 if (stepn .ge. 1) then 1716 RCRConvCoef(1,:) =-ValueListRCR(3,:)*exp(-dtRCR(:)*(stepn+alfi)) 1717 & *(1 + (1 - exp(dtRCR(:)))/dtRCR(:)) 1718 RCRConvCoef(stepn+1,:) = ValueListRCR(1,:)*(1-alfi) 1719 & - ValueListRCR(3,:)*(alfi - 1 - 1/dtRCR(:) 1720 & + exp(-alfi*dtRCR(:))/dtRCR(:)*(2 - exp(-dtRCR(:)))) 1721 RCRConvCoef(stepn+2,:) = ValueListRCR(1,:)*alfi 1722 & + ValueListRCR(3,:) 1723 & *(alfi - 1/dtRCR(:) + exp(-alfi*dtRCR(:))/dtRCR(:)) 1724 endif 1725 if (stepn .ge. 2) then 1726 do j=2,stepn 1727 RCRConvCoef(j,:) = ValueListRCR(3,:)/dtRCR(:)* 1728 & exp(-dtRCR(:)*(stepn + alfi + 2 - j))* 1729 & (1 - exp(dtRCR(:)))**2 1730 enddo 1731 endif 1732 1733c compensate for yalpha passed not y in Elmgmr() 1734 RCRConvCoef(stepn+1,:)= RCRConvCoef(stepn+1,:) 1735 & - RCRConvCoef(stepn+2,:)*(1.0-alfi)/alfi 1736 RCRConvCoef(stepn+2,:)= RCRConvCoef(stepn+2,:)/alfi 1737 1738 return 1739 end 1740 1741c 1742c...calculate the time dependent H operator for the RCR convolution 1743c 1744 subroutine CalcHopRCR (timestepRCR, stepn, numSrfs) 1745 1746 use convolRCRFlow !brings in HopRCR, dtRCR 1747 1748 include "common.h" 1749 1750 integer numSrfs, stepn 1751 real*8 PdistCur(0:MAXSURF), timestepRCR 1752 1753 HopRCR=zero 1754 call RCRint(timestepRCR*(stepn + alfi),PdistCur) 1755 HopRCR(1:numSrfs) = RCRic(1:numSrfs) 1756 & *exp(-dtRCR(1:numSrfs)*(stepn + alfi)) + PdistCur(1:numSrfs) 1757 return 1758 end 1759c 1760c ... initialize the influence of the initial conditions for the RCR BC 1761c 1762 subroutine calcRCRic(y,srfIdList,numSrfs) 1763 1764 use convolRCRFlow !brings RCRic, ValueListRCR, ValuePdist 1765 1766 include "common.h" 1767 1768 integer srfIdList(0:MAXSURF), numSrfs, irankCoupled 1769 real*8 y(nshg,4) !need velocity and pressure 1770 real*8 Qini(0:MAXSURF) !initial flow rate 1771 real*8 PdistIni(0:MAXSURF) !initial distal pressure 1772 real*8 Pini(0:MAXSURF),CoupleArea(0:MAXSURF) ! initial pressure 1773 real*8 VelOnly(nshg,3), POnly(nshg) 1774 1775 allocate (RCRic(0:MAXSURF)) 1776 1777 if(lstep.eq.0) then 1778 VelOnly(:,1:3)=y(:,1:3) 1779 call GetFlowQ(Qini,VelOnly,srfIdList,numSrfs) !get initial flow 1780 QHistRCR(1,1:numSrfs)=Qini(1:numSrfs) !initialize QHistRCR 1781 POnly(:)=y(:,4) ! pressure 1782 call integrScalar(Pini,POnly,srfIdList,numSrfs) !get initial pressure integral 1783 POnly(:)=one ! one to get area 1784 call integrScalar(CoupleArea,POnly,srfIdList,numSrfs) !get surf area 1785 Pini(1:numSrfs) = Pini(1:numSrfs)/CoupleArea(1:numSrfs) 1786 else 1787 Qini(1:numSrfs)=QHistRCR(1,1:numSrfs) 1788 Pini(1:numSrfs)=zero ! hack 1789 endif 1790 call RCRint(istep,PdistIni) !get initial distal P (use istep) 1791 RCRic(1:numSrfs) = Pini(1:numSrfs) 1792 & - ValueListRCR(1,:)*Qini(1:numSrfs)-PdistIni(1:numSrfs) 1793 return 1794 end 1795 1796c.........function that integrates a scalar over a boundary 1797 subroutine integrScalar(scalInt,scal,srfIdList,numSrfs) 1798 1799 use pvsQbi !brings ndsurf, NASC 1800 1801 include "common.h" 1802 include "mpif.h" 1803 1804 integer srfIdList(0:MAXSURF), numSrfs, irankCoupled, i, k 1805 real*8 scal(nshg), scalInt(0:MAXSURF), scalIntProc(0:MAXSURF) 1806 1807 scalIntProc = zero 1808 do i = 1,nshg 1809 if(numSrfs.gt.zero) then 1810 do k = 1,numSrfs 1811 irankCoupled = 0 1812 if (srfIdList(k).eq.ndsurf(i)) then 1813 irankCoupled=k 1814 scalIntProc(irankCoupled) = scalIntProc(irankCoupled) 1815 & + NASC(i)*scal(i) 1816 exit 1817 endif 1818 enddo 1819 endif 1820 enddo 1821c 1822c at this point, each scalint has its "nodes" contributions to the scalar 1823c accumulated into scalIntProc. Note, because NASC is on processor this 1824c will NOT be the scalar for the surface yet 1825c 1826c.... reduce integrated scalar for each surface, push on scalInt 1827c 1828 npars=MAXSURF+1 1829 call MPI_ALLREDUCE (scalIntProc, scalInt(:), npars, 1830 & MPI_DOUBLE_PRECISION,MPI_SUM, MPI_COMM_WORLD,ierr) 1831 1832 return 1833 end 1834 1835 subroutine writeTimingMessage(key,iomode,timing) 1836 use iso_c_binding 1837 use phstr 1838 implicit none 1839 1840 character(len=*) :: key 1841 integer :: iomode 1842 real*8 :: timing 1843 character(len=1024) :: timing_msg 1844 character(len=*), parameter :: 1845 & streamModeString = c_char_"stream"//c_null_char, 1846 & fileModeString = c_char_"disk"//c_null_char 1847 1848 timing_msg = c_char_"Time to write "//c_null_char 1849 call phstr_appendStr(timing_msg,key) 1850 if ( iomode .eq. -1 ) then 1851 call phstr_appendStr(timing_msg, streamModeString) 1852 else 1853 call phstr_appendStr(timing_msg, fileModeString) 1854 endif 1855 call phstr_appendStr(timing_msg, c_char_' = '//c_null_char) 1856 call phstr_appendDbl(timing_msg, timing) 1857 write(6,*) trim(timing_msg) 1858 return 1859 end subroutine 1860 1861