hydrostatic.F90       coverage:  50.00 %func     45.69 %block


     1) module Hydrostatic_module
     2)  
     3)   use PFLOTRAN_Constants_module
     4) 
     5)   implicit none
     6) 
     7)   private
     8) 
     9) #include "petsc/finclude/petscsys.h"
    10) 
    11)   public :: HydrostaticUpdateCoupler, &
    12)             HydrostaticTest
    13)  
    14) contains
    15) 
    16) ! ************************************************************************** !
    17) 
    18) subroutine HydrostaticUpdateCoupler(coupler,option,grid)
    19)   ! 
    20)   ! Computes the hydrostatic initial/boundary
    21)   ! condition
    22)   ! 
    23)   ! Author: Glenn Hammond
    24)   ! Date: 11/28/07
    25)   ! 
    26) 
    27)   use EOS_Water_module
    28) 
    29)   use Option_module
    30)   use Grid_module
    31)   use Coupler_module
    32)   use Condition_module
    33)   use Connection_module
    34)   use Region_module
    35)   use Grid_Structured_module
    36)   use Utility_module, only : DotProduct
    37)   use Dataset_Gridded_HDF5_class
    38)   use Dataset_Ascii_class
    39)   
    40)   use General_Aux_module
    41)   use TOilIms_Aux_module
    42)   
    43)   implicit none
    44) 
    45)   type(coupler_type) :: coupler
    46)   type(option_type) :: option
    47)   type(grid_type) :: grid
    48)   
    49)   PetscInt :: local_id, ghosted_id, iconn
    50)   PetscInt :: num_iteration, ipressure, idatum, num_pressures
    51)   PetscReal :: dist_x, dist_y, dist_z, delta_z, dist_z_for_pressure
    52)   PetscReal :: dx_conn, dy_conn, dz_conn
    53)   PetscReal :: rho_kg, rho_one, rho_zero, pressure, pressure0, pressure_at_datum
    54)   PetscReal :: temperature_at_datum, temperature
    55)   PetscReal :: concentration_at_datum
    56)   PetscReal :: gas_pressure
    57)   PetscReal :: xm_nacl
    58)   PetscReal :: max_z, min_z, temp_real
    59)   PetscInt :: num_faces, face_id_ghosted, conn_id, num_regions
    60)   type(connection_set_type), pointer :: conn_set_ptr
    61)   PetscReal, pointer :: pressure_array(:)
    62)   PetscReal, allocatable :: density_array(:), z(:)
    63)   PetscReal :: pressure_gradient(3), piezometric_head_gradient(3), datum(3)
    64)   PetscReal :: temperature_gradient(3), concentration_gradient(3)
    65)   PetscReal :: gravity_magnitude
    66)   PetscReal :: z_offset
    67)   PetscReal :: aux(1), dummy
    68)   PetscErrorCode :: ierr
    69)   
    70)   class(dataset_gridded_hdf5_type), pointer :: datum_dataset
    71)   PetscReal :: datum_dataset_rmax
    72)   PetscReal :: datum_dataset_rmin
    73)   
    74)   type(flow_condition_type), pointer :: condition
    75)   
    76)   type(connection_set_type), pointer :: cur_connection_set
    77)   
    78)   condition => coupler%flow_condition
    79)   
    80)   xm_nacl = option%m_nacl * FMWNACL
    81)   xm_nacl = xm_nacl /(1.d3 + xm_nacl)
    82)   aux(1) = xm_nacl
    83)   
    84)   nullify(pressure_array)
    85)   nullify(datum_dataset)
    86)   
    87)   delta_z = min((grid%z_max_global-grid%z_min_global)/500.d0,1.d0)
    88)   ! if zero, assign 1.d0 to avoid divide by zero below. essentially the grid
    89)   ! is flat.
    90)   if (delta_z < 1.d-40) delta_z = 1.d0
    91)   temperature_at_datum = option%reference_temperature
    92)   concentration_at_datum = 0.d0
    93)   datum = 0.d0
    94) 
    95)   gas_pressure = 0.d0
    96)   pressure_gradient = 0.d0
    97)   temperature_gradient = 0.d0
    98)   piezometric_head_gradient = 0.d0
    99)   concentration_gradient = 0.d0
   100)   
   101)   select case(option%iflowmode)
   102)     case(G_MODE)
   103)       temperature_at_datum = &
   104)         condition%general%temperature%dataset%rarray(1)
   105)       if (associated(condition%general%temperature%gradient)) then
   106)         temperature_gradient(1:3) = &
   107)           condition%general%temperature%gradient%rarray(1:3)
   108)       endif
   109)       concentration_at_datum = &
   110)         condition%general%mole_fraction%dataset%rarray(1)
   111)       if (associated(condition%general%mole_fraction%gradient)) then
   112)         concentration_gradient(1:3) = &
   113)         condition%general%mole_fraction%gradient%rarray(1:3)
   114)       endif
   115)       datum(1:3) = condition%datum%rarray(1:3)
   116)       pressure_at_datum = &
   117)         condition%general%liquid_pressure%dataset%rarray(1)    
   118)       gas_pressure = option%reference_pressure
   119)       if (associated(condition%general%gas_pressure)) then
   120)         gas_pressure = condition%general%gas_pressure%dataset%rarray(1)
   121)       endif
   122)       ! gradient is in m/m; needs conversion to Pa/m
   123)       if (associated(condition%general%liquid_pressure%gradient)) then
   124)         piezometric_head_gradient(1:3) = &
   125)           condition%general%liquid_pressure%gradient%rarray(1:3)
   126)       endif
   127)       ! for liquid state
   128)       coupler%flow_aux_mapping(GENERAL_LIQUID_PRESSURE_INDEX) = 1
   129)       coupler%flow_aux_mapping(GENERAL_MOLE_FRACTION_INDEX) = 2
   130)       coupler%flow_aux_mapping(GENERAL_TEMPERATURE_INDEX) = 3
   131)       ! for two-phase state
   132)       coupler%flow_aux_mapping(GENERAL_GAS_PRESSURE_INDEX) = 1
   133)       ! air pressure here is being hijacked to store capillary pressure
   134)       coupler%flow_aux_mapping(GENERAL_AIR_PRESSURE_INDEX) = 2
   135)       coupler%flow_aux_mapping(GENERAL_TEMPERATURE_INDEX) = 3
   136)       coupler%flow_aux_mapping(GENERAL_GAS_SATURATION_INDEX) = 3
   137)     case(TOIL_IMS_MODE)
   138)       temperature_at_datum = &
   139)         condition%toil_ims%temperature%dataset%rarray(1)
   140)       if (associated(condition%toil_ims%temperature%gradient)) then
   141)         temperature_gradient(1:3) = &
   142)           condition%toil_ims%temperature%gradient%rarray(1:3)
   143)       endif
   144)       datum(1:3) = condition%datum%rarray(1:3)
   145)       pressure_at_datum = &
   146)         condition%toil_ims%pressure%dataset%rarray(1)    
   147)       ! gradient is in m/m; needs conversion to Pa/m
   148)       if (associated(condition%toil_ims%pressure%gradient)) then
   149)         piezometric_head_gradient(1:3) = &
   150)           condition%toil_ims%pressure%gradient%rarray(1:3)
   151)       endif
   152)       coupler%flow_aux_mapping(TOIL_IMS_PRESSURE_INDEX) = 1
   153)       coupler%flow_aux_mapping(TOIL_IMS_TEMPERATURE_INDEX) = 3 
   154)     case default
   155)       ! for now, just set it; in future need to account for a different temperature datum
   156)       if (associated(condition%temperature)) then
   157)         if (condition%temperature%itype == DIRICHLET_BC) then
   158) #ifndef THDIRICHLET_TEMP_BC_HACK
   159)           temperature_at_datum = &
   160)             condition%temperature%dataset%rarray(1)
   161) #else
   162)           if (associated(condition%temperature%dataset%rarray)) then
   163)             temperature_at_datum = &
   164)               condition%temperature%dataset%rarray(1)
   165)           else
   166)             temperature_at_datum = option%reference_temperature
   167)           endif
   168) #endif
   169)           if (associated(condition%temperature%gradient)) then
   170)             temperature_gradient(1:3) = &
   171)               condition%temperature%gradient%rarray(1:3)
   172)           endif
   173)         endif
   174)       endif
   175)       if (associated(condition%concentration)) then
   176)         if (condition%concentration%itype == DIRICHLET_BC .and. &
   177)             associated(condition%concentration%dataset)) then
   178)             concentration_at_datum = &
   179)               condition%concentration%dataset%rarray(1)
   180)             if (associated(condition%concentration%gradient)) then
   181)               concentration_gradient(1:3) = &
   182)                 condition%concentration%gradient%rarray(1:3)
   183)             endif
   184)         else
   185)           concentration_at_datum = UNINITIALIZED_DOUBLE
   186)           concentration_gradient = 0.d0
   187)         endif
   188)       endif
   189) 
   190)       if (associated(condition%datum)) then
   191)         nullify(datum_dataset)
   192)         select type(dataset=>condition%datum)
   193)           class is (dataset_ascii_type)
   194)             datum = dataset%rarray(1:3)
   195)           class is (dataset_gridded_hdf5_type)
   196)             datum_dataset => dataset
   197)             ! set datum here equal to estimated mid value of dataset
   198)             datum(1:3) = UNINITIALIZED_DOUBLE
   199)             datum_dataset_rmax = maxval(datum_dataset%rarray)
   200)             datum_dataset_rmin = minval(datum_dataset%rarray)
   201)             datum(3) = 0.5d0*(datum_dataset_rmax+datum_dataset_rmin)
   202)             ! round the number to the nearest whole number
   203)             datum(3) = int(datum(3))
   204)           class default
   205)             option%io_buffer = &
   206)               'Incorrect dataset type in HydrostaticUpdateCoupler. ' // &
   207)               'Dataset "' // trim(condition%datum%name) // '" in file "' // &
   208)               trim(condition%datum%filename) // '".'
   209)             call printErrMsg(option)
   210)         end select
   211)       endif
   212)       pressure_at_datum = &
   213)         condition%pressure%dataset%rarray(1)
   214)       ! gradient is in m/m; needs conversion to Pa/m
   215)       if (associated(condition%pressure%gradient)) then
   216)         piezometric_head_gradient(1:3) = &
   217)           condition%pressure%gradient%rarray(1:3)
   218)       endif
   219)   end select      
   220)       
   221)   call EOSWaterDensityExt(temperature_at_datum,pressure_at_datum, &
   222)                           aux,rho_kg,dummy,ierr)
   223)   
   224)   gravity_magnitude = sqrt(DotProduct(option%gravity,option%gravity))
   225)   
   226)   if (dabs(gravity_magnitude-9.8068d0) > 0.1d0) then
   227)     option%io_buffer = 'Magnitude of gravity vector is not near 9.81.'
   228)     call printErrMsg(option)
   229)   endif
   230)   
   231)   ! if a pressure gradient is prescribed in Z (at this point it will be a
   232)   ! piezometric head gradient), the units of the pressure gradient are
   233)   ! Pa/m and the pressure gradient does not need conversion
   234)   if (dabs(piezometric_head_gradient(Z_DIRECTION)) < 1.d-40) then
   235)     pressure_gradient(1:3) = piezometric_head_gradient(1:3)* &
   236)                              rho_kg*gravity_magnitude
   237)   else
   238)     pressure_gradient(1:3) = piezometric_head_gradient(1:3)
   239)   endif
   240) 
   241)   if (dabs(pressure_gradient(Z_DIRECTION)) < 1.d-40) then
   242)     ! compute the vertical gradient based on a 1 meter vertical spacing and
   243)     ! interpolate the values from that array
   244)     if (associated(datum_dataset)) then
   245)       temp_real = grid%z_max_global - grid%z_min_global
   246)       max_z = max(grid%z_max_global,datum_dataset_rmax+temp_real)+1.d0
   247)       min_z = min(grid%z_min_global,datum_dataset_rmin-temp_real)-1.d0
   248)     else
   249)       max_z = max(grid%z_max_global,datum(Z_DIRECTION))+1.d0 ! add 1m buffer
   250)       min_z = min(grid%z_min_global,datum(Z_DIRECTION))-1.d0
   251)     endif
   252)     
   253)     num_pressures = int((max_z-min_z)/delta_z) + 1
   254)     allocate(pressure_array(num_pressures))
   255)     allocate(density_array(num_pressures))
   256)     allocate(z(num_pressures))
   257)     pressure_array = 0.d0
   258)     density_array = 0.d0
   259)     z = 0.d0
   260)     ! place this pressure in the array
   261)     idatum = int((datum(Z_DIRECTION)-min_z)/(max_z-min_z) * &
   262)                  dble(num_pressures))+1
   263)     pressure_array(idatum) = pressure_at_datum
   264)     call EOSWaterDensityExt(temperature_at_datum,pressure_at_datum, &
   265)                             aux,rho_kg,dummy,ierr)
   266)     temperature = temperature_at_datum
   267)     pressure0 = pressure_at_datum
   268)     density_array(idatum) = rho_kg
   269)     z(idatum) = datum(Z_DIRECTION)
   270)     ! compute pressures above datum, if any
   271)     dist_z = 0.d0
   272)     rho_zero = rho_kg
   273)     do ipressure=idatum+1,num_pressures
   274)       dist_z = dist_z + delta_z
   275)       select case(option%iflowmode)
   276)         case(TH_MODE,MPH_MODE,IMS_MODE,FLASH2_MODE,G_MODE, MIS_MODE, &
   277)              TOIL_IMS_MODE)
   278)           temperature = temperature + temperature_gradient(Z_DIRECTION)*delta_z
   279)       end select
   280)       call EOSWaterDensityExt(temperature,pressure0, &
   281)                               aux,rho_kg,dummy,ierr)
   282)       num_iteration = 0
   283)       do 
   284)         pressure = pressure0 + 0.5d0*(rho_kg+rho_zero) * &
   285)                    option%gravity(Z_DIRECTION) * delta_z
   286)         call EOSWaterDensityExt(temperature,pressure,aux,rho_one,dummy,ierr)
   287) !geh        call EOSWaterDensityNaCl(temperature,pressure,xm_nacl,rho_one) 
   288)         if (dabs(rho_kg-rho_one) < 1.d-10) exit
   289)         rho_kg = rho_one
   290)         num_iteration = num_iteration + 1
   291)         if (num_iteration > 100) then
   292)           print *,'Hydrostatic iteration failed to converge',num_iteration,rho_one,rho_kg
   293)           print *, condition%name, idatum
   294)           print *, pressure_array
   295)           stop
   296)         endif
   297)       enddo
   298)       rho_zero = rho_kg
   299)       pressure_array(ipressure) = pressure
   300)       density_array(ipressure) = rho_kg
   301)       z(ipressure) = z(idatum)+dist_z
   302)       pressure0 = pressure
   303)     enddo
   304) 
   305)     ! compute pressures below datum, if any
   306)     pressure0 = pressure_array(idatum)
   307)     select case(option%iflowmode)
   308)       case(TH_MODE,MPH_MODE,IMS_MODE,FLASH2_MODE,MIS_MODE,G_MODE,TOIL_IMS_MODE)
   309)         temperature = temperature_at_datum
   310)     end select
   311)     dist_z = 0.d0
   312)     rho_zero = density_array(idatum)
   313)     do ipressure=idatum-1,1,-1
   314)       dist_z = dist_z + delta_z
   315)       select case(option%iflowmode)
   316)         case(TH_MODE,MPH_MODE,IMS_MODE,MIS_MODE,FLASH2_MODE,G_MODE, &
   317)           TOIL_IMS_MODE)
   318)           temperature = temperature - temperature_gradient(Z_DIRECTION)*delta_z
   319)       end select
   320)       call EOSWaterDensityExt(temperature,pressure0,aux,rho_kg,dummy,ierr)
   321)       num_iteration = 0
   322)       do                   ! notice the negative sign (-) here
   323)         pressure = pressure0 - 0.5d0*(rho_kg+rho_zero) * &
   324)                    option%gravity(Z_DIRECTION) * delta_z
   325)         call EOSWaterDensityExt(temperature,pressure,aux,rho_one,dummy,ierr)
   326)         if (dabs(rho_kg-rho_one) < 1.d-10) exit
   327)         rho_kg = rho_one
   328)         num_iteration = num_iteration + 1
   329)         if (num_iteration > 100) then
   330)           print *,'Hydrostatic iteration failed to converge',num_iteration,rho_one,rho_kg
   331)           print *, condition%name, idatum
   332)           print *, pressure_array
   333)           stop
   334)         endif
   335)       enddo
   336)       rho_zero = rho_kg
   337)       pressure_array(ipressure) = pressure
   338)       density_array(ipressure) = rho_kg
   339)       z(ipressure) = z(idatum)-dist_z
   340)       pressure0 = pressure
   341)     enddo
   342)   endif
   343) 
   344)   dx_conn = 0.d0
   345)   dy_conn = 0.d0
   346)   dz_conn = 0.d0
   347) 
   348)   num_faces = coupler%connection_set%num_connections
   349) 
   350)   do iconn=1, num_faces !geh: this should really be num_faces!
   351)     local_id = coupler%connection_set%id_dn(iconn)
   352)     ghosted_id = grid%nL2G(local_id)
   353)   
   354)     ! geh: note that this is a boundary connection, thus the entire distance is between
   355)     ! the face and cell center
   356)     if (associated(coupler%connection_set%dist)) then
   357)       dx_conn = coupler%connection_set%dist(0,iconn)*coupler%connection_set%dist(1,iconn)
   358)       dy_conn = coupler%connection_set%dist(0,iconn)*coupler%connection_set%dist(2,iconn)
   359)       dz_conn = coupler%connection_set%dist(0,iconn)*coupler%connection_set%dist(3,iconn)
   360)     endif
   361)     if (associated(datum_dataset)) then
   362)       ! correct datum based on dataset value
   363)       ! if we interpolate in x and y, then we can use grid%x/y - dx/y_conn for x and y
   364)       ! then we set dist_x and dist_y = 0.
   365)       dist_x = 0.d0
   366)       dist_y = 0.d0
   367)       call DatasetGriddedHDF5InterpolateReal(datum_dataset, &
   368)                                           grid%x(ghosted_id)-dx_conn, &
   369)                                           grid%y(ghosted_id)-dy_conn, &
   370)                                           0.d0,temp_real,option)
   371)       ! temp_real is now the real datum
   372)       dist_z = grid%z(ghosted_id)-dz_conn-temp_real
   373)       z_offset = temp_real-datum(Z_DIRECTION)
   374)     else
   375)       ! note the negative (-) d?_conn is required due to the offset of the boundary face
   376)       dist_x = grid%x(ghosted_id)-dx_conn-datum(X_DIRECTION)
   377)       dist_y = grid%y(ghosted_id)-dy_conn-datum(Y_DIRECTION)
   378)       dist_z = grid%z(ghosted_id)-dz_conn-datum(Z_DIRECTION)
   379)       z_offset = 0.d0
   380)     endif
   381) 
   382)     if (associated(pressure_array)) then
   383)       ipressure = idatum+int(dist_z/delta_z)
   384)       dist_z_for_pressure = grid%z(ghosted_id)-dz_conn-(z(ipressure) + z_offset)
   385)       pressure = pressure_array(ipressure) + &
   386)                  density_array(ipressure)*option%gravity(Z_DIRECTION) * &
   387)                  dist_z_for_pressure + &
   388) !                 (grid%z(ghosted_id)-z(ipressure)) + &
   389)                  pressure_gradient(X_DIRECTION)*dist_x + & ! gradient in Pa/m
   390)                  pressure_gradient(Y_DIRECTION)*dist_y
   391)     else
   392)       pressure = pressure_at_datum + &
   393)                  pressure_gradient(X_DIRECTION)*dist_x + & ! gradient in Pa/m
   394)                  pressure_gradient(Y_DIRECTION)*dist_y + &
   395)                  pressure_gradient(Z_DIRECTION)*dist_z 
   396)     endif
   397)    
   398)  
   399)     if (pressure < option%minimum_hydrostatic_pressure) &
   400)       pressure = option%minimum_hydrostatic_pressure
   401) 
   402)     ! assign pressure
   403)     select case(option%iflowmode)
   404)       case(G_MODE)
   405)         coupler%flow_aux_real_var(1,iconn) = pressure
   406)       case (MPH_MODE)
   407)         coupler%flow_aux_real_var(1,iconn) = pressure
   408)       case(TOIL_IMS_MODE)
   409)         coupler%flow_aux_real_var(1,iconn) = pressure
   410)       case default
   411)         if (condition%pressure%itype == SEEPAGE_BC) then
   412)           coupler%flow_aux_real_var(1,iconn) = max(pressure,option%reference_pressure)
   413)         else if (condition%pressure%itype == CONDUCTANCE_BC) then
   414)           coupler%flow_aux_real_var(1,iconn) = max(pressure,option%reference_pressure)
   415)           coupler%flow_aux_real_var(2,iconn) = condition%pressure%aux_real(1)
   416)         else
   417)           coupler%flow_aux_real_var(1,iconn) = pressure
   418)         endif
   419)     end select
   420) 
   421)     ! assign other dofs
   422)     select case(option%iflowmode)
   423)       case(MPH_MODE,IMS_MODE,FLASH2_MODE)
   424)         temperature = temperature_at_datum + &
   425)                     temperature_gradient(X_DIRECTION)*dist_x + & ! gradient in K/m
   426)                     temperature_gradient(Y_DIRECTION)*dist_y + &
   427)                     temperature_gradient(Z_DIRECTION)*dist_z 
   428)         coupler%flow_aux_real_var(2,iconn) = temperature
   429)         coupler%flow_aux_real_var(3,iconn) = concentration_at_datum
   430) 
   431)         coupler%flow_aux_int_var(1,iconn) = condition%iphase
   432) 
   433)       case(TH_MODE)
   434)         temperature = temperature_at_datum + &
   435)                     temperature_gradient(X_DIRECTION)*dist_x + & ! gradient in K/m
   436)                     temperature_gradient(Y_DIRECTION)*dist_y + &
   437)                     temperature_gradient(Z_DIRECTION)*dist_z
   438)         coupler%flow_aux_real_var(TH_TEMPERATURE_DOF,iconn) = temperature
   439)         coupler%flow_aux_int_var(TH_PRESSURE_DOF,iconn) = condition%iphase
   440) 
   441)       case(MIS_MODE)
   442)         temperature = temperature_at_datum + &
   443)                     temperature_gradient(X_DIRECTION)*dist_x + & ! gradient in K/m
   444)                     temperature_gradient(Y_DIRECTION)*dist_y + &
   445)                     temperature_gradient(Z_DIRECTION)*dist_z 
   446) !       coupler%flow_aux_real_var(2,iconn) = temperature
   447)         coupler%flow_aux_real_var(2,iconn) = concentration_at_datum
   448) 
   449)         coupler%flow_aux_int_var(1,iconn) = condition%iphase
   450) 
   451)       case(G_MODE)
   452)         temperature = temperature_at_datum + &
   453)                     temperature_gradient(X_DIRECTION)*dist_x + & ! gradient in K/m
   454)                     temperature_gradient(Y_DIRECTION)*dist_y + &
   455)                     temperature_gradient(Z_DIRECTION)*dist_z 
   456)         coupler%flow_aux_real_var(3,iconn) = &
   457)           temperature
   458)         ! switch to two-phase if liquid pressure drops below gas pressure
   459)         if (pressure < gas_pressure) then
   460)           ! we hijack the air pressure entry, storing capillary pressure there
   461)           coupler%flow_aux_real_var(1,iconn) = gas_pressure
   462)           coupler%flow_aux_real_var(2,iconn) = gas_pressure - pressure
   463)           coupler%flow_aux_int_var(GENERAL_STATE_INDEX,iconn) = TWO_PHASE_STATE
   464)         else
   465)           coupler%flow_aux_real_var(2,iconn) = concentration_at_datum
   466)           coupler%flow_aux_int_var(GENERAL_STATE_INDEX,iconn) = LIQUID_STATE
   467)         endif
   468)       case(TOIL_IMS_MODE)
   469)         temperature = temperature_at_datum + &
   470)                     temperature_gradient(X_DIRECTION)*dist_x + & ! gradient in K/m
   471)                     temperature_gradient(Y_DIRECTION)*dist_y + &
   472)                     temperature_gradient(Z_DIRECTION)*dist_z 
   473)         coupler%flow_aux_real_var(3,iconn) = &
   474)           temperature
   475)       case default
   476)         coupler%flow_aux_int_var(COUPLER_IPHASE_INDEX,iconn) = 1
   477)     end select
   478) 
   479)   enddo
   480) 
   481)   if (associated(pressure_array)) deallocate(pressure_array)
   482)   nullify(pressure_array)
   483)   if (allocated(z)) deallocate(z)
   484)   if (allocated(density_array)) deallocate(density_array)
   485)   !geh: Do not deallocate datum_dataset as it is soleley a pointer to an
   486)   !     external dataset.
   487)   nullify(datum_dataset)
   488) 
   489) end subroutine HydrostaticUpdateCoupler
   490) 
   491) ! ************************************************************************** !
   492) 
   493) subroutine HydrostaticTest()
   494)   ! 
   495)   ! Computes the hydrostatic initial/boundary
   496)   ! condition (more accurately than before0
   497)   ! 
   498)   ! Author: Glenn Hammond
   499)   ! Date: 11/28/07
   500)   ! 
   501) 
   502)   use EOS_Water_module
   503)   
   504)   implicit none
   505)   
   506)   PetscInt :: iz, i, i_increment, num_increment
   507)   PetscInt :: max_num_pressures, i_up, i_dn, num_iteration
   508)   PetscReal :: rho_kg, rho_one, rho_zero, pressure0, pressure, temperature
   509)   PetscReal :: increment(4)
   510)   PetscReal :: xm_nacl, dist_z, dist
   511)   PetscReal :: aux(1)
   512)   PetscReal :: dummy
   513)   PetscErrorCode :: ierr
   514) 
   515)   PetscReal, pointer :: density_array(:,:), pressure_array(:,:)
   516)   
   517)   increment(1) = 1.d-1
   518)   increment(2) = 1.d-0
   519)   increment(3) = 1.d+1
   520)   increment(4) = 1.d+2
   521)   num_increment = size(increment)
   522)   
   523)   temperature = 25.d0
   524) 
   525)   xm_nacl = 0.d0
   526)   aux(1) = xm_nacl
   527)   
   528)   max_num_pressures = int(1000.d0/increment(1)+0.5d0)+1
   529)   
   530)   allocate(density_array(max_num_pressures,num_increment))
   531)   allocate(pressure_array(max_num_pressures,num_increment)) 
   532)   density_array = 0.d0
   533)   pressure_array = 0.d0
   534)   
   535)   do i_increment = 1, num_increment
   536)     pressure = 101325.d0
   537)     call EOSWaterDensityExt(temperature,pressure,aux,rho_kg,dummy,ierr)
   538)     dist_z = 0.d0
   539)     pressure_array(1,i_increment) = pressure
   540)     density_array(1,i_increment) = rho_kg
   541)     do iz=1,int(1000.d0/increment(i_increment)+0.5d0)
   542)       dist_z = dist_z + increment(i_increment)
   543)       pressure0 = pressure
   544)       num_iteration = 0
   545)       do
   546)         pressure = pressure0 + rho_kg * 9.8068d0 * increment(i_increment)
   547)         call EOSWaterDensityExt(temperature,pressure,aux,rho_one,dummy,ierr)
   548)         if (dabs(rho_kg-rho_one) < 1.d-10) exit
   549)         rho_kg = rho_one
   550)         num_iteration = num_iteration + 1
   551)         if (num_iteration > 100) then
   552)           print *,'HydrostaticInitCondition failed to converge',num_iteration,rho_one,rho_kg
   553)           stop
   554)         endif
   555)       enddo
   556)       i = int(dist_z/increment(1)+0.5d0)+1
   557)       pressure_array(i,i_increment) = pressure
   558)       density_array(i,i_increment) = rho_kg
   559)       pressure0 = pressure
   560)       rho_zero = rho_kg  
   561)     enddo
   562)   enddo
   563) 
   564)   do i_increment=2,num_increment
   565)     dist_z = 0.d0
   566)     i = 1
   567)     i_up = 1
   568)     do iz = 1,int(1000.d0/increment(i_increment)+0.5d0)
   569)       i_dn = i_up + int(increment(i_increment)/increment(1)+1.d-6)
   570)       dist = increment(1)
   571)       do 
   572)         i = i + 1
   573)         if (dist >= 0.9999d0*increment(i_increment)) exit
   574)         pressure_array(i,i_increment) = pressure_array(i_up,i_increment)*(1.d0-dist/increment(i_increment))+ &
   575)                                         pressure_array(i_dn,i_increment)*dist/increment(i_increment)
   576)         density_array(i,i_increment) = density_array(i_up,i_increment)*(1.d0-dist/increment(i_increment))+ &
   577)                                         density_array(i_dn,i_increment)*dist/increment(i_increment)
   578)         dist = dist + increment(1)
   579)       enddo
   580)       dist_z = dist_z + increment(i_increment)
   581)       i_up = i_dn
   582)     enddo
   583)   enddo
   584) 
   585)   
   586)   open(unit=86,file='pressures.dat')
   587)   dist_z = 0.d0
   588)   do iz = 1,max_num_pressures
   589)     write(86,'(100(es16.10,x))') dist_z,(density_array(iz,i_increment),i_increment=1,num_increment), &
   590)                        (pressure_array(iz,i_increment),i_increment=1,num_increment)
   591)     dist_z = dist_z + increment(1)
   592)   enddo
   593)   close(86)
   594)   
   595)   deallocate(pressure_array)
   596)   deallocate(density_array)
   597)     
   598) end subroutine HydrostaticTest
   599) 
   600) #if 0
   601) 
   602) ! ************************************************************************** !
   603) 
   604) function ProjectAOntoUnitB(A,B)
   605)   ! 
   606)   ! Projects vector a onto b, assuming b is a unit vector
   607)   ! 
   608)   ! Author: Glenn Hammond
   609)   ! Date: 02/20/09
   610)   ! 
   611) 
   612)   implicit none
   613)   
   614)   PetscReal :: A(3)
   615)   PetscReal :: B(3)
   616)   
   617)   PetscReal :: ProjectAOntoUnitB(3)
   618)   
   619)   ProjectAOntoUnitB = dot_product(A,B)*A
   620)   
   621) end function ProjectAOntoUnitB
   622) #endif
   623) 
   624) end module Hydrostatic_module
   625) 

generated by
Intel(R) C++/Fortran Compiler code-coverage tool
Web-Page Owner: Nobody