Changes between Version 1 and Version 2 of LE_Module
- Timestamp:
- 06/29/13 18:35:59 (12 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
LE_Module
v1 v2 8 8 == Requirements == 9 9 || poly_index || This is the index,n, of the polytrope equation of state || 10 || rho_cent || The central denisty of the clump object || 11 || xi_last || The root of the solve lame-emden equation - this represents the polytrope radius || 12 || R_outer || The maximum domain size, needed to determine computational step size || 10 || rho_cent || The central density of the clump object (cgs) || 11 || M_star || The mass of the object (cgs) || 13 12 14 13 If the polytrope index n that is given is greater than or equal to 5, we will get a solution with infinite radius - if the user explicitly provides a xi_last then the profile can be constructed, otherwise it is stopped. … … 16 15 == Output == 17 16 18 || K || K is the free parameter from the polytropic equation of state||17 || a_scale || scaling factor from dimensionless to physical values || 19 18 || p_cent || Central pressure of clump || 20 || M_star || Mass of clump || 21 || data(*,1:3) || profiles - data(*,2): density profile, data(*,3): pressure profile || 19 || t_cent || Central temp || 20 || R_outer || Radius of object || 21 || data(*,1:3) || profiles - data(*,2): density profile, data(*,3): pressure profile, data(*,4): temp profile || 22 22 23 23 == Code == 24 24 {{{ 25 25 Module LE_module 26 27 26 USE GlobalDeclarations 28 USE Physic alDeclarations27 USE PhysicsDeclarations 29 28 USE Profiles 30 29 Implicit None … … 36 35 CONTAINS 37 36 38 SUBROUTINE ConstructPolyTropeProfile(Profile, R_outer, poly_index, rho_cent, M_star, xi_last)37 SUBROUTINE ConstructPolyTropeProfile(Profile,R_outer, poly_index, rho_cent, M_star, xi_last,a_scale,p_cent,temp_cent,rho_outer) 39 38 TYPE(ProfileDef), POINTER :: Profile 40 INTEGER :: nPoints 41 REAL :: R_outer, poly_index, rho_cent, xi_last 42 REAL :: h, a_scale, K, p_cent, dxi, xi, theta, dtheta, M_star 39 INTEGER(KIND=8) :: nPoints 40 REAL(KIND=QPREC) :: nPointsf 41 REAL(KIND=QPREC) :: h, poly_index,press_profile,rho_profile 42 REAL(KIND=QPREC) :: M_star,rho_cent ! INPUT PARAMETERS 43 REAL(KIND=QPREC) :: xi, xi_last, dxi, dtheta, dtheta_last, theta, theta_last,ddxi,nsteps !calculated dimensionless variables 44 REAL(KIND=QPREC) :: a_scale, R_outer, p_cent,temp_cent !calculated scaling values and other useful relations 45 REAL(KIND=qPREC) :: theta_target, rho_outer 46 INTEGER :: i,j 47 !Profile data stored in Profile object 43 48 44 nPoints=max(R_outer/levels(maxLevel)%dx, 1000)45 h=R_outer/nPoints !Computational step size46 47 49 IF (poly_index >= 5) THEN 50 IF (MPI_ID == 0) THEN 51 write(*,*) 'not yet fully implemented for poly_index >= 5' 52 STOP 53 END IF 48 54 IF (xi_last <= 0) THEN 49 55 IF (MPI_ID == 0) write(*,*) 'Error - must specify dimensionless truncation cutoff xi_last if the polytropic index > 5 in ConstructPolyTropeProfile' … … 51 57 END IF 52 58 ELSE 59 60 theta_target=(rho_outer/rho_cent)**(1d0/poly_index) 61 53 62 !Initilize solution at some small xi 54 xi=1 e-455 theta=1 -(xi**2.0)/6.0+(poly_index/120.0)*(xi**4.0)-(8.0*poly_index**2.0-5.0*poly_index)/(15120.0)*(xi**5.0)56 dtheta=-xi/3 .0+(poly_index/30.0)*(xi**3.0)-(8.0*poly_index**2.0-5.0*poly_index)/(2520.0)*(xi**5.0)63 xi=1d-4 64 theta=1d0-(xi**2d0)/6d0+(poly_index/120d0)*(xi**4d0)-(8d0*poly_index**2d0-5d0*poly_index)/(15120d0)*(xi**5d0) 65 dtheta=-xi/3d0+(poly_index/30d0)*(xi**3d0)-(8d0*poly_index**2d0-5d0*poly_index)/(2520d0)*(xi**5d0) 57 66 58 67 !Initial step size 59 dxi=1e-2 60 68 dxi=1d-2 61 69 DO 62 theta_last=theta 63 xi_last=xi 64 dtheta_last=dtheta 65 CALL LE_Advance(xi, theta, dtheta, dxi) 70 CALL LE_Advance(xi,dtheta,poly_index,theta,dxi,1,0d0) 66 71 IF (xi > 10d0) dxi=.01*theta/dtheta !adjust step size once were beyond xi=10 in case poly_index is just under 5... 67 IF (theta < 0d0) EXIT 72 IF (theta <= 0d0) EXIT 73 ! write(*,*) xi, theta 68 74 END DO 69 dtheta = dtheta - (xi-xi_last)*(dtheta-dtheta_last)/dxi70 xi = xi + (theta/(theta_last-theta))*dxi71 theta=0d072 75 xi_last=xi 73 76 theta_last=theta 74 END IF 77 dtheta_last=dtheta 78 write(*,*) "xi_last :" ,xi_last 79 write(*,*) "dtheta_last: ", dtheta_last 80 END IF 75 81 76 !Construct Profile Object77 CALL CreateProfile(Profile, nPoints, (/Mass_Field, Press_Field/), RADIAL)78 82 !Calculate length scale 83 a_scale=(-M_star/(4d0*Pi*rho_cent*(xi_last**2)*dtheta_last))**(1d0/3d0) 84 write(*,*) "a_scale", a_scale, M_star, rho_cent, xi_last, dtheta_last 79 85 80 !Calculate various other scales 81 a_scale=xi_last/R_outer 82 K=4d0*pi*ScaleGrav/((poly_index+1)*a_scale**2)*rho_cent**((poly_index-1)/poly_index) 83 p_cent=K*rho_cent**(1d0+1d0/poly_index) 86 !Calculate polytrope physical radius 87 R_outer=a_scale*xi_last 84 88 85 !Start solution at small positive xi 86 xi=1e-4 87 theta=1-(xi**2.0)/6.0+(poly_index/120.0)*(xi**4.0)-(8.0*poly_index**2.0-5.0*poly_index)/(15120.0)*(xi**5.0) 89 !Determine number of points based on resolution with a minimum of 1000 90 nPoints=max(ceiling(R_outer/(levels(maxLevel)%dx*lScale)),999)+1 91 92 !Physical step size between profile points 93 h=R_outer/real(nPoints-1) 94 write(*,*) "step size h: ",h 95 96 !Construct Profile Object and initialize default values for no polytrope 97 CALL CreateProfile(Profile, nPoints, (/Mass_Field, P_Field, Temp_Field/), RADIAL) 98 Profile%data(:,1)=h*(/(i-1,i=1,nPoints)/) 99 Profile%data(:,2:4)=0d0 100 101 !Calculate central pressure 102 p_cent=4d0*Pi*G*(a_scale**2)*(rho_cent**2)/(poly_index+1d0) 103 write(*,*) "p_cent: ", p_cent 104 105 !Initialize center cell 106 profile%data(1,1:3)=(/0d0, rho_cent, p_cent/) 107 108 109 !Start solution at small positive xi - but don't go past 1st point 110 xi=min(h, 1d-4) 111 theta=1d0-(xi**2.0)/6.0+(poly_index/120.0)*(xi**4.0)-(8.0*poly_index**2.0-5.0*poly_index)/(15120.0)*(xi**5.0) 88 112 dtheta=-xi/3.0+(poly_index/30.0)*(xi**3.0)-(8.0*poly_index**2.0-5.0*poly_index)/(2520.0)*(xi**5.0) 89 90 !Integrate to first profile zone 91 dxi=.5*(h/a_scale)-xi 92 nsteps=ceiling(dxi/.01) 93 ddxi=dxi/nsteps 94 DO j=1,nsteps 95 CALL LE_Advance(xi, theta, dtheta, ddxi) 96 END DO 113 dxi=h/a_scale-xi 97 114 115 !Advance to second profile point 116 write(*,*), "dxi: ",dxi 117 CALL LE_Advance(xi,dtheta,poly_index,theta,dxi,100,theta_target) 118 write(*,*),"xi...WORK",xi 119 profile%data(2,1:3)=(/xi*a_scale,rho_cent*theta**poly_index, p_cent*theta**(poly_index+1d0)/) 98 120 99 121 !Calculate step sizes for rest of profile 100 122 dxi=h/a_scale 101 nsteps=ceiling(h/a_scale/dxi) 102 ddxi=dxi/nsteps 103 104 data(:,1)=h*(/(i,i=1,npoints)/)-.5*h 105 data(:,2:3)=0 123 write(*,*) "dxi for rest of profile: ", dxi 106 124 107 125 !Initialize profile 108 DO i=1, size(data, 1) 109 ! Convert from dimenionless to computational units 110 data(i,2)=rho_cent*theta**poly_index 111 data(i,3)=k*data(i,2)**(1d0+1d0/poly_index) 112 113 DO j=1,nsteps 114 !backup values for theta, xi, dtheta in case we overshoot 115 theta_last=theta 116 xi_last=xi 117 dtheta_last=dtheta 118 119 !Advance to next position 120 CALL LE_Advance(xi, theta, dtheta, ddxi) 121 IF (theta < 0d0) EXIT 122 END DO 123 IF (theta < 0d0) EXIT 126 DO i=2, size(Profile%data, 1) 127 CALL LE_ADvance(xi,dtheta,poly_index,theta,dxi,100,theta_target) 128 Profile%data(i,1:3)=(/xi*a_scale,rho_cent*theta**poly_index,p_cent*theta**(poly_index+1d0)/) 129 ! Print *, "Density: ", Profile%data(i,2) 130 ! IF (theta <= theta_target) EXIT 124 131 END DO 125 126 ! 127 dtheta = dtheta - (xi-xi_last)*(dtheta-dtheta_last)/ddxi 128 xi = xi + (theta/(theta_last-theta))*ddxi 129 theta=0d0 130 131 M_star=4d0*pi*rho_cent*(R_star**3)*(-1d0/xi_last)*(dtheta) 132 132 theta=theta_target 133 Print *, xi 134 profile%data(:,4)=profile%data(:,3)/profile%data(:,2) * Xmu*Hmass/Boltzmann 135 133 136 IF (MPI_ID == 0) THEN 134 137 print*,'final value for xi',xi 135 138 print*,'final value for theta',theta 136 139 print*,'final value for dtheta/dphi',dtheta 137 138 print*, 'first root of phi at xi=',xi139 print*, 'at this point dtheta/dt = ',dtheta140 140 END IF 141 142 141 143 END SUBROUTINE ConstructPolyTropeProfile 142 144 143 SUBROUTINE LE_Advance(xi,dtheta,poly_index,theta,h) 144 Real:: xi, dtheta, poly_index, theta, h 145 REAL :: k1(2), k2(2),k3(2),k4(2),g(2) 145 SUBROUTINE LE_Advance(xi,dtheta,poly_index,theta,step,nsteps,theta_target) 146 REAL(KIND=QPREC):: xi, dtheta, poly_index, theta, h, step, theta_target 147 REAL(KIND=QPREC) :: k1(2), k2(2),k3(2),k4(2) 148 REAL(KIND=QPREC), Dimension(2) :: g 149 REAL(KIND=QPREC) :: stepsize 150 INTEGER :: i,nsteps 151 IF (theta <= theta_target) THEN !use zero value for outside of polytrope 152 xi=xi+step 153 theta=theta_target 154 RETURN 155 END IF 156 h=step/real(nsteps) 157 DO i=1,nsteps 158 g=(/theta, dtheta/) 159 k1=h*f(poly_index,xi,g) 160 k2=h*f(poly_index,xi+h/2.0,g+k1/2.0) 161 k3=h*f(poly_index,xi+h/2.0,g+k2/2.0) 162 k4=h*f(poly_index,xi+h,g+k3) 146 163 147 g=(/theta, dtheta/) 148 k1=h*f(poly_index,xi,g) 149 k2=h*f(poly_index,xi+h/2.0,g+k1/2d0) 150 k3=h*f(poly_index,xi+h/2.0,g+k2/2d0) 151 k4=h*f(poly_index,xi+h,g+k3) 164 g=g+(k1+2.0*k2+2.0*k3+k4)/6.0 152 165 153 g=g+(k1+2.0*k2+2.0*k3+k4)/6.0 154 theta=g(1) 155 dtheta=g(2) 156 xi=xi+h 166 IF (g(1) <= theta_target .OR. ISNAN(g(1))) THEN !use previous values to estimate root 167 xi = xi - ((theta-theta_target)/dtheta) 168 theta=theta_target 169 EXIT 170 END IF 171 theta=g(1) 172 dtheta=g(2) 173 xi=xi+h 174 END DO 157 175 end SUBROUTINE LE_Advance 158 176 … … 162 180 function f(poly_index,xi,g) 163 181 implicit none 164 real poly_index,xi,g(2), f(2) 182 REAL(KIND=qPREC) poly_index,xi, f(2) 183 REAL(KIND=qPREC), dimension(2) :: g 165 184 f(1)=g(2) 166 185 f(2)=-g(1)**poly_index-2.0*g(2)/xi 167 186 end function f 168 169 170 171 172 173 174 175 187 END MODULE LE_module }}} 188