42 | | The state vectors W,,L,, and W,,R,, are created with overloaded constructors that also calculate useful parameters A and B and the speed of sound c for use later in the program. |
43 | | |
| 42 | The state vectors W,,L,, and W,,R,, are created with overloaded constructors that also calculate useful parameters A and B and the speed of sound c for use later in the program. (Note code between comment lines is excerpted from its actual location.) |
| 43 | |
| 44 | {{{#!fortran |
| 45 | L = region(rhoL,uL,pL) |
| 46 | R = region(rhoR,uR,pR) |
| 47 | |
| 48 | !∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨ |
| 49 | function ConstructRegion(rho,u,p) |
| 50 | |
| 51 | ConstructRegion%W(irho) = rho |
| 52 | ConstructRegion%W(iu) = u |
| 53 | ConstructRegion%W(ip) = p |
| 54 | ConstructRegion%A = 2/((gamma + 1)*ConstructRegion%W(irho)) |
| 55 | ConstructRegion%B = (gamma - 1)*ConstructRegion%W(ip)/(gamma + 1) |
| 56 | ConstructRegion%c = sqrt(gamma*ConstructRegion%W(ip)/ConstructRegion%W(irho)) |
| 57 | !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 58 | |
| 59 | call validate(L,R) |
| 60 | |
| 61 | !∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨ |
| 62 | validate(L,R) |
| 63 | |
| 64 | critdiff = 2.*L%c/(gamma - 1.) + 2.*R%c/(gamma - 1.) ! Difference between right and left velocities must be strictly less than this to prevent vacuum formation |
| 65 | |
| 66 | if (critdiff <= R%W(iu) - L%W(iu)) then |
| 67 | print *, 'Vacuum results from these initial states. Exiting.' |
| 68 | stop |
| 69 | end if |
| 70 | !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 71 | }}} |
| 97 | The velocity and densities for the star regions can then be calculated: |
| 98 | |
| 99 | {{{#!fortran |
| 100 | ! Calculates velocity in star region |
| 101 | exactVelocity(L,R,pstar) |
| 102 | |
| 103 | exactVelocity = 0.5*(L%W(iu) + R%W(iu)) + 0.5*(f(pstar,R) - f(pstar,L)) ! Velocity in star region is the same on either side of CD |
| 104 | |
| 105 | !---------------------------------------- |
| 106 | |
| 107 | ! Calculates densities in star regions |
| 108 | exactDensity(starReg,reg) |
| 109 | |
| 110 | ! Density is different for shocks and rarefactions - may differ on either side of CD |
| 111 | if (starReg%W(ip) > reg%W(ip)) then |
| 112 | exactDensity = reg%W(irho)*((gamma - 1.)/(gamma + 1.) + (starReg%W(ip)/reg%W(ip)))/(((gamma - 1.)/(gamma + 1.))*(starReg%W(ip)/reg%W(ip)) + 1.) |
| 113 | else |
| 114 | exactDensity = reg%W(irho)*(starReg%W(ip)/reg%W(ip))**(1./gamma) |
| 115 | end if |
| 116 | }}} |
| 117 | |
| 118 | The final value of pstar is printed to console, then output is written to files, one for each time state requested. During output, the speeds of shocks and rarefaction boundaries are calculated: |
| 119 | |
| 120 | {{{#!fortran |
| 121 | SL = L%W(iu) - L%c*sqrt((gamma + 1)*Lstar%W(ip)/(2*gamma*L%W(ip)) + (gamma - 1)/(2*gamma)) ! Left shock speed |
| 122 | SHL = L%W(iu) - L%c ! Head speed of left rarefaction |
| 123 | STL = Lstar%W(iu) - L%c*(Lstar%W(ip)/L%W(ip))**((gamma - 1)/(2*gamma)) ! Tail speed of left rarefaction |
| 124 | SR = R%W(iu) + R%c*sqrt((gamma + 1)*Rstar%W(ip)/(2*gamma*R%W(ip)) + (gamma - 1)/(2*gamma)) ! right |
| 125 | SHR = R%W(iu) + R%c ! right |
| 126 | STR = Rstar%W(iu) + R%c*(Lstar%W(ip)/L%W(ip))**((gamma - 1)/(2*gamma)) ! right |
| 127 | }}} |
| 128 | |
| 129 | Then a large conditional is entered to determine which region we are sampling at the given time and position: |
| 130 | |
| 131 | {{{#!fortran |
| 132 | ! End once t > finaltime (last output will be t = finaltime) |
| 133 | do while (t <= finaltime) |
| 134 | !print fileformat, "out/result",frame,".dat" |
| 135 | write(filename,fileformat) "out/result",frame,".dat" ! filename to output - goes to out/resultxxxxx.dat |
| 136 | open(unit=40,file=filename,iostat=stat,status='replace') |
| 137 | write (40,*) 'x rho u p' ! write column headers |
| 138 | x = xL |
| 139 | ! Calculate values for each position - similar to time above |
| 140 | !!! could parallelize if I changed from while to for loop |
| 141 | do while (x <= xR) |
| 142 | if (t == 0) then !initial state (so we don't divide by zero) |
| 143 | if (x < 0) write (40,*) x, L%W |
| 144 | if (x > 0) write (40,*) x, R%W |
| 145 | if (x == 0) write (40,*) x, 0, 0, 0 |
| 146 | else |
| 147 | if (x/t <= Lstar%W(iu)) then !left side of contact |
| 148 | lright = .false. |
| 149 | if (Lstar%W(ip) > L%W(ip)) then !shock on left side |
| 150 | if (x/t <= SL) then !left side of shock |
| 151 | write (40,*) x, L%W |
| 152 | else |
| 153 | write (40,*) x, Lstar%W |
| 154 | end if |
| 155 | else !rarefaction on left side |
| 156 | if (x/t <= SHL) then !left of the rarefaction fan |
| 157 | write (40,*) x, L%W |
| 158 | else if (x/t >= STL) then !right of the rarefaction fan |
| 159 | write (40,*) x, Lstar%W |
| 160 | else !in rarefaction fan |
| 161 | call rarefaction(L,x,t,Wfan,lright) |
| 162 | |
| 163 | !∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨ |
| 164 | rarefaction(reg,x,t,Wfan,lright) |
| 165 | |
| 166 | ! Rarefaction fan differs depending on whether it's a right or left rarefaction |
| 167 | if (.not. lright) then |
| 168 | Wfan(irho) = reg%W(irho)*(2/(gamma + 1) + (gamma - 1)*(reg%W(iu) - x/t)/((gamma + 1)*reg%c))**(2/(gamma + 1)) |
| 169 | Wfan(iu) = (2/(gamma + 1))*(reg%c + (gamma - 1)*reg%W(iu)/2 + x/t) |
| 170 | Wfan(ip) = reg%W(ip)*(2/(gamma + 1) + (gamma - 1)*(reg%W(iu) - x/t)/((gamma + 1)*reg%c))**(2*gamma/(gamma + 1)) |
| 171 | else |
| 172 | Wfan(irho) = reg%W(irho)*(2/(gamma + 1) - (gamma - 1)*(reg%W(iu) - x/t)/((gamma + 1)*reg%c))**(2/(gamma + 1)) |
| 173 | Wfan(iu) = (2/(gamma + 1))*(-reg%c + (gamma - 1)*reg%W(iu)/2 + x/t) |
| 174 | Wfan(ip) = reg%W(ip)*(2/(gamma + 1) - (gamma - 1)*(reg%W(iu) - x/t)/((gamma + 1)*reg%c))**(2*gamma/(gamma + 1)) |
| 175 | end if |
| 176 | !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 177 | |
| 178 | write (40,*) x, Wfan |
| 179 | end if |
| 180 | end if |
| 181 | ! Repeat entire sequence above for right side (lright = .true.) |
| 182 | end if |
| 183 | end if |
| 184 | x = x + dx ! increment x to next position |
| 185 | end do |
| 186 | t = t + dt ! increment t to next time |
| 187 | frame = frame + 1 ! update frame counter |
| 188 | end do |
| 189 | }}} |
| 190 | |
| 191 | These output files can then be processed by VisIt, Mathematica, etc. to make nice pictures. |
| 192 | |
| 193 | == Deriving the function f and the Newton-Raphson procedure == |
| 194 | {{{#!comment |
| 195 | Really these should be two separate sections, but I already had a nice transition between them. |
| 196 | }}} |
| 197 | |
| 198 | === f === |
| 199 | |