! $Id$ ! ! Equation of state for an ideal gas without ionization. ! !** 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 :: leos = .true. ! ! MVAR CONTRIBUTION 0 ! MAUX CONTRIBUTION 0 ! ! PENCILS PROVIDED lnTT; glnTT(3); TT; TT1; gTT(3) ! PENCILS PROVIDED pp; del2pp; mu1; gmu1(3); glnmu(3) ! PENCILS PROVIDED rho1gpp(3); glnpp(3); del2lnTT ! ! PENCILS PROVIDED hss(3,3); hlnTT(3,3); del2ss; del6ss; del6lnTT ! PENCILS PROVIDED yH; ee; ss; delta; glnmumol(3); ppvap; csvap2; cs2 ! PENCILS PROVIDED cp1tilde; cp; gamma_m1; gamma ! PENCILS PROVIDED rho_anel; gradcp(3) ! ! !*************************************************************** module EquationOfState ! use Cparam use Cdata use General, only: keep_compiler_quiet use Messages ! implicit none ! include '../eos.h' ! integer, parameter :: ilnrho_ss=1,ilnrho_ee=2,ilnrho_pp=3 integer, parameter :: ilnrho_lnTT=4,ilnrho_cs2=5 integer, parameter :: irho_cs2=6, irho_ss=7, irho_lnTT=8, ilnrho_TT=9 integer, parameter :: ipp_ss=11, irho_TT=10, ipp_cs2=12 integer, parameter :: irho_eth=13, ilnrho_eth=14 ! integer :: iglobal_cs2, iglobal_glnTT, ics ! real :: lnTT0=impossible ! real :: mu=1. real :: cs0=1., rho0=1. real :: cs20=1., lnrho0=0. real :: gamma=5./3. real :: Rgas_cgs=0., Rgas, Rgas_unit_sys=1., error_cp=1e-6 real :: gamma_m1 !(=gamma-1) real :: gamma1 !(=1/gamma) real :: cp=impossible, cp1=impossible, cv=impossible, cv1=impossible real :: cs2bot=1., cs2top=1. integer :: ieosvars=-1, ieosvar1=-1, ieosvar2=-1, ieosvar_count=0 integer :: ll1,ll2,mm1,mm2,nn1,nn2 logical :: leos_isothermal=.false., leos_isentropic=.false. logical :: leos_isochoric=.false., leos_isobaric=.false. logical :: leos_localisothermal=.false. character (len=20) :: input_file logical, SAVE :: lcheminp_eos=.false. logical :: l_gamma_m1=.false. logical :: l_gamma=.false. logical :: l_cp=.false. integer :: imass=1!, iTemp1=2,iTemp2=3,iTemp3=4 ! real, dimension(nchemspec,18) :: species_constants ! real :: Cp_const=impossible real :: Pr_number=0.7 ! !NILS: Why do we spend a lot of memory allocating these variables here???? !MR: Is now allocated only once. real, dimension(mx,my,mz), target :: mu1_full ! namelist /eos_init_pars/ mu, cp, cs0, rho0, gamma, error_cp ! namelist /eos_run_pars/ mu, cp, cs0, rho0, gamma, error_cp ! contains !*********************************************************************** subroutine register_eos ! ! 14-jun-03/axel: adapted from register_eos ! leos_chemistry=.true. ! ilnTT = 0 ! ! Identify version number. ! if (lroot) call svn_id( & '$Id$') ! endsubroutine register_eos !*********************************************************************** subroutine units_eos ! ! This routine calculates things related to units and must be called ! before the rest of the units are being calculated. ! ! 22-jun-06/axel: adapted from initialize_eos ! 16-mar-10/Natalia ! use Mpicomm, only: stop_it ! logical :: chemin=.false.,cheminp=.false. ! ! Initialize variable selection code (needed for RELOADing) ! ieosvars=-1 ieosvar_count=0 ! if (unit_system == 'cgs') then Rgas_unit_sys = k_B_cgs/m_u_cgs elseif (unit_system == 'SI') then Rgas_unit_sys = k_B_cgs/m_u_cgs*1.e-4 endif ! if (unit_temperature == impossible) then call stop_it('unit_temperature is not found!') else Rgas=Rgas_unit_sys*unit_temperature/unit_velocity**2 endif ! inquire(file='chem.inp',exist=cheminp) inquire(file='chem.in',exist=chemin) if(chemin .and. cheminp) call fatal_error('eos_chemistry',& 'chem.inp and chem.in found. Please decide for one') ! if (cheminp) input_file='chem.inp' if (chemin) input_file='chem.in' lcheminp_eos = cheminp .or. chemin ! inquire(FILE=input_file, EXIST=lcheminp_eos) ! if (lroot) then ! if (.not. lcheminp_eos ) then call fatal_error('initialize_eos',& 'chem.imp is not found!') else print*,'units_eos: chem.imp is found! Now cp, cv, gamma, mu are pencils ONLY!' endif endif ! endsubroutine units_eos !*********************************************************************** subroutine initialize_eos ! use SharedVariables, only: put_shared_variable ! ! Initialize variable selection code (needed for RELOADing) ! ieosvars=-1 ieosvar_count=0 ! ! write constants to disk. In future we may want to deal with this ! using an include file or another module. ! if (lroot) then open (1,file=trim(datadir)//'/pc_constants.pro',position="append") write (1,'(a,1pd26.16)') 'k_B=',k_B write (1,'(a,1pd26.16)') 'm_H=',m_H write (1,*) 'lnTTO=',lnTT0 write (1,*) 'cp=',cp close (1) endif ! if ((nxgrid==1) .and. (nygrid==1) .and. (nzgrid==1)) then ll1=1; ll2=mx; mm1=m1; mm2=m2; nn1=n1; nn2=n2 elseif (nxgrid==1) then ll1=l1; ll2=l2 else ll1=1; ll2=mx endif ! if (nygrid==1) then mm1=m1; mm2=m2 else mm1=1; mm2=my endif ! if (nzgrid==1) then nn1=n1; nn2=n2 else nn1=1; nn2=mz endif if (.not.ldensity) then call put_shared_variable('rho0',rho0,caller='initialize_eos') call put_shared_variable('lnrho0',lnrho0) endif if (lchemistry) call put_shared_variable('mu1_full',mu1_full,caller='initialize_eos') ! endsubroutine initialize_eos !*********************************************************************** subroutine select_eos_variable(variable,findex) ! ! Select eos variable ! ! 02-apr-06/tony: implemented ! use FArrayManager ! character (len=*), intent(in) :: variable integer, intent(in) :: findex integer :: this_var=0 integer, save :: ieosvar_selected=0 integer, parameter :: ieosvar_lnrho = 2**0 integer, parameter :: ieosvar_rho = 2**1 integer, parameter :: ieosvar_ss = 2**2 integer, parameter :: ieosvar_lnTT = 2**3 integer, parameter :: ieosvar_TT = 2**4 integer, parameter :: ieosvar_cs2 = 2**5 integer, parameter :: ieosvar_pp = 2**6 ! if (ieosvar_count==0) ieosvar_selected=0 ! if (ieosvar_count>=2) & call fatal_error("select_eos_variable", & "2 thermodynamic quantities have already been defined while attempting to add a 3rd: ") !//variable) ! ieosvar_count=ieosvar_count+1 ! ! select case (variable) if (variable=='ss') then this_var=ieosvar_ss if (findex<0) then leos_isentropic=.true. endif elseif (variable=='cs2') then this_var=ieosvar_cs2 if (findex==-2) then leos_localisothermal=.true. ! call farray_register_global('cs2',iglobal_cs2) call farray_register_global('glnTT',iglobal_glnTT,vector=3) ! elseif (findex<0) then leos_isothermal=.true. endif elseif (variable=='lnTT') then this_var=ieosvar_lnTT if (findex<0) then leos_isothermal=.true. endif elseif (variable=='TT') then this_var=ieosvar_TT elseif (variable=='lnrho') then this_var=ieosvar_lnrho if (findex<0) then leos_isochoric=.true. endif elseif (variable=='rho') then this_var=ieosvar_rho if (findex<0) then leos_isochoric=.true. endif elseif (variable=='pp') then this_var=ieosvar_pp if (findex<0) then leos_isobaric=.true. endif else call fatal_error("select_eos_variable", & "unknown thermodynamic variable") endif if (ieosvar_count==1) then ieosvar1=findex ieosvar_selected=ieosvar_selected+this_var return endif ! ! Ensure the indexes are in the correct order. ! if (this_varnchemspec) then print*,'nchemspec=',nchemspec call stop_it("There were too many species, "//& "please increase nchemspec!") endif varname(ichemspec(k))=trim(ChemInpLine(StartInd:StopInd-1)) StartInd=StopInd k=k+1 endif if (StartInd==80) exit enddo stringloop endif endif enddo dataloop ! ! Stop if chem.inp is empty ! 1000 if (emptyFile) call stop_it('The input file chem.inp was empty!') ! ! Check if nchemspec where not too large ! if (k0 .and. ind_chem<=nchemspec) then ! if (existing_specie) then if (found_specie) then ! ! Find molar mass ! MolMass=0 do iElement=1,4 In1=25+(iElement-1)*5 In2=26+(iElement-1)*5 In3=27+(iElement-1)*5 In4=29+(iElement-1)*5 if (ChemInpLine(In1:In1)==' ') then MolMass(iElement)=0 else element_string=trim(ChemInpLine(In1:In2)) call find_mass(element_string,MolMass(iElement)) In5=verify(ChemInpLine(In3:In4),' ')+In3-1 NumberOfElement_string=trim(ChemInpLine(In5:In4)) read (unit=NumberOfElement_string,fmt='(I5)') & NumberOfElement_i MolMass(iElement)=MolMass(iElement)*NumberOfElement_i endif enddo species_constants(ind_chem,imass)=sum(MolMass) ! ! Find temperature-ranges for low and high temperature fitting ! do iTemperature=1,3 In1=46+(iTemperature-1)*10 In2=55+(iTemperature-1)*10 if (iTemperature==3) In2=73 In3=verify(ChemInpLine(In1:In2),' ')+In1-1 TemperatureNr_i=trim(ChemInpLine(In3:In2)) read (unit=TemperatureNr_i,fmt='(F10.1)') nne tmp_temp(iTemperature)=nne enddo species_constants(ind_chem,iTemp1)=tmp_temp(1) species_constants(ind_chem,iTemp2)=tmp_temp(3) species_constants(ind_chem,iTemp3)=tmp_temp(2) ! elseif (ChemInpLine(80:80)=="2") then ! Read iaa1(1):iaa1(5) read (unit=ChemInpLine(1:75),fmt='(5E15.8)') & species_constants(ind_chem,iaa1(1):iaa1(5)) ! elseif (ChemInpLine(80:80)=="3") then ! Read iaa1(6):iaa5(3) read (unit=ChemInpLine(1:75),fmt='(5E15.8)') & species_constants(ind_chem,iaa1(6):iaa2(3)) elseif (ChemInpLine(80:80)=="4") then ! Read iaa2(4):iaa2(7) read (unit=ChemInpLine(1:75),fmt='(4E15.8)') & species_constants(ind_chem,iaa2(4):iaa2(7)) endif ! endif endif endif !(from ind_chem>0 query) endif enddo dataloop2 1001 continue close(file_id) ! endsubroutine read_thermodyn !*********************************************************************** subroutine write_thermodyn ! ! This subroutine writes the thermodynamical data for every specie ! to ./data/chem.out. ! ! 06-mar-08/nils: coded ! use General ! character (len=fnlen) :: input_file="./data/chem.out" character (len=intlen) :: ispec integer :: file_id=123,k integer, dimension(7) :: iaa1,iaa2 integer :: iTemp1=2,iTemp3=4 ! ! Initialize some index pointers ! iaa1(1)=5;iaa1(2)=6;iaa1(3)=7;iaa1(4)=8 iaa1(5)=9;iaa1(6)=10;iaa1(7)=11 ! iaa2(1)=12;iaa2(2)=13;iaa2(3)=14;iaa2(4)=15 iaa2(5)=16;iaa2(6)=17;iaa2(7)=18 ! open(file_id,file=input_file) write(file_id,*) 'Specie' write(file_id,*) 'MolMass Temp1 Temp2 Temp3' write(file_id,*) 'a1(1) a1(2) a1(3) a1(4) a1(5) a1(6) a1(7)' write(file_id,*) 'a2(1) a2(2) a2(3) a2(4) a2(5) a2(6) a2(7)' write(file_id,*) '***********************************************' dataloop2: do k=1,nchemspec write(file_id,*) varname(ichemspec(k)) write(file_id,'(F10.2,3F10.2)') species_constants(k,imass),& species_constants(k,iTemp1:iTemp3) write(file_id,'(7E12.5)') species_constants(k,iaa1) write(file_id,'(7E12.5)') species_constants(k,iaa2) enddo dataloop2 ! close(file_id) ! if (lroot) then print*,'Write pc_constants.pro in chemistry.f90' open (143,FILE=trim(datadir)//'/pc_constants.pro',POSITION="append") write (143,*) 'specname=strarr(',nchemspec,')' write (143,*) 'specmass=fltarr(',nchemspec,')' do k=1,nchemspec ispec=itoa(k-1) write (143,*) 'specname[',trim(ispec),']=',"'",& trim(varname(ichemspec(k))),"'" write (143,*) 'specmass[',trim(ispec),']=',species_constants(k,imass) enddo close (143) endif ! endsubroutine write_thermodyn !*********************************************************************** subroutine get_stratz(z, rho0z, dlnrho0dz, eth0z) ! ! Get background stratification in z direction. ! ! 13-oct-14/ccyang: dummy ! real, dimension(:), intent(in) :: z real, dimension(:), intent(out), optional :: rho0z, dlnrho0dz, eth0z ! call fatal_error('get_stratz', 'Stratification for this EOS is not implemented. ') ! call keep_compiler_quiet(z) if (present(rho0z)) call keep_compiler_quiet(rho0z) if (present(dlnrho0dz)) call keep_compiler_quiet(dlnrho0dz) if (present(eth0z)) call keep_compiler_quiet(eth0z) ! endsubroutine get_stratz !*********************************************************************** subroutine pushdiags2c(p_diag) integer, parameter :: n_diags=0 integer(KIND=ikind8), dimension(:) :: p_diag call keep_compiler_quiet(p_diag) endsubroutine pushdiags2c !*********************************************************************** subroutine pushpars2c(p_par) use Syscalls, only: copy_addr integer, parameter :: n_pars=1 integer(KIND=ikind8), dimension(n_pars) :: p_par call copy_addr(cs20,p_par(1)) endsubroutine pushpars2c !*********************************************************************** endmodule EquationOfState