! $Id$ ! !*********************************************************************** ! ! The Pencil Code is a high-order finite-difference code for compressible ! hydrodynamic flows with magnetic fields and particles. It is highly ! modular and can easily be adapted to different types of problems. ! ! MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ! MMMMMMM7MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ! MMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ! MMMMMMMIIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ! MMMMMMM7IMMMMMMMMMMMMMMMMMMM7IMMMMMMMMMMMMMMMMMMMMDMMMMMMM ! MMMMMMZIIMMMMMMMMMMMMMMMMMMMIIMMMMMMMMMMMMMMMMMMMMIMMMMMMM ! MMMMMMIIIZMMMMMMMMMMMMMMMMMMIIMMMMMMMMMMMMMMMMMMMMIMMMMMMM ! MMMMMMIIIIMMMMMMMMMMMMMMMMMNII$MMMMMMMMMMMMMMMMMM$IMMMMMMM ! MMMMM8IIIIMMMMMMMMMMMMMMMMM$IIIMMMMMMMMMMMMMMMMMMII7MMMMMM ! MMMMMD7II7MMMMMMMMMMMMMMMMMIIIIMMMMMMMMMMMMMMMMMMIIIMMMMMM ! MMMMN..:~=ZMMMMMMMMMMMMMMMMIIIIDMMMMMMMMMMMMMMMMDIIIMMMMMM ! MMMM8.,:~=?MMMMMMMMMMMMMMMMOII7NMMMMMMMMMMMMMMMMZIIIDMMMMM ! MMMM. ,::=+MMMMMMMMMMMMMMM..,~=?MMMMMMMMMMMMMMMMIIII$MMMMM ! MMMM..,:~=+MMMMMMMMMMMMMM8 .,~=+DMMMMMMMMMMMMMMM8II78MMMMM ! MMMM .,:~==?MMMMMMMMMMMMMN .,~=+NMMMMMMMMMMMMMM8 ,~~+MMMMM ! MMM7 ,:~+=?MMMMMMMMMMMMM .,~==?MMMMMMMMMMMMMM..,~~+DMMMM ! MMM. ,:~==?MMMMMMMMMMMMM .,~~=?MMMMMMMMMMMMMM. ,~~+?MMMM ! MMM. ,:~~=??MMMMMMMMMMMM ,,~~=?MMMMMMMMMMMMM8 .,~~=?NMMM ! MMM. ,:~~=+?MMMMMMMMMMMI ,,~~=+?MMMMMMMMMMMM. .,~~=?MMMM ! MM~. .,:~:==?MMMMMMMMMMM ,,~~==?MMMMMMMMMMMM .,~~=+?MMM ! MMN8 .D,D+=M=8MMMMMMMMMM ,,~~==?MMMMMMMMMMMM. .,~~==?MMM ! MM==8. .8===MMMMMMMMMM .,,~~==?$MMMMMMMMMM= .,~~==?MMM ! MM==D. +===MMMMMMMMMO$ .I?7$=7=NMMMMMMMMMM. ,,~~==?$MM ! MM==D. +===MMMMMMMMM==O?.. ====MMMMMMMMMM. ,,~~==??MM ! MM==D. +===MMMMMMMMM===. .===MMMMMMMMMM+$.?=,7==?7MM ! MM==D. +===MMMMMMMMM===. .===MMMMMMMMMZ==8 .8==MM ! MM==D. +===MMMMMMMMM===. .===MMMMMMMMMZ==I .Z==MM ! MM==D. . +===MMMMMMMMM===.... .===MMMMMMMMMZ==I .Z==MM ! MM==D. +===MMMMMMMMM===. .===MMMMMMMMMZ==I .Z==MM ! MM==D. +===MMMMMMMMM===. .===MMMMMMMMMZ==I .Z==MM ! MM==D. +===MMMMMMMMM===.. .===MMMMMMMMMZ==I .Z==MM ! MM==D. . +===MMMMMMMMM===.... .===MMMMMMMMMZ==I .Z==MM ! ! More information can be found in the Pencil Code manual and at the ! website http://www.nordita.org/software/pencil-code/. ! !*********************************************************************** program run ! ! 8-mar-13/MR: changed calls to wsnap and rsnap to grant reference to f by ! address ! 31-oct-13/MR: replaced rparam by read_all_init_pars ! 10-feb-14/MR: initialize_mpicomm now called before read_all_run_pars ! 13-feb-13/MR: call of wsnap_down added ! use Boundcond, only: update_ghosts use Cdata use Chemistry, only: chemistry_clean_up, write_net_reaction, lchemistry_diag use Density, only: boussinesq use Diagnostics use Dustdensity, only: init_nd use Dustvelocity, only: init_uud use Equ, only: debug_imn_arrays,initialize_pencils use EquationOfState, only: ioninit,ioncalc use FArrayManager, only: farray_clean_up use Filter use Fixed_point, only: fixed_points_prepare, wfixed_points use Forcing, only: forcing_clean_up,addforce use General, only: random_seed_wrapper, touch_file use Hydro, only: hydro_clean_up,kinematic_random_phase use ImplicitPhysics, only: calc_heatcond_ADI use Interstellar, only: check_SN,addmassflux use IO, only: rgrid, directory_names, rproc_bounds, output_globals, input_globals use Magnetic, only: rescaling_magnetic use Messages use Mpicomm use NSCBC, only: NSCBC_clean_up use Param_IO use Particles_main use Pencil_check, only: pencil_consistency_check use Register use SharedVariables, only: sharedvars_clean_up use Signal_handling, only: signal_prepare, emergency_stop use Slices use Snapshot use Solid_Cells, only: solid_cells_clean_up use Streamlines, only: tracers_prepare, wtracers use Sub use Grid, only: construct_grid, box_vol, grid_bound_data, set_coords_switches use IO, only: wgrid use Syscalls, only: is_nan use Testscalar, only: rescaling_testscalar use Testfield, only: rescaling_testfield use TestPerturb, only: testperturb_begin, testperturb_finalize use Timeavg use Timestep, only: time_step ! implicit none ! real, dimension (mx,my,mz,mfarray) :: f real, dimension (mx,my,mz,mvar) :: df type (pencil_case) :: p double precision :: time1, time2 double precision :: time_last_diagnostic, time_this_diagnostic real :: wall_clock_time=0.0, time_per_step=0.0 integer :: icount, i, mvar_in, isave_shift=0 integer :: it_last_diagnostic, it_this_diagnostic logical :: lstop=.false., lsave=.false., timeover=.false., resubmit=.false. logical :: suppress_pencil_check=.false. logical :: lreload_file=.false., lreload_always_file=.false. ! lrun = .true. ! ! Get processor numbers and define whether we are root. ! call mpicomm_init ! ! Identify version. ! if (lroot) call svn_id('$Id$') ! ! Initialize the message subsystem, eg. color setting etc. ! call initialize_messages ! ! Define the lenergy logical ! lenergy=lentropy.or.ltemperature.or.lthermal_energy ! ! Read parameters from start.x (set in start.in/default values; possibly overwritten by 'read_all_run_pars'). ! call read_all_init_pars ! ! Read parameters and output parameter list. ! call read_all_run_pars ! call set_coords_switches ! ! Initialise MPI communication. ! call initialize_mpicomm ! if (any(downsampl>1)) then ! ! If downsampling, calculate local start indices and number of data in ! output for each direction; inner ghost zones are here disregarded ! ldownsampl = .true. if (dsnap_down<=0.) dsnap_down=dsnap ! call get_downpars(1,nx,ipx) call get_downpars(2,ny,ipy) call get_downpars(3,nz,ipz) ! endif ! ! Derived parameters (that may still be overwritten). ! [might better be put into another routine, possibly in 'read_all_run_pars'] ! x0 = xyz0(1) ; y0 = xyz0(2) ; z0 = xyz0(3) Lx = Lxyz(1) ; Ly = Lxyz(2) ; Lz = Lxyz(3) ! ! Set up directory names. ! call directory_names ! ! Read coordinates (if luse_oldgrid=T, otherwise regenerate grid). ! luse_oldgrid=T can be useful if nghost_read_fewer > 0, ! i.e. if one is changing the order of spatial derivatives. ! Also write dim.dat (important when reading smaller meshes, for example) ! if (luse_oldgrid) then if (ip<=6.and.lroot) print*, 'reading grid coordinates' call rgrid('grid.dat') call grid_bound_data else if (luse_xyz1) Lxyz = xyz1-xyz0 call construct_grid(x,y,z,dx,dy,dz) endif ! ! Size of box at local processor. The if-statement is for ! backward compatibility. ! if (lequidist(1)) then Lxyz_loc(1) = Lxyz(1)/nprocx xyz0_loc(1) = xyz0(1)+ipx*Lxyz_loc(1) xyz1_loc(1) = xyz0_loc(1)+Lxyz_loc(1) else ! ! In the equidistant grid, the processor boundaries (xyz[01]_loc) do NOT ! coincide with the l[mn]1[2] points. Also, xyz0_loc[ipx+1]=xyz1_loc[ipx], i.e., ! the inner boundary of one is exactly the outer boundary of the other. Reproduce ! this behavior also for non-equidistant grids. ! if (ipx==0) then xyz0_loc(1) = x(l1) else xyz0_loc(1) = x(l1) - .5/dx_1(l1) endif if (ipx==nprocx-1) then xyz1_loc(1) = x(l2) else xyz1_loc(1) = x(l2+1) - .5/dx_1(l2+1) endif Lxyz_loc(1) = xyz1_loc(1) - xyz0_loc(1) endif ! if (lequidist(2)) then Lxyz_loc(2) = Lxyz(2)/nprocy xyz0_loc(2) = xyz0(2)+ipy*Lxyz_loc(2) xyz1_loc(2) = xyz0_loc(2)+Lxyz_loc(2) else if (ipy==0) then xyz0_loc(2) = y(m1) else xyz0_loc(2) = y(m1) - .5/dy_1(m1) endif if (ipy==nprocy-1) then xyz1_loc(2) = y(m2) else xyz1_loc(2) = y(m2+1) - .5/dy_1(m2+1) endif Lxyz_loc(2) = xyz1_loc(2) - xyz0_loc(2) endif ! if (lequidist(3)) then Lxyz_loc(3) = Lxyz(3)/nprocz xyz0_loc(3) = xyz0(3)+ipz*Lxyz_loc(3) xyz1_loc(3) = xyz0_loc(3)+Lxyz_loc(3) else if (ipz==0) then xyz0_loc(3) = z(n1) else xyz0_loc(3) = z(n1) - .5/dz_1(n1) endif if (ipz==nprocz-1) then xyz1_loc(3) = z(n2) else xyz1_loc(3) = z(n2+1) - .5/dz_1(n2+1) endif Lxyz_loc(3) = xyz1_loc(3) - xyz0_loc(3) endif ! ! Calculate dimensionality ! dimensionality=min(nxgrid-1,1)+min(nygrid-1,1)+min(nzgrid-1,1) ! ! Register physics modules. ! call register_modules if (lparticles) call particles_register_modules ! ! Only after register it is possible to write the correct dim.dat ! file with the correct number of variables ! if (.not.luse_oldgrid) then call wgrid('grid.dat') call wdim(trim(directory)//'/dim.dat') if (lroot) call wdim(trim(datadir)//'/dim.dat', & nxgrid+2*nghost,nygrid+2*nghost,nzgrid+2*nghost,lglobal=.true.) if (ip<11) print*,'Lz=',Lz if (ip<11) print*,'z=',z elseif (lwrite_dim_again) then call wdim(trim(directory)//'/dim.dat') if (lroot) call wdim(trim(datadir)//'/dim.dat', & nxgrid+2*nghost,nygrid+2*nghost,nzgrid+2*nghost,lglobal=.true.) if (ip<11) print*,'Lz=',Lz if (ip<11) print*,'z=',z endif ! ! Inform about verbose level. ! if (lroot) print*, 'The verbose level is ip=', ip, ' (ldebug=', ldebug, ')' ! ! Call rprint_list to initialize diagnostics and write indices to file. ! call rprint_list(LRESET=.false.) if (lparticles) call particles_rprint_list(.false.) ! ! Populate wavenumber arrays for fft and calculate Nyquist wavenumber. ! if (nxgrid/=1) then kx_fft=cshift((/(i-(nxgrid+1)/2,i=0,nxgrid-1)/),+(nxgrid+1)/2)*2*pi/Lx kx_fft2=kx_fft**2 kx_nyq=nxgrid/2 * 2*pi/Lx else kx_fft=0.0 kx_nyq=0.0 endif ! if (nygrid/=1) then ky_fft=cshift((/(i-(nygrid+1)/2,i=0,nygrid-1)/),+(nygrid+1)/2)*2*pi/Ly ky_fft2=ky_fft**2 ky_nyq=nygrid/2 * 2*pi/Ly else ky_fft=0.0 ky_nyq=0.0 endif ! if (nzgrid/=1) then kz_fft=cshift((/(i-(nzgrid+1)/2,i=0,nzgrid-1)/),+(nzgrid+1)/2)*2*pi/Lz kz_fft2=kz_fft**2 kz_nyq=nzgrid/2 * 2*pi/Lz else kz_fft=0.0 kz_nyq=0.0 endif ! ! Position of equator (if any). ! if (lequatory) yequator=xyz0(2)+0.5*Lxyz(2) if (lequatorz) zequator=xyz0(3)+0.5*Lxyz(3) ! ! Print resolution and dimension of the simulation. ! if (lroot) then write(*,'(a,i1,a)') ' This is a ', dimensionality, '-D run' print*, 'nxgrid, nygrid, nzgrid=', nxgrid, nygrid, nzgrid print*, 'Lx, Ly, Lz=', Lxyz call box_vol if (lyinyang) then print*, ' Vbox(Yin,Yang)=', box_volume print*, ' total volume =', 4./3.*pi*(xyz1(1)**3-xyz0(1)**3) else print*, ' Vbox=', box_volume endif endif ! ! Limits to xaveraging. ! if (lav_smallx) call init_xaver ! ! Inner radius for freezing variables defaults to r_min. ! Note: currently (July 2005), hydro.f90 uses a different approach: ! r_int will override rdampint, which doesn't seem to make much sense (if ! you want rdampint to be overridden, then don't specify it in the first ! place). ! if (rfreeze_int==-impossible .and. r_int>epsi) rfreeze_int=r_int if (rfreeze_ext==-impossible) rfreeze_ext=r_ext ! ! Will we write all slots of f? ! if (lwrite_aux) then mvar_io=mvar+maux else mvar_io=mvar endif ! ! Shall we read also auxiliary variables or fewer variables (ex: turbulence ! field with 0 species as an input file for a chemistry problem)? ! if (lread_aux) then mvar_in=mvar+maux else if (lread_less) then mvar_in=4 else mvar_in=mvar endif ! ! Get state length of random number generator and put the default value. ! With lreset_seed (which is not the default) we can reset the seed during ! the run. This is necessary when lreinitialize_uu=T, inituu='gaussian-noise'. ! if (lreset_seed) then seed(1)=-((seed0-1812+1)*10+iproc_world) call random_seed_wrapper(PUT=seed) else call get_nseed(nseed) call random_seed_wrapper (GET=seed) seed = seed0 call random_seed_wrapper (PUT=seed) endif ! ! Write particle block dimensions to file (may have been changed for better ! load balancing). ! if (lroot) then if (lparticles) call particles_write_block(trim(datadir)//'/bdim.dat') endif ! ! Read data. ! Snapshot data are saved in the data subdirectory. ! This directory must exist, but may be linked to another disk. ! If we decided to use a new grid, we need to overwrite the data ! that we just read in from var.dat. (Note that grid information ! was also used above, so we really need to do it twice then.) ! f=0. call rsnap('var.dat',f,mvar_in,lread_nogrid) ! if (.not.luse_oldgrid) call construct_grid(x,y,z,dx,dy,dz) ! if (lparticles) call read_snapshot_particles(directory_dist) ! call get_nseed(nseed) ! ! Read global variables (if any). ! if (mglobal/=0) & call input_globals('global.dat', & f(:,:,:,mvar+maux+1:mvar+maux+mglobal),mglobal) ! ! Set initial time to zero if requested. ! if (lini_t_eq_zero) t=0.0 ! ! Set last tsound output time ! if (lwrite_sound) then if (tsound<0.0) then ! if sound output starts new tsound=t ! output initial values lout_sound=.true. endif endif ! ! Read processor boundaries. ! if (lparticles) then if (ip<=6.and.lroot) print*, 'reading processor boundaries' call rproc_bounds(trim(directory)//'/proc_bounds.dat') endif ! ! The following is here to avoid division in sub.f90 for diagnostic ! outputs of integrated values in the non equidistant case. ! Do this even for uniform meshes, in which case xprim=dx, etc. ! Remember that dx_1=0 for runs without extent in that direction. ! if (nxgrid==1) then; xprim=1.0; else; xprim=1./dx_1; endif if (nygrid==1) then; yprim=1.0; else; yprim=1./dy_1; endif if (nzgrid==1) then; zprim=1.0; else; zprim=1./dz_1; endif ! ! Determine slice positions and whether slices are to be written on this ! processor. This can only be done after the grid has been established. ! call setup_slices ! ! Initialize the list of neighboring processes. ! call update_neighbors !MR: Isn't this only needed for particles? ! ! Allow modules to do any physics modules do parameter dependent ! initialization. And final pre-timestepping setup. ! (must be done before need_XXXX can be used, for example) ! call initialize_modules(f) ! if (it1d==impossible_int) then it1d=it1 else if (it1d= soundeps ) then lout_sound = .true. tsound = t endif endif ! if (lout .or. emergency_stop) then ! ! Exit do loop if file `STOP' exists. ! lstop=control_file_exists('STOP',DELETE=.true.) if (lstop .or. t>tmax .or. emergency_stop) then if (lroot) then print* if (emergency_stop) print*, 'Emergency stop requested' if (lstop) print*, 'Found STOP file' if (t>tmax) print*, 'Maximum simulation time exceeded' endif resubmit=control_file_exists('RESUBMIT',DELETE=.true.) if (resubmit) print*, 'Cannot be resubmitted' exit Time_loop endif ! ! initialize timer ! call timing('run','entered Time_loop',INSTRUCT='initialize') ! ! Re-read parameters if file `RELOAD' exists; then remove the file ! (this allows us to change parameters on the fly). ! Re-read parameters if file `RELOAD_ALWAYS' exists; don't remove file ! (only useful for debugging RELOAD issues). ! lreload_file =control_file_exists('RELOAD') lreload_always_file=control_file_exists('RELOAD_ALWAYS') lreloading =lreload_file .or. lreload_always_file ! if (lreloading) then if (lroot) write(*,*) 'Found RELOAD file -- reloading parameters' ! Re-read configuration dt=0.0 call read_all_run_pars(logging=.true.) ! ! Before reading the rprint_list deallocate the arrays allocated for ! 1-D and 2-D diagnostics. ! call vnames_clean_up call xyaverages_clean_up call xzaverages_clean_up call yzaverages_clean_up if (lwrite_phizaverages) call phizaverages_clean_up if (lwrite_yaverages) call yaverages_clean_up if (lwrite_zaverages) call zaverages_clean_up if (lwrite_phiaverages) call phiaverages_clean_up if (lwrite_sound) call sound_clean_up if (lforcing) call forcing_clean_up if (lhydro_kinematic) call hydro_clean_up if (lsolid_cells) call solid_cells_clean_up call rprint_list(LRESET=.true.) !(Re-read output list) call initialize_modules(f) if (lparticles) then call particles_rprint_list(.false.) call particles_initialize_modules(f) endif call choose_pencils call write_all_run_pars('IDL') ! lreload_file=control_file_exists('RELOAD', DELETE=.true.) lreload_file = .false. lreload_always_file = .false. lreloading = .false. endif endif ! ! Remove wiggles in lnrho in sporadic time intervals. ! Necessary on moderate-sized grids. When this happens, ! this is often an indication of bad boundary conditions! ! iwig=500 is a typical value. For iwig=0 no action is taken. ! (The two queries below must come separately on compaq machines.) ! ! N.B.: We now (July 2003) know that boundary conditions ! change practically nothing, apart from avoiding stationary ! stagnation points/surfaces in the first place. ! rmwig is superseeded by the switches lupw_lnrho, lupw_ss, ! which should provide a far better solution to the problem. ! if (iwig/=0) then if (mod(it,iwig)==0) then if (lrmwig_xyaverage) call rmwig_xyaverage(f,ilnrho) if (lrmwig_full) call rmwig(f,df,ilnrho,ilnrho,awig) if (lrmwig_rho) call rmwig(f,df,ilnrho,ilnrho,awig,explog=.true.) endif endif ! ! If we want to write out video data, wvid_prepare sets lvideo=.true. ! This allows pde to prepare some of the data. ! if (lwrite_slices) call wvid_prepare if (lwrite_2daverages) call write_2daverages_prepare ! ! Prepare for the writing of the trcers and the fixed points. ! if (lwrite_tracers) call tracers_prepare if (lwrite_fixed_points) call fixed_points_prepare ! ! Find out which pencils to calculate at current time-step. ! lpencil = lpenc_requested if (lout) lpencil=lpencil .or. lpenc_diagnos if (l2davg) lpencil=lpencil .or. lpenc_diagnos2d if (lvideo) lpencil=lpencil .or. lpenc_video ! ! Save state vector prior to update for the (implicit) ADI scheme. ! if (lADI) f(:,:,:,iTTold)=f(:,:,:,ilnTT) ! if (ltestperturb) call testperturb_begin(f,df) ! ! A random phase for the hydro_kinematic module ! if (lhydro_kinematic) call kinematic_random_phase ! ! Time advance. ! call time_step(f,df,p) ! ! Print diagnostic averages to screen and file. ! if (lout) then call prints if (lchemistry_diag) call write_net_reaction endif if (l1davg) call write_1daverages if (l2davg) call write_2daverages ! if (lout_sound) then call write_sound(tsound) lout_sound = .false. endif ! ! Ensure better load balancing of particles by giving equal number of ! particles to each CPU. This only works when block domain decomposition of ! particles is activated. ! if (lparticles) call particles_load_balance(f) ! ! 07-Sep-07/dintrans+gastine: Implicit advance of the radiative diffusion ! in the temperature equation (using the implicit_physics module). ! if (lADI) call calc_heatcond_ADI(f) ! if (ltestperturb) call testperturb_finalize(f) ! if (lboussinesq) call boussinesq(f) ! if (lroot) icount=icount+1 ! reliable loop count even for premature exit ! ! Update time averages and time integrals. ! if (ltavg) call update_timeavgs(f,dt) ! ! Add forcing and/or do rescaling (if applicable). ! if (lforcing) call addforce(f) if (lparticles_lyapunov) call particles_stochastic() ! if (lspecial) call special_stochastic if (lrescaling_magnetic) call rescaling_magnetic(f) if (lrescaling_testfield) call rescaling_testfield(f) if (lrescaling_testscalar) call rescaling_testscalar(f) ! ! Check for SNe, and update f if necessary (see interstellar.f90). ! if (linterstellar) call check_SN(f) ! ! Check if mass flux replacement required fred test ! if (linterstellar) call addmassflux(f) ! ! Check wall clock time, for diagnostics and for user supplied simulation time ! limit. ! if (lroot.and.(idiag_walltime/=0.or.max_walltime/=0.0)) then time2=mpiwtime() wall_clock_time=(time2-time1) if (lout) call save_name(wall_clock_time,idiag_walltime) endif ! if (lout.and.lroot.and.idiag_timeperstep/=0) then it_this_diagnostic = it time_this_diagnostic = mpiwtime() time_per_step = (time_this_diagnostic - time_last_diagnostic) & /( it_this_diagnostic - it_last_diagnostic) it_last_diagnostic = it_this_diagnostic time_last_diagnostic = time_this_diagnostic call save_name(time_per_step,idiag_timeperstep) endif ! ! Setting ialive=1 can be useful on flaky machines! ! The iteration number is written into thi file "data/proc*/alive.info". ! Set ialive=0 to fully switch this off. ! if (ialive /= 0) then if (mod(it,ialive)==0) call output_form('alive.info',it,.false.) endif if (lparticles) & call write_snapshot_particles(directory_dist,f,ENUM=.true.) ! call wsnap('VAR',f,mvar_io,ENUM=.true.,FLIST='varN.list') if (ldownsampl) call wsnap_down(f,mvar_io,FLIST='varN_down.list') call wsnap_timeavgs('TAVG',ENUM=.true.,FLIST='tavgN.list') ! ! Write slices (for animation purposes). ! if (lvideo.and.lwrite_slices) call wvid(f,trim(directory)//'/slice_') ! ! Write tracers (for animation purposes). ! if (ltracers.and.lwrite_tracers) call wtracers(f,trim(directory)//'/tracers_') ! ! Write fixed points (for animation purposes). ! if (lfixed_points.and.lwrite_fixed_points) call wfixed_points(f,trim(directory)//'/fixed_points_') ! ! Save snapshot every isnap steps in case the run gets interrupted. ! The time needs also to be written. ! lsave = control_file_exists('SAVE', DELETE=.true.) if (lsave .or. ((isave /= 0) .and. .not. lnowrite)) then if (lsave .or. (mod(it-isave_shift, isave) == 0)) then call wsnap('var.dat',f, mvar_io,ENUM=.false.,noghost=noghost_for_isave) call wsnap_timeavgs('timeavg.dat',ENUM=.false.) if (lparticles) & call write_snapshot_particles(directory_dist,f,ENUM=.false.) if (lsave) isave_shift = mod(it+isave-isave_shift, isave) + isave_shift endif endif ! ! Save spectrum snapshot. ! if (dspec/=impossible) call powersnap(f) ! ! Save global variables. ! if (isaveglobal/=0) then if ((mod(it,isaveglobal)==0) .and. (mglobal/=0)) then call output_globals('global.dat', & f(:,:,:,mvar+maux+1:mvar+maux+mglobal),mglobal) endif endif ! ! Do exit when timestep has become too short. ! This may indicate an MPI communication problem, so the data are useless ! and won't be saved! ! if ((it1) then if (lparticles) then write(*,'(A,1pG10.3)') & ' Wall clock time/timestep/(meshpoint+particle) [microsec] =', & wall_clock_time/icount/(nw+npar/ncpus)/ncpus/1.0e-6 else write(*,'(A,1pG10.3)') & ' Wall clock time/timestep/meshpoint [microsec] =', & wall_clock_time/icount/nw/ncpus/1.0e-6 endif endif print* endif ! ! Give all modules the possibility to exit properly. ! call finalize_modules(f) ! ! Write success file, if the requested simulation is complete. ! if ((it > nt) .or. (t > tmax)) call touch_file('COMPLETED') ! ! Stop MPI. ! call mpifinalize ! ! Free any allocated memory. ! MR: Is this needed? the program terminates anyway ! call farray_clean_up call sharedvars_clean_up call chemistry_clean_up call NSCBC_clean_up call fnames_clean_up call vnames_clean_up call xyaverages_clean_up call xzaverages_clean_up call yzaverages_clean_up if (lparticles) call particles_cleanup if (lwrite_phizaverages) call phizaverages_clean_up if (lwrite_yaverages) call yaverages_clean_up if (lwrite_zaverages) call zaverages_clean_up if (lwrite_phiaverages) call phiaverages_clean_up if (lwrite_sound) call sound_clean_up ! endprogram run !**************************************************************************