Changes between Version 2 and Version 3 of u/adebrech/code


Ignore:
Timestamp:
03/15/17 18:21:33 (8 years ago)
Author:
adebrech
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • u/adebrech/code

    v2 v3  
    4040}}}
    4141
    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 
     42The 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
     45L = region(rhoL,uL,pL)
     46R = region(rhoR,uR,pR)
     47
     48!∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨
     49function ConstructRegion(rho,u,p)
     50       
     51ConstructRegion%W(irho) = rho
     52ConstructRegion%W(iu) = u
     53ConstructRegion%W(ip) = p
     54ConstructRegion%A = 2/((gamma + 1)*ConstructRegion%W(irho))
     55ConstructRegion%B = (gamma - 1)*ConstructRegion%W(ip)/(gamma + 1)
     56ConstructRegion%c = sqrt(gamma*ConstructRegion%W(ip)/ConstructRegion%W(irho))
     57!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     58       
     59call validate(L,R)
     60
     61!∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨
     62validate(L,R)
     63
     64critdiff = 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       
     66if (critdiff <= R%W(iu) - L%W(iu)) then
     67 print *, 'Vacuum results from these initial states. Exiting.'
     68 stop
     69end if
     70!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     71}}}
    4472
    4573These state vectors are then passed to the Newton-Raphson solver, which calls a subroutine to guess a good value for p,,0,, (currently not very effective - just uses tol) and then iterates until the tolerance for change in pressure between steps is met.
    4674
    47 
    48 {{{#!latex
    49 $f_reg(p_*) = (p_* - p_reg) [\frac{2}{(\gamma + 1) \rho_reg (p_* + \frac{\gamma - 1}{\gamma + 1} p_reg)}]$
    50 }}}
    51 
     75{{{#!fortran
     76pstar = pguess(L,R)
     77       
     78! do while loop (exits once change is less than tolerance)
     79do
     80 pstar_old = pstar
     81 pstar = pstar_old - ((f(pstar_old,L) + f(pstar_old,R) + R%W(iu)-L%W(iu))/(df(pstar_old,L) + df(pstar_old,R)))          ! Newton-Raphson formula
     82 delta = 2.*abs((pstar - pstar_old)/(pstar + pstar_old))                                                                ! Relative change in pressure from previous iteration
     83 if (delta < tol) exit                                                                                                  ! Exit upon sufficient accuracy
     84end do
     85}}}
     86
     87The functions f and df ($f'$) for either the left or right regions are given by
     88
     89{{{#!latex
     90$f_{reg}(p_*) = \begin{cases} (p_* - p_{reg}) [\frac{A_{reg}}{p_* + B_{reg})}], & p_* > p_{reg} \\ f_{reg}(p_*) = \frac{2 c_{reg}}{\gamma - 1}[(\frac{p_*}{p_{reg}})^{\frac{\gamma - 1}{2 \gamma}} - 1], & p_* \leq p_{reg} \end{cases}$
     91
     92$f'_{reg}(p_*) = \begin{cases} (\frac{A_{reg}}{B_{reg} + p_*})^{\frac{1}{2}}[1 - \frac{p_* - p_{reg}}{2(B_{reg} + p_*)}], & p_* > p_{reg} \\ \frac{1}{\rho_{reg} c_{reg}}(\frac{p_*}{p_{reg}})^{-\frac{\gamma + 1}{2 \gamma}}, & p_* \leq p_{reg} \end{cases}$
     93}}}
    5294
    5395See below for derivation of function f.
    5496
     97The velocity and densities for the star regions can then be calculated:
     98
     99{{{#!fortran
     100! Calculates velocity in star region
     101exactVelocity(L,R,pstar)
     102       
     103exactVelocity = 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
     108exactDensity(starReg,reg)
     109       
     110! Density is different for shocks and rarefactions - may differ on either side of CD
     111if (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.)
     113else
     114 exactDensity = reg%W(irho)*(starReg%W(ip)/reg%W(ip))**(1./gamma)
     115end if
     116}}}
     117
     118The 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
     121SL = L%W(iu) - L%c*sqrt((gamma + 1)*Lstar%W(ip)/(2*gamma*L%W(ip)) + (gamma - 1)/(2*gamma))      ! Left shock speed
     122SHL = L%W(iu) - L%c                                                                             ! Head speed of left rarefaction
     123STL = Lstar%W(iu) - L%c*(Lstar%W(ip)/L%W(ip))**((gamma - 1)/(2*gamma))                          ! Tail speed of left rarefaction
     124SR = R%W(iu) + R%c*sqrt((gamma + 1)*Rstar%W(ip)/(2*gamma*R%W(ip)) + (gamma - 1)/(2*gamma))      ! right
     125SHR = R%W(iu) + R%c                                                                             ! right
     126STR = Rstar%W(iu) + R%c*(Lstar%W(ip)/L%W(ip))**((gamma - 1)/(2*gamma))                          ! right
     127}}}
     128
     129Then 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)
     133do 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!∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨
     164rarefaction(reg,x,t,Wfan,lright)
     165
     166! Rarefaction fan differs depending on whether it's a right or left rarefaction
     167if (.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))
     171else
     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))
     175end 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
     188end do
     189}}}
     190
     191These 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
     195Really these should be two separate sections, but I already had a nice transition between them.
     196}}}
     197
     198=== f ===
     199
    55200From the shock jump conditions
    56201
     
    97242The same analysis can be performed on the right side of the system to yield the same results.
    98243
     244=== Newton-Raphson ===
     245
    99246The Riemann problem can then be solved by finding the value $p = p_*$ such that
    100247