diff --git a/docs/binary.rst b/docs/binary.rst index 41bb6b8f8..a6a7ec221 100644 --- a/docs/binary.rst +++ b/docs/binary.rst @@ -1,17 +1,37 @@ Binary stars and common envelope evolution ============================================ -Using SETUP=binary ------------------- -The one-stop-shop to setup a binary star simulation is to use SETUP=binary:: +Setting up and relaxing binary stars (the easy way) +--------------------------------------------------- +The one-stop-shop to setup a binary star simulation is as follows:: - ~/phantom/scripts/writemake.sh binary > Makefile - make setup - ./phantomsetup sim +make a new directory and write a local Makefile +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -giving:: +:: - ----------------------------------------------------------------- + $ mkdir mybinarysim + $ cd mybinarysim + $ ~/phantom/scripts/writemake.sh binary > Makefile + +compile phantom and phantomsetup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + $ make + $ make setup + $ ls + Makefile phantom* phantomsetup* + +run phantomsetup +~~~~~~~~~~~~~~~~ + +:: + + ./phantomsetup sim + + ----------------------------------------------------------------- Welcome to the Ultimate Binary Setup ----------------------------------------------------------------- @@ -19,13 +39,17 @@ giving:: Edit sim.setup and rerun phantomsetup -This will create a file called sim.setup which contains setup options. Open this file in -your favourite text editor to proceed... +This will create a file called sim.setup which contains setup options. +Open this file in your favourite text editor to proceed... Two sink particles in orbit -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The simplest is to setup two sink particles in a binary (iprofile=0), by amending the iprofile flags:: +---------------------------- + +Set iprofile=0 for both stars in the .setup file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: # options for star 1 iprofile1 = 0 ! 0=Sink,1=Unif,2=Poly,3=Dens,4=KEPL,5=MESA,6=Pie @@ -33,23 +57,30 @@ The simplest is to setup two sink particles in a binary (iprofile=0), by amendin # options for star 2 iprofile2 = 0 ! 0=Sink,1=Unif,2=Poly,3=Dens,4=KEPL,5=MESA,6=Pie -Then run phantomsetup again to rewrite the required options:: - - $ ./phantomsetup sim +run phantomsetup again to rewrite the required options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -which will give:: +:: + $ ./phantomsetup sim + ... ERROR: hacc1 not found ERROR: hacc2 not found 2 error(s) during read of setup file: re-writing... writing setup options file sim.setup Edit sim.setup and rerun phantomsetup -Run this again to finish the setup:: +run phantomsetup again to complete the setup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: ./phantomsetup sim -This creates a sim.in file for the main code. You should edit the tmax and dtmax +This creates a sim.in file for the main code. + +edit the .in file as desired +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You should edit the tmax and dtmax to give the desired finishing time (tmax) and time between snapshots (dtmax):: cat sim.in @@ -66,20 +97,30 @@ to give the desired finishing time (tmax) and time between snapshots (dtmax):: f_acc = 0.500 ! particles < f_acc*h_acc accreted without checks -After editing the .in file, proceed to run the simulation:: +run the simulation +~~~~~~~~~~~~~~~~~~ + +:: make ./phantom sim -and have a look at the outputs with splash:: +have a look at the outputs with splash +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: splash sim_0* Two polytropes in orbit -~~~~~~~~~~~~~~~~~~~~~~~~~ -The default is to setup-and-relax two polytropes and place them in orbit. For this edit -your sim.setup file to give:: +------------------------ +The default is to setup two polytropes and place them in orbit. + +Edit .setup file to specify iprofile=2 for both stars +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: # options for star 1 iprofile1 = 2 ! 0=Sink,1=Unif,2=Poly,3=Dens,4=KEPL,5=MESA,6=Pie @@ -92,9 +133,30 @@ your sim.setup file to give:: Mstar2 = 1.000 ! mass of star2 Rstar2 = 1.000 ! radius of star2 -Then run phantomsetup again to rewrite the required options:: +run phantomsetup again to rewrite the required options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + $ ./phantomsetup sim + +set the relaxation flag to true +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + # relaxation options + relax = T ! relax stars into equilibrium + tol_ekin = 1.000E-07 ! tolerance on ekin/epot to stop relaxation + tol_dens = 1.000 ! % error in density to stop relaxation + maxits = 1000 ! maximum number of relaxation iterations + +run phantomsetup again +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + $ ./phantomsetup sim - $ ./phantomsetup sim This time you should see the automated relax-a-star procedure kick in:: @@ -104,15 +166,27 @@ This time you should see the automated relax-a-star procedure kick in:: Relaxing star: Iter 2/1000, dens error: 10.97%, R*: 0.915 Ekin/Epot: 4.673E-03 ... -As previously, you can then just proceed to run the simulation after editing the sim.in file -:: +restart the relaxation if needed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The relaxation process will continue where it left off if you simply +run phantomsetup again, stopping when the criteria above are met:: + + $ ./phantomsetup sim + + +run the simulation after editing the sim.in file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +After successfully completing the setup process, you can proceed +to run your Very Happy Binary Star Simulation^TM:: ./phantom sim.in Two stars from MESA profiles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To use stellar profiles from the MESA code, select iprofile=5 in your .setup file -and enter the name of the ascii data file containing the input profile +----------------------------- + +select iprofile=5 in your .setup file and enter name of MESA file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Enter the name of the ascii data file containing the input profile (most files produced by MESA just work...):: # options for star 1 @@ -131,8 +205,8 @@ and enter the name of the ascii data file containing the input profile Notice that you do not get to set the particle resolution for the second star, since the mass of the particles is fixed by the mass and particle number in star 1. -Replacing dense stellar cores with sink particles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Replace dense stellar cores with sink particles (as necessary) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the options above you have the option to remove the dense core of the star which causes small timesteps in the code, and replace it with a softened point mass. The default option for this is isoftcore1=2 and isinkcore1=1. @@ -140,8 +214,8 @@ mass. The default option for this is isoftcore1=2 and isinkcore1=1. For more details, see :doc:`Setting up a softened star ` -Using SETUP=star and moddump_binary ------------------------------------- +Setting up and relaxing binary stars (the old fashioned way) +------------------------------------------------------------- See :doc:`Setting up stars and tidal disruption events ` for the older two-step procedure. The options available are identical, but with a bit more flexibility and without having to re-run the relaxation procedure over and over again. diff --git a/scripts/buildbot.sh b/scripts/buildbot.sh index c45abdfb9..beb1bd68c 100755 --- a/scripts/buildbot.sh +++ b/scripts/buildbot.sh @@ -321,9 +321,11 @@ for setup in $listofsetups; do colour=$white; # white (default) ncheck=$((ncheck + 1)); + mydebug='' printf "Checking $setup ($target)... "; if [[ "$component" == "setup" ]]; then rm -f $phantomdir/bin/phantomsetup; + mydebug='DEBUG=yes' # compile phantomsetup with DEBUG=yes for setup test #make clean >& /dev/null; fi if [[ "$setup" == "blob" ]]; then @@ -332,7 +334,7 @@ for setup in $listofsetups; do else mynowarn=$nowarn; fi - make SETUP=$setup $nolibs $mynowarn $maxp $target 1> $makeout 2> $errorlog; err=$?; + make SETUP=$setup $nolibs $mynowarn $maxp $target $mydebug 1> $makeout 2> $errorlog; err=$?; #--remove line numbers from error log files sed -e 's/90(.*)/90/g' -e 's/90:.*:/90/g' $errorlog | grep -v '/tmp' > $errorlog.tmp && mv $errorlog.tmp $errorlog; if [ $err -eq 0 ]; then diff --git a/src/main/bondiexact.f90 b/src/main/bondiexact.f90 index 46f14c724..7254d93d5 100644 --- a/src/main/bondiexact.f90 +++ b/src/main/bondiexact.f90 @@ -24,6 +24,9 @@ module bondiexact real, public :: rcrit = 5. real, private :: rhocrit = 1. + logical, public :: iswind = .false. + integer, public :: isol = 0 + private contains diff --git a/src/main/boundary.f90 b/src/main/boundary.f90 index 5f8e31d70..349cec742 100644 --- a/src/main/boundary.f90 +++ b/src/main/boundary.f90 @@ -138,7 +138,6 @@ subroutine cross_boundary(isperiodic,xyz,ncross) endif endif - return end subroutine cross_boundary !----------------------------------------------------------------------- diff --git a/src/main/checksetup.F90 b/src/main/checksetup.F90 index 1a9558eea..fb8b187a7 100644 --- a/src/main/checksetup.F90 +++ b/src/main/checksetup.F90 @@ -48,12 +48,13 @@ subroutine check_setup(nerror,nwarn,restart) use centreofmass, only:get_centreofmass use options, only:ieos,icooling,iexternalforce,use_dustfrac,use_hybrid use io, only:id,master - use externalforces, only:accrete_particles,accradius1,iext_star,iext_corotate + use externalforces, only:accrete_particles,update_externalforce,accradius1,iext_star,iext_corotate use timestep, only:time use units, only:G_is_unity,get_G_code use boundary, only:xmin,xmax,ymin,ymax,zmin,zmax use boundary_dyn, only:dynamic_bdy,adjust_particles_dynamic_boundary use nicil, only:n_nden + use metric_tools, only:imetric,imet_minkowski integer, intent(out) :: nerror,nwarn logical, intent(in), optional :: restart integer :: i,nbad,itype,iu,ndead @@ -95,11 +96,11 @@ subroutine check_setup(nerror,nwarn,restart) nwarn = nwarn + 1 endif #endif - if (hfact < 1. .or. hfact /= hfact) then + if (hfact < 1. .or. isnan(hfact)) then print*,'ERROR: hfact = ',hfact,', should be >= 1' nerror = nerror + 1 endif - if (polyk < 0. .or. polyk /= polyk) then + if (polyk < 0. .or. isnan(polyk)) then print*,'ERROR: polyk = ',polyk,', should be >= 0' nerror = nerror + 1 endif @@ -300,12 +301,18 @@ subroutine check_setup(nerror,nwarn,restart) ! !--check for particles placed inside accretion boundaries ! - if (iexternalforce > 0 .and. .not.dorestart) then + if (iexternalforce > 0 .and. .not.dorestart .and. (.not.(gr .and. imetric==imet_minkowski))) then + call update_externalforce(iexternalforce,time,0.) nbad = 0 + !$omp parallel do default(none) & + !$omp shared(npart,xyzh,massoftype,time,iexternalforce) & + !$omp private(i,accreted) & + !$omp reduction(+:nbad) do i=1,npart call accrete_particles(iexternalforce,xyzh(1,i),xyzh(2,i),xyzh(3,i),xyzh(4,i),massoftype(1),time,accreted) if (accreted) nbad = nbad + 1 enddo + !$omp end parallel do if (nbad > 0) then print*,'WARNING: ',nbad,' of ',npart,' particles setup within the accretion boundary' nwarn = nwarn + 1 @@ -314,7 +321,7 @@ subroutine check_setup(nerror,nwarn,restart) hi = 0. call accrete_particles(iexternalforce,0.,0.,0.,hi,massoftype(1),time,accreted) !--if so, check for unresolved accretion radius - if (accreted .and. accradius1 < 0.5*hmin) then + if (accreted .and. accradius1 < 0.5*hmin .and. accradius1 > 0.) then print*,'WARNING: accretion radius is unresolved by a factor of hmin/racc = ',hmin/accradius1 print*,'(this will cause the code to run needlessly slow)' nwarn = nwarn + 1 @@ -450,6 +457,10 @@ subroutine check_NaN(npart,array,label,nerror) integer :: nbad,i nbad = 0 + !$omp parallel do default(none) schedule(static) & + !$omp shared(npart,array,label) & + !$omp private(i) & + !$omp reduction(+:nbad) do i=1,npart !--check for NaNs in xyzh if (any(isnan(array(:,i)))) then @@ -457,6 +468,7 @@ subroutine check_NaN(npart,array,label,nerror) nbad = nbad + 1 endif enddo + !$omp end parallel do if (nbad > 0) then print*,'ERROR: NaN in '//trim(label)//' on ',nbad,' of ',npart,' particles' nerror = nerror + 1 @@ -844,7 +856,6 @@ subroutine check_for_identical_positions(npart,xyzh,nbad) ! allocate(index(npart)) call indexxfunc(npart,r2func,xyzh,index) - ! ! check for identical positions. Stop checking as soon as non-identical ! positions are found. @@ -852,6 +863,11 @@ subroutine check_for_identical_positions(npart,xyzh,nbad) nbad = 0 itypei = igas itypej = igas + !$omp parallel do default(none) & + !$omp shared(npart,xyzh,index,maxphase,maxp,iphase) & + !$omp firstprivate(itypei,itypej) & + !$omp private(i,j,dx,dx2) & + !$omp reduction(+:nbad) do i=1,npart if (.not.isdead_or_accreted(xyzh(4,index(i)))) then j = i+1 @@ -864,7 +880,7 @@ subroutine check_for_identical_positions(npart,xyzh,nbad) dx2 = dot_product(dx,dx) if (dx2 < epsilon(dx2) .and. itypei==itypej) then nbad = nbad + 1 - if (nbad <= 100) then + if (nbad <= 10) then print*,'WARNING: particles of same type at same position: ' print*,' ',index(i),':',xyzh(1:3,index(i)) print*,' ',index(j),':',xyzh(1:3,index(j)) @@ -874,6 +890,7 @@ subroutine check_for_identical_positions(npart,xyzh,nbad) enddo endif enddo + !$omp end parallel do deallocate(index) diff --git a/src/main/dens.F90 b/src/main/dens.F90 index bf666407f..71f4ba968 100644 --- a/src/main/dens.F90 +++ b/src/main/dens.F90 @@ -404,7 +404,10 @@ subroutine densityiterate(icall,npart,nactive,xyzh,vxyzu,divcurlv,divcurlB,Bevol enddo endif - call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,irequestsend,thread_complete,cell_counters,ncomplete_mpi) + if (mpi) then + call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,& + irequestsend,thread_complete,cell_counters,ncomplete_mpi) + endif !$omp master call get_timings(t2,tcpu2) @@ -422,6 +425,7 @@ subroutine densityiterate(icall,npart,nactive,xyzh,vxyzu,divcurlv,divcurlB,Bevol n_remote_its = 0 iterations_finished = .false. + if (.not.mpi) iterations_finished = .true. !$omp end master !$omp barrier @@ -469,11 +473,12 @@ subroutine densityiterate(icall,npart,nactive,xyzh,vxyzu,divcurlv,divcurlB,Bevol enddo endif igot_remote - call recv_while_wait(stack_waiting,xrecvbuf,irequestrecv,irequestsend,thread_complete,cell_counters,ncomplete_mpi) + if (mpi) call recv_while_wait(stack_waiting,xrecvbuf,irequestrecv,& + irequestsend,thread_complete,cell_counters,ncomplete_mpi) call reset_cell_counters(cell_counters) !$omp barrier - iam_waiting: if (stack_waiting%n > 0) then + iam_waiting: if (mpi .and. stack_waiting%n > 0) then !$omp do schedule(runtime) over_waiting: do i = 1, stack_waiting%n cell = stack_waiting%cells(i) @@ -525,7 +530,8 @@ subroutine densityiterate(icall,npart,nactive,xyzh,vxyzu,divcurlv,divcurlB,Bevol enddo endif iam_waiting - call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,irequestsend,thread_complete,cell_counters,ncomplete_mpi) + if (mpi) call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,& + irequestsend,thread_complete,cell_counters,ncomplete_mpi) !$omp master if (reduceall_mpi('max',stack_redo%n) > 0) then diff --git a/src/main/extern_binary.f90 b/src/main/extern_binary.f90 index 317f7894e..5c53956be 100644 --- a/src/main/extern_binary.f90 +++ b/src/main/extern_binary.f90 @@ -141,7 +141,6 @@ subroutine binary_force(xi,yi,zi,ti,fxi,fyi,fzi,phi) phi2 = -(1.-binarymassri)*dr2 phi = phi1 + phi2 - return end subroutine binary_force !---------------------------------------------- @@ -175,7 +174,6 @@ subroutine binary_posvel(ti,posmh,vels) vels(5) = -binarymassri*cos(ti) vels(6) = 0. - return end subroutine binary_posvel !---------------------------------------------- diff --git a/src/main/externalforces.F90 b/src/main/externalforces.F90 index d8d13c633..940278203 100644 --- a/src/main/externalforces.F90 +++ b/src/main/externalforces.F90 @@ -26,8 +26,6 @@ module externalforces use extern_binary, only:accradius1 use extern_corotate, only:omega_corotate ! so public from this module implicit none - character(len=80), parameter, public :: & ! module version - modid="$Id$" private public :: externalforce,externalforce_vdependent diff --git a/src/main/force.F90 b/src/main/force.F90 index 561362ab3..1d9100ffa 100644 --- a/src/main/force.F90 +++ b/src/main/force.F90 @@ -537,8 +537,11 @@ subroutine force(icall,npart,xyzh,vxyzu,fxyzu,divcurlv,divcurlB,Bevol,dBevol,& enddo endif - call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,irequestsend,thread_complete,cell_counters,ncomplete_mpi) - call reset_cell_counters(cell_counters) + if (mpi) then + call recv_while_wait(stack_remote,xrecvbuf,irequestrecv,& + irequestsend,thread_complete,cell_counters,ncomplete_mpi) + call reset_cell_counters(cell_counters) + endif !$omp master call get_timings(t2,tcpu2) @@ -547,7 +550,7 @@ subroutine force(icall,npart,xyzh,vxyzu,fxyzu,divcurlv,divcurlB,Bevol,dBevol,& !$omp end master !$omp barrier - igot_remote: if (stack_remote%n > 0) then + igot_remote: if (mpi .and. stack_remote%n > 0) then !$omp do schedule(runtime) over_remote: do i = 1,stack_remote%n cell = get_cell(stack_remote,i) @@ -587,9 +590,10 @@ subroutine force(icall,npart,xyzh,vxyzu,fxyzu,divcurlv,divcurlB,Bevol,dBevol,& endif igot_remote - call recv_while_wait(stack_waiting,xrecvbuf,irequestrecv,irequestsend,thread_complete,cell_counters,ncomplete_mpi) + if (mpi) call recv_while_wait(stack_waiting,xrecvbuf,irequestrecv,& + irequestsend,thread_complete,cell_counters,ncomplete_mpi) - iam_waiting: if (stack_waiting%n > 0) then + iam_waiting: if (mpi .and. stack_waiting%n > 0) then !$omp do schedule(runtime) over_waiting: do i = 1, stack_waiting%n cell = get_cell(stack_waiting,i) diff --git a/src/main/readwrite_infile.F90 b/src/main/readwrite_infile.F90 index 4d57cf21c..31cbf3084 100644 --- a/src/main/readwrite_infile.F90 +++ b/src/main/readwrite_infile.F90 @@ -17,7 +17,7 @@ module readwrite_infile ! - C_cour : *Courant number* ! - C_force : *dt_force number* ! - alpha : *shock viscosity parameter* -! - alphaB : *art. resistivity parameter* +! - alphaB : *shock resistivity parameter* ! - alphamax : *MAXIMUM shock viscosity parameter* ! - alphau : *shock conductivity parameter* ! - avdecayconst : *decay time constant for viscosity switches* @@ -82,7 +82,7 @@ module readwrite_infile use viscosity, only:irealvisc,shearparam,bulkvisc use part, only:hfact,ien_type use io, only:iverbose - use dim, only:do_radiation,nucleation + use dim, only:do_radiation,nucleation,use_dust,use_dustgrowth implicit none logical :: incl_runtime2 = .false. @@ -103,12 +103,8 @@ subroutine write_infile(infile,logfile,evfile,dumpfile,iwritein,iprint) use externalforces, only:write_options_externalforces use damping, only:write_options_damping use linklist, only:write_inopts_link -#ifdef DUST use dust, only:write_options_dust -#ifdef DUSTGROWTH use growth, only:write_options_growth -#endif -#endif #ifdef PHOTO use photoevap, only:write_options_photoevap #endif @@ -196,7 +192,7 @@ subroutine write_infile(infile,logfile,evfile,dumpfile,iwritein,iprint) call write_inopts_link(iwritein) - write(iwritein,"(/,a)") '# options controlling hydrodynamics, artificial dissipation' + write(iwritein,"(/,a)") '# options controlling hydrodynamics, shock capturing' if (maxalpha==maxp .and. nalpha > 0) then call write_inopt(alpha,'alpha','MINIMUM shock viscosity parameter',iwritein) call write_inopt(alphamax,'alphamax','MAXIMUM shock viscosity parameter',iwritein) @@ -207,7 +203,7 @@ subroutine write_infile(infile,logfile,evfile,dumpfile,iwritein,iprint) call write_inopt(alphau,'alphau','shock conductivity parameter',iwritein) endif if (mhd) then - call write_inopt(alphaB,'alphaB','art. resistivity parameter',iwritein) + call write_inopt(alphaB,'alphaB','shock resistivity parameter',iwritein) call write_inopt(psidecayfac,'psidecayfac','div B diffusion parameter',iwritein) call write_inopt(overcleanfac,'overcleanfac','factor to increase cleaning speed (decreases time step)',iwritein) call write_inopt(hdivbbmax_max,'hdivbbmax_max','max factor to decrease cleaning timestep propto B/(h|divB|)',iwritein) @@ -270,12 +266,8 @@ subroutine write_infile(infile,logfile,evfile,dumpfile,iwritein,iprint) call write_options_forcing(iwritein) #endif -#ifdef DUST - call write_options_dust(iwritein) -#ifdef DUSTGROWTH - call write_options_growth(iwritein) -#endif -#endif + if (use_dust) call write_options_dust(iwritein) + if (use_dustgrowth) call write_options_growth(iwritein) #ifdef PHOTO call write_options_photoevap(iwritein) @@ -286,8 +278,6 @@ subroutine write_infile(infile,logfile,evfile,dumpfile,iwritein,iprint) call write_options_inject(iwritein) #endif if (nucleation) call write_options_dust_formation(iwritein) - - write(iwritein,"(/,a)") '# options for injecting/removing particles' call write_inopt(rkill,'rkill','deactivate particles outside this radius (<0 is off)',iwritein) if (sink_radiation) then @@ -340,12 +330,8 @@ subroutine read_infile(infile,logfile,evfile,dumpfile) #endif use externalforces, only:read_options_externalforces use linklist, only:read_inopts_link -#ifdef DUST use dust, only:read_options_dust -#ifdef DUSTGROWTH use growth, only:read_options_growth -#endif -#endif #ifdef GR use metric, only:read_options_metric #endif @@ -362,7 +348,8 @@ subroutine read_infile(infile,logfile,evfile,dumpfile) use part, only:mhd,nptmass use cooling, only:read_options_cooling use ptmass, only:read_options_ptmass - use ptmass_radiation, only:read_options_ptmass_radiation,isink_radiation,alpha_rad,iget_tdust,iray_resolution + use ptmass_radiation, only:read_options_ptmass_radiation,isink_radiation,& + alpha_rad,iget_tdust,iray_resolution use radiation_utils, only:kappa_cgs use radiation_implicit, only:tol_rad,itsmax_rad,cv_type use damping, only:read_options_damping @@ -567,13 +554,9 @@ subroutine read_infile(infile,logfile,evfile,dumpfile) if (.not.imatch) call read_options_forcing(name,valstring,imatch,igotallturb,ierr) #endif if (.not.imatch) call read_inopts_link(name,valstring,imatch,igotalllink,ierr) -#ifdef DUST !--Extract if one-fluid dust is used from the fileid - if (.not.imatch) call read_options_dust(name,valstring,imatch,igotalldust,ierr) -#ifdef DUSTGROWTH - if (.not.imatch) call read_options_growth(name,valstring,imatch,igotallgrowth,ierr) -#endif -#endif + if (.not.imatch .and. use_dust) call read_options_dust(name,valstring,imatch,igotalldust,ierr) + if (.not.imatch .and. use_dustgrowth) call read_options_growth(name,valstring,imatch,igotallgrowth,ierr) #ifdef GR if (.not.imatch) call read_options_metric(name,valstring,imatch,igotallgr,ierr) #endif diff --git a/src/setup/phantomsetup.F90 b/src/setup/phantomsetup.F90 index 0a3483788..7026c3c90 100644 --- a/src/setup/phantomsetup.F90 +++ b/src/setup/phantomsetup.F90 @@ -17,7 +17,7 @@ program phantomsetup ! :Dependencies: boundary, checksetup, dim, eos, fileutils, gravwaveutils, ! io, krome_interface, memory, mpidomain, mpiutils, options, part, ! physcon, readwrite_dumps, readwrite_infile, setBfield, setup, -! setup_params, systemutils, units +! setup_params, systemutils, timestep, units ! use memory, only:allocate_memory,deallocate_memory use dim, only:tagline,maxp,maxvxyzu,mpi,& @@ -34,6 +34,7 @@ program phantomsetup use setup, only:setpart use setup_params, only:ihavesetupB,npart_total use checksetup, only:check_setup + use timestep, only:time use physcon, only:pi use units, only:set_units,print_units,c_is_unity use mpiutils, only:init_mpi,finalise_mpi,reduceall_mpi @@ -51,7 +52,7 @@ program phantomsetup integer, parameter :: lenprefix = 120 character(len=lenprefix) :: fileprefix character(len=lenprefix+10) :: dumpfile,infile,evfile,logfile - real :: time,pmassi + real :: pmassi logical :: iexist nprocs = 1 ! for MPI, this is not initialised until init_mpi, but an initialised value is required for init_part @@ -79,9 +80,6 @@ program phantomsetup print*,' (these are assigned automatically)' print "(/,a)",' e.g. "phantomsetup mysim"' stop - elseif (fileprefix=='test') then - print*,'Error: cannot use ''test'' as the job name, please rename your .setup file' - stop endif infile = trim(fileprefix)//'.in' inquire(file=trim(infile),exist=iexist) diff --git a/src/setup/relax_star.f90 b/src/setup/relax_star.f90 index 18107960f..65db5de98 100644 --- a/src/setup/relax_star.f90 +++ b/src/setup/relax_star.f90 @@ -18,8 +18,8 @@ module relaxstar ! - tol_dens : *% error in density to stop relaxation* ! - tol_ekin : *tolerance on ekin/epot to stop relaxation* ! -! :Dependencies: checksetup, damping, deriv, dim, energies, eos, -! externalforces, fileutils, infile_utils, initial, io, io_summary, +! :Dependencies: checksetup, damping, deriv, dim, dump_utils, energies, +! eos, externalforces, fileutils, infile_utils, initial, io, io_summary, ! memory, options, part, physcon, ptmass, readwrite_dumps, setstar_utils, ! sortutils, step_lf_global, table_utils, units ! @@ -61,13 +61,13 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np use table_utils, only:yinterp use deriv, only:get_derivs_global use dim, only:maxp,maxvxyzu,gr,gravity - use part, only:vxyzu,rad,eos_vars + use part, only:vxyzu,rad,eos_vars,massoftype,igas use step_lf_global, only:init_step,step use initial, only:initialise use memory, only:allocate_memory use energies, only:compute_energies,ekin,epot,etherm use checksetup, only:check_setup - use io, only:error,warning + use io, only:error,warning,fatal,id,master use fileutils, only:getnextfilename use readwrite_dumps, only:write_fulldump,init_readwrite_dumps use eos, only:gamma,eos_outputs_mu @@ -87,7 +87,7 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np integer :: nits,nerr,nwarn,iunit,i1 real :: t,dt,dtmax,rmserr,rstar,mstar,tdyn real :: entrop(nt),utherm(nt),mr(nt),rmax,dtext,dtnew - logical :: converged,use_step + logical :: converged,use_step,restart logical, parameter :: fix_entrop = .true. ! fix entropy instead of thermal energy logical, parameter :: write_files = .true. character(len=20) :: filename,mylabel @@ -107,7 +107,24 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np mr = get_mr(rho,r) mstar = mr(nt) tdyn = 2.*pi*sqrt(rstar**3/(32.*mstar)) - print*,'rstar = ',rstar,' mstar = ',mstar, ' tdyn = ',tdyn + if (id==master) print*,'rstar = ',rstar,' mstar = ',mstar, ' tdyn = ',tdyn + ! + ! see if we can restart or skip the relaxation process + ! based on a previous run + ! + filename = 'relax'//trim(mylabel)//'_00000' + if (write_files) call init_readwrite_dumps() + call check_for_existing_file(filename,npart,massoftype(igas),& + xyzh,vxyzu,restart,ierr) + ! + ! quit with fatal error if non-matching file found, otherwise + ! this will be overwritten + ! + if (write_files .and. ierr /= 0) then + if (id==master) print "(a)",' ERROR: pre-existing relaxed star dump(s) do not match' + call fatal('relax_star','please delete relax'//trim(mylabel)//'_* and restart...') + endif + call set_options_for_relaxation(tdyn) call summary_initialise() ! @@ -154,20 +171,18 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np ! if (etherm > abs(epot)) then call error('relax_star','cannot relax star because it is unbound (etherm > epot)') - print*,' Etherm = ',etherm,' Epot = ',Epot + if (id==master) print*,' Etherm = ',etherm,' Epot = ',Epot if (maxvxyzu < 4) print "(/,a,/)",' *** Try compiling with ISOTHERMAL=no instead... ***' call restore_original_options(i1,npart) ierr = ierr_unbound return endif - print "(/,3(a,1pg11.3),/,a,0pf6.2,a,es11.3,a,i4)",& + if (id==master) print "(/,3(a,1pg11.3),/,a,0pf6.2,a,es11.3,a,i4)",& ' RELAX-A-STAR-O-MATIC: Etherm:',etherm,' Epot:',Epot, ' R*:',maxval(r), & ' WILL stop WHEN: dens error < ',tol_dens,'% AND Ekin/Epot < ',tol_ekin,' OR Iter=',maxits - filename = 'relax'//trim(mylabel)//'_00000' if (write_files) then - call init_readwrite_dumps() - if (len_trim(mylabel)==0) call write_fulldump(t,filename) + if (.not.restart) call write_fulldump(t,filename) open(newunit=iunit,file='relax'//trim(mylabel)//'.ev',status='replace') write(iunit,"(a)") '# nits,rmax,etherm,epot,ekin/epot,L2_{err}' endif @@ -205,11 +220,13 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np ! print information to screen ! if (use_step) then - print "(a,es10.3,a,2pf6.2,2(a,1pg11.3))",' Relaxing star: t/dyn:',t/tdyn,', dens error:',rmserr,'%, R*:',rmax, & + if (id==master) print "(a,es10.3,a,2pf6.2,2(a,1pg11.3))",& + ' Relaxing star: t/dyn:',t/tdyn,', dens error:',rmserr,'%, R*:',rmax, & ' Ekin/Epot:',ekin/abs(epot) else - print "(a,i4,a,i4,a,2pf6.2,2(a,1pg11.3))",' Relaxing star: Iter',nits,'/',maxits, & - ', dens error:',rmserr,'%, R*:',rmax,' Ekin/Epot:',ekin/abs(epot) + if (id==master) print "(a,i4,a,i4,a,2pf6.2,2(a,1pg11.3))",& + ' Relaxing star: Iter',nits,'/',maxits, & + ', dens error:',rmserr,'%, R*:',rmax,' Ekin/Epot:',ekin/abs(epot) endif ! ! additional diagnostic output, mainly for debugging/checking @@ -222,20 +239,22 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np ! ! write dump files ! - if (mod(nits,100)==0) then + if (mod(nits,100)==0 .or. ((nits==maxits .or. converged).and.nits > 1)) then filename = getnextfilename(filename) ! ! before writing a file, set the real thermal energy profile ! so the file is useable as a starting file for the main calculation ! - if (use_var_comp) call set_star_composition(use_var_comp,eos_outputs_mu(ieos_prev),& - npart,xyzh,Xfrac,Yfrac,mu,mr,mstar,eos_vars,npin=i1) + if (use_var_comp) call set_star_composition(use_var_comp,& + eos_outputs_mu(ieos_prev),npart,xyzh,& + Xfrac,Yfrac,mu,mr,mstar,eos_vars,npin=i1) - if (maxvxyzu==4) call set_star_thermalenergy(ieos_prev,rho,pr,r,nt,npart,& - xyzh,vxyzu,rad,eos_vars,.true.,use_var_comp=.false.,initialtemp=1.e3,npin=i1) + if (maxvxyzu==4) call set_star_thermalenergy(ieos_prev,rho,pr,& + r,nt,npart,xyzh,vxyzu,rad,eos_vars,.true.,& + use_var_comp=.false.,initialtemp=1.e3,npin=i1) ! write relaxation snapshots - if (len_trim(mylabel)==0) call write_fulldump(t,filename) + if (write_files) call write_fulldump(t,filename) ! flush the relax.ev file call flush(iunit) @@ -253,6 +272,13 @@ subroutine relax_star(nt,rho,pr,r,npart,xyzh,use_var_comp,Xfrac,Yfrac,mu,ierr,np if (.not.converged) then call warning('relax_star','relaxation did not converge, just reached max iterations') ierr = ierr_notconverged + else + if (id==master) print "(5(a,/))",& + " _ _ ",& + " _ __ ___| | __ ___ _____ __| |",& + " | '__/ _ \ |/ _` \ \/ / _ \/ _` |",& + " | | | __/ | (_| |> < __/ (_| |",& + " o o o |_| \___|_|\__,_/_/\_\___|\__,_| o o o" endif ! ! unfake some things @@ -397,6 +423,76 @@ subroutine set_options_for_relaxation(tdyn) if (gr) mass1 = 0. ! use Minkowski metric during relaxation end subroutine set_options_for_relaxation +!---------------------------------------------------------------- +!+ +! check if a previous snapshot exists of the relaxed star +!+ +!---------------------------------------------------------------- +subroutine check_for_existing_file(filename,npart,mgas,xyzh,vxyzu,restart,ierr) + use dump_utils, only:open_dumpfile_r,read_header,dump_h,lenid,extract + use fileutils, only:getnextfilename + use io, only:idump,idisk1,id,nprocs,iprint + use readwrite_dumps, only:read_dump + character(len=*), intent(inout) :: filename + integer, intent(in) :: npart + real, intent(in) :: mgas + real, intent(inout) :: xyzh(:,:),vxyzu(:,:) + logical, intent(out) :: restart + integer, intent(out) :: ierr + logical :: iexist,tagged + character(len=len(filename)) :: restart_file,filetmp + character(len=lenid) :: fileid + type(dump_h) :: hdr + integer :: npartfile + real :: hfactfile,tfile,mfile + ! + ! check for the last file in the list relax_00000, relax_00001 etc + ! + ierr = 0 + iexist = .true. + filetmp = filename + restart_file = '' + restart = .false. + do while (iexist) + inquire(file=filetmp,exist=iexist) + if (iexist) then + restart_file = filetmp + filetmp = getnextfilename(filetmp) + endif + enddo + if (len_trim(restart_file) <= 0) return + + print "(/,1x,a)",'>> RESTARTING relaxation from '//trim(restart_file) + call open_dumpfile_r(idump,restart_file,fileid,ierr) + call read_header(idump,hdr,tagged,ierr) + close(idump) + if (ierr /= 0) then + print "(a)",' ERROR: could not read file header' + return + else + call extract('nparttot',npartfile,hdr,ierr,default=0) + if (npartfile /= npart) then + print "(a,i0,a,i0)",' ERROR: np=',npartfile,' in '//& + trim(restart_file)//' differs from current np=',npart + ierr = 2 + return + else + call extract('massoftype',mfile,hdr,ierr,default=0.) + if (abs(mfile-mgas) > epsilon(0.)) then + print "(a,es10.3,a,es10.3)",' ERROR: M=',npart*mfile,' in '//& + trim(restart_file)//' differs from current M=',npart*mgas + ierr = 3 + return + else + restart = .true. + call read_dump(restart_file,tfile,hfactfile,& + idisk1,iprint,id,nprocs,ierr) + filename = restart_file + endif + endif + endif + +end subroutine check_for_existing_file !-------------------------------------------------- !+ diff --git a/src/setup/set_hierarchical_utils.f90 b/src/setup/set_hierarchical_utils.f90 index 64b3240e0..699b72925 100644 --- a/src/setup/set_hierarchical_utils.f90 +++ b/src/setup/set_hierarchical_utils.f90 @@ -126,7 +126,7 @@ pure recursive subroutine recursive_splitting(sink_num, sink_list, split_list, s character(len=10) :: longests(max_hier_levels), new_splits(max_hier_levels) character(len=10) :: new_sink_list(max_hier_levels), longest_cut, sink_list_temp(max_hier_levels) - sink_list_temp = sink_list + sink_list_temp(:) = sink_list(:) !print *, 'sink to generate: ', sink_list_temp @@ -172,7 +172,7 @@ pure recursive subroutine recursive_splitting(sink_num, sink_list, split_list, s !print *, 'up to now splits are ', split_list ! Add new splits to split_list - do i=splits+1, splits+count + do i=splits+1, min(splits+count,size(split_list)) split_list(i) = new_splits(i-splits) enddo splits = splits + count @@ -197,7 +197,7 @@ pure recursive subroutine recursive_splitting(sink_num, sink_list, split_list, s !print *, split_list(:splits) !print *, splits - call recursive_splitting(count, new_sink_list(:count), split_list(:splits), splits) + call recursive_splitting(count, new_sink_list(:), split_list(:), splits) endif end subroutine recursive_splitting diff --git a/src/setup/set_star.f90 b/src/setup/set_star.f90 index 5724b83eb..7e6b0a8fe 100644 --- a/src/setup/set_star.f90 +++ b/src/setup/set_star.f90 @@ -49,7 +49,7 @@ module setstar end type star_t public :: star_t - public :: set_defaults_star,set_star,shift_star + public :: set_star,set_defaults_star,shift_star public :: write_options_star,read_options_star,set_star_interactive public :: ikepler,imesa,ibpwpoly,ipoly,iuniform,ifromfile,ievrard public :: need_polyk @@ -445,6 +445,9 @@ subroutine set_star_interactive(id,master,star,need_iso,use_var_comp,ieos,polyk) real, intent(inout) :: polyk integer :: i + ! set defaults + call set_defaults_star(star) + ! Select sphere & set default values do i = 1, nprofile_opts write(*,"(i2,')',1x,a)") i, profile_opt(i) @@ -627,6 +630,9 @@ subroutine read_options_star(star,need_iso,ieos,polyk,db,nerr,label) character(len=*), intent(in), optional :: label character(len=10) :: c + ! set defaults + call set_defaults_star(star) + ! append optional label e.g. '1', '2' c = '' if (present(label)) c = trim(adjustl(label)) diff --git a/src/setup/set_star_utils.f90 b/src/setup/set_star_utils.f90 index 5d26826a0..a07d903c0 100644 --- a/src/setup/set_star_utils.f90 +++ b/src/setup/set_star_utils.f90 @@ -272,7 +272,7 @@ subroutine set_star_density(lattice,id,master,rmin,Rstar,Mstar,hfact,& if (npart_old /= 0 .and. massoftype(igas) > tiny(0.)) then n = nint(Mstar/massoftype(igas)) mass_is_set = .true. - print "(a,i0)",' WARNING: particle mass is already set, using np = ',n + !print "(a,i0)",' WARNING: particle mass is already set, using np = ',n endif ! ! place particles in sphere diff --git a/src/setup/set_unifdis.f90 b/src/setup/set_unifdis.f90 index fb986eb68..d327b6865 100644 --- a/src/setup/set_unifdis.f90 +++ b/src/setup/set_unifdis.f90 @@ -19,7 +19,7 @@ module unifdis use stretchmap, only:rho_func implicit none public :: set_unifdis, get_ny_nz_closepacked, get_xyzmin_xyzmax_exact - public :: is_valid_lattice, is_closepacked + public :: is_valid_lattice, is_closepacked, latticetype ! following lines of code allow an optional mask= argument ! to setup only certain subsets of the particle domain (used for MPI) @@ -29,6 +29,11 @@ logical function mask_prototype(ip) end function mask_prototype end interface + integer, parameter, public :: i_cubic = 1, & + i_closepacked = 2, & + i_hexagonal = 3, & + i_random = 4 + public :: mask_prototype, mask_true, rho_func private @@ -718,6 +723,29 @@ pure logical function is_valid_lattice(latticetype) end function is_valid_lattice +!------------------------------------------------------------- +!+ +! utility function to give correct lattice string +! given integer lattice choice +!+ +!------------------------------------------------------------- +function latticetype(ilattice) + integer, intent(in) :: ilattice + character(len=11) :: latticetype + + select case(ilattice) + case(i_random) + latticetype = 'random' + case(i_hexagonal) + latticetype = 'hexagonal' + case(i_closepacked) + latticetype = 'closepacked' + case default + latticetype = 'cubic' + end select + +end function latticetype + !--------------------------------------------------------------- !+ ! check that the latticetype is closepacked diff --git a/src/setup/set_units.f90 b/src/setup/set_units.f90 index a1cf40960..e3a950bd6 100644 --- a/src/setup/set_units.f90 +++ b/src/setup/set_units.f90 @@ -14,8 +14,8 @@ module setunits ! :Owner: Daniel Price ! ! :Runtime parameters: -! - dist_unit : *distance unit (e.g. au)* -! - mass_unit : *mass unit (e.g. solarm)* +! - dist_unit : *distance unit (e.g. au,pc,kpc,0.1pc)* +! - mass_unit : *mass unit (e.g. solarm,jupiterm,1e6*solarm)* ! ! :Dependencies: infile_utils, io, prompting, units ! @@ -81,8 +81,8 @@ subroutine write_options_units(iunit,gr) ! units write(iunit,"(/,a)") '# units' - call write_inopt(mass_unit,'mass_unit','mass unit (e.g. solarm)',iunit) - if (nogr) call write_inopt(dist_unit,'dist_unit','distance unit (e.g. au)',iunit) + call write_inopt(mass_unit,'mass_unit','mass unit (e.g. solarm,jupiterm,1e6*solarm)',iunit) + if (nogr) call write_inopt(dist_unit,'dist_unit','distance unit (e.g. au,pc,kpc,0.1pc)',iunit) end subroutine write_options_units diff --git a/src/setup/setup_alfvenwave.f90 b/src/setup/setup_alfvenwave.f90 index 8a302ffa8..2c54c12c8 100644 --- a/src/setup/setup_alfvenwave.f90 +++ b/src/setup/setup_alfvenwave.f90 @@ -53,17 +53,20 @@ module setup ! setup for MHD wave tests !+ !---------------------------------------------------------------- -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,& + polyk,gamma,hfact,time,fileprefix) use dim, only:maxvxyzu use setup_params, only:rhozero,ihavesetupB use unifdis, only:set_unifdis,rho_func - use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound - use part, only:Bxyz,mhd,periodic + use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,& + dxbound,dybound,dzbound + use part, only:Bxyz,mhd,periodic,igas use io, only:master use prompting, only:prompt use mpiutils, only:bcast_mpi use physcon, only:pi - use geometry, only:igeom_rotated,igeom_cartesian,set_rotation_angles,coord_transform + use geometry, only:igeom_rotated,igeom_cartesian,& + set_rotation_angles,coord_transform use timestep, only:tmax,dtmax use mpidomain, only:i_belong integer, intent(in) :: id @@ -75,7 +78,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real, intent(out) :: polyk,gamma real, intent(in) :: hfact real, intent(inout) :: time - character(len=20), intent(in) :: fileprefix + character(len=*), intent(in) :: fileprefix real :: deltax,totmass integer :: i,ierr,igeom real :: przero,uuzero,Bvec(3),vvec(3),Bnew(3),Bzero(3),vzero(3) @@ -102,9 +105,13 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! setupfile = trim(fileprefix)//'.setup' call read_setupfile(setupfile,gamma,ierr) - if (ierr /= 0 .and. id==master) then - call interactive_setup() - call write_setupfile(setupfile,gamma) + if (ierr /= 0) then + if (id==master) then + call interactive_setup() + call write_setupfile(setupfile,gamma) + print*,' Edit '//trim(setupfile)//' and rerun phantomsetup' + endif + stop endif gamma = 5./3. ! @@ -148,6 +155,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, Bzero = (/1.,0.,0./) vzero = 0. uuzero = przero/(gam1*rhozero) + vwave = sqrt(dot_product(Bzero,Bzero)/rhozero) ! Alfven speed end select call prim_to_cons(rhozero,vzero,Bzero,uuzero,q0) @@ -159,8 +167,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ' vwave = ',f6.3,', period = ',f6.3,/) call print_amplitudes(rhozero,drho,vzero,dv,Bzero,dB,uuzero,du) - print*,' rhozero = ',rhozero,'dv = ',dv,' dB = ',dB - print*,drho,rhozero*dv,dB,du,du + dot_product(vzero,dv) + dot_product(Bzero,dB)/rhozero if (maxvxyzu < 4) then polyk = przero/rhozero**gamma @@ -188,11 +194,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, deltax,hfact,npart,xyzh,periodic,mask=i_belong) endif npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart - print*,'npart = ',npart,' particle mass = ',massoftype(1) + print*,'npart = ',npart,' particle mass = ',massoftype(igas) do i=1,npart diff --git a/src/setup/setup_binary.f90 b/src/setup/setup_binary.f90 index 1d33fa81e..d089c8b18 100644 --- a/src/setup/setup_binary.f90 +++ b/src/setup/setup_binary.f90 @@ -90,11 +90,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,& vxyzu(:,:) = 0. nptmass = 0 nstar = 2 - relax = .true. - corotate = .false. do i=1,nstar call set_defaults_star(star(i)) enddo + relax = .true. + corotate = .false. semi_major_axis = '10.' a = 10. ecc = 0. diff --git a/src/setup/setup_bondi.F90 b/src/setup/setup_bondi.F90 index 950ec8174..78389239f 100644 --- a/src/setup/setup_bondi.F90 +++ b/src/setup/setup_bondi.F90 @@ -20,35 +20,27 @@ module setup ! - rmin : *inner edge* ! ! :Dependencies: bondiexact, centreofmass, dim, externalforces, -! infile_utils, io, kernel, metric, metric_tools, options, part, physcon, +! infile_utils, io, kernel, metric_tools, options, part, physcon, ! prompting, setup_params, spherical, stretchmap, timestep, units ! use physcon, only:pi use externalforces, only:accradius1,accradius1_hard - use dim, only:gr -#ifdef GR - use metric, only:mass1 + use dim, only:gr,maxvxyzu use metric_tools, only:imet_schwarzschild,imetric -#else use externalforces, only:mass1 -#endif use setup_params, only:rhozero,npart_total use io, only:master,fatal use spherical, only:set_sphere use options, only:ieos,iexternalforce,nfulldump use timestep, only:tmax,dtmax use centreofmass, only:reset_centreofmass - use units, only:udist,umass,utime,set_units + use units, only:set_units,get_G_code use physcon, only:pc,solarm,gg use part, only:xyzmh_ptmass,vxyz_ptmass,nptmass,ihacc,igas,set_particle_type,iboundary use stretchmap, only:get_mass_r,rho_func use kernel, only:radkern use prompting, only:prompt - use bondiexact, only:get_bondi_solution,rcrit -#ifdef GR - use bondiexact, only:isol,iswind -#endif - + use bondiexact, only:get_bondi_solution,rcrit,isol,iswind implicit none public :: setpart @@ -89,7 +81,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, !-- Set code units ! call set_units(G=1.d0,c=1.d0) - print*,' gcode = ',gg*umass*utime**2/udist**3 + print*,' G in code units = ',get_G_code() ! !--Set general parameters @@ -101,9 +93,10 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, rmax = 8. np = 10000 -#ifdef GR - if (imetric/=imet_schwarzschild) call fatal('setup_bondi','You are not using the Schwarzschild metric.') -#endif + if (gr) then + if (imetric/=imet_schwarzschild) call fatal('setup_bondi',& + 'You are not using the Schwarzschild metric.') + endif ! !-- Read things from setup file @@ -119,14 +112,16 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, endif elseif (id==master) then print "(a,/)",trim(filename)//' not found: using interactive setup' -#ifdef GR - call prompt(' Enter solution type isol (1 = geodesic | 2 = sonic point flow) ',isol,1,2) - call prompt(' Do you want a wind (y/n)? ',iswind) -#endif + if (gr) then + call prompt(' Enter solution type isol (1 = geodesic | 2 = sonic point flow) ',isol,1,2) + call prompt(' Do you want a wind (y/n)? ',iswind) + endif call prompt(' Enter inner edge: ',rmin,0.) call prompt(' Enter outer edge: ',rmax,rmin) call prompt(' Enter the desired number of particles: ',np,0) call write_setupfile(filename) + print*,' Edit '//trim(filename)//' and rerun phantomsetup' + stop endif if (gr) then @@ -176,7 +171,8 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, !--- Add stretched sphere npart = 0 npart_total = 0 - call set_sphere('closepacked',id,master,rmin,rmax,psep,hfact,npart,xyzh,rhotab=rhotab,nptot=npart_total) + call set_sphere('closepacked',id,master,rmin,rmax,psep,hfact,npart,& + xyzh,rhotab=rhotab,nptot=npart_total) massoftype(:) = totmass/npart print "(a,i0,/)",' npart = ',npart @@ -187,7 +183,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, r = sqrt(dot_product(pos,pos)) call get_bondi_solution(rhor,vr,ur,r,mass1,gamma) vxyzu(1:3,i) = vr*pos/r - vxyzu(4,i) = ur + if (maxvxyzu >= 4) vxyzu(4,i) = ur if (set_boundary_particles) then if (r + radkern*xyzh(4,i)>rmax .or. r - radkern*xyzh(4,i) 0) then print "(1x,a,i2,a)",'Setup_convergingflows: ',nerr,' error(s) during read of setup file. Re-writing.' endif diff --git a/src/setup/setup_disc.f90 b/src/setup/setup_disc.f90 index 497e57e2d..574d37219 100644 --- a/src/setup/setup_disc.f90 +++ b/src/setup/setup_disc.f90 @@ -1009,6 +1009,7 @@ subroutine calculate_disc_mass() real :: Q_mintmp,disc_mtmp,annulus_mtmp totmass_gas = 0. + disc_mdust = 0. do i=1,maxdiscs if (iuse_disc(i)) then @@ -1346,7 +1347,6 @@ subroutine setup_discs(id,fileprefix,hfact,gamma,npart,polyk,& !--dust disc(s) do j=1,ndustlarge - npindustdisc = int(disc_mdust(i,j)/sum(disc_mdust(:,j))*np_dust(j)) itype = idust + j - 1 diff --git a/src/setup/setup_grtde.f90 b/src/setup/setup_grtde.f90 index 903ef3927..72bf24033 100644 --- a/src/setup/setup_grtde.f90 +++ b/src/setup/setup_grtde.f90 @@ -18,11 +18,12 @@ module setup ! - ecc : *eccentricity (1 for parabolic)* ! - mhole : *mass of black hole (solar mass)* ! - norbits : *number of orbits* +! - relax : *relax star into hydrostatic equilibrium* ! - theta : *inclination of orbit (degrees)* ! ! :Dependencies: eos, externalforces, gravwaveutils, infile_utils, io, -! kernel, metric, mpidomain, part, physcon, setbinary, setstar, -! setup_params, timestep, units, vectorutils +! kernel, metric, mpidomain, part, physcon, relaxstar, setbinary, +! setstar, setup_params, timestep, units, vectorutils ! use setstar, only:star_t implicit none @@ -245,10 +246,10 @@ subroutine write_setupfile(filename) use setstar, only:write_options_star use relaxstar, only:write_options_relax character(len=*), intent(in) :: filename - integer, parameter :: iunit = 20 + integer :: iunit print "(a)",' writing setup options file '//trim(filename) - open(unit=iunit,file=filename,status='replace',form='formatted') + open(newunit=iunit,file=filename,status='replace',form='formatted') write(iunit,"(a)") '# input file for tidal disruption setup' call write_options_star(star,iunit) @@ -256,13 +257,12 @@ subroutine write_setupfile(filename) if (relax) call write_options_relax(iunit) write(iunit,"(/,a)") '# options for black hole and orbit' - - call write_inopt(mhole, 'mhole', 'mass of black hole (solar mass)', iunit) - call write_inopt(beta, 'beta', 'penetration factor', iunit) - call write_inopt(ecc, 'ecc', 'eccentricity (1 for parabolic)', iunit) - call write_inopt(norbits, 'norbits', 'number of orbits', iunit) - call write_inopt(dumpsperorbit, 'dumpsperorbit', 'number of dumps per orbit', iunit) - call write_inopt(theta, 'theta', 'inclination of orbit (degrees)', iunit) + call write_inopt(mhole, 'mhole', 'mass of black hole (solar mass)',iunit) + call write_inopt(beta, 'beta', 'penetration factor', iunit) + call write_inopt(ecc, 'ecc', 'eccentricity (1 for parabolic)', iunit) + call write_inopt(norbits, 'norbits', 'number of orbits', iunit) + call write_inopt(dumpsperorbit,'dumpsperorbit','number of dumps per orbit', iunit) + call write_inopt(theta, 'theta', 'inclination of orbit (degrees)', iunit) close(iunit) end subroutine write_setupfile diff --git a/src/setup/setup_kh.f90 b/src/setup/setup_kh.f90 index fb8f156c9..66d0172d3 100644 --- a/src/setup/setup_kh.f90 +++ b/src/setup/setup_kh.f90 @@ -38,12 +38,14 @@ module setup ! setup for uniform particle distributions !+ !---------------------------------------------------------------- -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,& + polyk,gamma,hfact,time,fileprefix) use setup_params, only:npart_total use io, only:master use options, only:nfulldump use unifdis, only:set_unifdis,rho_func - use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound + use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,& + dxbound,dybound,dzbound use mpiutils, only:bcast_mpi use part, only:igas,periodic use prompting, only:prompt @@ -69,6 +71,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! time = 0. gamma = 5./3 + polyk = 0. filename= trim(fileprefix)//'.in' inquire(file=filename,exist=iexist) if (.not. iexist) then @@ -100,12 +103,12 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, rhofunc=density_func,dir=2,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart print*,' npart = ',npart,npart_total totmass = dy2*dxbound*dzbound*rho2 + (dybound-dy2)*dxbound*dzbound*rho1 massoftype(igas) = totmass/npart_total - print*,' particle mass = ',massoftype(1) + print*,' particle mass = ',massoftype(igas) do i=1,npart vxyzu(1,i) = v1 + Rfunc(xyzh(2,i))*(v2 - v1) diff --git a/src/setup/setup_mhdblast.f90 b/src/setup/setup_mhdblast.f90 index 78c258a39..721e84ece 100644 --- a/src/setup/setup_mhdblast.f90 +++ b/src/setup/setup_mhdblast.f90 @@ -17,8 +17,8 @@ module setup ! - plasmaB : *plasma beta in the initial blast* ! ! :Dependencies: boundary, dim, infile_utils, io, kernel, mpidomain, -! mpiutils, options, part, physcon, prompting, setup_params, timestep, -! unifdis, units +! mpiutils, options, part, physcon, setup_params, timestep, unifdis, +! units ! implicit none public :: setpart @@ -36,7 +36,7 @@ module setup !+ !---------------------------------------------------------------- subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) - use dim, only:maxp,maxvxyzu,mhd + use dim, only:maxvxyzu,mhd use setup_params, only:rhozero,ihavesetupB use unifdis, only:set_unifdis use io, only:master,fatal @@ -44,10 +44,9 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use physcon, only:pi use timestep, only:tmax,dtmax use options, only:nfulldump - use prompting, only:prompt use kernel, only:wkern,cnormk,radkern2,hfact_default use part, only:Bxyz,igas,periodic - use mpiutils, only:bcast_mpi,reduceall_mpi + use mpiutils, only:reduceall_mpi use mpidomain, only:i_belong integer, intent(in) :: id integer, intent(out) :: npart @@ -84,6 +83,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, Rblast = 0.125 npartx = 64 gamma = 1.4 + polyk = 0. plasmaB0 = 2.0*Pblast/(Bx*Bx + By*By + Bz*Bz) plasmaB = plasmaB0 ihavesetupB = .true. @@ -106,12 +106,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, call fatal('setup','failed to read in all the data from .setup. Aborting') endif elseif (id==master) then - print "(a,/)",trim(filename)//' not found: using interactive setup' - call prompt(' Enter number of particles in x ',npartx,8,nint((maxp)**(1/3.))) - call prompt(' Enter the plasma beta in the blast (this will adjust the magnetic field strength) ',plasmaB) call write_setupfile(filename) + stop 'edit .setup file and try again' + else + stop endif - call bcast_mpi(npartx) deltax = dxbound/npartx ! ! Put particles on grid @@ -145,10 +144,10 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, endif enddo - write(*,'(2x,a,3Es11.4)')'Magnetic field (Bx,By,Bz): ',Bx,By,Bz - write(*,'(2x,a,2Es11.4)')'Pressure in blast, medium: ',Pblast,Pmed - write(*,'(2x,a,2Es11.4)')'Plasma beta in blast, medium: ',plasmaB,2.0*Pmed/(Bx*Bx + By*By + Bz*Bz) - write(*,'(2x,a, Es11.4)')'Initial blast radius: ',Rblast + write(*,'(2x,a,3es11.4)')'Magnetic field (Bx,By,Bz): ',Bx,By,Bz + write(*,'(2x,a,2es11.4)')'Pressure in blast, medium: ',Pblast,Pmed + write(*,'(2x,a,2es11.4)')'Plasma beta in blast, medium: ',plasmaB,2.0*Pmed/(Bx*Bx + By*By + Bz*Bz) + write(*,'(2x,a, es11.4)')'Initial blast radius: ',Rblast end subroutine setpart diff --git a/src/setup/setup_mhdrotor.f90 b/src/setup/setup_mhdrotor.f90 index 4382a7791..d33fb7148 100644 --- a/src/setup/setup_mhdrotor.f90 +++ b/src/setup/setup_mhdrotor.f90 @@ -29,12 +29,14 @@ module setup ! setup for uniform particle distributions !+ !---------------------------------------------------------------- -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,& + polyk,gamma,hfact,time,fileprefix) use dim, only:maxp,maxvxyzu,mhd use setup_params, only:npart_total,ihavesetupB use io, only:master use unifdis, only:set_unifdis - use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound + use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,& + dxbound,dybound,dzbound use mpiutils, only:bcast_mpi use part, only:igas,Bxyz,periodic use prompting, only:prompt @@ -58,6 +60,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! time = 0. gamma = 1.4 + polyk = 0. ! !--set particles ! @@ -103,7 +106,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, rcylmax=rdisk,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart print*,' npart = ',npart,npart_total totvol = (dxbound*dybound - pi*rdisk**2)*dzbound diff --git a/src/setup/setup_mhdsine.f90 b/src/setup/setup_mhdsine.f90 index 6df41870f..1b82b39de 100644 --- a/src/setup/setup_mhdsine.f90 +++ b/src/setup/setup_mhdsine.f90 @@ -29,14 +29,13 @@ module setup ! Sets up Bx = sin(2*pi*x), zero magnetic and velocity field otherwise ! ! The amplitude should decay as exp(-eta * 4 * pi^2 * t) -! !+ !---------------------------------------------------------------- subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) use setup_params, only:rhozero,ihavesetupB use unifdis, only:set_unifdis use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound - use part, only:Bxyz,mhd,periodic + use part, only:Bxyz,mhd,periodic,igas use io, only:master use physcon, only:pi use prompting, only:prompt @@ -77,6 +76,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, gamma = 5./3. gam1 = gamma - 1. uuzero = przero/(gam1*rhozero) + polyk = 0. else gamma = 1. polyk = przero/rhozero @@ -94,11 +94,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, hfact,npart,xyzh,periodic,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart - print*,'npart = ',npart,' particle mass = ',massoftype(1) + print*,'npart = ',npart,' particle mass = ',massoftype(igas) do i=1,npart vxyzu(1,i) = 0. diff --git a/src/setup/setup_mhdwave.f90 b/src/setup/setup_mhdwave.f90 index 07885f802..495b8f668 100644 --- a/src/setup/setup_mhdwave.f90 +++ b/src/setup/setup_mhdwave.f90 @@ -6,15 +6,14 @@ !--------------------------------------------------------------------------! module setup ! -! Setup for simple MHD wave propagation test as per section 5.1 of Iwasaki (2015) +! Setup for simple MHD wave propagation test +! as per section 5.1 of Iwasaki (2015) ! ! :References: None ! ! :Owner: James Wurster ! -! :Runtime parameters: -! - npartx : *number of particles in x-direction* -! - plasmaB : *plasma beta in the initial blast* +! :Runtime parameters: None ! ! :Dependencies: boundary, infile_utils, io, kernel, mpidomain, mpiutils, ! options, part, physcon, prompting, setup_params, timestep, unifdis, @@ -23,8 +22,8 @@ module setup implicit none public :: setpart !--private module variables - integer :: npartx - real :: plasmabzero + integer :: npartx + real :: plasmabzero private @@ -32,16 +31,15 @@ module setup !---------------------------------------------------------------- !+ -! -! -! +! setup particles in uniform box with velocity perturbation !+ !---------------------------------------------------------------- -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,& + polyk,gamma,hfact,time,fileprefix) use setup_params, only:rhozero,ihavesetupB use unifdis, only:set_unifdis use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound - use part, only:Bxyz,mhd,periodic + use part, only:Bxyz,mhd,periodic,igas use io, only:master,fatal use timestep, only:dtmax,tmax use options, only:nfulldump @@ -92,6 +90,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, gamma = 5./3. gam1 = gamma - 1. uuzero = przero/(gam1*rhozero) + polyk = przero/rhozero**gamma else gamma = 1. polyk = przero/rhozero @@ -111,11 +110,15 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, if (id==master) call write_setupfile(filename) call fatal('setup','failed to read in all the data from .setup. Aborting') endif - elseif (id==master) then - print "(a,/)",trim(filename)//' not found: using interactive setup' - call prompt(' Enter number of particles in x ',npartx,8,nint((maxp)**(1/3.))) - call prompt(' Enter the plasma beta in the blast (this will adjust the magnetic field strength) ',plasmabzero) - call write_setupfile(filename) + else + if (id==master) then + print "(a,/)",trim(filename)//' not found: using interactive setup' + call prompt(' Enter number of particles in x ',npartx,8,nint((maxp)**(1/3.))) + call prompt(' Enter the plasma beta in the blast (this will adjust the magnetic field strength) ',plasmabzero) + call write_setupfile(filename) + print*,' Edit '//trim(filename)//' and rerun phantomsetup' + endif + stop endif call bcast_mpi(npartx) deltax = dxbound/npartx @@ -126,14 +129,14 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, hfact,npart,xyzh,periodic,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart - print*,'npart = ',npart,' particle mass = ',massoftype(1) + print*,'npart = ',npart,' particle mass = ',massoftype(igas) Bxyz = 0.0 - hzero = hfact*(massoftype(1)/rhozero)**(1./3.) + hzero = hfact*(massoftype(igas)/rhozero)**(1./3.) do i=1,npart vxyzu(1,i) = 0.01*exp(-(xyzh(1,i)/(3.0*hzero))**2) vxyzu(2,i) = 0. @@ -161,9 +164,11 @@ subroutine write_setupfile(filename) open(unit=iunit,file=filename,status='replace',form='formatted') write(iunit,"(a)") '# input file for MHD Blast Wave setup routine' write(iunit,"(/,a)") '# dimensions' - call write_inopt(npartx,'npartx','number of particles in x-direction',iunit) + call write_inopt(npartx,'npartx',& + 'number of particles in x-direction',iunit) write(iunit,"(/,a)") '# magnetic field strength' - call write_inopt(plasmabzero,'plasmaB','plasma beta in the initial blast',iunit) + call write_inopt(plasmabzero,'plasmaB',& + 'plasma beta in the initial blast',iunit) close(iunit) end subroutine write_setupfile diff --git a/src/setup/setup_planetdisc.f90 b/src/setup/setup_planetdisc.f90 index bcb29c68b..6f58bc2c6 100644 --- a/src/setup/setup_planetdisc.f90 +++ b/src/setup/setup_planetdisc.f90 @@ -191,7 +191,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! vxyzu(3,i) = vxyzu(3,i) + vbinary(3) ! enddo - return end subroutine setpart @@ -205,7 +204,7 @@ subroutine write_setupfile(filename) print "(a)",' writing setup options file '//trim(filename) open(unit=iunit,file=filename,status='replace',form='formatted') - write(iunit,"(a)") '# input file for gwdisc setup routines' + write(iunit,"(a)") '# input file for planetdisc setup routine' write(iunit,"(/,a)") '# resolution' diff --git a/src/setup/setup_quebec.f90 b/src/setup/setup_quebec.f90 index f6c0f5e9c..128b4c41c 100644 --- a/src/setup/setup_quebec.f90 +++ b/src/setup/setup_quebec.f90 @@ -32,8 +32,9 @@ module setup ! setup for uniform particle distributions !+ !---------------------------------------------------------------- -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) - use part, only:maxvxyzu +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,& + vxyzu,polyk,gamma,hfact,time,fileprefix) + use part, only:maxvxyzu,igas use spherical, only:set_sphere,rho_func use io, only:master use setup_params, only:rhozero,npart_total @@ -55,7 +56,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real :: Rg_codeunits procedure(rho_func), pointer :: density_func - call set_units(dist=solarr, mass=solarm, G=1.0) + call set_units(dist=solarr, mass=solarm, G=1.0d0) ! !--parameters for this setup @@ -82,9 +83,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! xyzh(:,:) = 0. vxyzu(:,:) = 0. + polyk = 0. np = min(10000000,int(2.0/3.0*size(xyzh(1,:)))) ! approx max number allowed in sphere given size(xyzh(1,:)) npmax = np + np = 100000 call prompt('Enter the approximate number of particles in the sphere ',np,0,npmax) totvol = 4./3.*pi*rmax**3 @@ -100,22 +103,21 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, npart_total = 0 density_func => rhofunc - call set_sphere('closepacked',id,master,rmin,rmax,psep,hfact,npart,xyzh,rhofunc=density_func,nptot=npart_total) - + call set_sphere('closepacked',id,master,rmin,rmax,psep,& + hfact,npart,xyzh,rhofunc=density_func,nptot=npart_total) ! !--set particle properties ! - npart_total = npart rhozero = total_mass / totvol print *, ' total mass = ',total_mass,' mean density = ',rhozero npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart print *, ' npart = ',npart_total - massoftype(1) = total_mass / npart_total - print *, ' particle mass = ',massoftype(1) + massoftype(igas) = total_mass / npart_total + print *, ' particle mass = ',massoftype(igas) print *, '' ! convert Rg to code units @@ -150,7 +152,11 @@ real function rhofunc(r) a = a / udist ! cgs units - rhofunc = rho_crit * a * sin(r/a) / r + if (r > 0.) then + rhofunc = rho_crit * a * sin(r/a) / r + else + rhofunc = huge(0.) + endif ! convert to code units rhofunc = rhofunc / (umass / udist**3) diff --git a/src/setup/setup_radiativebox.f90 b/src/setup/setup_radiativebox.f90 index 375f3f4b0..0850a5624 100644 --- a/src/setup/setup_radiativebox.f90 +++ b/src/setup/setup_radiativebox.f90 @@ -13,31 +13,28 @@ module setup ! :Owner: Sergei Biriukov ! ! :Runtime parameters: -! - cs0 : *initial sound speed in code units* -! - dist_unit : *distance unit (e.g. au)* -! - ilattice : *lattice type (1=cubic, 2=closepacked)* -! - mass_unit : *mass unit (e.g. solarm)* -! - nx : *number of particles in x direction* -! - rhozero : *initial density in code units* -! - xmax : *xmax boundary* -! - xmin : *xmin boundary* -! - ymax : *ymax boundary* -! - ymin : *ymin boundary* -! - zmax : *zmax boundary* -! - zmin : *zmin boundary* +! - cs0 : *initial sound speed in code units* +! - ilattice : *lattice type (1=cubic, 2=closepacked)* +! - nx : *number of particles in x direction* +! - rhozero : *initial density in code units* +! - xmax : *xmax boundary* +! - xmin : *xmin boundary* +! - ymax : *ymax boundary* +! - ymin : *ymin boundary* +! - zmax : *zmax boundary* +! - zmin : *zmin boundary* ! -! :Dependencies: boundary, eos, infile_utils, io, kernel, mpidomain, -! mpiutils, options, part, physcon, set_dust, setup_params, timestep, -! unifdis, units +! :Dependencies: boundary, dim, eos, infile_utils, io, kernel, mpidomain, +! mpiutils, options, part, physcon, set_dust, setunits, setup_params, +! timestep, unifdis, units ! use setup_params, only:rhozero + use dim, only:gr implicit none public :: setpart integer :: npartx,ilattice,iradtype real :: cs0,xmini,xmaxi,ymini,ymaxi,zmini,zmaxi - character(len=20) :: dist_unit,mass_unit - real(kind=8) :: udist,umass private @@ -53,7 +50,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use io, only:master,fatal,warning use unifdis, only:set_unifdis use boundary, only:xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound,set_boundary - use physcon, only:pi,mass_proton_cgs,kboltz,years,pc,solarm,c,Rg,steboltz use set_dust, only:set_dustfrac use units, only:set_units,unit_ergg,unit_velocity,unit_opacity,get_c_code,get_radconst_code @@ -83,6 +79,8 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real :: a,c_code,cv1,kappa_code,pmassi,Tref,xi0 real :: rhoi,h0,rho0 + call setup_setdefaults(id,polyk,gamma,xmin,xmax,ymin,ymax,zmin,zmax,npartx,cs0) + filename=trim(fileprefix)//'.setup' inquire(file=filename,exist=iexist) if (iexist) then @@ -93,18 +91,14 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, stop endif elseif (id==master) then - call setup_setdefaults(& - id,polyk,gamma,xmin,xmax,ymin,ymax,zmin,zmax,mass_unit,dist_unit,& - npartx,cs0) call write_setupfile(filename,gamma) stop 'rerun phantomsetup after editing .setup file' else stop endif ! - ! set units and boundaries + ! set boundaries ! - call set_units(dist=udist,mass=umass,G=1.d0) call set_boundary(xmini,xmaxi,ymini,ymaxi,zmini,zmaxi) ! ! setup particles @@ -128,12 +122,12 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, end select npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart print*,' npart = ',npart,npart_total totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart_total - if (id==master) print*,' particle mass = ',massoftype(1) + if (id==master) print*,' particle mass = ',massoftype(igas) if (id==master) print*,' initial sound speed = ',cs0,' pressure = ',cs0**2/gamma vxyzu(1:3,:) = 0. @@ -187,6 +181,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, case default call fatal('setup_radiativebox', 'radiation setup is not available') end select + end subroutine setpart !------------------------------------------------------------------------ @@ -194,17 +189,16 @@ end subroutine setpart ! interactive setup ! !------------------------------------------------------------------------ -subroutine setup_setdefaults(& - id,polyk,gamma,xmin,xmax,ymin,ymax,zmin,zmax,mass_unit,dist_unit,& - npartx,cs0) +subroutine setup_setdefaults(id,polyk,gamma,xmin,xmax,ymin,ymax,zmin,zmax,& + npartx,cs0) use io, only:master use mpiutils, only:bcast_mpi use options, only:exchange_radiation_energy,limit_radiation_flux + use setunits, only:mass_unit,dist_unit integer, intent(in) :: id integer, intent(out) :: npartx real, intent(in) :: xmin,xmax,ymin,ymax,zmin,zmax real, intent(out) :: polyk,gamma,cs0 - character(len=*),intent(out) :: mass_unit,dist_unit mass_unit = 'solarm' dist_unit = 'au' @@ -233,6 +227,7 @@ subroutine setup_setdefaults(& call bcast_mpi(ilattice) call bcast_mpi(iradtype) endif + end subroutine setup_setdefaults !------------------------------------------------------------------------ @@ -243,6 +238,7 @@ end subroutine setup_setdefaults subroutine write_setupfile(filename,gamma) use infile_utils, only:write_inopt use options, only:exchange_radiation_energy,limit_radiation_flux + use setunits, only:write_options_units character(len=*), intent(in) :: filename integer :: iunit real, intent(in) :: gamma @@ -251,9 +247,7 @@ subroutine write_setupfile(filename,gamma) open(newunit=iunit,file=filename,status='replace',form='formatted') write(iunit,"(a)") '# input file for uniform setup routine' - write(iunit,"(/,a)") '# units' - call write_inopt(dist_unit,'dist_unit','distance unit (e.g. au)',iunit) - call write_inopt(mass_unit,'mass_unit','mass unit (e.g. solarm)',iunit) + call write_options_units(iunit) ! ! boundaries ! @@ -290,7 +284,7 @@ end subroutine write_setupfile !------------------------------------------------------------------------ subroutine read_setupfile(filename,gamma,ierr) use infile_utils, only:open_db_from_file,inopts,read_inopt,close_db - use units, only:select_unit + use setunits, only:read_options_and_set_units use io, only:error use options, only:exchange_radiation_energy,limit_radiation_flux character(len=*), intent(in) :: filename @@ -307,8 +301,7 @@ subroutine read_setupfile(filename,gamma,ierr) ! ! units ! - call read_inopt(mass_unit,'mass_unit',db,errcount=nerr) - call read_inopt(dist_unit,'dist_unit',db,errcount=nerr) + call read_options_and_set_units(db,nerr,gr) ! ! boundaries ! @@ -331,19 +324,6 @@ subroutine read_setupfile(filename,gamma,ierr) call read_inopt(limit_radiation_flux,'flux_limiter',db,errcount=nerr) call close_db(db) - ! - ! parse units - ! - call select_unit(mass_unit,umass,nerr) - if (nerr /= 0) then - call error('setup_unifdis','mass unit not recognised') - ierr = ierr + 1 - endif - call select_unit(dist_unit,udist,nerr) - if (nerr /= 0) then - call error('setup_unifdis','length unit not recognised') - ierr = ierr + 1 - endif if (nerr > 0) then print "(1x,i2,a)",nerr,' error(s) during read of setup file: re-writing...' diff --git a/src/setup/setup_sedov.f90 b/src/setup/setup_sedov.f90 index 8b8ffb4ad..bc3ea4814 100644 --- a/src/setup/setup_sedov.f90 +++ b/src/setup/setup_sedov.f90 @@ -10,26 +10,24 @@ module setup ! ! :References: None ! -! :Owner: James Wurster +! :Owner: Daniel Price ! ! :Runtime parameters: -! - lattice : *particle lattice (random,cubic,closepacked,hcp,hexagonal)* +! - lattice : *particle lattice (1=cubic,2=closepacked,3=hcp,4=random)* ! - npartx : *number of particles in x-direction* ! - shuffle_parts : *relax particles by shuffling* ! ! :Dependencies: boundary, infile_utils, io, kernel, mpidomain, mpiutils, -! options, part, physcon, prompting, setup_params, timestep, unifdis, -! units, utils_shuffleparticles +! options, part, physcon, setup_params, timestep, unifdis, +! utils_shuffleparticles ! implicit none public :: setpart private !--private module variables - integer :: npartx + integer :: npartx,ilattice logical :: shuffle_parts - character(len=20) :: lattice - contains @@ -40,13 +38,12 @@ module setup !---------------------------------------------------------------- subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_out,time,fileprefix) use setup_params, only:rhozero - use unifdis, only:set_unifdis + use unifdis, only:set_unifdis,latticetype,i_random,i_closepacked use io, only:iprint,master,fatal use boundary, only:xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound use physcon, only:pi use timestep, only:tmax,dtmax use options, only:alphau - use prompting, only:prompt use kernel, only:wkern,cnormk,radkern2,hfact_default use part, only:hfact,igas,periodic,set_particle_type use mpiutils, only:bcast_mpi,reduceall_mpi @@ -63,7 +60,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_ real, intent(out) :: vxyzu(:,:) real :: deltax,totmass,toten real :: enblast,gam1,uui,hsmooth,q2,r2 - integer :: i,maxp,maxvxyzu,ierr,ilattice + integer :: i,maxp,maxvxyzu,ierr character(len=100) :: filename logical :: iexist ! @@ -78,6 +75,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_ maxp = size(xyzh(1,:)) maxvxyzu = size(vxyzu(:,1)) npartx = 50 + ilattice = i_closepacked ! Read values from file if it exists, else prompt user for answers filename=trim(fileprefix)//'.setup' @@ -90,26 +88,10 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_ call fatal('setup','failed to read in all the data from .setup. Aborting') endif elseif (id==master) then - print "(a,/)",trim(filename)//' not found: using interactive setup' - call prompt(' Enter number of particles in x ',npartx,8,nint((maxp)**(1/3.))) - - lattice = 'cubic' - ilattice = 2 - call prompt('Enter the type of particle lattice (1=random,2=cubic,3=closepacked,4=hexagonal)',ilattice,0,4) - if (ilattice==1) then - lattice = 'random' - shuffle_parts = .false. - elseif (ilattice==3) then - lattice = 'closepacked' - elseif (ilattice==4) then - lattice = 'hexagonal' - endif - - shuffle_parts = .false. - if (ilattice==1) shuffle_parts = .true. - call prompt('Relax particles by shuffling?',shuffle_parts) - call write_setupfile(filename) + stop 'rerun phantomsetup after editing .setup file' + else + stop endif call bcast_mpi(npartx) deltax = dxbound/npartx @@ -126,7 +108,8 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_ gamma = 5./3. gam1 = gamma - 1. - call set_unifdis(trim(lattice),id,master,xmin,xmax,ymin,ymax,zmin,zmax,deltax,hfact,npart,xyzh,periodic,mask=i_belong) + call set_unifdis(latticetype(ilattice),id,master,xmin,xmax,ymin,ymax,zmin,zmax,& + deltax,hfact,npart,xyzh,periodic,mask=i_belong) npartoftype(:) = 0 npartoftype(igas) = npart @@ -139,7 +122,8 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact_ call set_particle_type(i,igas) enddo if (shuffle_parts) then - call shuffleparticles(iprint,npart,xyzh,massoftype(igas),duniform=rhozero,is_setup=.true.,prefix=trim(fileprefix)) + call shuffleparticles(iprint,npart,xyzh,massoftype(igas),duniform=rhozero,& + is_setup=.true.,prefix=trim(fileprefix)) endif toten = 0. @@ -187,7 +171,7 @@ subroutine write_setupfile(filename) write(iunit,"(a)") '# input file for Sedov Blast Wave setup routine' write(iunit,"(/,a)") '# particle resolution & placement' call write_inopt(npartx,'npartx','number of particles in x-direction',iunit) - call write_inopt(lattice,'lattice','particle lattice (random,cubic,closepacked,hcp,hexagonal)',iunit) + call write_inopt(ilattice,'lattice','particle lattice (1=cubic,2=closepacked,3=hcp,4=random)',iunit) call write_inopt(shuffle_parts,'shuffle_parts','relax particles by shuffling',iunit) close(iunit) @@ -200,26 +184,25 @@ end subroutine write_setupfile !---------------------------------------------------------------- subroutine read_setupfile(filename,ierr) use infile_utils, only: open_db_from_file,inopts,read_inopt,close_db - use unifdis, only: is_valid_lattice use io, only: error - use units, only: select_unit character(len=*), intent(in) :: filename integer, intent(out) :: ierr integer, parameter :: iunit = 21 type(inopts), allocatable :: db(:) + integer :: nerr + nerr = 0 print "(a)",' reading setup options from '//trim(filename) call open_db_from_file(db,filename,iunit,ierr) - call read_inopt(npartx,'npartx',db,ierr) - call read_inopt(lattice,'lattice',db,ierr) - if (ierr/=0 .or. .not. is_valid_lattice(trim(lattice))) then - print*, ' invalid lattice. Setting to cubic.' - lattice = 'cubic' + call read_inopt(npartx,'npartx',db,errcount=nerr) + call read_inopt(ilattice,'lattice',db,ierr,min=1,max=4,errcount=nerr) + call read_inopt(shuffle_parts,'shuffle_parts',db,errcount=nerr) + if (nerr > 0) then + print "(1x,i2,a)",nerr,' error(s) during read of setup file: re-writing...' + ierr = nerr endif - call read_inopt(shuffle_parts,'shuffle_parts',db,ierr) - call close_db(db) end subroutine read_setupfile -!---------------------------------------------------------------- + end module setup diff --git a/src/setup/setup_srblast.f90 b/src/setup/setup_srblast.f90 index 566f4a0eb..f2c51e692 100644 --- a/src/setup/setup_srblast.f90 +++ b/src/setup/setup_srblast.f90 @@ -21,8 +21,8 @@ module setup ! - smoothfac : *IC smoothing factor (in terms of particle spacing)* ! ! :Dependencies: boundary, dim, infile_utils, io, kernel, mpidomain, -! mpiutils, options, part, physcon, prompting, setup_params, timestep, -! unifdis, units +! mpiutils, options, part, physcon, setup_params, timestep, unifdis, +! units ! implicit none public :: setpart @@ -41,7 +41,7 @@ module setup !+ !---------------------------------------------------------------- subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) - use dim, only:maxp,maxvxyzu,gr + use dim, only:maxvxyzu,gr use setup_params, only:rhozero use unifdis, only:set_unifdis use io, only:master,fatal @@ -49,10 +49,9 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use physcon, only:pi use timestep, only:tmax,dtmax use options, only:nfulldump - use prompting, only:prompt use kernel, only:hfact_default use part, only:igas,periodic - use mpiutils, only:bcast_mpi,reduceall_mpi + use mpiutils, only:reduceall_mpi use units, only:set_units use mpidomain, only:i_belong integer, intent(in) :: id @@ -80,7 +79,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! ! Must have G=c=1 in relativity ! - call set_units(G=1.,c=1.) + call set_units(G=1.d0,c=1.d0) ! ! General parameters @@ -89,6 +88,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, hfact = hfact_default rhozero = 1.0 gamma = 5./3. + polyk = 0. ! ! Default setup parameters @@ -125,17 +125,11 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, call fatal('setup','failed to read in all the data from .setup. Aborting') endif elseif (id==master) then - print "(a,/)",trim(filename)//' not found: using interactive setup' - call prompt(' Enter number of particles in x ',npartx,8,nint((maxp)**(1/3.))) - call prompt(' Enter pressure in blast ',Pblast,0.) - call prompt(' Enter pressure in medium ',Pmed,0.) - call prompt(' Enter size of box ',boxsize,0.) - call prompt(' Enter radius of blast ',Rblast,0.,boxsize/2.) - call prompt(' IC smoothing factor (in terms of particle spacing) ',smoothfac) call write_setupfile(filename) + stop 'edit .setup file and try again' + else + stop endif - call bcast_mpi(npartx) - ! ! Set boundaries ! @@ -167,9 +161,9 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, vxyzu(4,i) = (ublast-umed)/(1. + exp((r-Rblast)/del)) + umed enddo - write(*,'(2x,a,2Es11.4)')'Pressure in blast, medium: ',Pblast,Pmed - write(*,'(2x,a, Es11.4)')'Initial blast radius: ',Rblast - write(*,'(2x,a, Es11.4)')'Initial blast energy: ',toten + write(*,'(2x,a,2es11.4)') 'Pressure in blast, medium: ',Pblast,Pmed + write(*,'(2x,a, es11.4)') 'Initial blast radius: ',Rblast + write(*,'(2x,a, es11.4)') 'Initial blast energy: ',toten end subroutine setpart @@ -221,5 +215,5 @@ subroutine read_setupfile(filename,ierr) call close_db(db) end subroutine read_setupfile -!---------------------------------------------------------------- + end module setup diff --git a/src/setup/setup_star.f90 b/src/setup/setup_star.f90 index 356bc41ca..3eb33b4e5 100644 --- a/src/setup/setup_star.f90 +++ b/src/setup/setup_star.f90 @@ -71,7 +71,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use mpiutils, only:reduceall_mpi use mpidomain, only:i_belong use setup_params, only:rhozero,npart_total - use setstar, only:set_star,set_defaults_star + use setstar, only:set_star integer, intent(in) :: id integer, intent(inout) :: npart integer, intent(out) :: npartoftype(:) @@ -105,9 +105,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, X_in = 0.74 Z_in = 0.02 use_var_comp = .false. - - call set_defaults_star(star) - ! ! defaults needed for error checking ! diff --git a/src/setup/setup_taylorgreen.f90 b/src/setup/setup_taylorgreen.f90 index ca7214452..734395340 100644 --- a/src/setup/setup_taylorgreen.f90 +++ b/src/setup/setup_taylorgreen.f90 @@ -39,7 +39,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use physcon, only:pi use prompting, only:prompt use mpidomain, only:i_belong - use part, only:periodic + use part, only:periodic,igas integer, intent(in) :: id integer, intent(inout) :: npart integer, intent(out) :: npartoftype(:) @@ -50,7 +50,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real, intent(inout) :: time character(len=20), intent(in) :: fileprefix real :: totmass,deltax,vzero,dz - integer :: ipart,i,maxp,maxvxyzu,nx + integer :: i,maxp,maxvxyzu,nx ! !--general parameters ! @@ -88,12 +88,12 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, hfact,npart,xyzh,periodic,nptot=npart_total,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart - print*,' npart = ',ipart,npart,npart_total + npartoftype(igas) = npart + print*,' npart = ',npart,npart_total totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart_total - print*,' particle mass = ',massoftype(1) + print*,' particle mass = ',massoftype(igas) vzero = 0.1 diff --git a/src/setup/setup_torus.f90 b/src/setup/setup_torus.f90 index a6e53c440..ee410b98e 100644 --- a/src/setup/setup_torus.f90 +++ b/src/setup/setup_torus.f90 @@ -6,9 +6,19 @@ !--------------------------------------------------------------------------! module setup ! -! this module does setup +! Setup for a rotating torus, for simulations of +! the magnetorotational instability and/or the +! Papaloizoi-Pringle instbaility ! -! :References: None +! Originally written over a few beers in collaboration +! with Owen Matthews and Laure Fouchet. This shows. +! +! Most recently used in Nealon et al. (2018) +! +! :References: +! - Papaloizoi & Pringle (1984), MNRAS 208, 721 +! - Zurek & Benz (1986), ApJ 308, 123 +! - Nealon et al. (2018), MNRAS 474, 1737 ! ! :Owner: Daniel Price ! @@ -23,13 +33,14 @@ module setup contains -subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) +subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,& + gamma,hfact,time,fileprefix) use part, only:Bxyz,rhoh,hrho,mhd - use part, only:iphase,iamtype,igas,maxphase + use part, only:igas use dim, only:maxp,maxvxyzu use setup_params, only:ihavesetupB use physcon, only:pi,au,solarm,solarr - use units, only:set_units + use units, only:set_units,get_G_code integer, intent(in) :: id integer, intent(out) :: npart integer, intent(out) :: npartoftype(:) @@ -39,19 +50,19 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real, intent(out) :: massoftype(:) real, intent(in) :: time character(len=20), intent(in) :: fileprefix - integer :: i,nrings,nlayers,iring,iz,ipart,npartphi,ii,iamtypei - real :: Rtorus,dfac,Mstar,Mtorus,zmax,deltaz,bigG + integer :: i,nrings,nlayers,iring,iz,ipart,npartphi + real :: Rtorus,dfac,Mstar,Mtorus,zmax,deltaz real :: massp,r_in,r_out,deltar,polyn,np - real :: ri,zi,rhofac,deltaphi,densi,pri + real :: ri,zi,rhofac,deltaphi,densi,pri,bigG real :: deltartemp,denstemp,rtemp,deltar0,dens0 - real :: omegai,v2onr,rcyl2,rcyl,rsph,rhosum,pmassi,pmassii + real :: omegai,v2onr,rcyl2,rcyl,rsph,rhosum,pmassi real :: beta,Bzi,dbeta,densmax,densmin real, parameter :: dndim = 1./3. ! call set_units(dist=au,mass=solarm,G=1.d0) - bigG = 1.d0 - call set_units(dist=100.*solarr,mass=10.E6*solarm,G=bigG) + call set_units(dist=100.*solarr,mass=1.e7*solarm,G=1.d0) + bigG = get_G_code() Rtorus = 1.0 dfac = 1.01 Mstar = 1.0 @@ -61,7 +72,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, gamma = 5./3. print*,'Setup for beer-related torus thing (Owen, Laure)' - print*,'maxvxyzu value: ',maxvxyzu print*,'particles: ',npart ! @@ -219,9 +229,9 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, enddo npart = ipart - npartoftype(1) = ipart + npartoftype(igas) = ipart print*,'Mtorus = ',Mtorus,massp*npart - massoftype(1) = Mtorus/real(npart) + massoftype(igas) = Mtorus/real(npart) print*,'Number of particles used',npart ! @@ -230,10 +240,9 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, !--set magnetic field using plasma beta beta = 100. !1.e4 rhosum = 0.0 - pmassii = massoftype(igas) - do ii=1,npart - if (maxphase==maxp) pmassii = massoftype(iamtype(iphase(ii))) - rhosum = rhosum + rhoh(xyzh(4,ii),pmassii) + pmassi = massoftype(igas) + do i=1,npart + rhosum = rhosum + rhoh(xyzh(4,i),pmassi) enddo rhosum = rhosum/npart @@ -253,13 +262,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, ! !--analytic velocities ! - pmassi = massoftype(igas) - iamtypei = igas do i=1,npart - if (maxphase==maxp) then - iamtypei = iamtype(iphase(i)) - pmassi = massoftype(iamtypei) - endif densi = rhoh(xyzh(4,i),pmassi) Bzi = sqrt(2.*polyk*densi**gamma/beta) rcyl2 = dot_product(xyzh(1:2,i),xyzh(1:2,i)) @@ -277,7 +280,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, vxyzu(3,i) = 0. ! Poloidal Field - if (mhd .and. iamtypei==igas) then + if (mhd) then Bxyz(3,i) = dbeta*(densi**2/rcyl & + 2.*Mstar/(polyk*gamma)*densi**(3.-gamma) & *(Rtorus/rcyl**3 - rcyl/rsph**3)) @@ -289,14 +292,16 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, endif enddo -! Toroidal field - - +! Toroidal field (not implemented) return contains - +!--------------------------------------------- +!+ +! density function needed for Torus +!+ +!--------------------------------------------- real function rhofunc(rr,zz,polyn,dd,Mstar,R0) real, intent(in) :: rr,zz,polyn,dd,Mstar,R0 real :: term @@ -312,10 +317,12 @@ real function rhofunc(rr,zz,polyn,dd,Mstar,R0) end function rhofunc -! -!--sets several ring of particles above and below the midplane -! and around in phi -! +!--------------------------------------------- +!+ +! setup several rings of particles above +! and below the midplane and around in phi +!+ +!--------------------------------------------- subroutine setring(npartphi,ipart,ri,deltar,deltaphi,densi) integer, intent(in) :: npartphi integer, intent(inout) :: ipart @@ -387,7 +394,6 @@ subroutine setring(npartphi,ipart,ri,deltar,deltaphi,densi) endif !print*,'zi = ',ri,zi,denszi,ipart enddo - ! print*,'set ring: r = ',ri,' npart = ',ipart end subroutine setring diff --git a/src/setup/setup_turb.f90 b/src/setup/setup_turb.f90 index d8f898cb3..bbc8626da 100644 --- a/src/setup/setup_turb.f90 +++ b/src/setup/setup_turb.f90 @@ -41,10 +41,10 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use options, only:use_dustfrac,nfulldump,beta use setup_params, only:rhozero,npart_total,ihavesetupB use io, only:master - use unifdis, only:set_unifdis + use unifdis, only:set_unifdis,latticetype use boundary, only:set_boundary,xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound use mpiutils, only:bcast_mpi - use part, only:Bxyz,mhd,dustfrac,grainsize,graindens,ndusttypes,ndustsmall + use part, only:Bxyz,mhd,dustfrac,grainsize,graindens,ndusttypes,ndustsmall,igas use physcon, only:pi,solarm,pc,km use units, only:set_units,udist,umass use prompting, only:prompt @@ -63,7 +63,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, real, intent(inout) :: time character(len=20), intent(in) :: fileprefix character(len=26) :: filename - integer :: ipart,i + integer :: i logical :: iexist real :: totmass,deltax real :: Bz_0 @@ -185,24 +185,16 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, npart = 0 npart_total = 0 - - select case(ilattice) - case(2) - call set_unifdis('closepacked',id,master,xmin,xmax,ymin,ymax,zmin,zmax,deltax,hfact,npart,& - xyzh,periodic,nptot=npart_total,mask=i_belong) - case default - if (ilattice==1) print*,' error: chosen lattice not available, using cubic' - call set_unifdis('cubic',id,master,xmin,xmax,ymin,ymax,zmin,zmax,deltax,hfact,npart,& - xyzh,periodic,nptot=npart_total,mask=i_belong) - end select + call set_unifdis(latticetype(ilattice),id,master,xmin,xmax,ymin,ymax,zmin,zmax,& + deltax,hfact,npart,xyzh,periodic,nptot=npart_total,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart - print *, ' npart = ',ipart,npart,npart_total + npartoftype(igas) = npart + print *, ' npart = ',npart,npart_total totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart_total - print *, ' particle mass = ',massoftype(1) + print *, ' particle mass = ',massoftype(igas) do i=1,npart vxyzu(1:3,i) = 0. diff --git a/src/setup/setup_unifdis.f90 b/src/setup/setup_unifdis.f90 index 0db04670e..44b4ad316 100644 --- a/src/setup/setup_unifdis.f90 +++ b/src/setup/setup_unifdis.f90 @@ -15,10 +15,8 @@ module setup ! :Runtime parameters: ! - Bzero : *magnetic field strength in code units* ! - cs0 : *initial sound speed in code units* -! - dist_unit : *distance unit (e.g. au)* ! - dust_to_gas : *dust-to-gas ratio* ! - ilattice : *lattice type (1=cubic, 2=closepacked)* -! - mass_unit : *mass unit (e.g. solarm)* ! - nx : *number of particles in x direction* ! - rhozero : *initial density in code units* ! - xmax : *xmax boundary* @@ -29,10 +27,10 @@ module setup ! - zmin : *zmin boundary* ! ! :Dependencies: boundary, cooling, cooling_ism, dim, eos, infile_utils, -! io, mpidomain, mpiutils, options, part, physcon, prompting, set_dust, +! io, mpidomain, options, part, physcon, prompting, set_dust, setunits, ! setup_params, timestep, unifdis, units ! - use dim, only:use_dust,mhd + use dim, only:use_dust,mhd,gr use options, only:use_dustfrac use setup_params, only:rhozero implicit none @@ -40,8 +38,6 @@ module setup integer :: npartx,ilattice real :: cs0,xmini,xmaxi,ymini,ymaxi,zmini,zmaxi,Bzero - character(len=20) :: dist_unit,mass_unit - real(kind=8) :: udist,umass !--change default defaults to reproduce the test from Section 5.6.7 of Price+(2018) logical :: BalsaraKim = .false. @@ -59,15 +55,16 @@ module setup !+ !---------------------------------------------------------------- subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact,time,fileprefix) - use dim, only:maxvxyzu,h2chemistry,gr + use dim, only:maxvxyzu,h2chemistry use setup_params, only:npart_total,ihavesetupB use io, only:master - use unifdis, only:set_unifdis + use unifdis, only:set_unifdis,latticetype use boundary, only:xmin,ymin,zmin,xmax,ymax,zmax,dxbound,dybound,dzbound,set_boundary - use part, only:Bxyz,periodic,abundance,iHI,dustfrac,ndustsmall,ndusttypes,grainsize,graindens + use part, only:Bxyz,periodic,abundance,igas,iHI,dustfrac,ndustsmall,ndusttypes,grainsize,graindens use physcon, only:pi,mass_proton_cgs,kboltz,years,pc,solarm,micron use set_dust, only:set_dustfrac - use units, only:set_units,unit_density + use setunits, only:dist_unit,mass_unit + use units, only:unit_density,udist use mpidomain, only:i_belong use eos, only:gmw use options, only:icooling,alpha,alphau @@ -122,10 +119,6 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, if (use_dust) then use_dustfrac = .true. dust_to_gas = 0.01 - ndustsmall = 1 - ndusttypes = 1 - grainsize(1) = 1.*micron/udist - graindens(1) = 3./unit_density endif if (BalsaraKim) then ! there is a typo in Price+ (2018) in stating the physical density; @@ -178,20 +171,24 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, stop endif elseif (id==master) then - call setup_interactive(id,polyk) + call setup_interactive call write_setupfile(filename) stop 'rerun phantomsetup after editing .setup file' else stop endif ! - ! set units and boundaries + ! set dust grain sizes ! - if (gr) then - call set_units(mass=umass,c=1.d0,G=1.d0) - else - call set_units(dist=udist,mass=umass,G=1.d0) + if (use_dust) then + ndustsmall = 1 + ndusttypes = 1 + grainsize(1) = 1.*micron/udist + graindens(1) = 3./unit_density endif + ! + ! set boundaries + ! call set_boundary(xmini,xmaxi,ymini,ymaxi,zmini,zmaxi) ! ! setup particles @@ -200,23 +197,16 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, npart = 0 npart_total = 0 - select case(ilattice) - case(2) - call set_unifdis('closepacked',id,master,xmin,xmax,ymin,ymax,zmin,zmax,deltax,hfact,& - npart,xyzh,periodic,nptot=npart_total,mask=i_belong) - case default - if (ilattice /= 1) print*,' error: chosen lattice not available, using cubic' - call set_unifdis('cubic',id,master,xmin,xmax,ymin,ymax,zmin,zmax,deltax,hfact,npart,xyzh,& - periodic,nptot=npart_total,mask=i_belong) - end select + call set_unifdis(latticetype(ilattice),id,master,xmin,xmax,ymin,ymax,zmin,zmax,& + deltax,hfact,npart,xyzh,periodic,nptot=npart_total,mask=i_belong) npartoftype(:) = 0 - npartoftype(1) = npart + npartoftype(igas) = npart print*,' npart = ',npart,npart_total totmass = rhozero*dxbound*dybound*dzbound massoftype = totmass/npart_total - if (id==master) print*,' particle mass = ',massoftype(1) + if (id==master) print*,' particle mass = ',massoftype(igas) if (id==master) print*,' initial sound speed = ',cs0,' pressure = ',cs0**2/gamma if (maxvxyzu < 4 .or. gamma <= 1.) then @@ -249,6 +239,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, enddo ihavesetupB = .true. endif + end subroutine setpart !------------------------------------------------------------------------ @@ -256,77 +247,47 @@ end subroutine setpart ! interactive setup ! !------------------------------------------------------------------------ -subroutine setup_interactive(id,polyk) +subroutine setup_interactive() use io, only:master - use mpiutils, only:bcast_mpi use dim, only:maxp,maxvxyzu use prompting, only:prompt - use units, only:select_unit - integer, intent(in) :: id - real, intent(out) :: polyk - integer :: ierr + use setunits, only:set_units_interactive - if (id==master) then - ierr = 1 - do while (ierr /= 0) - call prompt('Enter mass unit (e.g. solarm,jupiterm,earthm)',mass_unit) - call select_unit(mass_unit,umass,ierr) - if (ierr /= 0) print "(a)",' ERROR: mass unit not recognised' - enddo - ierr = 1 - do while (ierr /= 0) - call prompt('Enter distance unit (e.g. au,pc,kpc,0.1pc)',dist_unit) - call select_unit(dist_unit,udist,ierr) - if (ierr /= 0) print "(a)",' ERROR: length unit not recognised' - enddo + call set_units_interactive(gr) - call prompt('enter xmin boundary',xmini) - call prompt('enter xmax boundary',xmaxi,xmini) - call prompt('enter ymin boundary',ymini) - call prompt('enter ymax boundary',ymaxi,ymini) - call prompt('enter zmin boundary',zmini) - call prompt('enter zmax boundary',zmaxi,zmini) - endif + call prompt('enter xmin boundary',xmini) + call prompt('enter xmax boundary',xmaxi,xmini) + call prompt('enter ymin boundary',ymini) + call prompt('enter ymax boundary',ymaxi,ymini) + call prompt('enter zmin boundary',zmini) + call prompt('enter zmax boundary',zmaxi,zmini) ! ! number of particles ! - if (id==master) then - print*,' uniform setup... (max = ',nint((maxp)**(1/3.)),')' - call prompt('enter number of particles in x direction ',npartx,1) - endif - call bcast_mpi(npartx) + print*,' uniform setup... (max = ',nint((maxp)**(1/3.)),')' + call prompt('enter number of particles in x direction ',npartx,1) ! ! mean density ! - if (id==master) call prompt(' enter density (gives particle mass)',rhozero,0.) - call bcast_mpi(rhozero) + call prompt(' enter density (gives particle mass)',rhozero,0.) ! ! sound speed in code units ! - if (id==master) then - call prompt(' enter sound speed in code units (sets polyk)',cs0,0.) - endif - call bcast_mpi(cs0) + call prompt(' enter sound speed in code units (sets polyk)',cs0,0.) ! ! dust to gas ratio ! - if (use_dustfrac) then - call prompt('Enter dust to gas ratio',dust_to_gas,0.) - call bcast_mpi(dust_to_gas) - endif + if (use_dustfrac) call prompt('Enter dust to gas ratio',dust_to_gas,0.) ! ! magnetic field strength if (mhd .and. balsarakim) then call prompt('Enter magnetic field strength in code units ',Bzero,0.) - call bcast_mpi(Bzero) endif ! ! type of lattice ! - if (id==master) then - call prompt(' select lattice type (1=cubic, 2=closepacked)',ilattice,1) - endif - call bcast_mpi(ilattice) + call prompt(' select lattice type (1=cubic, 2=closepacked)',ilattice,1) + end subroutine setup_interactive !------------------------------------------------------------------------ @@ -336,6 +297,7 @@ end subroutine setup_interactive !------------------------------------------------------------------------ subroutine write_setupfile(filename) use infile_utils, only:write_inopt + use setunits, only:write_options_units character(len=*), intent(in) :: filename integer :: iunit @@ -343,9 +305,7 @@ subroutine write_setupfile(filename) open(newunit=iunit,file=filename,status='replace',form='formatted') write(iunit,"(a)") '# input file for uniform setup routine' - write(iunit,"(/,a)") '# units' - call write_inopt(dist_unit,'dist_unit','distance unit (e.g. au)',iunit) - call write_inopt(mass_unit,'mass_unit','mass unit (e.g. solarm)',iunit) + call write_options_units(iunit) ! ! boundaries ! @@ -381,8 +341,7 @@ end subroutine write_setupfile !------------------------------------------------------------------------ subroutine read_setupfile(filename,ierr) use infile_utils, only:open_db_from_file,inopts,read_inopt,close_db - use units, only:select_unit - use io, only:error + use setunits, only:read_options_and_set_units character(len=*), intent(in) :: filename integer, intent(out) :: ierr integer, parameter :: iunit = 21 @@ -396,8 +355,7 @@ subroutine read_setupfile(filename,ierr) ! ! units ! - call read_inopt(mass_unit,'mass_unit',db,errcount=nerr) - call read_inopt(dist_unit,'dist_unit',db,errcount=nerr) + call read_options_and_set_units(db,nerr,gr) ! ! boundaries ! @@ -421,19 +379,6 @@ subroutine read_setupfile(filename,ierr) endif call read_inopt(ilattice,'ilattice',db,min=1,max=2,errcount=nerr) call close_db(db) - ! - ! parse units - ! - call select_unit(mass_unit,umass,nerr) - if (nerr /= 0) then - call error('setup_unifdis','mass unit not recognised') - ierr = ierr + 1 - endif - call select_unit(dist_unit,udist,nerr) - if (nerr /= 0) then - call error('setup_unifdis','length unit not recognised') - ierr = ierr + 1 - endif if (nerr > 0) then print "(1x,i2,a)",nerr,' error(s) during read of setup file: re-writing...' diff --git a/src/setup/setup_wavedamp.f90 b/src/setup/setup_wavedamp.f90 index 08320991d..8464bb638 100644 --- a/src/setup/setup_wavedamp.f90 +++ b/src/setup/setup_wavedamp.f90 @@ -109,6 +109,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, use_ohm = .false. use_hall = .false. use_ambi = .false. + ierr = 0 ! !--Prompt the user for relevant input to create .setup if file does not already exist ! @@ -223,7 +224,7 @@ subroutine setpart(id,npart,npartoftype,xyzh,massoftype,vxyzu,polyk,gamma,hfact, !--Convert to real values ! if (realvals) then - !--matches dimensions of spereinbox + !--matches dimensions of sphereinbox udist = 1.d16 umass = solarm call set_units(dist=udist,mass=umass,G=1.d0)