| | 2 | |
| | 3 | == Examples == |
| | 4 | === 1). Extracted Subroutine === |
| | 5 | File: ../source/physics/Eos/EosMain/Eos_getData/Eos_getData_loop1.F90 |
| | 6 | |
| | 7 | {{{ |
| | 8 | !!****if* source/physics/Eos/EosMain/Eos_getData |
| | 9 | !! NAME |
| | 10 | !! |
| | 11 | !! Eos_getData |
| | 12 | !! |
| | 13 | !! SYNOPSIS |
| | 14 | !! |
| | 15 | !! call Eos_getData( integer(IN) :: range(LOW:HIGH,MDIM), |
| | 16 | !! integer(IN) :: vecLen, |
| | 17 | !! real, pointer :: solnData(:,:,:,:), |
| | 18 | !! integer(IN) :: gridDataStruct, |
| | 19 | !! real(INOUT),dimension(EOS_NUM*vecLen) :: eosData(*), |
| | 20 | !! optional,real(OUT) :: massFrac(:), |
| | 21 | !! optional,logical(INOUT) :: eosMask(EOS_VARS+1:) ) |
| | 22 | !! |
| | 23 | !! DESCRIPTION |
| | 24 | !! |
| | 25 | !! Eos_getData gets data from a Grid data structure into an eosData array, for |
| | 26 | !! passing to a subsequent Eos call. Additionally, mass fractions from the Grid |
| | 27 | !! data structure may be extracted to the optional massFrac argument array. |
| | 28 | !! |
| | 29 | !! The Eos_wrapped function is provided for the user's convenience and acts as a simple |
| | 30 | !! wrapper to the Eos interface. The Eos interface uses a single, flexible data |
| | 31 | !! structure "eosData" to pass the thermodynamic quantities in and out of the |
| | 32 | !! function (see Eos). The wrapper hides formation and use of eosData |
| | 33 | !! from the users. The wrapper function uses the Eos_getData function to construct the |
| | 34 | !! data structure eosData. |
| | 35 | !! |
| | 36 | !! While Eos does not know anything about blocks, Eos_getData takes its |
| | 37 | !! input thermodynamic state variables from a given block's storage area, |
| | 38 | !! a vector at a time. It works by taking a selected vector of a block |
| | 39 | !! described by the arguments axis, pos and vecLen. |
| | 40 | !! |
| | 41 | !! |
| | 42 | !! ARGUMENTS |
| | 43 | !! |
| | 44 | !! |
| | 45 | !! range : the bounds of the section that we are flattening |
| | 46 | !! vecLen : the length of the vector |
| | 47 | !! solnData: data from the current block; unmodified on return. |
| | 48 | !! various components (variables) of solnData will determine the |
| | 49 | !! contents of eosData. |
| | 50 | !! gridDataStruct : the relevant grid data structure, on whose data Eos was applied. |
| | 51 | !! One of CENTER, FACEVAR{X,Y,Z}, GRIDVAR, defined in constants.h . |
| | 52 | !! eosData : the data structure native to the Eos unit; input and to Eos() as |
| | 53 | !! well as output from Eos(). |
| | 54 | !! massFrac : this is an optional argument which is used when there is more |
| | 55 | !! than one species in the simulation |
| | 56 | !! eosMask : if the caller passes in an eosMask array, Eos_getData may modify |
| | 57 | !! this mask for the following Eos() calls, probably removing |
| | 58 | !! some of the requested derived quantities. |
| | 59 | !! Not used in the current implementation. |
| | 60 | !! |
| | 61 | !! EXAMPLE |
| | 62 | !! if axis = IAXIS, pos(IAXIS)=1,pos(JAXIS)=1,pos(KAXIS)=1 and vecLen=4 |
| | 63 | !! then Eos is to be applied to four cells in the first row along IAXIS |
| | 64 | !! of the lower left hand corner of the guard cells in the block. |
| | 65 | !! |
| | 66 | !! However if the value were |
| | 67 | !! pos(IAXIS)=iguard+1, |
| | 68 | !! pos(JAXIS)=jguard+1, |
| | 69 | !! pos(KAXIS)=kguard+1, vecLen = NYB, and axis = JAXIS |
| | 70 | !! then Eos is applied to the first column along Y axis in the interior of the block. |
| | 71 | !! |
| | 72 | !! NOTES |
| | 73 | !! |
| | 74 | !! This interface is called from Eos_wrappped, and is normally not called |
| | 75 | !! by user code directly. |
| | 76 | !! |
| | 77 | !! The actual arguments in a call should match those used in a subsequent |
| | 78 | !! Eos_putData call that will extract results from the Eos() call out of |
| | 79 | !! the eosData array. |
| | 80 | !! |
| | 81 | !! This interface is defined in Fortran Module |
| | 82 | !! Eos_interface. All functions calling this routine should include |
| | 83 | !! a statement like |
| | 84 | !! use Eos_interface, ONLY : Eos_putData |
| | 85 | !! |
| | 86 | !! This routine cannot use "INTERIOR" mode of indexing the range. In the |
| | 87 | !! second example given above, although only the interior cells are being |
| | 88 | !! calculated with EOS, the range indices still must include the guard cells. |
| | 89 | !! See, for example, IsentropicVortex/Simulation_initBlock where the data is |
| | 90 | !! generated on INTERIOR cells with Grid_putRowData, but the same indices can't |
| | 91 | !! be used for the EOS call. |
| | 92 | !! |
| | 93 | !! SEE ALSO |
| | 94 | !! |
| | 95 | !! Eos |
| | 96 | !! Eos_putData |
| | 97 | !! Eos.h |
| | 98 | !! |
| | 99 | !! |
| | 100 | !!*** |
| | 101 | |
| | 102 | ! solnData depends on the ordering on unk |
| | 103 | !!REORDER(4): solnData |
| | 104 | |
| | 105 | |
| | 106 | subroutine Eos_getData(range,vecLen,solnData,gridDataStruct,eosData,massFrac, eosMask) |
| | 107 | |
| | 108 | use Eos_data, ONLY: eos_eintSwitch, eos_smalle, eos_mapLookup |
| | 109 | use Driver_interface, ONLY : Driver_abortFlash |
| | 110 | implicit none |
| | 111 | |
| | 112 | #include "Eos.h" |
| | 113 | #include "Eos_map.h" |
| | 114 | #include "constants.h" |
| | 115 | #include "Flash.h" |
| | 116 | |
| | 117 | integer, intent(in) :: vecLen, gridDataStruct |
| | 118 | integer, dimension(LOW:HIGH,MDIM), intent(in) :: range |
| | 119 | real, dimension(EOS_NUM*vecLen),intent(INOUT) :: eosData |
| | 120 | real,dimension(:),optional,intent(OUT) :: massFrac |
| | 121 | logical, optional, INTENT(INOUT),dimension(EOS_VARS+1:) :: eosMask |
| | 122 | real, pointer:: solnData(:,:,:,:) |
| | 123 | |
| | 124 | |
| | 125 | integer :: i,j,k,n,m,pres,dens,gamc,temp,abar,zbar,eint,ekin,entr |
| | 126 | integer :: pres_map,dens_map,gamc_map,game_map,temp_map,entr_map |
| | 127 | integer :: eint_map,ener_map, velx_map, vely_map, velz_map, sumy_map, ye_map |
| | 128 | integer :: ib,ie,jb,je,kb,ke |
| | 129 | real :: kineticEnergy, internalEnergy |
| | 130 | !! --------------------------------------------------------------------------------- |
| | 131 | ! Test calling arguments |
| | 132 | |
| | 133 | ! Initializations: grab the solution data from UNK and determine |
| | 134 | ! the length of the data being operated upon |
| | 135 | |
| | 136 | ib=range(LOW,IAXIS) |
| | 137 | jb=range(LOW,JAXIS) |
| | 138 | kb=range(LOW,KAXIS) |
| | 139 | ie=range(HIGH,IAXIS) |
| | 140 | je=range(HIGH,JAXIS) |
| | 141 | ke=range(HIGH,KAXIS) |
| | 142 | !!$ select case(axis) |
| | 143 | !!$ case(IAXIS) |
| | 144 | !!$ ie=ie+vecLen-1 |
| | 145 | !!$ case(JAXIS) |
| | 146 | !!$ je=je+vecLen-1 |
| | 147 | !!$ case(KAXIS) |
| | 148 | !!$ ke=ke+vecLen-1 |
| | 149 | !!$ end select |
| | 150 | ! These integers are indexes into the location in eosData just before the storage area for the appropriate variable. |
| | 151 | pres = (EOS_PRES-1)*vecLen |
| | 152 | dens = (EOS_DENS-1)*vecLen |
| | 153 | temp = (EOS_TEMP-1)*vecLen |
| | 154 | gamc = (EOS_GAMC-1)*vecLen |
| | 155 | eint = (EOS_EINT-1)*vecLen |
| | 156 | ekin = (EOS_EKIN-1)*vecLen |
| | 157 | abar = (EOS_ABAR-1)*vecLen |
| | 158 | zbar = (EOS_ZBAR-1)*vecLen |
| | 159 | entr = (EOS_ENTR-1)*vecLen |
| | 160 | |
| | 161 | pres_map = eos_mapLookup(EOSMAP_PRES,EOS_IN,gridDataStruct) |
| | 162 | dens_map = eos_mapLookup(EOSMAP_DENS,EOS_IN,gridDataStruct) |
| | 163 | temp_map = eos_mapLookup(EOSMAP_TEMP,EOS_IN,gridDataStruct) |
| | 164 | gamc_map = eos_mapLookup(EOSMAP_GAMC,EOS_IN,gridDataStruct) |
| | 165 | game_map = eos_mapLookup(EOSMAP_GAME,EOS_IN,gridDataStruct) |
| | 166 | eint_map = eos_mapLookup(EOSMAP_EINT,EOS_IN,gridDataStruct) |
| | 167 | ener_map = eos_mapLookup(EOSMAP_ENER,EOS_IN,gridDataStruct) |
| | 168 | velx_map = eos_mapLookup(EOSMAP_VELX,EOS_IN,gridDataStruct) |
| | 169 | vely_map = eos_mapLookup(EOSMAP_VELY,EOS_IN,gridDataStruct) |
| | 170 | velz_map = eos_mapLookup(EOSMAP_VELZ,EOS_IN,gridDataStruct) |
| | 171 | sumy_map = eos_mapLookup(EOSMAP_SUMY,EOS_IN,gridDataStruct) |
| | 172 | ye_map = eos_mapLookup(EOSMAP_YE, EOS_IN,gridDataStruct) |
| | 173 | entr_map = eos_mapLookup(EOSMAP_ENTR,EOS_IN,gridDataStruct) |
| | 174 | |
| | 175 | if(gridDataStruct == SCRATCH) then |
| | 176 | call Driver_abortFlash("Eos_getData : the use of SCRATCH is deprecated") |
| | 177 | end if |
| | 178 | |
| | 179 | if(present(massFrac)) then |
| | 180 | m=1 |
| | 181 | do k = kb,ke |
| | 182 | do j = jb,je |
| | 183 | do i = ib,ie |
| | 184 | do n = SPECIES_BEGIN,SPECIES_END |
| | 185 | massFrac(m) = solnData(n,i,j,k) |
| | 186 | m=m+1 |
| | 187 | end do |
| | 188 | end do |
| | 189 | end do |
| | 190 | end do |
| | 191 | end if |
| | 192 | |
| | 193 | n = 0 |
| | 194 | !! DEV: If / when we add a ptr dummy argument for passing in an offset, this will be n = ptr |
| | 195 | do k = kb,ke |
| | 196 | do j = jb,je |
| | 197 | do i = ib,ie |
| | 198 | if (velx_map > 0 .AND. vely_map > 0 .AND. velz_map > 0) then |
| | 199 | kineticEnergy = 0.5*(solnData(velx_map,i,j,k)**2 + & |
| | 200 | solnData(vely_map,i,j,k)**2 + & |
| | 201 | solnData(velz_map,i,j,k)**2) |
| | 202 | else |
| | 203 | kineticEnergy = 0.0 |
| | 204 | end if |
| | 205 | |
| | 206 | n=n+1 |
| | 207 | eosData(ekin+n) = kineticEnergy |
| | 208 | !! kineticEnergy holds velocity vector information -- 1/2 * Vmag**2 |
| | 209 | !! internalEnergy holds eint (directly) or energyTotal - ekinetic (calculated), |
| | 210 | !! depending upon eintSwitch |
| | 211 | if(eint_map /= NONEXISTENT) then |
| | 212 | internalEnergy = solnData(eint_map,i,j,k) |
| | 213 | if(ener_map /= NONEXISTENT) then |
| | 214 | if ( solnData(ener_map,i,j,k) - kineticEnergy > max(eos_smalle, eos_eintSwitch*kineticEnergy)) then |
| | 215 | internalEnergy = solnData(ener_map,i,j,k) - kineticEnergy |
| | 216 | end if |
| | 217 | end if |
| | 218 | else if(game_map /= NONEXISTENT) then ! This case should be usable for R(elativistic)HD - KW |
| | 219 | internalEnergy = solnData(pres_map,i,j,k) / solnData(dens_map,i,j,k) / & |
| | 220 | (solnData(game_map,i,j,k) - 1.0) |
| | 221 | if(ener_map /= NONEXISTENT) then |
| | 222 | if ( solnData(ener_map,i,j,k) - kineticEnergy > max(eos_smalle, eos_eintSwitch*kineticEnergy)) then |
| | 223 | internalEnergy = solnData(ener_map,i,j,k) - kineticEnergy |
| | 224 | end if |
| | 225 | end if |
| | 226 | else if(ener_map /= NONEXISTENT) then |
| | 227 | internalEnergy = solnData(ener_map,i,j,k)-kineticEnergy |
| | 228 | else |
| | 229 | internalEnergy = eos_smalle |
| | 230 | endif |
| | 231 | |
| | 232 | internalEnergy = max(internalEnergy, eos_smalle) |
| | 233 | eosData(eint+n) = internalEnergy |
| | 234 | |
| | 235 | eosData(pres+n) = solnData(pres_map,i,j,k) |
| | 236 | eosData(dens+n) = solnData(dens_map,i,j,k) |
| | 237 | eosData(temp+n) = solnData(temp_map,i,j,k) |
| | 238 | eosData(gamc+n) = solnData(gamc_map,i,j,k) |
| | 239 | if((ye_map /= NONEXISTENT).and.(sumy_map /= NONEXISTENT)) then |
| | 240 | !! cal says abar=1/sumy |
| | 241 | !! cal says zbar=ye / sumy and he claims sumy are never zero |
| | 242 | eosData(abar+n) = 1.0 / solnData(sumy_map,i,j,k) |
| | 243 | eosData(zbar+n) = solnData(ye_map,i,j,k) / solnData(sumy_map,i,j,k) |
| | 244 | endif |
| | 245 | if(entr_map /= NONEXISTENT) eosData(entr+n) = solnData(entr_map,i,j,k) |
| | 246 | end do |
| | 247 | end do |
| | 248 | end do |
| | 249 | |
| | 250 | return |
| | 251 | end subroutine Eos_getData |
| | 252 | }}} |