! $Id$ ! ! This module is used both for the initial condition and during run time. ! It contains dlnrhon_dt and init_lnrhon, among other auxiliary routines. ! !** AUTOMATIC CPARAM.INC GENERATION **************************** ! Declare (for generation of cparam.inc) the number of f array ! variables and auxiliary variables added by this module ! ! CPARAM logical, parameter :: lneutraldensity = .true. ! ! MVAR CONTRIBUTION 1 ! MAUX CONTRIBUTION 0 ! ! PENCILS PROVIDED lnrhon; rhon; rhon1; glnrhon(3); grhon(3); ! PENCILS PROVIDED unglnrhon; ungrhon; del2lnrhon; del2rhon; glnrhon2 ! PENCILS PROVIDED del6lnrhon; del6rhon; snglnrhon(3); alpha; zeta ! !*************************************************************** module NeutralDensity ! use Cparam use Cdata use Messages ! implicit none ! include 'neutraldensity.h' ! real :: kx_lnrhon=1.,ky_lnrhon=1.,kz_lnrhon=1. real :: ampllnrhon=0.,rhon_left=1.,rhon_right=1. real :: diffrhon=0.,diffrhon_hyper3=0.,diffrhon_shock=0. real :: lnrhon_const=0., rhon_const=1. real :: lnrhon_int=0.,lnrhon_ext=0. real :: lnrhon0,lnrhon_left,lnrhon_right,alpha,zeta real, dimension(3) :: diffrhon_hyper3_aniso=0. integer, parameter :: ndiff_max=4 logical :: lmass_source=.false.,lcontinuity_neutral=.true. logical :: lupw_lnrhon=.false.,lupw_rhon=.false. logical :: ldiffn_normal=.false.,ldiffn_hyper3=.false.,ldiffn_shock=.false. logical :: ldiffn_hyper3lnrhon=.false.,ldiffn_hyper3_aniso=.false. logical :: lfreeze_lnrhonint=.false.,lfreeze_lnrhonext=.false. logical :: ldiffn_hyper3_polar=.false. logical :: lpretend_star,lramp_up real :: star_form_threshold=1.,star_form_exponent=1.5 character (len=labellen), dimension(ninit) :: initlnrhon='nothing' character (len=labellen), dimension(ndiff_max) :: idiffn='' character (len=labellen) :: borderlnrhon='nothing' character (len=intlen) :: iinit_str integer :: iglobal_rhon=0 ! namelist /neutraldensity_init_pars/ & ampllnrhon,initlnrhon, & rhon_left,rhon_right,lnrhon_const,rhon_const, & idiffn,lneutraldensity_nolog, & lcontinuity_neutral,lnrhon0,lnrhon_left,lnrhon_right, & alpha,zeta,kx_lnrhon,ky_lnrhon,kz_lnrhon,lpretend_star,& star_form_threshold,lramp_up,star_form_exponent ! namelist /neutraldensity_run_pars/ & diffrhon,diffrhon_hyper3,diffrhon_shock, & lupw_lnrhon,lupw_rhon,idiffn, & lnrhon_int,lnrhon_ext, & lfreeze_lnrhonint,lfreeze_lnrhonext, & lnrhon_const,lcontinuity_neutral,borderlnrhon, & diffrhon_hyper3_aniso,alpha,zeta,lpretend_star, & star_form_threshold,lramp_up,star_form_exponent ! ! Diagnostic variables (needs to be consistent with reset list below). ! integer :: idiag_rhonm=0,idiag_rhon2m=0,idiag_lnrhon2m=0 integer :: idiag_rhonmin=0,idiag_rhonmax=0,idiag_unglnrhonm=0 integer :: idiag_lnrhonmphi=0,idiag_rhonmphi=0,idiag_dtnd=0 integer :: idiag_rhonmz=0, idiag_rhonmy=0, idiag_rhonmx=0 integer :: idiag_rhonmxy=0, idiag_rhonmr=0 integer :: idiag_neutralmass=0 ! contains !*********************************************************************** subroutine register_neutraldensity() ! ! Initialise variables which should know that we solve the ! compressible hydro equations: ilnrhon; increase nvar accordingly. ! ! 28-feb-07/wlad: adapted from density ! use FArrayManager ! if (.not.lcartesian_coords) & call fatal_error('register_neutraldensity','non cartesian '//& 'not yet implemented in the neutrals module') ! if (lneutraldensity_nolog) then call farray_register_pde('rhon',irhon) ilnrhon=irhon else call farray_register_pde('lnrhon',ilnrhon) endif ! ! Identify version number (generated automatically by SVN). ! if (lroot) call svn_id( & "$Id$") ! endsubroutine register_neutraldensity !*********************************************************************** subroutine initialize_neutraldensity() ! ! Perform any post-parameter-read initialization i.e. calculate derived ! parameters. ! ! For compatibility with other applications, we keep the possibility ! of giving diffrhon units of dxmin*cs0, but cs0 is not well defined general ! ! 28-feb-07/wlad: adapted ! ! use BorderProfiles, only: request_border_driving use FArrayManager ! integer :: i logical :: lnothing ! ! Turn off continuity equation term for 0-D runs. ! if (nxgrid*nygrid*nzgrid==1) then lcontinuity_neutral=.false. print*, 'initialize_neutraldensity: 0-D run, turned off continuity equation' endif ! ! Initialize dust diffusion ! ldiffn_normal=.false. ldiffn_shock=.false. ldiffn_hyper3=.false. ldiffn_hyper3lnrhon=.false. ldiffn_hyper3_aniso=.false. ldiffn_hyper3_polar=.false. ! lnothing=.false. ! do i=1,ndiff_max select case (idiffn(i)) case ('normal') if (lroot) print*,'diffusion: div(D*grad(rhon))' ldiffn_normal=.true. case ('hyper3') if (lroot) print*,'diffusion: (d^6/dx^6+d^6/dy^6+d^6/dz^6)rhon' ldiffn_hyper3=.true. case ('hyper3lnrhon') if (lroot) print*,'diffusion: (d^6/dx^6+d^6/dy^6+d^6/dz^6)lnrhon' ldiffn_hyper3lnrhon=.true. case ('hyper3_aniso') if (lroot) print*,'diffusion: (Dx*d^6/dx^6 + Dy*d^6/dy^6 + Dz*d^6/dz^6)rhon' ldiffn_hyper3_aniso=.true. case ('hyper3_cyl','hyper3-cyl','hyper3_sph','hyper3-sph') if (lroot) print*,'diffusion: Dhyper/pi^4 *(Delta(rhon))^6/Deltaq^2' ldiffn_hyper3_polar=.true. case ('shock') if (lroot) print*,'diffusion: shock diffusion' ldiffn_shock=.true. call fatal_error("shock diffusion assumes the ions velocity",& "not yet implemented for neutrals") case ('') if (lroot .and. (.not. lnothing)) print*,'diffusion: nothing' case default write(unit=errormsg,fmt=*) 'initialize_neutraldensity: ', & 'No such value for idiff(',i,'): ', trim(idiffn(i)) call fatal_error('initialize_neutraldensity',errormsg) endselect lnothing=.true. enddo ! ! If we're timestepping, die or warn if the the diffusion coefficient that ! corresponds to the chosen diffusion type is not set. ! if (lrun) then if (ldiffn_normal.and.diffrhon==0.0) & call warning('initialize_neutraldensity', & 'Diffusion coefficient diffrhon is zero!') if ( (ldiffn_hyper3 .or. ldiffn_hyper3lnrhon) & .and. diffrhon_hyper3==0.0) & call fatal_error('initialize_neutraldensity', & 'Diffusion coefficient diffrhon_hyper3 is zero!') if ( (ldiffn_hyper3_aniso) .and. & ((diffrhon_hyper3_aniso(1)==0. .and. nxgrid/=1 ).or. & (diffrhon_hyper3_aniso(2)==0. .and. nygrid/=1 ).or. & (diffrhon_hyper3_aniso(3)==0. .and. nzgrid/=1 )) ) & call fatal_error('initialize_neutraldensity', & 'A diffusion coefficient of diffrhon_hyper3 is zero!') if (ldiffn_shock .and. diffrhon_shock==0.0) & call fatal_error('initialize_neutraldensity', & 'diffusion coefficient diffrhon_shock is zero!') endif ! ! Hyperdiffusion only works with (not log) density. One must either use ! ldensity_nolog=T or work with GLOBAL = global_nolog_density. ! if ((ldiffn_hyper3.or.ldiffn_hyper3_aniso) .and. (.not. lneutraldensity_nolog)) then if (lroot) print*,"initialize_neutraldensity: Creating global array for rhon to use hyperdiffusion" call farray_register_global('rhon',iglobal_rhon) endif ! if (lfreeze_lnrhonint) lfreeze_varint(ilnrhon) = .true. if (lfreeze_lnrhonext) lfreeze_varext(ilnrhon) = .true. ! ! Tell the BorderProfiles module if we intend to use border driving, so ! that the module can request the right pencils. ! if (borderlnrhon/='nothing') call request_border_driving(borderlnrhon) ! endsubroutine initialize_neutraldensity !*********************************************************************** subroutine read_neutraldensity_init_pars(iostat) ! use File_io, only: parallel_unit ! integer, intent(out) :: iostat ! read(parallel_unit, NML=neutraldensity_init_pars, IOSTAT=iostat) ! endsubroutine read_neutraldensity_init_pars !*********************************************************************** subroutine write_neutraldensity_init_pars(unit) ! integer, intent(in) :: unit ! write(unit, NML=neutraldensity_init_pars) ! endsubroutine write_neutraldensity_init_pars !*********************************************************************** subroutine read_neutraldensity_run_pars(iostat) ! use File_io, only: parallel_unit ! integer, intent(out) :: iostat ! read(parallel_unit, NML=neutraldensity_run_pars, IOSTAT=iostat) ! endsubroutine read_neutraldensity_run_pars !*********************************************************************** subroutine write_neutraldensity_run_pars(unit) ! integer, intent(in) :: unit ! write(unit, NML=neutraldensity_run_pars) ! endsubroutine write_neutraldensity_run_pars !*********************************************************************** subroutine init_lnrhon(f) ! ! initialise lnrhon; called from start.f90 ! ! 28-feb-07/wlad: adapted ! use General, only: itoa,complex_phase use Initcond use InitialCondition, only: initial_condition_lnrhon use General, only: notanumber use EquationOfState, only: cs20, cs2bot,cs2top ! real, dimension (mx,my,mz,mfarray) :: f ! real :: zbot, ztop logical :: lnothing integer :: j ! ! define bottom and top height ! zbot=xyz0(3) ztop=xyz0(3)+Lxyz(3) ! ! Set default values for sound speed at top and bottom. ! These may be updated in one of the following initialization routines. ! cs2top=cs20; cs2bot=cs20 ! ! different initializations of lnrhon (called from start). ! If initrhon does't match, f=0 is assumed (default). ! lnothing=.true. do j=1,ninit if (initlnrhon(j)/='nothing') then lnothing=.false. iinit_str=itoa(j) select case (initlnrhon(j)) ! ! some one-liners from density ! case ('zero', '0'); f(:,:,:,ilnrhon)=0. case ('const_lnrhon'); f(:,:,:,ilnrhon)=lnrhon_const case ('const_rhon'); f(:,:,:,ilnrhon)=log(rhon_const) case ('constant'); f(:,:,:,ilnrhon)=log(rhon_left) case ('scale-ions') if (ldensity_nolog) then f(:,:,:,ilnrhon)=log(rhon_const)+log(f(:,:,:,ilnrho)) else f(:,:,:,ilnrhon)=log(rhon_const)+f(:,:,:,ilnrho) endif case ('sinwave-z'); call sinwave(ampllnrhon,f,ilnrhon,kz=kz_lnrhon) case ('gaussian-noise') if (lnrhon_left /= 0.) f(:,:,:,ilnrhon)=lnrhon_left call gaunoise(ampllnrhon,f,ilnrhon,ilnrhon) case default ! ! Catch unknown values ! write(unit=errormsg,fmt=*) 'No such value for initlnrhon(' & //trim(iinit_str)//'): ',trim(initlnrhon(j)) call fatal_error('init_lnrhon',errormsg) ! endselect if (lroot) print*,'init_lnrhon: initlnrhon(' & //trim(iinit_str)//') = ',trim(initlnrhon(j)) endif enddo ! ! Interface for user's own initial conditon ! if (linitial_condition) call initial_condition_lnrhon(f) ! if (lnothing.and.lroot) print*,'init_lnrhon: nothing' ! ! If unlogarithmic density considered, take exp of lnrhon resulting from ! initlnrhon ! if (lneutraldensity_nolog) f(:,:,:,irhon)=exp(f(:,:,:,ilnrhon)) ! ! sanity check ! if (notanumber(f(l1:l2,m1:m2,n1:n2,ilnrhon))) then call error('init_lnrhon', 'Imaginary density values') endif ! endsubroutine init_lnrhon !*********************************************************************** subroutine pencil_criteria_neutraldensity() ! ! All pencils that the NeutralDensity module depends on are specified here. ! ! 28-feb-07/wlad: adapted ! ! always needed for ionization and recombination ! lpenc_requested(i_rho) =.true. lpenc_requested(i_rhon) =.true. lpenc_requested(i_alpha)=.true. lpenc_requested(i_zeta)=.true. ! if (.not.lneutraldensity_nolog) then lpenc_requested(i_rho1) =.true. lpenc_requested(i_rhon1)=.true. endif ! if (lpretend_star) then lpenc_requested(i_rho1)=.true. lpenc_requested(i_uu)=.true. lpenc_requested(i_rcyl_mn1)=.true. endif ! if (lcontinuity_neutral) then lpenc_requested(i_divun)=.true. if (lneutraldensity_nolog) then lpenc_requested(i_ungrhon)=.true. else lpenc_requested(i_unglnrhon)=.true. endif endif if (ldiffn_shock) then lpenc_requested(i_shock)=.true. lpenc_requested(i_gshock)=.true. if (lneutraldensity_nolog) then lpenc_requested(i_grhon)=.true. lpenc_requested(i_del2rhon)=.true. else lpenc_requested(i_glnrhon)=.true. lpenc_requested(i_glnrhon2)=.true. lpenc_requested(i_del2lnrhon)=.true. endif endif if (ldiffn_normal) then if (lneutraldensity_nolog) then lpenc_requested(i_del2rhon)=.true. else lpenc_requested(i_glnrhon2)=.true. lpenc_requested(i_del2lnrhon)=.true. endif endif if (ldiffn_hyper3.or.ldiffn_hyper3_aniso) & lpenc_requested(i_del6rhon)=.true. if (ldiffn_hyper3.and..not.lneutraldensity_nolog) & lpenc_requested(i_rhon)=.true. if (ldiffn_hyper3lnrhon) & lpenc_requested(i_del6lnrhon)=.true. if (ldiffn_hyper3_polar.and..not.lneutraldensity_nolog) & lpenc_requested(i_rhon1)=.true. ! if (lmass_source) lpenc_requested(i_rcyl_mn)=.true. ! lpenc_diagnos2d(i_lnrhon)=.true. lpenc_diagnos2d(i_rhon)=.true. ! if (idiag_rhonm/=0 .or. idiag_rhonmz/=0 .or. idiag_rhonmy/=0 .or. & idiag_rhonmx/=0 .or. idiag_rhon2m/=0 .or. idiag_rhonmin/=0 .or. & idiag_rhonmax/=0 .or. idiag_rhonmxy/=0 .or. idiag_neutralmass/=0) & lpenc_diagnos(i_rhon)=.true. if (idiag_lnrhon2m/=0) lpenc_diagnos(i_lnrhon)=.true. if (idiag_unglnrhonm/=0) lpenc_diagnos(i_unglnrhon)=.true. ! endsubroutine pencil_criteria_neutraldensity !*********************************************************************** subroutine pencil_interdep_neutraldensity(lpencil_in) ! ! Interdependency among pencils from the NeutralDensity module is ! specified here. ! ! 28-feb-07/wlad: adapted ! logical, dimension(npencils) :: lpencil_in ! if (lneutraldensity_nolog) then if (lpencil_in(i_rhon1)) lpencil_in(i_rhon)=.true. else if (lpencil_in(i_rhon)) lpencil_in(i_rhon1)=.true. endif if (lpencil_in(i_unglnrhon)) then lpencil_in(i_uun)=.true. lpencil_in(i_glnrhon)=.true. endif if (lpencil_in(i_ungrhon)) then lpencil_in(i_uun)=.true. lpencil_in(i_grhon)=.true. endif if (lpencil_in(i_glnrhon2)) lpencil_in(i_glnrhon)=.true. if (lpencil_in(i_snglnrhon)) then lpencil_in(i_snij)=.true. lpencil_in(i_glnrhon)=.true. endif ! The pencils glnrhon and grhon come in a bundle. if (lpencil_in(i_glnrhon) .and. lpencil_in(i_grhon)) then if (lneutraldensity_nolog) then lpencil_in(i_grhon)=.false. else lpencil_in(i_glnrhon)=.false. endif endif ! endsubroutine pencil_interdep_neutraldensity !*********************************************************************** subroutine calc_pencils_neutraldensity(f,p) ! ! Calculate NeutralDensity pencils. ! Most basic pencils should come first, as others may depend on them. ! ! 28-feb-07/wlad: adapted ! use Sub, only: grad,dot,dot2,u_dot_grad,del2,del6,multmv,g2ij ! real, dimension (mx,my,mz,mfarray) :: f real, dimension (nx) :: tmp,smooth_step_threshold real :: alpha_time,ramping_period type (pencil_case) :: p ! integer :: i, mm, nn ! intent(inout) :: f,p ! lnrhon if (lpencil(i_lnrhon)) then if (lneutraldensity_nolog) then p%lnrhon=log(f(l1:l2,m,n,irhon)) else p%lnrhon=f(l1:l2,m,n,ilnrhon) endif endif ! rhon1 and rhon if (lneutraldensity_nolog) then if (lpencil(i_rhon)) p%rhon=f(l1:l2,m,n,irhon) if (lpencil(i_rhon1)) p%rhon1=1.0/p%rhon else if (lpencil(i_rhon1)) p%rhon1=exp(-f(l1:l2,m,n,ilnrhon)) if (lpencil(i_rhon)) p%rhon=1.0/p%rhon1 endif ! glnrhon and grhon if (lpencil(i_glnrhon).or.lpencil(i_grhon)) then if (lneutraldensity_nolog) then call grad(f,ilnrhon,p%grhon) if (lpencil(i_glnrhon)) then do i=1,3 p%glnrhon(:,i)=p%grhon(:,i)/p%rhon enddo endif else call grad(f,ilnrhon,p%glnrhon) if (lpencil(i_grhon)) then do i=1,3 p%grhon(:,i)=p%rhon*p%glnrhon(:,i) enddo endif endif endif ! unglnrhon if (lpencil(i_unglnrhon)) then if (lneutraldensity_nolog) then call dot(p%uun,p%glnrhon,p%unglnrhon) else call u_dot_grad(f,ilnrhon,p%glnrhon,p%uun,p%unglnrhon,UPWIND=lupw_lnrhon) endif endif ! ungrhon if (lpencil(i_ungrhon)) then if (lneutraldensity_nolog) then call u_dot_grad(f,ilnrhon,p%grhon,p%uun,p%ungrhon,UPWIND=lupw_rhon) else call dot(p%uun,p%grhon,p%ungrhon) endif endif ! glnrhon2 if (lpencil(i_glnrhon2)) call dot2(p%glnrhon,p%glnrhon2) ! del2lnrhon if (lpencil(i_del2lnrhon)) then if (lneutraldensity_nolog) then if (headtt) then call fatal_error('calc_pencils_neutraldensity', & 'del2lnrhon not available for non-logarithmic mass density') endif else call del2(f,ilnrhon,p%del2lnrhon) endif endif ! del2rhon if (lpencil(i_del2rhon)) then if (lneutraldensity_nolog) then call del2(f,ilnrhon,p%del2rhon) else if (headtt) then call fatal_error('calc_pencils_neutraldensity', & 'del2rhon not available for logarithmic mass density') endif endif endif ! del6rhon if (lpencil(i_del6rhon)) then if (lneutraldensity_nolog) then call del6(f,ilnrhon,p%del6rhon) else if (lfirstpoint) then ! ! Fill global rhon array using the ilnrhon data !ajwm This won't work unless earlt_finalize is used... ? if (iglobal_rhon/=0) then do mm=1,my; do nn=1,mz f(:,mm,nn,iglobal_rhon) = exp(f(:,mm,nn,ilnrhon)) enddo; enddo else call fatal_error("calc_pencils_neutraldensity",& "A global rhon slot must be available for calculating del6rhon from lnrhon") endif endif if (iglobal_rhon/=0) call del6(f,iglobal_rhon,p%del6rhon) endif endif ! del6lnrhon if (lpencil(i_del6lnrhon)) then if (lneutraldensity_nolog) then if (headtt) then call fatal_error('calc_pencils_neutraldensity', & 'del6lnrhon not available for non-logarithmic mass density') endif else call del6(f,ilnrhon,p%del6lnrhon) endif endif ! snglnrhon if (lpencil(i_snglnrhon)) call multmv(p%snij,p%glnrhon,p%snglnrhon) ! ! ionization and recombination pencils ! p%zeta=zeta if (lpretend_star) then if (.not.lcylindrical_coords) & call fatal_error("lpretend_star",& "not implemented for other than cylindrical coordinates") !smooth transition over a ramping period of 5 orbits if (lramp_up) then ramping_period=2*pi*x(lpoint) !omega=v/r; v=1; 1/omega=r if (t <= ramping_period) then alpha_time=alpha*(sin((.5*pi)*(t/ramping_period))**2) else alpha_time=alpha endif else alpha_time=alpha endif ! ! Star formation rate ! These lines below recover d/dt(rho_star)=sfr_const*omega*rho_gas**1.5 ! ! There is threshold that has to be smoothed. The star formation ! rate falls drastically after the threshold of 5-10 solar masses ! per cubic parsec. A arctangent smoothing over a tenth of this value ! is okay to avoid numerical disasters. ! tmp=(p%rho-star_form_threshold)/(.1*star_form_threshold) smooth_step_threshold=.5*(1+atan(tmp)*2*pi_1) !OO=p%uu(*,2)*p%rcyl_mn1 p%alpha=(alpha_time*smooth_step_threshold)*& (p%uu(:,2)*p%rcyl_mn1)*p%rho1**(2-star_form_exponent) ! else p%alpha=alpha endif ! endsubroutine calc_pencils_neutraldensity !*********************************************************************** subroutine dlnrhon_dt(f,df,p) ! ! continuity equation ! calculate dlnrhon/dt = - un.gradlnrhon - divun ! ! 28-feb-07/wlad: adapted ! use Deriv, only: der6 use Diagnostics use Mpicomm, only: stop_it use Sub, only: identify_bcs, del6fj, dot_mn ! real, dimension (mx,my,mz,mfarray) :: f real, dimension (mx,my,mz,mvar) :: df type (pencil_case) :: p ! intent(in) :: f,p intent(out) :: df ! real, dimension (nx) :: fdiff, gshockglnrhon, gshockgrhon, tmp, diffus_diffrhon, diffus_diffrhon3 integer :: j ! ! identify module and boundary conditions ! if (headtt.or.ldebug) print*,'dlnrhon_dt: SOLVE dlnrhon_dt' if (headtt) call identify_bcs('lnrhon',ilnrhon) ! ! continuity equation ! if (lcontinuity_neutral) then if (lneutraldensity_nolog) then df(l1:l2,m,n,irhon) = df(l1:l2,m,n,irhon) - p%ungrhon - p%rhon*p%divun else df(l1:l2,m,n,ilnrhon) = df(l1:l2,m,n,ilnrhon) - p%unglnrhon - p%divun endif endif ! ! Ionization and recombination ! if (lneutraldensity_nolog) then df(l1:l2,m,n,irhon) = df(l1:l2,m,n,irhon) - p%zeta*p%rhon + p%alpha*p%rho**2 df(l1:l2,m,n,ilnrho ) = df(l1:l2,m,n,ilnrho ) + p%zeta*p%rhon - p%alpha*p%rho**2 else df(l1:l2,m,n,ilnrhon) = df(l1:l2,m,n,ilnrhon) - p%zeta + p%alpha*p%rho**2*p%rhon1 df(l1:l2,m,n,ilnrho ) = df(l1:l2,m,n,ilnrho ) + p%zeta*p%rhon*p%rho1 - p%alpha*p%rho endif ! ! Mass diffusion ! fdiff=0.0 diffus_diffrhon=0.; diffus_diffrhon3=0. ! if (ldiffn_normal) then ! Normal diffusion operator if (lneutraldensity_nolog) then fdiff = fdiff + diffrhon*p%del2rhon else fdiff = fdiff + diffrhon*(p%del2lnrhon+p%glnrhon2) endif if (lfirst.and.ldt) diffus_diffrhon=diffus_diffrhon+diffrhon*dxyz_2 if (headtt) print*,'dlnrhon_dt: diffrhon=', diffrhon endif ! ! Hyper diffusion ! if (ldiffn_hyper3) then if (lneutraldensity_nolog) then fdiff = fdiff + diffrhon_hyper3*p%del6rhon else fdiff = fdiff + 1/p%rhon*diffrhon_hyper3*p%del6rhon endif if (lfirst.and.ldt) diffus_diffrhon3=diffus_diffrhon3+diffrhon_hyper3*dxyz_6 if (headtt) print*,'dlnrhon_dt: diffrhon_hyper3=', diffrhon_hyper3 endif ! if (ldiffn_hyper3_aniso) then if (lneutraldensity_nolog) then call del6fj(f,diffrhon_hyper3_aniso,ilnrhon,tmp) fdiff = fdiff + tmp if (lfirst.and.ldt) diffus_diffrhon3=diffus_diffrhon3+ & diffrhon_hyper3_aniso(1)*dline_1(:,1)**6 + & diffrhon_hyper3_aniso(2)*dline_1(:,2)**6 + & diffrhon_hyper3_aniso(3)*dline_1(:,3)**6 if (headtt) & print*,'dlnrhon_dt: diffrhon_hyper3=(Dx,Dy,Dz)=',& diffrhon_hyper3_aniso else call stop_it("anisotropic hyperdiffusion not implemented for lnrhon") endif endif ! if (ldiffn_hyper3_polar) then do j=1,3 call der6(f,ilnrhon,tmp,j,IGNOREDX=.true.) if (.not.lneutraldensity_nolog) tmp=tmp*p%rhon1 fdiff = fdiff + diffrhon_hyper3*pi4_1*tmp*dline_1(:,j)**2 enddo if (lfirst.and.ldt) & diffus_diffrhon3=diffus_diffrhon3+diffrhon_hyper3*pi4_1*dxmin_pencil**4 if (headtt) print*,'dlnrhon_dt: diffrhon_hyper3=', diffrhon_hyper3 endif ! if (ldiffn_hyper3lnrhon) then if (.not. lneutraldensity_nolog) then fdiff = fdiff + diffrhon_hyper3*p%del6lnrhon endif if (lfirst.and.ldt) diffus_diffrhon3=diffus_diffrhon3+diffrhon_hyper3*dxyz_6 if (headtt) print*,'dlnrhon_dt: diffrhon_hyper3=', diffrhon_hyper3 endif ! ! Shock diffusion ! if (ldiffn_shock) then if (lneutraldensity_nolog) then call dot_mn(p%gshock,p%grhon,gshockgrhon) df(l1:l2,m,n,ilnrhon) = df(l1:l2,m,n,ilnrhon) + & diffrhon_shock*p%shock*p%del2rhon + diffrhon_shock*gshockgrhon else call dot_mn(p%gshock,p%glnrhon,gshockglnrhon) df(l1:l2,m,n,ilnrhon) = df(l1:l2,m,n,ilnrhon) + & diffrhon_shock*p%shock*(p%del2lnrhon+p%glnrhon2) + & diffrhon_shock*gshockglnrhon endif if (lfirst.and.ldt) & diffus_diffrhon=diffus_diffrhon+diffrhon_shock*p%shock*dxyz_2 if (headtt) print*,'dlnrhon_dt: diffrhon_shock=', diffrhon_shock endif ! ! Add diffusion term to continuity equation ! if (lneutraldensity_nolog) then df(l1:l2,m,n,irhon) = df(l1:l2,m,n,irhon) + fdiff else df(l1:l2,m,n,ilnrhon) = df(l1:l2,m,n,ilnrhon) + fdiff endif ! if (lfirst.and.ldt) then if (headtt.or.ldebug) & print*,'dlnrhon_dt: max(diffus_diffrhon) =', maxval(diffus_diffrhon) maxdiffus=max(maxdiffus,diffus_diffrhon) maxdiffus3=max(maxdiffus3,diffus_diffrhon3) endif ! ! Apply border profile ! if (lborder_profiles) call set_border_neutraldensity(f,df,p) ! ! 2d-averages ! Note that this does not necessarily happen with ldiagnos=.true. ! if (l2davgfirst) then call zsum_mn_name_xy(p%rhon,idiag_rhonmxy) call phisum_mn_name_rz(p%lnrhon,idiag_lnrhonmphi) call phisum_mn_name_rz(p%rhon,idiag_rhonmphi) endif ! ! 1d-averages. Happens at every it1d timesteps, NOT at every it1 ! if (l1davgfirst) then call phizsum_mn_name_r(p%rhon,idiag_rhonmr) call xysum_mn_name_z(p%rhon,idiag_rhonmz) call yzsum_mn_name_x(p%rhon,idiag_rhonmx) call xzsum_mn_name_y(p%rhon,idiag_rhonmy) endif ! ! Calculate density diagnostics ! if (ldiagnos) then call sum_mn_name(p%rhon,idiag_rhonm) call sum_lim_mn_name(p%rhon,idiag_neutralmass,p) if (idiag_rhonmin/=0) & call max_mn_name(-p%rhon,idiag_rhonmin,lneg=.true.) call max_mn_name(p%rhon,idiag_rhonmax) if (idiag_rhon2m/=0) call sum_mn_name(p%rhon**2,idiag_rhon2m) if (idiag_lnrhon2m/=0) call sum_mn_name(p%lnrhon**2,idiag_lnrhon2m) call sum_mn_name(p%unglnrhon,idiag_unglnrhonm) if (idiag_dtnd/=0) & call max_mn_name(diffus_diffrhon/cdtv,idiag_dtnd,l_dt=.true.) endif ! endsubroutine dlnrhon_dt !*********************************************************************** subroutine set_border_neutraldensity(f,df,p) ! ! Calculates the driving term for the border profile ! of the lnrhon variable. ! ! 28-jul-06/wlad: coded ! use BorderProfiles, only: border_driving use EquationOfState, only: cs0,cs20 ! real, dimension(mx,my,mz,mfarray) :: f type (pencil_case) :: p real, dimension(mx,my,mz,mvar) :: df real, dimension(nx) :: f_target !,OO_sph,OO_cyl,cs,theta ! real :: r0_pot=0.1 ! select case (borderlnrhon) ! case ('zero','0') f_target=0. case ('constant') f_target=lnrhon_const case ('stratification') !OO_sph = sqrt((r_mn**2 + r0_pot**2)**(-1.5)) !OO_cyl = sqrt((rcyl_mn**2 + r0_pot**2)**(-1.5)) !cs = OO_cyl*rcyl_mn*cs0 !f_target=lnrhon_const - 0.5*(theta/cs0)**2 f_target=(p%rcyl_mn-p%r_mn)/(cs20*p%r_mn) case ('nothing') if (lroot.and.ip<=5) & print*,"set_border_neutraldensity: borderlnrhon='nothing'" case default write(unit=errormsg,fmt=*) & 'set_border_neutraldensity: No such value for borderlnrhon: ', & trim(borderlnrhon) call fatal_error('set_border_neutraldensity',errormsg) endselect ! if (lneutraldensity_nolog) f_target=exp(f_target) ! if (borderlnrhon /= 'nothing') then call border_driving(f,df,p,f_target,ilnrhon) endif ! endsubroutine set_border_neutraldensity !*********************************************************************** subroutine rprint_neutraldensity(lreset,lwrite) ! ! reads and registers print parameters relevant for compressible part ! ! 28-feb-07/wlad: adapted ! use Diagnostics, only: parse_name use FArrayManager, only: farray_index_append ! logical :: lreset logical, optional :: lwrite ! integer :: iname, inamex, inamey, inamez, inamexy, irz, inamer logical :: lwr ! lwr = .false. if (present(lwrite)) lwr=lwrite ! ! reset everything in case of reset ! (this needs to be consistent with what is defined above!) ! if (lreset) then idiag_rhonm=0; idiag_rhon2m=0; idiag_lnrhon2m=0; idiag_unglnrhonm=0 idiag_rhonmin=0; idiag_rhonmax=0; idiag_dtnd=0 idiag_lnrhonmphi=0; idiag_rhonmphi=0 idiag_rhonmz=0; idiag_rhonmy=0; idiag_rhonmx=0 idiag_rhonmxy=0; idiag_rhonmr=0; idiag_neutralmass=0 diffrhon=0. endif ! ! iname runs through all possible names that may be listed in print.in ! if (lroot.and.ip<14) print*,'rprint_neutraldensity: run through parse list' do iname=1,nname call parse_name(iname,cname(iname),cform(iname),'rhonm',idiag_rhonm) call parse_name(iname,cname(iname),cform(iname),'rhon2m',idiag_rhon2m) call parse_name(iname,cname(iname),cform(iname),'rhonmin',idiag_rhonmin) call parse_name(iname,cname(iname),cform(iname),'rhonmax',idiag_rhonmax) call parse_name(iname,cname(iname),cform(iname),'lnrhon2m',idiag_lnrhon2m) call parse_name(iname,cname(iname),cform(iname),'unglnrhonm',idiag_unglnrhonm) call parse_name(iname,cname(iname),cform(iname),'dtnd',idiag_dtnd) call parse_name(iname,cname(iname),cform(iname),'neutralmass',idiag_neutralmass) enddo ! ! check for those quantities for which we want xy-averages ! do inamez=1,nnamez call parse_name(inamez,cnamez(inamez),cformz(inamez),'rhonmz',idiag_rhonmz) enddo ! ! check for those quantities for which we want xz-averages ! do inamey=1,nnamey call parse_name(inamey,cnamey(inamey),cformy(inamey),'rhonmy',idiag_rhonmy) enddo ! ! check for those quantities for which we want yz-averages ! do inamex=1,nnamex call parse_name(inamex,cnamex(inamex),cformx(inamex),'rhonmx',idiag_rhonmx) enddo ! ! check for those quantities for which we want phiz-averages ! do inamer=1,nnamer call parse_name(inamer,cnamer(inamer),cformr(inamer),'rhonmr',idiag_rhonmr) enddo ! ! check for those quantities for which we want z-averages ! do inamexy=1,nnamexy call parse_name(inamexy,cnamexy(inamexy),cformxy(inamexy),'rhonmxy',idiag_rhonmxy) enddo ! ! check for those quantities for which we want phi-averages ! do irz=1,nnamerz call parse_name(irz,cnamerz(irz),cformrz(irz),& 'lnrhonmphi',idiag_lnrhonmphi) call parse_name(irz,cnamerz(irz),cformrz(irz),'rhonmphi',idiag_rhonmphi) enddo ! ! write column where which density variable is stored ! if (lwr) then call farray_index_append('ilnrhon',ilnrhon) endif ! endsubroutine rprint_neutraldensity !*********************************************************************** endmodule NeutralDensity